NDStein@aol.com wrote:
I'm working on the chip8 emulator for the TI-92/92+/89. It requires a delay
timer that runs at 60 Hz, which I implemented with interrupts. This is my
first time working with interrupts. I looked at other people's code and found
out how it works, so I implemented it in mine, and the delay works correctly.
I remembered to back up all registers used in the interrupt function at the
beginning of the function and restore them at the end. However, it causes
random data to be written to the screen and after a few minutes of sitting
there with the random data being written to the screen (along with the normal
data) it will crash with an address error. I am really lost as to why this is
happening, and as I couldn't find a very good reference on interrupts, I
decided to pose the question here. This is my interrupt handler routine:
DelayRegTimer:
movem d0/a0,-(a7)
lea dtimer(PC),a0
move.w (a0),d0
cmp.w #0,d0
beq AfterDec
sub.w #1,d0
move.w d0,(a0)
AfterDec:
movem (a7)+,d0/a0
rteIt is supposed to decrement dtimer if it's not zero, and leave it alone if it
is, and then return to wherever the program was at before. Can you tell me
why this causes the random data to be written to the screen?
First of all, your movem probably defaults to movem.w (this is very bad...especially in interrupt code!); you're only preserving the lower 16-bits of each register. When you restore registers from the stack (also defaults to movem.w) the 68000 will sign extend the lower 16-bits of A0 and D0 into the upper 16-bits, just as if you had coded "ext A0" and "ext D0" right before your "rte". Now, I know that "ext A0" doesn't exist as an instruction, but I wrote that to illustrate what the 68000 does when moving multiple word values to registers.
Try one of these methods instead --
Non-relocatable (easiest and fastest, but requires physical relocation in order to find "dtimer"):
tst.w dtimer
beq.s AfterDec
subq.w #1,dtimer
AfterDec:
rte
Relocatable (the "proper" method) --
move.l A0,-(A7)
lea.l dtimer(PC),A0
tst.w (A0)
beq.s AfterDec
subq.w #1,(A0)
AfterDec:
movea.l (A7)+,A0
rte
Note that with the relocatable method you must ensure that the object
"dtimer" is within 32K +/- of the "lea" instruction.
Hope that helps...