Re: A92: Strange interrupt behavior


[Prev][Next][Index][Thread]

Re: A92: Strange interrupt behavior



 

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
 rte

It 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...
 


References: