From 2a9ac602d3f879caa1661a8fc7a347ea1132eee9 Mon Sep 17 00:00:00 2001 From: Astrid Smith Date: Sat, 13 Nov 2010 00:26:25 -0800 Subject: First bit of the new interrupts code added --- interrupts.asm | 87 +++++++++++++++++++++++++++------------------------------- 1 file changed, 40 insertions(+), 47 deletions(-) (limited to 'interrupts.asm') diff --git a/interrupts.asm b/interrupts.asm index 9592d0b..cf2b195 100644 --- a/interrupts.asm +++ b/interrupts.asm @@ -4,23 +4,10 @@ ;; this, it can be any of 0, 1, 2. int_mode: dc.b 0 - ;; 0 if interrupts are turned on. - ;; 1 if they are being held. -int_held: dc.b 0 + ;; 0 if the emulated device doesn't want interrupts. + ;; 1 if interrupts are turned on. +int_enabled: dc.b 1 - ;; 0 if no interrupt is pending. - ;; 1 if an interrupt occurred while interrupts were being - ;; held. - ;; 3 (==1|2) if an NMI is pending. -int_waiting: dc.b 0 - - ;; The value of epc as a result of a held interrupt. This is - ;; stored as a derefenced value (pointer into host memory). - - ;; I store it as a native pointer because Z80 interrupts can - ;; be very strange. Interrupt mode 0 in particular requires - ;; a shim. -int_jump: dc.l 0 ;; In interrupt mode 0, an interrupt will force a byte onto ;; the data bus for the processor to execute. To handle @@ -42,37 +29,41 @@ int_opcode: dc.b 0 int_return: dc.w 0 ; the destination address - ;; This is a macro to hold interrupts. - - ;; When interrupts are "disabled" (held), host interrupts will - ;; still fire. The ISR will see that they are held and update - ;; the above fields with the interrupt type and location. - ;; Then the EI macro to enable them will cause it to fire. -HOLD_INTS MACRO - move.b #1,int_held - ENDM - - ;; This is a macro to release a held interrupt. -CONTINUE_INTS MACRO - bsr ints_continue ; 18 cycles - ENDM - -ints_continue: - tst.b int_waiting ; 4 cycles - bne.b ints_continue_pending ; 8 cycles not taken - ;; Common case: no interrupt pending - move.b #0,int_held ; 4 cycles - rts ; 16 cycles - ;; typical case: 4+18+4+8+4+16 = 54 cycles - - ;; I can go faster (24 cycles typical case) by using 68k - ;; hardware interrupt disable/reenable. -ints_continue_pending: - subq.b #3,int_waiting - beq int_do_nmi - move.b int_mode, + ;; This is the interrupt routine. It can come at any point + ;; during an instruction, though routines that use a5 (e.g. by + ;; calling C subroutines) will have to turn off interrupts. + ;; Routines that call into TIOS will have to remove this + ;; interrupt handler. +int_handler: + sub.l #4,a5 + rte +int_nevermind: + rts +do_interrupt: + ;; todo: make this file m4'd + add.l #INT_OFFSET,a5 ; clear the interrupt flag + + tst.b int_enabled ; 4 cycles + beq.b int_nevermind ; 8 cycles not taken + ;; Common case: interrupts enabled, fall through + + ;; Since this is an instruction all its own, we have D0, D1, + ;; and D2 available. + + pop.l a0 + + ;; Interrupts are most often in mode 1, then mode 2, and + ;; almost never in mode 0. + move.b int_mode,d0 + cmpi.b #1,d0 + beq int_do_mode2 + cmpi.b #2,d0 + beq int_do_mode1 + cmpi.b #1,d0 + beq int_do_mode0 + jmp (a0) ;; This routine emulates a mode 0 interrupt. @@ -85,9 +76,11 @@ int_do_mode0: ;; This routine emulates a mode 1 interrupt. - ;; IM 1: RST 38 is executed on every interrupt. + ;; IM 1: RST 38 is executed on every interrupt. This is what + ;; the TI-83+ uses almost all the time. int_do_mode1: - rts + jmp emu_op_ff + ;; This routine emulates a mode 2 interrupt. -- cgit v1.2.3