From 541bce94a4d73e754ce522758dd25ecddb818f04 Mon Sep 17 00:00:00 2001 From: Astrid Smith Date: Fri, 21 Oct 2011 01:07:19 -0700 Subject: First stage of converting to be GAS-compliant I (think I) have converted all the A68k directives to their GAS equivalents. Still remaining are all the inline expressions. --- interrupts.s.m4 | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 interrupts.s.m4 (limited to 'interrupts.s.m4') diff --git a/interrupts.s.m4 b/interrupts.s.m4 new file mode 100644 index 0000000..66b71d8 --- /dev/null +++ b/interrupts.s.m4 @@ -0,0 +1,115 @@ +;;; interrupt handling code, in -*- asm -*- + +.data + ;; Current interrupt mode. IM 1 and friends will modify + ;; this. It can be any of 0, 1, 2. +int_mode: dc.b 0 + + ;; 0 if the emulated device doesn't want interrupts. + ;; 1 if interrupts are turned on. +int_enabled: dc.b 1 + + + ;; In interrupt mode 0, an interrupt will force a byte onto + ;; the data bus for the processor to execute. To handle + ;; those, the emulator will store the bus byte in int_opcode, + ;; which is followed by an absolute jump to the "next + ;; instruction". The value of int_jump will then be + ;; &int_opcode. + ;; + ;; This differs slightly from what I understand to be actual + ;; handling. The hardware will fetch an immediate argument to + ;; the interrupting instruction from the next location in + ;; memory. + ;; + ;; This emulator, on the other hand, will fetch the immediate + ;; argument from the JP instruction in the shim, and then + ;; dance off into la-la land. +int0_opcode: dc.b 0 + dc.b $c3 ; JP immed.w +int0_return: dc.w 0 ; the destination address + + +.text + ;; 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 or hold + ;; interrupts. + ;; + ;; Routines that call into TIOS will have to remove this + ;; interrupt handler. +int_handler: + sub.l #INT_OFFSET,a5 + rte + + +int_nevermind: + rts +do_interrupt: + add.l #INT_OFFSET,a5 ; clear the interrupt flag + pea 0(a5,d0.w) ; allows us to rts properly + + 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. + + ;; 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 + rts + + ;; This routine emulates a mode 0 interrupt. + + ;; IM 0: A byte is placed on the bus and executed as if it + ;; were inline in the program. This emulator will put that + ;; byte into int0_opcode and set epc (or int_jump) to point + ;; there. +int_do_mode0: + move epc,int0_opcode + rts + + ;; This routine emulates a mode 1 interrupt. + + ;; IM 1: RST 38 is executed on every interrupt. This is what + ;; the TI-83+ uses almost all the time. +int_do_mode1: + jmp emu_op_ff + + + ;; This routine emulates a mode 2 interrupt. + + ;; IM 2: Vectored, the address jumped to is as follows: + ;; + ;; (I << 8) | (byte & 0xfe) + ;; + ;; where I is the I register, and byte is the byte that was + ;; found on the bus. +int_do_mode2: + rts + + ;; This routine emulates a non-maskable interrupt. +int_do_nmi: + rts + + + + + ;; This routine is used by the emulated DI instruction, which + ;; turns off emulator interrupts. +ints_stop: + rts + + ;; This routine is used by the emulated EI instruction, which + ;; turns on emulator interrupts. +ints_start: + rts + -- cgit v1.2.3