Don't use the IY register unless you have to. The OS expects it to point to flags (pointer to the system flags) at all time, including during interrupts. That's why you can do things like this without assigning IY beforehand: set textInverse,(IY+textFlags)
If you really need to use IY, you should always disable interrupts first, and when you're done enable interrupts and return IY to its usual place: di
; mess with IY all you want
ld IY,flags
ei
EDIT: I don't think you meant to do djnz -9. The assembler will try to send control to address $FFF7, and since djnz has only a 256-byte relative jump range, that can basically be anywhere in a 256-byte block surrounding the routine depending on where the routine is located.
I think you meant to do djnz double. Same thing with the jr nz stuff. The assembler calculates the appropriate offset for you.
EDIT: DeepThought: For djnz/jr, would a value like -9 really trip it up? I think you might end up jumping to the wrong place because the calculator calculates relative jumps differently from the assembler. Wouldn't the assembler just load $F7 (even if it gets interpreted as $FFF7, the assembler might truncate it down to $F7) after the djnz/jr byte (i don't know what the hex codes are), essentially jumping to $-7 (2 bytes after double, aka the 2nd byte of the "rr l"?
It'll try to subtract the $+2 from $F7 and make the jump to there, since it has to be relative to the byte following the jump instruction.
Basically, it'll jump to the nearest address that ends in $F7.Example: jr $1 would skip one byte. jr $-5 would jump to byte 3 before "jr". jr $-2 would make it stuck in an endless loop.
jr $1 would jump to the nearest address ending in 01h; jr $-5 would jump to five bytes before the start of the jr instruction; and jr $-2 would jump to two bytes before the start of the jr instruction. jr $ would be an endless loop.
I don't think you understand what $ means in this context. Besides signifying that the following number is in hexadecimal, $ on its own also refers to the address of the current instruction.
So if you had a program that started with this:.org $9D95-2
.db $BB,$6D
ld HL, $+2
The value of HL would be 9D97h—since $ at that instruction equals 9D95h and you're adding two to the value. If you had done this instead:.org $9D95-2
.db $BB,$6D
ld HL, $2
The value of HL would simply be 0002h.
The point about this is that any assembler will try to convert an address following a relative jump instruction into the appropriate offset. That's why jp 12345 and jr 12345 do the same thing (assuming the jr is in range). With the first instruction, the assembler will give you C3 39 30 (a straightforward jump to 3039h), whereas with the second instruction, what the assembler assembles depends on the value of $ (where you are in memory). If the jr instruction is placed at address 12350, the next instruction starts at 12352 (since jr is a two-byte instruction), so it needs to create a relative jump seven bytes back. In this case, the instruction would be identical to jr $-5, since it's jumping to $ minus five. What you get is 18 F9 (0F9h being -7 as a signed byte).
So what happens when you try to jr -9? Let's say the instruction starts at 12350 again. The compiler reads -9 as absolute address 0FFF7h, but that's way out of range, since 12350 is only 303Eh. A decent assembler will throw you an error or warning on this, but some assemblers may just truncate and try to jump to there. In that case, it would move you to the only valid address ending in $F7, which in this case is 2FF7h. That's 71 bytes back from the start of the instruction, so the generated hexadecimal is 18 B7 (0B7h being -73 as a signed byte).
Hope that clears some stuff up for you :)