diff options
| author | Duncan Smith | 2010-11-12 21:30:13 -0800 |
|---|---|---|
| committer | Duncan Smith | 2010-11-12 21:30:13 -0800 |
| commit | 2164cc7b99ab44b9efe03d5f4dc2392fc34791f3 (patch) | |
| tree | 160c87551ac0e6232408d8582c95bac04ed18ffe /opcodes.asm.m4 | |
| parent | 27a6de6da13ff3afc1740cf193ed11623a75829d (diff) | |
Reworked opcodes.asm to use m4. Soon, it will be clean.
Diffstat (limited to 'opcodes.asm.m4')
| -rw-r--r-- | opcodes.asm.m4 | 2234 |
1 files changed, 2234 insertions, 0 deletions
diff --git a/opcodes.asm.m4 b/opcodes.asm.m4 new file mode 100644 index 0000000..9f3a3fe --- /dev/null +++ b/opcodes.asm.m4 @@ -0,0 +1,2234 @@ +;;; ======================================================================== +;;; ======================================================================== +;;; ___ ___ ======= ============================== +;;; ___( _ ) / _ \ emulation core ==================================== +;;; |_ / _ \| | | | emulation core =================================== +;;; / ( (_) | |_| | emulation core ================================== +;;; /___\___/ \___/ emulation core ================================= +;;; ======= ============================== +;;; ======================================================================== +;;; ======================================================================== + +;;; http://z80.info/z80oplist.txt + + ;; == Memory Macros ================================================ + + ;; Macro to read a byte from main memory at register \1. Puts + ;; the byte read in \2. +FETCHB MACRO + move.w \1,d1 + bsr deref + move.b (a0),\2 + ENDM + + ;; Macro to write a byte in \1 to main memory at \2 +PUTB MACRO + move.w \2,d1 + bsr deref + move.b \1,(a0) + ENDM + + ;; Macro to read a word from main memory at register \1 + ;; (unaligned). Puts the word read in \2. +FETCHW MACRO ; ?/16 + move.w \1,d1 ; 4/2 + bsr deref ; ?/4 + ;; XXX SPEED + move.b (a0)+,d2 + move.b (a0),\2 + rol.w #8,\2 + move.b d2,\2 + ENDM + + ;; Macro to write a word in \1 to main memory at \2 (regs only) +PUTW MACRO ; + move.w \2,d1 + bsr deref + move.w \1,d0 + move.b d0,(a0)+ + LOHI d0 + move.b d0,(a0) + ENDM + + ;; Push the word in \1 (register) using stack register a4. + ;; Sadly, I can't trust the stack register to be aligned. + ;; Destroys d2. + + ;; (SP-2) <- \1_l + ;; (SP-1) <- \1_h + ;; SP <- SP - 2 +PUSHW MACRO + move.w \1,d2 + LOHI d2 ;slow + move.b d2,-(a4) ; high byte + move.b \1,-(a4) ; low byte + ENDM + + ;; Pop the word at the top of stack a4 into \1. + ;; Destroys d0. + + ;; \1_h <- (SP+1) + ;; \1_l <- (SP) + ;; SP <- SP + 2 +POPW MACRO + move.b (esp)+,\1 + LOHI \1 ;slow + move.b (esp)+,\1 ; high byte + HILO \1 ;slow + ENDM + + ;; == Immediate Memory Macros == + + ;; Macro to read an immediate byte into \1. +FETCHBI MACRO ; 8 cycles, 2 bytes + move.b (epc)+,\1 ; 8/2 + ENDM + + ;; Macro to read an immediate word (unaligned) into \1. +FETCHWI MACRO ; 42 cycles, 8 bytes + ;; XXX SPEED + move.b (epc)+,d2 + move.b (epc)+,\1 + rol.w #8,\1 + move.b d2,\1 + ENDM + + ;; == Common Opcode Macros ========================================= + + ;; To align opcode routines. +_align SET 0 + +START MACRO + ORG emu_plain_op+_align +_align SET _align+$40 + ENDM + + ;; LOHI/HILO are hideously slow for instructions used often. + ;; Interleave registers instead: + ;; + ;; d4 = [B' B C' C] + ;; + ;; Thus access to B is fast (swap d4) while access to BC is + ;; slow. + + ;; When you want to use the high reg of a pair, use this first +LOHI MACRO ; 22 cycles, 2 bytes + ror.w #8,\1 ; 22/2 + ENDM + + ;; Then do your shit and finish with this +HILO MACRO ; 22 cycles, 2 bytes + rol.w #8,\1 + ENDM + + ;; Rearrange a register: ABCD -> ACBD. +WORD MACRO + move.l \1,-(sp) ;12 cycles / 2 bytes + movep.w 0(sp),\1 ;16 cycles / 4 bytes + swap \1 ; 4 cycles / 2 bytes + movep.w 1(sp),\1 ;16 cycles / 4 bytes + addq #4,sp ; 4 cycles / 2 bytes + ;; overhead: 52 cycles /14 bytes + ENDM + + ;; == Special Opcode Macros ======================================== + + ;; Do an ADD \1,\2 +F_ADD_W MACRO + ENDM + ;; Do an SUB \1,\2 +F_SUB_W MACRO + ENDM + + ;; INC and DEC macros +F_INC_B MACRO + move.b #1,f_tmp_byte-flag_storage(a3) + move.b #1,f_tmp_src_b-flag_storage(a3) + move.b \1,f_tmp_dst_b-flag_storage(a3) + addq #1,\1 + moveq #2,d0 + F_CLEAR d0 + F_OVFL + ENDM + +F_DEC_B MACRO + move.b #1,f_tmp_byte-flag_storage(a3) + st f_tmp_src_b-flag_storage(a3) ;; why did I do this? + move.b \1,f_tmp_dst_b-flag_storage(a3) + subq #1,\1 + F_SET #2 + ENDM + +F_INC_W MACRO + addq.w #1,\1 + ENDM + +F_DEC_W MACRO + subq.w #1,\1 + ENDM + + ;; I might be able to unify rotation flags or maybe use a + ;; lookup table + + + ;; This is run at the end of every instruction routine. +done: + clr.w d0 ; 4 cycles / 2 bytes + move.b (epc)+,d0 ; 8 cycles / 2 bytes + move.b d0,$4c00+32*(128/8) + rol.w #6,d0 ;18 cycles / 2 bytes + jmp 0(a5,d0.w) ;14 cycles / 4 bytes + ;; overhead: 42 cycles /10 bytes + + +DONE MACRO + bra done + ENDM + + ;; Timing correction for more precise emulation + ;; + ;; \1 is number of tstates the current instruction should take + ;; \2 is number of cycles taken already +TIME MACRO + ENDM + + CNOP 0,32 + +emu_plain_op: ; Size(bytes) Time(cycles) + ; S0 T0 + ;; NOP +OPCODE(00,`',4) + + ; S12 T36 + ;; LD BC,immed.w + ;; Read a word and put it in BC + ;; No flags +OPCODE(01,` + HOLD_INTS + FETCHWI ebc + CONTINUE_INTS + ') + + ; S4 T14 + ;; LD (BC),A + ;; (BC) <- A + ;; No flags +OPCODE(02,` + PUTB eaf,ebc + ') + + ; S2 T4 + ;; INC BC + ;; BC <- BC+1 + ;; No flags +OPCODE(03,` + F_INC_W ebc + ') + + ;; INC B + ;; B <- B+1 +OPCODE(04,` + LOHI ebc + F_INC_B ebc + HILO ebc + ') + + ;; DEC B + ;; B <- B-1 +OPCODE(05,` + LOHI ebc + F_DEC_B ebc + HILO ebc + ') ;nok + + ; S10 T26 + ;; LD B,immed.b + ;; Read a byte and put it in B + ;; B <- immed.b + ;; No flags +OPCODE(06,` + HOLD_INTS + LOHI ebc + FETCHBI ebc + CONTINUE_INTS + HILO ebc + ') ;nok + + ;; RLCA + ;; Rotate A left, carry bit gets top bit + ;; Flags: H,N=0; C aff. + ;; XXX flags +OPCODE(07,` ; S2 T4 + rol.b #1,eaf + ') ;nok + + ;; EX AF,AF' + ;; No flags + ;; XXX AF +OPCODE(08,` ; S2 T4 + swap eaf + ') ;nok + + ;; ADD HL,BC + ;; HL <- HL+BC + ;; Flags: H, C aff.; N=0 +OPCODE(09,` + F_ADD_W ebc,ehl + ') ;nok + + ; S4 T14 + ;; LD A,(BC) + ;; A <- (BC) + ;; No flags +OPCODE(0a,` + FETCHB ebc,eaf + ') + + ;; DEC BC + ;; BC <- BC-1 + ;; No flags +OPCODE(0b,` ; S2 T4 + F_DEC_W ebc + ') ;nok + + ;; INC C + ;; C <- C+1 + ;; Flags: S,Z,H aff.; P=overflow, N=0 +OPCODE(0c,` + F_INC_B ebc + ') ;nok + + ;; DEC C + ;; C <- C-1 + ;; Flags: S,Z,H aff., P=overflow, N=1 +OPCODE(0d,` + F_DEC_B ebc + ') ;nok + + ; S6 T18 + ;; LD C,immed.b + ;; No flags +OPCODE(0e,` + HOLD_INTS + FETCHBI ebc + CONTINUE_INTS + ') ;nok + + ;; RRCA + ;; Rotate A right, carry bit gets top bit + ;; Flags: H,N=0; C aff. + ;; XXX FLAGS +OPCODE(0f,` + ror.b #1,eaf + ') ;nok + + ; S32 + ;; DJNZ immed.w + ;; Decrement B + ;; and branch by immed.b + ;; if B not zero + ;; No flags +OPCODE(10,` + HOLD_INTS + LOHI ebc + subq.b #1,ebc + beq.s end_10 ; slooooow + FETCHBI d1 + move.l epc,a0 + bsr underef + add.w d1,d0 ; ??? Can I avoid underef/deref cycle? + bsr deref + move.l a0,epc +end_10: + HILO ebc + CONTINUE_INTS + ') ;nok + + ;; LD DE,immed.w + ;; No flags +OPCODE(11,` + HOLD_INTS + FETCHWI ede + CONTINUE_INTS + ') ;nok + + ;; LD (DE),A + ;; No flags +OPCODE(12,` + move.w ede,d0 + rol.w #8,d0 + FETCHB d0,eaf + ') ;nok + + ;; INC DE + ;; No flags +OPCODE(13,` + F_INC_W ede + ') ;nok + + ;; INC D + ;; Flags: S,Z,H aff.; P=overflow, N=0 +OPCODE(14,` + LOHI ede + F_INC_B ede + HILO ede + ') ;nok + + ;; DEC D + ;; Flags: S,Z,H aff.; P=overflow, N=1 +OPCODE(15,` + LOHI ede + F_DEC_B ede + HILO ede + ') ;nok + + ;; LD D,immed.b + ;; No flags +OPCODE(16,` + HOLD_INTS + LOHI ede + FETCHBI ede + CONTINUE_INTS + HILO ede + ') ;nok + + ;; RLA + ;; Flags: P,N=0; C aff. + ;; XXX flags +OPCODE(17,` + roxl.b #1,eaf + ') ;nok + + ;; JR immed.b + ;; PC <- immed.b + ;; Branch relative by a signed immediate byte + ;; No flags +OPCODE(18,` + HOLD_INTS + clr.w d1 + FETCHBI d1 + move.l epc,a0 + bsr underef + add.w d0,d1 ; ??? Can I avoid underef/deref cycle? + bsr deref + move.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; ADD HL,DE + ;; HL <- HL+DE + ;; Flags: H,C aff,; N=0 +OPCODE(19,` + F_ADD_W ede,ehl + ') ;nok + + ;; LD A,(DE) + ;; A <- (DE) + ;; No flags +OPCODE(1a,` + FETCHB ede,eaf + ') ;nok + + ;; DEC DE + ;; No flags +OPCODE(1b,` + subq.w #1,ede + ') ;nok + + ;; INC E + ;; Flags: S,Z,H aff.; P=overflow; N=0 +OPCODE(1c,` + F_INC_B ede + ') ;nok + + ;; DEC E + ;; Flags: S,Z,H aff.; P=overflow, N=1 +OPCODE(1d,` + F_DEC_B ede + ') ;nok + + ;; LD E,immed.b + ;; No flags +OPCODE(1e,` + HOLD_INTS + FETCHBI ede + CONTINUE_INTS + ') ;nok + + ;; RRA + ;; Flags: H,N=0; C aff. + ;; XXX FLAGS +OPCODE(1f,` + roxr.b #1,eaf + ') ;nok + + ;; JR NZ,immed.b + ;; if ~Z, + ;; PC <- PC+immed.b + ;; No flags +OPCODE(20,` + HOLD_INTS + bsr f_norm_z + ;; if the emulated Z flag is set, this will be clear + beq emu_op_18 ; branch taken: Z reset -> eq (zero set) + add.l #1,epc ; skip over the immediate byte + CONTINUE_INTS + ') + + ;; LD HL,immed.w + ;; No flags +OPCODE(21,` + HOLD_INTS + FETCHWI ehl + CONTINUE_INTS + ') ;nok + + ;; LD immed.w,HL + ;; (address) <- HL + ;; No flags +OPCODE(22,` + HOLD_INTS + FETCHWI d1 + CONTINUE_INTS + PUTW ehl,d1 + ') ;nok + + ;; INC HL + ;; No flags +OPCODE(23,` + addq.w #1,ehl + ') ;nok + + ;; INC H + ;; Flags: S,Z,H aff.; P=overflow, N=0 +OPCODE(24,` + LOHI ehl + F_INC_B ehl + HILO ehl + ') ;nok + + ;; DEC H + ;; Flags: S,Z,H aff.; P=overflow, N=1 +OPCODE(25,` + LOHI ehl + F_DEC_B ehl + HILO ehl + ') ;nok + + ;; LD H,immed.b + ;; No flags +OPCODE(26,` + HOLD_INTS + LOHI ehl + FETCHBI ehl + CONTINUE_INTS + HILO ehl + ') ;nok + + ;; DAA + ;; Decrement, adjust accum + ;; http://www.z80.info/z80syntx.htm#DAA + ;; Flags: oh lord they're fucked up + ;; XXX DO THIS +OPCODE(27,` + + F_PAR eaf + ') ;nok + + ;; JR Z,immed.b + ;; If zero + ;; PC <- PC+immed.b + ;; SPEED can be made faster + ;; No flags +OPCODE(28,` + HOLD_INTS + bsr f_norm_z + bne emu_op_18 + add.l #1,epc + CONTINUE_INTS + ') ;nok + + ;; ADD HL,HL + ;; No flags +OPCODE(29,` + F_ADD_W ehl,ehl + ') ;nok + + ;; LD HL,(immed.w) + ;; address is absolute +OPCODE(2a,` + HOLD_INTS + FETCHWI d1 + CONTINUE_INTS + FETCHW d1,ehl + ') ;nok + + ;; XXX TOO LONG + + ;; DEC HL +OPCODE(2b,` + F_DEC_W ehl + ') ;nok + + ;; INC L +OPCODE(2c,` + F_INC_B ehl + ') ;nok + + ;; DEC L +OPCODE(2d,` + F_DEC_B ehl + ') ;nok + + ;; LD L,immed.b +OPCODE(2e,` + HOLD_INTS + FETCHBI ehl + CONTINUE_INTS + ') ;nok + + ;; CPL + ;; A <- NOT A + ;; XXX flags +OPCODE(2f,` + not.b eaf + ') ;nok + + ;; JR NC,immed.b + ;; If carry clear + ;; PC <- PC+immed.b +OPCODE(30,` + bsr f_norm_c + beq emu_op_18 ; branch taken: carry clear + add.l #1,epc + ') + + ;; LD SP,immed.w +OPCODE(31,` + HOLD_INTS + FETCHWI d1 + bsr deref + movea.l a0,esp + CONTINUE_INTS + ') ;nok + + ;; LD (immed.w),A + ;; store indirect +OPCODE(32,` + HOLD_INTS + FETCHWI d1 + CONTINUE_INTS + rol.w #8,d1 + PUTB eaf,d1 + ') ;nok + + ;; INC SP + ;; No flags + ;; + ;; FYI: Do not have to deref because this will never cross a + ;; page boundary. So sayeth BrandonW. +OPCODE(33,` + HOLD_INTS + addq.w #1,esp + CONTINUE_INTS + ') ;nok + + ;; INC (HL) + ;; Increment byte + ;; SPEED can be made faster +OPCODE(34,` + FETCHB ehl,d1 + F_INC_B d1 + PUTB d1,ehl + ') ;nok + + ;; DEC (HL) + ;; Decrement byte + ;; SPEED can be made faster +OPCODE(35,` + FETCHB ehl,d1 + F_DEC_B d1 + PUTB d1,ehl + ') ;nok + + ;; LD (HL),immed.b +OPCODE(36,` + HOLD_INTS + FETCHBI d1 + CONTINUE_INTS + PUTB ehl,d1 + ') ;nok + + ;; SCF + ;; Set Carry Flag + ;; XXX flags are more complicated than this :( +OPCODE(37,` + ori.b #%00111011,flag_valid-flag_storage(a3) + move.b eaf,d1 + ori.b #%00000001,d1 + andi.b #%11101101,d1 + or.b d1,flag_byte-flag_storage(a3) + ') ;nok + + ;; JR C,immed.b + ;; If carry set + ;; PC <- PC+immed.b +OPCODE(38,` + HOLD_INTS + bsr f_norm_c + bne emu_op_18 + add.l #1,epc + CONTINUE_INTS + ') + + ;; ADD HL,SP + ;; HL <- HL+SP +OPCODE(39,` + HOLD_INTS + move.l esp,a0 + bsr underef + F_ADD_W ehl,d0 ; ??? Can I avoid underef/deref cycle? + bsr deref + move.l a0,esp + CONTINUE_INTS + ') ;nok + + ;; LD A,(immed.w) +OPCODE(3a,` + HOLD_INTS + FETCHWI d1 + CONTINUE_INTS + FETCHB d1,eaf + ') ;nok + + ;; DEC SP + ;; No flags +OPCODE(3b,` + subq.l #1,esp + ') ;nok + + ;; INC A +OPCODE(3c,` + F_INC_B eaf + ') + + ;; DEC A +OPCODE(3d,` + F_DEC_B eaf + ') ;nok + + ;; LD A,immed.b +OPCODE(3e,` + HOLD_INTS + FETCHBI eaf + CONTINUE_INTS + ') + + ;; CCF + ;; Clear carry flag + ;; XXX fuck flags +OPCODE(3f,` + bsr flags_normalize + ;; SZ5H3PNC + ori.b #%00000001,flag_valid-flag_storage(a3) + andi.b #%11111110,flag_byte-flag_storage(a3) + ') ;nok + + ;; LD B,B + ;; SPEED +OPCODE(40,` + LOHI ebc + move.b ebc,ebc + HILO ebc + ') ;nok + + ;; LD B,C +OPCODE(41,` + move.w ebc,d1 + LOHI d1 + move.b d1,ebc + ') ;nok + + ;; LD B,D + ;; B <- D + ;; SPEED +OPCODE(42,` + LOHI ebc + LOHI ede + move.b ede,ebc + HILO ebc + HILO ede + ') ;nok + + ;; LD B,E + ;; B <- E +OPCODE(43,` + LOHI ebc + move.b ebc,ede ; 4 + HILO ebc + ') ;nok + + ;; LD B,H + ;; B <- H + ;; SPEED +OPCODE(44,` + LOHI ebc + LOHI ehl + move.b ehl,ebc + HILO ebc + HILO ehl + ') ;nok + + ;; LD B,L + ;; B <- L +OPCODE(45,` + LOHI ebc + move.b ehl,ebc + HILO ebc + ') ;nok + + ;; LD B,(HL) + ;; B <- (HL) +OPCODE(46,` + LOHI ebc + FETCHB ehl,ebc + HILO ebc + ') ;nok + + ;; LD B,A + ;; B <- A +OPCODE(47,` + LOHI ebc + move.b eaf,ebc + HILO ebc + ') ;nok + + ;; LD C,B + ;; C <- B +OPCODE(48,` + move.w ebc,-(sp) + move.b (sp),ebc + ;; XXX emfasten? + addq.l #2,sp + ') ;nok + ;14 cycles + ;; LD C,C +OPCODE(49,` + move.b ebc,ebc + ') ;nok + + ;; LD C,D +OPCODE(4a,` + move.w ede,-(sp) + move.b (sp),ebc + ;; XXX emfasten? + addq.l #2,sp + ') ;nok + + ;; LD C,E +OPCODE(4b,` + move.b ebc,ede + ') ;nok + + ;; LD C,H +OPCODE(4c,` + LOHI ehl + move.b ebc,ehl + HILO ehl + ') ;nok + + ;; LD C,L +OPCODE(4d,` + move.b ebc,ehl + ') ;nok + + ;; LD C,(HL) + ;; C <- (HL) +OPCODE(4e,` + FETCHB ehl,ebc + ') ;nok + + ;; LD C,A +OPCODE(4f,` + move.b eaf,ebc + ') ;nok + +; faster (slightly bigger) if we abuse sp again, something along the lines of (UNTESTED) +; move.w ebc,-(sp) ; 8, 2 +; move.w ede,-(sp) ; 8, 2 +; move.b 2(sp),(sp) ; 16, 4 +; move.w (sp)+,ede ; 8, 2 +; addq.l #2,sp ; 8, 2 + ;; LD D,B +OPCODE(50,` + LOHI ebc + LOHI ede + move.b ebc,ede + HILO ebc + HILO ede + ') ;nok + + ;; LD D,C +OPCODE(51,` + LOHI ede + move.b ebc,ede + HILO ede + ') ;nok + + ;; LD D,D +OPCODE(52,` + ') ;nok + + ;; LD D,E +OPCODE(53,` + andi.w #$00ff,ede + move.b ede,d1 + lsl #8,d1 + or.w d1,ede + ') ;nok + + ;; LD D,H +OPCODE(54,` + LOHI ede ; 4 + LOHI ehl ; 4 + move.b ehl,ede ; 4 + HILO ede ; 4 + HILO ehl ; 4 + ') ;nok + ;20 cycles + + ;; LD D,L +OPCODE(55,` + LOHI ede + move.b ehl,ede + HILO ede + ') ;nok + + ;; LD D,(HL) + ;; D <- (HL) +OPCODE(56,` + LOHI ede + FETCHB ehl,ede + HILO ede + ') ;nok + + ;; LD D,A +OPCODE(57,` + LOHI ede + move.b eaf,ede + HILO ede + ') ;nok + + ;; LD E,B +OPCODE(58,` + LOHI ebc + move.b ebc,ede + HILO ebc + ') ;nok + + ;; LD E,C +OPCODE(59,` + move.b ebc,ede + ') ;nok + + ;; LD E,D +OPCODE(5a,` + andi.w #$ff00,ede ; 8/4 + move.b ede,d1 ; 4/2 + lsr.w #8,d1 ;22/2 + or.w d1,ede ; 4/2 + ') ;nok + ;38/2 + + ;; LD E,E +OPCODE(5b,` + move.b ede,ede + ') ;nok + + ;; LD E,H +OPCODE(5c,` + LOHI ehl + move.b ede,ehl + HILO ehl + ') ;nok + + ;; LD E,L +OPCODE(5d,` + move.b ede,ehl + ') ;nok + + ;; LD E,(HL) +OPCODE(5e,` + FETCHB ehl,d1 + ') ;nok + + ;; LD E,A +OPCODE(5f,` + move.b ede,eaf + ') ;nok + + ;; LD H,B +OPCODE(60,` + LOHI ebc + LOHI ehl + move.b ehl,ebc + HILO ebc + HILO ehl + ') ;nok + + ;; LD H,C +OPCODE(61,` + LOHI ehl + move.b ebc,ehl + HILO ehl + ') ;nok + + ;; LD H,D +OPCODE(62,` + LOHI ede + LOHI ehl + move.b ede,ehl + HILO ede + HILO ehl + ') ;nok + + ;; LD H,E +OPCODE(63,` + LOHI ehl + move.b ede,ehl + HILO ehl + ') ;nok + + ;; LD H,H +OPCODE(64,` + LOHI ehl + move.b ehl,ehl + HILO ehl + ') ;nok + + ;; LD H,L + ;; H <- L +OPCODE(65,` + move.b ehl,d1 + LOHI ehl + move.b d1,ehl + HILO ehl + ') ;nok + + ;; LD H,(HL) +OPCODE(66,` + FETCHB ehl,d1 + LOHI ehl + move.b d1,ehl + HILO ehl + ') ;nok + + ;; LD H,A +OPCODE(67,` + LOHI ehl + move.b eaf,ehl + HILO ehl + ') ;nok + + ;; LD L,B +OPCODE(68,` + LOHI ebc + move.b ebc,ehl + HILO ebc + ') ;nok + + ;; LD L,C +OPCODE(69,` + move.b ebc,ehl + ') ;nok + + ;; LD L,D +OPCODE(6a,` + LOHI ede + move.b ede,ehl + HILO ede + ') ;nok + + ;; LD L,E +OPCODE(6b,` + move.b ede,ehl + ') ;nok + + ;; LD L,H +OPCODE(6c,` + move.b ehl,d1 + LOHI d1 + move.b d1,ehl + ') ;nok + + ;; LD L,L +OPCODE(6d,` + move.b ehl,ehl + ') ;nok + + ;; LD L,(HL) + ;; L <- (HL) +OPCODE(6e,` + FETCHB ehl,ehl + ') ;nok + + ;; LD L,A +OPCODE(6f,` + move.b eaf,ehl + ') ;nok + + ;; LD (HL),B +OPCODE(70,` + LOHI ebc + PUTB ehl,ebc + HILO ebc + ') ;nok + + ;; LD (HL),C +OPCODE(71,` + PUTB ehl,ebc + ') ;nok + + ;; LD (HL),D +OPCODE(72,` + LOHI ede + PUTB ehl,ede + HILO ede + ') ;nok + + ;; LD (HL),E +OPCODE(73,` + PUTB ehl,ede + ') ;nok + + ;; LD (HL),H +OPCODE(74,` + move.w ehl,d1 + HILO d1 + PUTB d1,ehl + ') ;nok + + ;; LD (HL),L +OPCODE(75,` + move.b ehl,d1 + PUTB d1,ehl + ') ;nok + + ;; HALT + ;; XXX do this +OPCODE(76,` + bra emu_op_76 + ') ;nok + + ;; LD (HL),A +OPCODE(77,` + PUTB eaf,ehl + ') ;nok + + ;; LD A,B +OPCODE(78,` + move.w ebc,d1 + LOHI d1 + move.b d1,eaf + ') ;nok + + ;; LD A,C +OPCODE(79,` + move.b ebc,eaf + ') ;nok + + ;; LD A,D +OPCODE(7a,` + move.w ede,d1 + LOHI d1 + move.b d1,eaf + ') ;nok + + ;; LD A,E +OPCODE(7b,` + move.b ede,eaf + ') ;nok + + ;; LD A,H +OPCODE(7c,` + move.w ehl,d1 + LOHI d1 + move.b d1,eaf + ') ;nok + + ;; LD A,L +OPCODE(7d,` + move.b ehl,eaf + ') ;nok + + ;; LD A,(HL) + ;; A <- (HL) +OPCODE(7e,` + FETCHB ehl,eaf + ') ;nok + + ;; LD A,A +OPCODE(7f,` + ') ;nok + + + + ;; Do an ADD \2,\1 +F_ADD_B MACRO ; 14 bytes? + move.b \2,d1 + move.b \1,d0 + bsr alu_add + move.b d1,\2 + ENDM + + ;; ADD A,B +OPCODE(80,` + LOHI ebc + F_ADD_B ebc,eaf + HILO ebc + ') ;nok + + ;; ADD A,C +OPCODE(81,` + F_ADD_B ebc,eaf + ') ;nok + + ;; ADD A,D +OPCODE(82,` + LOHI ede + F_ADD_B ede,eaf + HILO ede + ') ;nok + + ;; ADD A,E +OPCODE(83,` + F_ADD_B ede,eaf + ') ;nok + + ;; ADD A,H +OPCODE(84,` + LOHI ehl + F_ADD_B ehl,eaf + HILO ehl + ') ;nok + + ;; ADD A,L +OPCODE(85,` + F_ADD_B ehl,eaf + ') ;nok + + ;; ADD A,(HL) + ;; XXX size? +OPCODE(86,` + FETCHB ehl,d2 + F_ADD_B d2,eaf + PUTB d2,ehl + ') ;nok + + ;; ADD A,A +OPCODE(87,` + F_ADD_B eaf,eaf + ') ;nok + + + + ;; Do an ADC \2,\1 +F_ADC_B MACRO ; S34 + move.b \2,d1 + move.b \1,d0 + bsr alu_adc + move.b d1,\2 + ENDM + + ;; ADC A,B + ;; A <- A + B + (carry) +OPCODE(88,` + LOHI ebc + F_ADC_B ebc,eaf + HILO ebc + ') ;nok + + ;; ADC A,C + ;; A <- A + C + (carry) +OPCODE(89,` + F_ADC_B ebc,eaf + ') ;nok + + ;; ADC A,D +OPCODE(8a,` + LOHI ede + F_ADC_B ede,eaf + HILO ede + ') ;nok + + ;; ADC A,E + ;; A <- A + E + carry +OPCODE(8b,` + F_ADC_B ede,eaf + ') ;nok + + ;; ADC A,H +OPCODE(8c,` + LOHI eaf + F_ADC_B ehl,eaf + HILO eaf + ') ;nok + + ;; ADC A,L +OPCODE(8d,` + F_ADC_B ehl,eaf + ') ;nok + + ;; ADC A,(HL) +OPCODE(8e,` + FETCHB ehl,d2 + F_ADC_B d2,eaf + PUTB d2,ehl + ') ;nok + + ;; ADC A,A +OPCODE(8f,` + F_ADC_B eaf,eaf + ') ;nok + + + + + + ;; Do a SUB \2,\1 +F_SUB_B MACRO + move.b \2,d1 + move.b \1,d0 + bsr alu_sub + move.b d1,\2 + ENDM + + ;; SUB A,B +OPCODE(90,` + LOHI ebc + F_SUB_B ebc,eaf + HILO ebc + ') ;nok + + ;; SUB A,C +OPCODE(91,` + F_SUB_B ebc,eaf + ') ;nok + + ;; SUB A,D +OPCODE(92,` + LOHI ede + F_SUB_B ede,eaf + HILO ede + ') ;nok + + ;; SUB A,E +OPCODE(93,` + F_SUB_B ede,eaf + ') ;nok + + ;; SUB A,H +OPCODE(94,` + LOHI ehl + F_SUB_B ehl,eaf + HILO ehl + ') ;nok + + ;; SUB A,L +OPCODE(95,` + F_SUB_B ehl,eaf + ') + + ;; SUB A,(HL) +OPCODE(96,` + FETCHB ehl,d2 + F_SUB_B d2,eaf + PUTB d2,ehl + ') ;nok + + ;; SUB A,A +OPCODE(97,` + F_SUB_B eaf,eaf + ') ;nok + + + + + ;; Do a SBC \2,\1 +F_SBC_B MACRO + move.b \2,d1 + move.b \1,d0 + bsr alu_sbc + move.b d1,\2 + ENDM + + ;; SBC A,B +OPCODE(98,` + LOHI ebc + F_SBC_B ebc,eaf + HILO ebc + ') ;nok + + ;; SBC A,C +OPCODE(99,` + F_SBC_B ebc,eaf + ') ;nok + + ;; SBC A,D +OPCODE(9a,` + LOHI ede + F_SBC_B ede,eaf + HILO ede + ') ;nok + + ;; SBC A,E +OPCODE(9b,` + F_SBC_B ede,eaf + ') ;nok + + ;; SBC A,H +OPCODE(9c,` + LOHI ehl + F_SBC_B ehl,eaf + HILO ehl + ') ;nok + + ;; SBC A,L +OPCODE(9d,` + F_SBC_B ehl,eaf + ') ;nok + + ;; SBC A,(HL) +OPCODE(9e,` + FETCHB ehl,d2 + F_SBC_B d2,eaf + PUTB d2,ehl + ') ;nok + + ;; SBC A,A +OPCODE(9f,` + F_SBC_B eaf,eaf + ') ;nok + + + + + +F_AND_B MACRO + move.b \2,d1 + move.b \1,d0 + bsr alu_and + move.b d1,\2 + ENDM + + ;; AND B +OPCODE(a0,` + LOHI ebc + F_AND_B ebc,eaf + HILO ebc + ') ;nok + + ;; AND C +OPCODE(a1,` + F_AND_B ebc,eaf + ') + + ;; AND D +OPCODE(a2,` + LOHI ede + F_AND_B ede,eaf + HILO ede + ') ;nok + + ;; AND E +OPCODE(a3,` + F_AND_B ede,eaf + ') ;nok + + ;; AND H +OPCODE(a4,` + LOHI ehl + F_AND_B ehl,eaf + HILO ehl + ') ;nok + + ;; AND L +OPCODE(a5,` + F_AND_B ehl,eaf + ') ;nok + + ;; AND (HL) +OPCODE(a6,` + FETCHB ehl,d2 + F_AND_B d2,eaf + PUTB d2,ehl + ') ;nok + + ;; AND A + ;; SPEED ... It's probably not necessary to run this faster. +OPCODE(a7,` + F_AND_B eaf,eaf + ') ;nok + + + + + +F_XOR_B MACRO + move.b \2,d1 + move.b \1,d0 + bsr alu_xor + move.b d1,\2 + ENDM + + ;; XOR B +OPCODE(a8,` + LOHI ebc + F_XOR_B ebc,eaf + HILO ebc + ') ;nok + + ;; XOR C +OPCODE(a9,` + F_XOR_B ebc,eaf + ') ;nok + + ;; XOR D +OPCODE(aa,` + LOHI ede + F_XOR_B ede,eaf + HILO ede + ') ;nok + + ;; XOR E +OPCODE(ab,` + F_XOR_B ede,eaf + ') ;nok + + ;; XOR H +OPCODE(ac,` + LOHI ehl + F_XOR_B ehl,eaf + HILO ehl + ') ;nok + + ;; XOR L +OPCODE(ad,` + F_XOR_B ehl,eaf + ') ;nok + + ;; XOR (HL) +OPCODE(ae,` + FETCHB ehl,d2 + F_XOR_B d2,eaf + PUTB d2,ehl + ') ;nok + + ;; XOR A +OPCODE(af,` + F_XOR_B eaf,eaf + ;; XXX + ') ;nok + + + + + +F_OR_B MACRO + move.b \2,d1 + move.b \1,d0 + bsr alu_or + move.b d1,\2 + ENDM + + ;; OR B +OPCODE(b0,` + LOHI ebc + F_OR_B ebc,eaf + HILO ebc + ') ;nok + + ;; OR C +OPCODE(b1,` + F_OR_B ebc,eaf + ') ;nok + + ;; OR D +OPCODE(b2,` + LOHI ede + F_OR_B ede,eaf + HILO ede + ') ;nok + + ;; OR E +OPCODE(b3,` + F_OR_B ede,eaf + ') ;nok + + ;; OR H +OPCODE(b4,` + LOHI ehl + F_OR_B ehl,eaf + HILO ehl + ') ;nok + + ;; OR L +OPCODE(b5,` + F_OR_B ehl,eaf + ') ;nok + + ;; OR (HL) +OPCODE(b6,` + FETCHB ehl,d2 + F_OR_B d2,eaf + PUTB d2,ehl + ') ;nok + +OPCODE(b7,` + ;; OR A + F_OR_B eaf,eaf + ') ;nok + + + + + + ;; COMPARE instruction +F_CP_B MACRO + ;; XXX deal with \2 or \1 being d1 or d0 + move.b \2,d1 + move.b \1,d0 + bsr alu_cp + ;; no result to save + ENDM + + ;; CP B +OPCODE(b8,` + move.w ebc,d2 + LOHI d2 + F_CP_B d2,eaf + ') ;nok + + ;; CP C +OPCODE(b9,` + F_CP_B ebc,eaf + ') ;nok + + ;; CP D +OPCODE(ba,` + move.w ede,d2 + LOHI d2 + F_CP_B d2,eaf + ') ;nok + + ;; CP E +OPCODE(bb,` + F_CP_B ede,eaf + ') ;nok + + ;; CP H +OPCODE(bc,` + move.w ehl,d2 + LOHI d2 + F_CP_B d2,eaf + ') ;nok + + ;; CP L +OPCODE(bd,` + F_CP_B ehl,eaf + ') ;nok + + ;; CP (HL) +OPCODE(be,` + FETCHB ehl,d2 + F_CP_B d2,eaf + ;; no result to store + ') ;nok + + ;; CP A +OPCODE(bf,` + F_CP_B eaf,eaf + ') + + ;; RET NZ + ;; if ~Z + ;; PCl <- (SP) + ;; PCh <- (SP+1) + ;; SP <- (SP+2) +OPCODE(c0,` + HOLD_INTS + bsr f_norm_z + ;; SPEED inline RET + beq emu_op_c9 ; RET + CONTINUE_INTS + ') ;nok + + ;; POP BC + ;; Pops a word into BC +OPCODE(c1,` ; S10 T + HOLD_INTS + POPW ebc + CONTINUE_INTS + ') ;nok + + ;; JP NZ,immed.w + ;; if ~Z + ;; PC <- immed.w +OPCODE(c2,` + HOLD_INTS + bsr f_norm_z + bne.s emu_op_c3 + add.l #2,epc + CONTINUE_INTS + ') ;nok + + ; S12 T36 + ;; JP immed.w + ;; PC <- immed.w +OPCODE(c3,` + HOLD_INTS + FETCHWI d1 + bsr deref + movea.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; CALL NZ,immed.w + ;; If ~Z, CALL immed.w +OPCODE(c4,` + HOLD_INTS + bsr f_norm_z + ;; CALL (emu_op_cd) will run HOLD_INTS again. This doesn't + ;; matter with the current implementation because HOLD_INTS + ;; simply sets a bit. + bne emu_op_cd + add.l #2,epc + CONTINUE_INTS + ') ;nok + + ;; PUSH BC +OPCODE(c5,` + HOLD_INTS + PUSHW ebc + CONTINUE_INTS + ') ;nok + + ;; ADD A,immed.b +OPCODE(c6,` + HOLD_INTS + FETCHBI d1 + CONTINUE_INTS + F_ADD_B d1,eaf + ') ;nok + + ;; RST &0 + ;; == CALL 0 + ;; XXX check +OPCODE(c7,` + HOLD_INTS + move.l epc,a0 + bsr underef + PUSHW d0 + move.w #$00,d0 + bsr deref + move.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; RET Z +OPCODE(c8,` + HOLD_INTS + bsr f_norm_z + beq.s emu_op_c9 + CONTINUE_INTS + ') ;nok + + ;; RET + ;; PCl <- (SP) + ;; PCh <- (SP+1) POPW + ;; SP <- (SP+2) +OPCODE(c9,` + HOLD_INTS + POPW d1 + bsr deref + movea.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; JP Z,immed.w + ;; If Z, jump +OPCODE(ca,` + HOLD_INTS + bsr f_norm_z + beq emu_op_c3 + add.l #2,epc + CONTINUE_INTS + ') ;nok + +OPCODE(cb,` ; prefix + movea.w emu_op_undo_cb(pc),a2 + ') + ;; nok + + ;; CALL Z,immed.w +OPCODE(cc,` + HOLD_INTS + bsr f_norm_z + beq.s emu_op_cd + add.l #2,epc + CONTINUE_INTS + ') ;nok + + ;; CALL immed.w + ;; (Like JSR on 68k) + ;; (SP-1) <- PCh + ;; (SP-2) <- PCl + ;; SP <- SP - 2 + ;; PC <- address +OPCODE(cd,` + HOLD_INTS ; released in JP routine + move.l epc,a0 + bsr underef ; d0 has PC + add.w #2,d0 + PUSHW d0 + bra emu_op_c3 ; JP + ') + + ;; ADC A,immed.b +OPCODE(ce,` + HOLD_INTS + FETCHWI d1 + CONTINUE_INTS + F_ADC_B d1,eaf + ') ;nok + + ;; RST &08 + ;; == CALL 8 +OPCODE(cf,` + HOLD_INTS + move.l epc,a0 + bsr underef ; d0 has PC + PUSHW d0 + move.w #$08,d0 + bsr deref + move.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; RET NC +OPCODE(d0,` + HOLD_INTS + bsr f_norm_c + beq emu_op_c9 + CONTINUE_INTS + ') ;nok + + ;; POP DE +OPCODE(d1,` + HOLD_INTS + POPW ede + CONTINUE_INTS + ') ;nok + + ;; JP NC,immed.w +OPCODE(d2,` + HOLD_INTS + bsr f_norm_c + beq emu_op_c3 + add.l #2,epc + CONTINUE_INTS + ') + + ;; OUT immed.b,A +OPCODE(d3,` + HOLD_INTS + move.b eaf,d1 + FETCHBI d0 + bsr port_out + CONTINUE_INTS + ') ;nok + + ;; CALL NC,immed.w +OPCODE(d4,` + HOLD_INTS + bsr f_norm_c + beq emu_op_cd + add.l #2,epc + CONTINUE_INTS + ') ;nok + + ;; PUSH DE +OPCODE(d5,` + HOLD_INTS + PUSHW ede + CONTINUE_INTS + ') ;nok + + ;; SUB A,immed.b +OPCODE(d6,` + HOLD_INTS + FETCHBI d1 + CONTINUE_INTS + F_SUB_B eaf,d1 + ') ;nok + + ;; RST &10 + ;; == CALL 10 +OPCODE(d7,` + HOLD_INTS + move.l epc,a0 + bsr underef + PUSHW d0 + move.w #$10,d0 + bsr deref + move.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; RET C +OPCODE(d8,` + HOLD_INTS + bsr f_norm_c + bne emu_op_c9 + CONTINUE_INTS + ') ;nok + + ;; EXX +OPCODE(d9,` + swap ebc + swap ede + swap ehl + ') ;nok + + ;; JP C,immed.w +OPCODE(da,` + HOLD_INTS + bsr f_norm_c + bne emu_op_c3 + CONTINUE_INTS + ') ;nok + +OPCODE(db,` + ;; IN A,immed.b + HOLD_INTS + move.b eaf,d1 + FETCHBI d0 + CONTINUE_INTS + bsr port_in + ') ;nok + + ;; CALL C,immed.w +OPCODE(dc,` + HOLD_INTS + bsr f_norm_c + bne emu_op_cd + add.l #2,epc + CONTINUE_INTS + ') ;nok + +OPCODE(dd,` ; prefix + movea.w emu_op_undo_dd(pc),a2 + ') + + ;; SBC A,immed.b +OPCODE(de,` + HOLD_INTS + FETCHWI d1 + CONTINUE_INTS + F_SBC_B d1,eaf + ') ;nok + + ;; RST &18 + ;; == CALL 18 +OPCODE(df,` + HOLD_INTS + move.l epc,a0 + bsr underef + PUSHW d0 + move.w #$18,d0 + bsr deref + move.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; RET PO + ;; If parity odd (P zero), return +OPCODE(e0,` + HOLD_INTS + bsr f_norm_pv + beq emu_op_c9 + CONTINUE_INTS + ') ;nok + + ;; POP HL +OPCODE(e1,` + POPW ehl + ') ;nok + + ;; JP PO,immed.w +OPCODE(e2,` + HOLD_INTS + bsr f_norm_pv + beq emu_op_c3 + add.l #2,epc + CONTINUE_INTS + ') ;nok + + ;; EX (SP),HL + ;; Exchange +OPCODE(e3,` + HOLD_INTS + POPW d1 + PUSHW ehl + CONTINUE_INTS + move.w d1,ehl + ') ;nok + + ;; CALL PO,immed.w + ;; if parity odd (P=0), call +OPCODE(e4,` + HOLD_INTS + bsr f_norm_pv + beq emu_op_cd + add.l #2,epc + CONTINUE_INTS + ') ;nok + + ;; PUSH HL +OPCODE(e5,` + HOLD_INTS + PUSHW ehl + CONTINUE_INTS + ') ;nok + + ;; AND immed.b +OPCODE(e6,` + HOLD_INTS + FETCHBI d1 + CONTINUE_INTS + F_AND_B d1,eaf + ') ;nok + + ;; RST &20 + ;; == CALL 20 +OPCODE(e7,` + HOLD_INTS + move.l epc,a0 + bsr underef + PUSHW d0 + move.w #$20,d0 + bsr deref + move.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; RET PE + ;; If parity odd (P zero), return +OPCODE(e8,` + HOLD_INTS + bsr f_norm_pv + bne emu_op_c9 + CONTINUE_INTS + ') ;nok + + ;; JP (HL) +OPCODE(e9,` + HOLD_INTS + FETCHB ehl,d1 + bsr deref + movea.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; JP PE,immed.w +OPCODE(ea,` + HOLD_INTS + bsr f_norm_pv + bne emu_op_c3 + add.l #2,epc + CONTINUE_INTS + ') ;nok + + ;; EX DE,HL +OPCODE(eb,` + exg.w ede,ehl + ') ;nok + + ;; CALL PE,immed.w + ;; If parity even (P=1), call +OPCODE(ec,` + HOLD_INTS + bsr f_norm_c + bne emu_op_cd + add.l #2,epc + CONTINUE_INTS + ') ;nok + + ;; XXX this probably ought to hold interrupts too +OPCODE(ed,` ; prefix + movea.w emu_op_undo_ed(pc),a2 + ') ;nok + + ;; XOR immed.b +OPCODE(ee,` + HOLD_INTS + FETCHBI d1 + CONTINUE_INTS + F_XOR_B d1,eaf + ') ;nok + + ;; RST &28 + ;; == CALL 28 +OPCODE(ef,` + HOLD_INTS + move.l epc,a0 + bsr underef + PUSHW d0 + move.w #$28,d0 + bsr deref + move.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; RET P + ;; Return if Positive +OPCODE(f0,` + HOLD_INTS + bsr f_norm_sign + beq emu_op_c9 ; RET + CONTINUE_INTS + ') ;nok + + ;; POP AF + ;; SPEED this can be made faster ... + ;; XXX AF +OPCODE(f1,` + POPW eaf + move.w eaf,(flag_byte-flag_storage)(a3) + move.b #$ff,(flag_valid-flag_storage)(a3) + ') ;nok + + ;; JP P,immed.w +OPCODE(f2,` + HOLD_INTS + bsr f_norm_sign + beq emu_op_c3 ; JP + add.l #2,epc + CONTINUE_INTS + ') ;nok + +OPCODE(f3,` + ;; DI + bsr ints_stop + ') + + ;; CALL P,&0000 + ;; Call if positive (S=0) +OPCODE(f4,` + HOLD_INTS + bsr f_norm_sign + beq emu_op_cd + CONTINUE_INTS + ') ;nok + + ;; PUSH AF +OPCODE(f5,` + HOLD_INTS + bsr flags_normalize + LOHI eaf + move.b flag_byte(pc),eaf + ;; XXX wrong, af is not normalized by flags_normalize? + CONTINUE_INTS + HILO eaf + PUSHW eaf + ') ;nok + +OPCODE(f6,` + ;; OR immed.b + HOLD_INTS + FETCHBI d1 + CONTINUE_INTS + F_OR_B d1,eaf + ') ;nok + + ;; RST &30 + ;; == CALL 30 +OPCODE(f7,` + HOLD_INTS + move.l epc,a0 + bsr underef + PUSHW d0 + move.w #$08,d0 + bsr deref + move.l a0,epc + CONTINUE_INTS + ') ;nok + + ;; RET M + ;; Return if Sign == 1, minus +OPCODE(f8,` + HOLD_INTS + bsr f_norm_sign + bne emu_op_c9 ; RET + CONTINUE_INTS + ') ;nok + + ;; LD SP,HL + ;; SP <- HL +OPCODE(f9,` + HOLD_INTS + move.w ehl,d1 + bsr deref + movea.l a0,esp + CONTINUE_INTS + ') ;nok + + ;; JP M,immed.w +OPCODE(fa,` + HOLD_INTS + bsr f_norm_sign + bne emu_op_c3 ; JP + add.l #2,epc + CONTINUE_INTS + ') ;nok + + ;; EI +OPCODE(fb,` + bsr ints_start + ') ;nok + + ;; CALL M,immed.w + ;; Call if minus (S=1) +OPCODE(fc,` + HOLD_INTS + bsr f_norm_sign + bne emu_op_cd + add.l #2,epc + CONTINUE_INTS + ') ;nok + + ;; swap IY, HL +OPCODE(fd,` ; prefix + movea.w emu_op_undo_fd(pc),a2 + ') + + ;; CP immed.b +OPCODE(fe,` + HOLD_INTS + FETCHBI d1 + CONTINUE_INTS + F_CP_B d1,eaf + ') ;nok + + ;; RST &38 + ;; == CALL 38 +OPCODE(ff,` + HOLD_INTS + move.l epc,a0 + bsr underef + PUSHW d0 + move.w #$08,d0 + bsr deref + move.l a0,epc + CONTINUE_INTS + ') ;nok |
