From 2164cc7b99ab44b9efe03d5f4dc2392fc34791f3 Mon Sep 17 00:00:00 2001 From: Duncan Smith Date: Fri, 12 Nov 2010 21:30:13 -0800 Subject: Reworked opcodes.asm to use m4. Soon, it will be clean. --- Makefile | 10 +- opcodes.asm | 2476 -------------------------------------------------------- opcodes.asm.m4 | 2234 ++++++++++++++++++++++++++++++++++++++++++++++++++ opcodes.inc.m4 | 8 + 4 files changed, 2249 insertions(+), 2479 deletions(-) delete mode 100644 opcodes.asm create mode 100644 opcodes.asm.m4 create mode 100644 opcodes.inc.m4 diff --git a/Makefile b/Makefile index 0c22d46..745424c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ -ASM_FILES=alu.asm flags.asm opcodes.asm ports.asm interrupts.asm main.asm +ASM_FILES=alu.asm flags.asm ports.asm interrupts.asm main.asm +M4_ASM_OUTPUT=opcodes.asm ASM=main.asm C_HEADERS=680.h asm_vars.h C_FILES=loader.c bankswap.c video.c misc.c debug.c @@ -13,15 +14,18 @@ CFLAGS=-Wall -ltifiles .PHONY: clean -z680k.89z: $(ASM_FILES) $(C_FILES) $(MADE_FILES) $(C_HEADERS) +z680k.89z: $(ASM_FILES) $(M4_ASM_OUTPUT) $(C_FILES) $(MADE_FILES) $(C_HEADERS) $ tigcc $(TIGCCFLAGS) $(ASM) $(C_FILES) -o $(OBJ) clean: - rm -f $(S_FILES) $(O_FILES) $(MADE_FILES) $(OBJ) $(MADE_BINS) + rm -f $(S_FILES) $(O_FILES) $(M4_ASM_OUTPUT) $(MADE_FILES) $(OBJ) $(MADE_BINS) packager: packager.c gcc $(CFLAGS) packager.c -o packager +opcodes.asm: opcodes.inc.m4 opcodes.asm.m4 + m4 opcodes.inc.m4 opcodes.asm.m4 > opcodes.asm + testbenches/zexdoc.h: testbenches/zexdoc.bin echo 'char zexdoc[] = {' > testbenches/zexdoc.h hexdump -v -e '12/1 "0x%02x, "' -e '"\n"' testbenches/zexdoc.bin | sed -e 's/0x *,//g' >> testbenches/zexdoc.h diff --git a/opcodes.asm b/opcodes.asm deleted file mode 100644 index e1e0922..0000000 --- a/opcodes.asm +++ /dev/null @@ -1,2476 +0,0 @@ -;;; ======================================================================== -;;; ======================================================================== -;;; ___ ___ ======= ============================== -;;; ___( _ ) / _ \ 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) - START -emu_op_00: ; S0 T0 - ;; NOP - TIME 4,0 - DONE - - START -emu_op_01: ; S12 T36 - ;; LD BC,immed.w - ;; Read a word and put it in BC - ;; No flags - HOLD_INTS - FETCHWI ebc - CONTINUE_INTS - DONE - - START -emu_op_02: ; S4 T14 - ;; LD (BC),A - ;; (BC) <- A - ;; No flags - PUTB eaf,ebc - DONE - - START -emu_op_03: ; S2 T4 - ;; INC BC - ;; BC <- BC+1 - ;; No flags - F_INC_W ebc - DONE - - START -emu_op_04: - ;; INC B - ;; B <- B+1 - LOHI ebc - F_INC_B ebc - HILO ebc - DONE - - START -emu_op_05: - ;; DEC B - ;; B <- B-1 - LOHI ebc - F_DEC_B ebc - HILO ebc - DONE ;nok - - START -emu_op_06: ; S10 T26 - ;; LD B,immed.b - ;; Read a byte and put it in B - ;; B <- immed.b - ;; No flags - HOLD_INTS - LOHI ebc - FETCHBI ebc - CONTINUE_INTS - HILO ebc - DONE ;nok - - START -emu_op_07: ; S2 T4 - ;; RLCA - ;; Rotate A left, carry bit gets top bit - ;; Flags: H,N=0; C aff. - ;; XXX flags - rol.b #1,eaf - DONE ;nok - - START -emu_op_08: ; S2 T4 - ;; EX AF,AF' - ;; No flags - ;; XXX AF - swap eaf - DONE ;nok - - START -emu_op_09: - ;; ADD HL,BC - ;; HL <- HL+BC - ;; Flags: H, C aff.; N=0 - F_ADD_W ebc,ehl - DONE ;nok - - START -emu_op_0a: ; S4 T14 - ;; LD A,(BC) - ;; A <- (BC) - ;; No flags - FETCHB ebc,eaf - DONE - - START -emu_op_0b: ; S2 T4 - ;; DEC BC - ;; BC <- BC-1 - ;; No flags - F_DEC_W ebc - DONE ;nok - - START -emu_op_0c: - ;; INC C - ;; C <- C+1 - ;; Flags: S,Z,H aff.; P=overflow, N=0 - F_INC_B ebc - DONE ;nok - - START -emu_op_0d: - ;; DEC C - ;; C <- C-1 - ;; Flags: S,Z,H aff., P=overflow, N=1 - F_DEC_B ebc - DONE ;nok - - START -emu_op_0e: ; S6 T18 - ;; LD C,immed.b - ;; No flags - HOLD_INTS - FETCHBI ebc - CONTINUE_INTS - DONE ;nok - - START -emu_op_0f: - ;; RRCA - ;; Rotate A right, carry bit gets top bit - ;; Flags: H,N=0; C aff. - ;; XXX FLAGS - ror.b #1,eaf - DONE ;nok - - START -emu_op_10: ; S32 - ;; DJNZ immed.w - ;; Decrement B - ;; and branch by immed.b - ;; if B not zero - ;; No flags - 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 - DONE ;nok - - START -emu_op_11: ; S - ;; LD DE,immed.w - ;; No flags - HOLD_INTS - FETCHWI ede - CONTINUE_INTS - DONE ;nok - - START -emu_op_12: - ;; LD (DE),A - ;; No flags - move.w ede,d0 - rol.w #8,d0 - FETCHB d0,eaf - DONE ;nok - - START -emu_op_13: - ;; INC DE - ;; No flags - F_INC_W ede - DONE ;nok - - START -emu_op_14: - ;; INC D - ;; Flags: S,Z,H aff.; P=overflow, N=0 - LOHI ede - F_INC_B ede - HILO ede - DONE ;nok - - START -emu_op_15: - ;; DEC D - ;; Flags: S,Z,H aff.; P=overflow, N=1 - LOHI ede - F_DEC_B ede - HILO ede - DONE ;nok - - START -emu_op_16: - ;; LD D,immed.b - ;; No flags - HOLD_INTS - LOHI ede - FETCHBI ede - CONTINUE_INTS - HILO ede - DONE ;nok - - START -emu_op_17: - ;; RLA - ;; Flags: P,N=0; C aff. - ;; XXX flags - roxl.b #1,eaf - DONE ;nok - - START -emu_op_18: - ;; JR immed.b - ;; PC <- immed.b - ;; Branch relative by a signed immediate byte - ;; No flags - 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 - DONE ;nok - - START -emu_op_19: - ;; ADD HL,DE - ;; HL <- HL+DE - ;; Flags: H,C aff,; N=0 - F_ADD_W ede,ehl - DONE ;nok - - START -emu_op_1a: - ;; LD A,(DE) - ;; A <- (DE) - ;; No flags - FETCHB ede,eaf - DONE ;nok - - START -emu_op_1b: - ;; DEC DE - ;; No flags - subq.w #1,ede - DONE ;nok - - START -emu_op_1c: - ;; INC E - ;; Flags: S,Z,H aff.; P=overflow; N=0 - F_INC_B ede - DONE ;nok - - START -emu_op_1d: - ;; DEC E - ;; Flags: S,Z,H aff.; P=overflow, N=1 - F_DEC_B ede - DONE ;nok - - START -emu_op_1e: - ;; LD E,immed.b - ;; No flags - HOLD_INTS - FETCHBI ede - CONTINUE_INTS - DONE ;nok - - START -emu_op_1f: - ;; RRA - ;; Flags: H,N=0; C aff. - ;; XXX FLAGS - roxr.b #1,eaf - DONE ;nok - - START -emu_op_20: - ;; JR NZ,immed.b - ;; if ~Z, - ;; PC <- PC+immed.b - ;; No flags - 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 - DONE - - START -emu_op_21: - ;; LD HL,immed.w - ;; No flags - HOLD_INTS - FETCHWI ehl - CONTINUE_INTS - DONE ;nok - - START -emu_op_22: - ;; LD immed.w,HL - ;; (address) <- HL - ;; No flags - HOLD_INTS - FETCHWI d1 - CONTINUE_INTS - PUTW ehl,d1 - DONE ;nok - - START -emu_op_23: - ;; INC HL - ;; No flags - addq.w #1,ehl - DONE ;nok - - START -emu_op_24: - ;; INC H - ;; Flags: S,Z,H aff.; P=overflow, N=0 - LOHI ehl - F_INC_B ehl - HILO ehl - DONE ;nok - - START -emu_op_25: - ;; DEC H - ;; Flags: S,Z,H aff.; P=overflow, N=1 - LOHI ehl - F_DEC_B ehl - HILO ehl - DONE ;nok - - START -emu_op_26: - ;; LD H,immed.b - ;; No flags - HOLD_INTS - LOHI ehl - FETCHBI ehl - CONTINUE_INTS - HILO ehl - DONE ;nok - - START -emu_op_27: - ;; DAA - ;; Decrement, adjust accum - ;; http://www.z80.info/z80syntx.htm#DAA - ;; Flags: oh lord they're fucked up - ;; XXX DO THIS - - F_PAR eaf - DONE ;nok - - START -emu_op_28: - ;; JR Z,immed.b - ;; If zero - ;; PC <- PC+immed.b - ;; SPEED can be made faster - ;; No flags - HOLD_INTS - bsr f_norm_z - bne emu_op_18 - add.l #1,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_29: - ;; ADD HL,HL - ;; No flags - F_ADD_W ehl,ehl - DONE ;nok - - START -emu_op_2a: - ;; LD HL,(immed.w) - ;; address is absolute - HOLD_INTS - FETCHWI d1 - CONTINUE_INTS - FETCHW d1,ehl - DONE ;nok - - ;; XXX TOO LONG - - START -emu_op_2b: - ;; DEC HL - F_DEC_W ehl - DONE ;nok - - START -emu_op_2c: - ;; INC L - F_INC_B ehl - DONE ;nok - - START -emu_op_2d: - ;; DEC L - F_DEC_B ehl - DONE ;nok - - START -emu_op_2e: - ;; LD L,immed.b - HOLD_INTS - FETCHBI ehl - CONTINUE_INTS - DONE ;nok - - START -emu_op_2f: - ;; CPL - ;; A <- NOT A - ;; XXX flags - not.b eaf - DONE ;nok - - START -emu_op_30: - ;; JR NC,immed.b - ;; If carry clear - ;; PC <- PC+immed.b - bsr f_norm_c - beq emu_op_18 ; branch taken: carry clear - add.l #1,epc - DONE - - START -emu_op_31: - ;; LD SP,immed.w - HOLD_INTS - FETCHWI d1 - bsr deref - movea.l a0,esp - CONTINUE_INTS - DONE ;nok - - START -emu_op_32: - ;; LD (immed.w),A - ;; store indirect - HOLD_INTS - FETCHWI d1 - CONTINUE_INTS - rol.w #8,d1 - PUTB eaf,d1 - DONE ;nok - - START -emu_op_33: - ;; INC SP - ;; No flags - ;; - ;; FYI: Do not have to deref because this will never cross a - ;; page boundary. So sayeth BrandonW. - HOLD_INTS - addq.w #1,esp - CONTINUE_INTS - DONE ;nok - - START -emu_op_34: - ;; INC (HL) - ;; Increment byte - ;; SPEED can be made faster - FETCHB ehl,d1 - F_INC_B d1 - PUTB d1,ehl - DONE ;nok - - START -emu_op_35: - ;; DEC (HL) - ;; Decrement byte - ;; SPEED can be made faster - FETCHB ehl,d1 - F_DEC_B d1 - PUTB d1,ehl - DONE ;nok - - START -emu_op_36: - ;; LD (HL),immed.b - HOLD_INTS - FETCHBI d1 - CONTINUE_INTS - PUTB ehl,d1 - DONE ;nok - - START -emu_op_37: - ;; SCF - ;; Set Carry Flag - ;; XXX flags are more complicated than this :( - 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) - DONE ;nok - - START -emu_op_38: - ;; JR C,immed.b - ;; If carry set - ;; PC <- PC+immed.b - HOLD_INTS - bsr f_norm_c - bne emu_op_18 - add.l #1,epc - CONTINUE_INTS - DONE - - START -emu_op_39: - ;; ADD HL,SP - ;; HL <- HL+SP - 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 - DONE ;nok - - START -emu_op_3a: - ;; LD A,(immed.w) - HOLD_INTS - FETCHWI d1 - CONTINUE_INTS - FETCHB d1,eaf - DONE ;nok - - START -emu_op_3b: - ;; DEC SP - ;; No flags - subq.l #1,esp - DONE ;nok - - START -emu_op_3c: - ;; INC A - F_INC_B eaf - DONE - - START -emu_op_3d: - ;; DEC A - F_DEC_B eaf - DONE ;nok - - START -emu_op_3e: - ;; LD A,immed.b - HOLD_INTS - FETCHBI eaf - CONTINUE_INTS - DONE - - START -emu_op_3f: - ;; CCF - ;; Clear carry flag - ;; XXX fuck flags - bsr flags_normalize - ;; SZ5H3PNC - ori.b #%00000001,flag_valid-flag_storage(a3) - andi.b #%11111110,flag_byte-flag_storage(a3) - DONE ;nok - - START -emu_op_40: - ;; LD B,B - ;; SPEED - LOHI ebc - move.b ebc,ebc - HILO ebc - DONE ;nok - - START -emu_op_41: - ;; LD B,C - move.w ebc,d1 - LOHI d1 - move.b d1,ebc - DONE ;nok - - START -emu_op_42: - ;; LD B,D - ;; B <- D - ;; SPEED - LOHI ebc - LOHI ede - move.b ede,ebc - HILO ebc - HILO ede - DONE ;nok - - START -emu_op_43: - ;; LD B,E - ;; B <- E - LOHI ebc - move.b ebc,ede ; 4 - HILO ebc - DONE ;nok - - START -emu_op_44: - ;; LD B,H - ;; B <- H - ;; SPEED - LOHI ebc - LOHI ehl - move.b ehl,ebc - HILO ebc - HILO ehl - DONE ;nok - - START -emu_op_45: - ;; LD B,L - ;; B <- L - LOHI ebc - move.b ehl,ebc - HILO ebc - DONE ;nok - - START -emu_op_46: - ;; LD B,(HL) - ;; B <- (HL) - LOHI ebc - FETCHB ehl,ebc - HILO ebc - DONE ;nok - - START -emu_op_47: - ;; LD B,A - ;; B <- A - LOHI ebc - move.b eaf,ebc - HILO ebc - DONE ;nok - - START -emu_op_48: - ;; LD C,B - ;; C <- B - move.w ebc,-(sp) - move.b (sp),ebc - ;; XXX emfasten? - addq.l #2,sp - DONE ;nok - ;14 cycles - START -emu_op_49: - ;; LD C,C - move.b ebc,ebc - DONE ;nok - - START -emu_op_4a: - ;; LD C,D - move.w ede,-(sp) - move.b (sp),ebc - ;; XXX emfasten? - addq.l #2,sp - DONE ;nok - - START -emu_op_4b: - ;; LD C,E - move.b ebc,ede - DONE ;nok - - START -emu_op_4c: - ;; LD C,H - LOHI ehl - move.b ebc,ehl - HILO ehl - DONE ;nok - - START -emu_op_4d: - ;; LD C,L - move.b ebc,ehl - DONE ;nok - - START -emu_op_4e: - ;; LD C,(HL) - ;; C <- (HL) - FETCHB ehl,ebc - DONE ;nok - - START -emu_op_4f: - ;; LD C,A - move.b eaf,ebc - DONE ;nok - - START -emu_op_50: -; 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 - LOHI ebc - LOHI ede - move.b ebc,ede - HILO ebc - HILO ede - DONE ;nok - - START -emu_op_51: - ;; LD D,C - LOHI ede - move.b ebc,ede - HILO ede - DONE ;nok - - START -emu_op_52: - ;; LD D,D - DONE ;nok - - START -emu_op_53: - ;; LD D,E - andi.w #$00ff,ede - move.b ede,d1 - lsl #8,d1 - or.w d1,ede - DONE ;nok - - START -emu_op_54: - ;; LD D,H - LOHI ede ; 4 - LOHI ehl ; 4 - move.b ehl,ede ; 4 - HILO ede ; 4 - HILO ehl ; 4 - DONE ;nok - ;20 cycles - - START -emu_op_55: - ;; LD D,L - LOHI ede - move.b ehl,ede - HILO ede - DONE ;nok - - START -emu_op_56: - ;; LD D,(HL) - ;; D <- (HL) - LOHI ede - FETCHB ehl,ede - HILO ede - DONE ;nok - - START -emu_op_57: - ;; LD D,A - LOHI ede - move.b eaf,ede - HILO ede - DONE ;nok - - START -emu_op_58: - ;; LD E,B - LOHI ebc - move.b ebc,ede - HILO ebc - DONE ;nok - - START -emu_op_59: - ;; LD E,C - move.b ebc,ede - DONE ;nok - - START -emu_op_5a: - ;; LD E,D - andi.w #$ff00,ede ; 8/4 - move.b ede,d1 ; 4/2 - lsr.w #8,d1 ;22/2 - or.w d1,ede ; 4/2 - DONE ;nok - ;38/2 - - START -emu_op_5b: - ;; LD E,E - move.b ede,ede - DONE ;nok - - START -emu_op_5c: - ;; LD E,H - LOHI ehl - move.b ede,ehl - HILO ehl - DONE ;nok - - START -emu_op_5d: - ;; LD E,L - move.b ede,ehl - DONE ;nok - - START -emu_op_5e: - ;; LD E,(HL) - FETCHB ehl,d1 - DONE ;nok - - START -emu_op_5f: - ;; LD E,A - move.b ede,eaf - DONE ;nok - - START -emu_op_60: - ;; LD H,B - LOHI ebc - LOHI ehl - move.b ehl,ebc - HILO ebc - HILO ehl - DONE ;nok - - START -emu_op_61: - ;; LD H,C - LOHI ehl - move.b ebc,ehl - HILO ehl - DONE ;nok - - START -emu_op_62: - ;; LD H,D - LOHI ede - LOHI ehl - move.b ede,ehl - HILO ede - HILO ehl - DONE ;nok - - START -emu_op_63: - ;; LD H,E - LOHI ehl - move.b ede,ehl - HILO ehl - DONE ;nok - - START -emu_op_64: - ;; LD H,H - LOHI ehl - move.b ehl,ehl - HILO ehl - DONE ;nok - - START -emu_op_65: - ;; LD H,L - ;; H <- L - move.b ehl,d1 - LOHI ehl - move.b d1,ehl - HILO ehl - DONE ;nok - - START -emu_op_66: - ;; LD H,(HL) - FETCHB ehl,d1 - LOHI ehl - move.b d1,ehl - HILO ehl - DONE ;nok - - START -emu_op_67: - ;; LD H,A - LOHI ehl - move.b eaf,ehl - HILO ehl - DONE ;nok - - START -emu_op_68: - ;; LD L,B - LOHI ebc - move.b ebc,ehl - HILO ebc - DONE ;nok - - START -emu_op_69: - ;; LD L,C - move.b ebc,ehl - DONE ;nok - - START -emu_op_6a: - ;; LD L,D - LOHI ede - move.b ede,ehl - HILO ede - DONE ;nok - - START -emu_op_6b: - ;; LD L,E - move.b ede,ehl - DONE ;nok - - START -emu_op_6c: - ;; LD L,H - move.b ehl,d1 - LOHI d1 - move.b d1,ehl - DONE ;nok - - START -emu_op_6d: - ;; LD L,L - move.b ehl,ehl - DONE ;nok - - START -emu_op_6e: - ;; LD L,(HL) - ;; L <- (HL) - FETCHB ehl,ehl - DONE ;nok - - START -emu_op_6f: - ;; LD L,A - move.b eaf,ehl - DONE ;nok - - START -emu_op_70: - ;; LD (HL),B - LOHI ebc - PUTB ehl,ebc - HILO ebc - DONE ;nok - - START -emu_op_71: - ;; LD (HL),C - PUTB ehl,ebc - DONE ;nok - - START -emu_op_72: - ;; LD (HL),D - LOHI ede - PUTB ehl,ede - HILO ede - DONE ;nok - - START -emu_op_73: - ;; LD (HL),E - PUTB ehl,ede - DONE ;nok - - START -emu_op_74: - ;; LD (HL),H - move.w ehl,d1 - HILO d1 - PUTB d1,ehl - DONE ;nok - - START -emu_op_75: - ;; LD (HL),L - move.b ehl,d1 - PUTB d1,ehl - DONE ;nok - - START -emu_op_76: - ;; HALT - ;; XXX do this - bra emu_op_76 - DONE ;nok - - START -emu_op_77: - ;; LD (HL),A - PUTB eaf,ehl - DONE ;nok - - START -emu_op_78: - ;; LD A,B - move.w ebc,d1 - LOHI d1 - move.b d1,eaf - DONE ;nok - - START -emu_op_79: - ;; LD A,C - move.b ebc,eaf - DONE ;nok - - START -emu_op_7a: - ;; LD A,D - move.w ede,d1 - LOHI d1 - move.b d1,eaf - DONE ;nok - - START -emu_op_7b: - ;; LD A,E - move.b ede,eaf - DONE ;nok - - START -emu_op_7c: - ;; LD A,H - move.w ehl,d1 - LOHI d1 - move.b d1,eaf - DONE ;nok - - START -emu_op_7d: - ;; LD A,L - move.b ehl,eaf - DONE ;nok - - START -emu_op_7e: - ;; LD A,(HL) - ;; A <- (HL) - FETCHB ehl,eaf - DONE ;nok - - START -emu_op_7f: - ;; LD A,A - DONE ;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 - - START -emu_op_80: - ;; ADD A,B - LOHI ebc - F_ADD_B ebc,eaf - HILO ebc - DONE ;nok - - START -emu_op_81: - ;; ADD A,C - F_ADD_B ebc,eaf - DONE ;nok - - START -emu_op_82: - ;; ADD A,D - LOHI ede - F_ADD_B ede,eaf - HILO ede - DONE ;nok - - START -emu_op_83: - ;; ADD A,E - F_ADD_B ede,eaf - DONE ;nok - - START -emu_op_84: - ;; ADD A,H - LOHI ehl - F_ADD_B ehl,eaf - HILO ehl - DONE ;nok - - START -emu_op_85: - ;; ADD A,L - F_ADD_B ehl,eaf - DONE ;nok - - START -emu_op_86: - ;; ADD A,(HL) - ;; XXX size? - FETCHB ehl,d2 - F_ADD_B d2,eaf - PUTB d2,ehl - DONE ;nok - - START -emu_op_87: - ;; ADD A,A - F_ADD_B eaf,eaf - DONE ;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 - - START -emu_op_88: - ;; ADC A,B - ;; A <- A + B + (carry) - LOHI ebc - F_ADC_B ebc,eaf - HILO ebc - DONE ;nok - - START -emu_op_89: - ;; ADC A,C - ;; A <- A + C + (carry) - F_ADC_B ebc,eaf - DONE ;nok - - START -emu_op_8a: - ;; ADC A,D - LOHI ede - F_ADC_B ede,eaf - HILO ede - DONE ;nok - - START -emu_op_8b: - ;; ADC A,E - ;; A <- A + E + carry - F_ADC_B ede,eaf - DONE ;nok - - START -emu_op_8c: - ;; ADC A,H - LOHI eaf - F_ADC_B ehl,eaf - HILO eaf - DONE ;nok - - START -emu_op_8d: - ;; ADC A,L - F_ADC_B ehl,eaf - DONE ;nok - - START -emu_op_8e: - ;; ADC A,(HL) - FETCHB ehl,d2 - F_ADC_B d2,eaf - PUTB d2,ehl - DONE ;nok - - START -emu_op_8f: - ;; ADC A,A - F_ADC_B eaf,eaf - DONE ;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 - - START -emu_op_90: - ;; SUB A,B - LOHI ebc - F_SUB_B ebc,eaf - HILO ebc - DONE ;nok - - START -emu_op_91: - ;; SUB A,C - F_SUB_B ebc,eaf - DONE ;nok - - START -emu_op_92: - ;; SUB A,D - LOHI ede - F_SUB_B ede,eaf - HILO ede - DONE ;nok - - START -emu_op_93: - ;; SUB A,E - F_SUB_B ede,eaf - DONE ;nok - - START -emu_op_94: - ;; SUB A,H - LOHI ehl - F_SUB_B ehl,eaf - HILO ehl - DONE ;nok - - START -emu_op_95: - ;; SUB A,L - F_SUB_B ehl,eaf - - START -emu_op_96: - ;; SUB A,(HL) - FETCHB ehl,d2 - F_SUB_B d2,eaf - PUTB d2,ehl - DONE ;nok - - START -emu_op_97: - ;; SUB A,A - F_SUB_B eaf,eaf - DONE ;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 - - START -emu_op_98: - ;; SBC A,B - LOHI ebc - F_SBC_B ebc,eaf - HILO ebc - DONE ;nok - - START -emu_op_99: - ;; SBC A,C - F_SBC_B ebc,eaf - DONE ;nok - - START -emu_op_9a: - ;; SBC A,D - LOHI ede - F_SBC_B ede,eaf - HILO ede - DONE ;nok - - START -emu_op_9b: - ;; SBC A,E - F_SBC_B ede,eaf - DONE ;nok - - START -emu_op_9c: - ;; SBC A,H - LOHI ehl - F_SBC_B ehl,eaf - HILO ehl - DONE ;nok - - START -emu_op_9d: - ;; SBC A,L - F_SBC_B ehl,eaf - DONE ;nok - - START -emu_op_9e: - ;; SBC A,(HL) - FETCHB ehl,d2 - F_SBC_B d2,eaf - PUTB d2,ehl - DONE ;nok - - START -emu_op_9f: - ;; SBC A,A - F_SBC_B eaf,eaf - DONE ;nok - - - - - -F_AND_B MACRO - move.b \2,d1 - move.b \1,d0 - bsr alu_and - move.b d1,\2 - ENDM - - START -emu_op_a0: - ;; AND B - LOHI ebc - F_AND_B ebc,eaf - HILO ebc - DONE ;nok - - START -emu_op_a1: - ;; AND C - F_AND_B ebc,eaf - - START -emu_op_a2: - ;; AND D - LOHI ede - F_AND_B ede,eaf - HILO ede - DONE ;nok - - START -emu_op_a3: - ;; AND E - F_AND_B ede,eaf - DONE ;nok - - START -emu_op_a4: - ;; AND H - LOHI ehl - F_AND_B ehl,eaf - HILO ehl - DONE ;nok - - START -emu_op_a5: - ;; AND L - F_AND_B ehl,eaf - DONE ;nok - - START -emu_op_a6: - ;; AND (HL) - FETCHB ehl,d2 - F_AND_B d2,eaf - PUTB d2,ehl - DONE ;nok - - START -emu_op_a7: - ;; AND A - ;; SPEED ... It's probably not necessary to run this faster. - F_AND_B eaf,eaf - DONE ;nok - - - - - -F_XOR_B MACRO - move.b \2,d1 - move.b \1,d0 - bsr alu_xor - move.b d1,\2 - ENDM - - START -emu_op_a8: - ;; XOR B - LOHI ebc - F_XOR_B ebc,eaf - HILO ebc - DONE ;nok - - START -emu_op_a9: - ;; XOR C - F_XOR_B ebc,eaf - DONE ;nok - - START -emu_op_aa: - ;; XOR D - LOHI ede - F_XOR_B ede,eaf - HILO ede - DONE ;nok - - START -emu_op_ab: - ;; XOR E - F_XOR_B ede,eaf - DONE ;nok - - START -emu_op_ac: - ;; XOR H - LOHI ehl - F_XOR_B ehl,eaf - HILO ehl - DONE ;nok - - START -emu_op_ad: - ;; XOR L - F_XOR_B ehl,eaf - DONE ;nok - - START -emu_op_ae: - ;; XOR (HL) - FETCHB ehl,d2 - F_XOR_B d2,eaf - PUTB d2,ehl - DONE ;nok - - START -emu_op_af: - ;; XOR A - F_XOR_B eaf,eaf - ;; XXX - DONE ;nok - - - - - -F_OR_B MACRO - move.b \2,d1 - move.b \1,d0 - bsr alu_or - move.b d1,\2 - ENDM - - START -emu_op_b0: - ;; OR B - LOHI ebc - F_OR_B ebc,eaf - HILO ebc - DONE ;nok - - START -emu_op_b1: - ;; OR C - F_OR_B ebc,eaf - DONE ;nok - - START -emu_op_b2: - ;; OR D - LOHI ede - F_OR_B ede,eaf - HILO ede - DONE ;nok - - START -emu_op_b3: - ;; OR E - F_OR_B ede,eaf - DONE ;nok - - START -emu_op_b4: - ;; OR H - LOHI ehl - F_OR_B ehl,eaf - HILO ehl - DONE ;nok - - START -emu_op_b5: - ;; OR L - F_OR_B ehl,eaf - DONE ;nok - - START -emu_op_b6: - ;; OR (HL) - FETCHB ehl,d2 - F_OR_B d2,eaf - PUTB d2,ehl - DONE ;nok - - START -emu_op_b7: - ;; OR A - F_OR_B eaf,eaf - DONE ;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 - - START -emu_op_b8: - ;; CP B - move.w ebc,d2 - LOHI d2 - F_CP_B d2,eaf - DONE ;nok - - START -emu_op_b9: - ;; CP C - F_CP_B ebc,eaf - DONE ;nok - - START -emu_op_ba: - ;; CP D - move.w ede,d2 - LOHI d2 - F_CP_B d2,eaf - DONE ;nok - - START -emu_op_bb: - ;; CP E - F_CP_B ede,eaf - DONE ;nok - - START -emu_op_bc: - ;; CP H - move.w ehl,d2 - LOHI d2 - F_CP_B d2,eaf - DONE ;nok - - START -emu_op_bd: - ;; CP L - F_CP_B ehl,eaf - DONE ;nok - - START -emu_op_be: - ;; CP (HL) - FETCHB ehl,d2 - F_CP_B d2,eaf - ;; no result to store - DONE ;nok - - START -emu_op_bf: - ;; CP A - F_CP_B eaf,eaf - DONE - - START -emu_op_c0: - ;; RET NZ - ;; if ~Z - ;; PCl <- (SP) - ;; PCh <- (SP+1) - ;; SP <- (SP+2) - HOLD_INTS - bsr f_norm_z - ;; SPEED inline RET - beq emu_op_c9 ; RET - CONTINUE_INTS - DONE ;nok - - START -emu_op_c1: ; S10 T - ;; POP BC - ;; Pops a word into BC - HOLD_INTS - POPW ebc - CONTINUE_INTS - DONE ;nok - - START -emu_op_c2: - ;; JP NZ,immed.w - ;; if ~Z - ;; PC <- immed.w - HOLD_INTS - bsr f_norm_z - bne.s emu_op_c3 - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_c3: ; S12 T36 - ;; JP immed.w - ;; PC <- immed.w - HOLD_INTS - FETCHWI d1 - bsr deref - movea.l a0,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_c4: - ;; CALL NZ,immed.w - ;; If ~Z, CALL immed.w - 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 - DONE ;nok - - START -emu_op_c5: - ;; PUSH BC - HOLD_INTS - PUSHW ebc - CONTINUE_INTS - DONE ;nok - - START -emu_op_c6: - ;; ADD A,immed.b - HOLD_INTS - FETCHBI d1 - CONTINUE_INTS - F_ADD_B d1,eaf - DONE ;nok - - START -emu_op_c7: - ;; RST &0 - ;; == CALL 0 - ;; XXX check - HOLD_INTS - move.l epc,a0 - bsr underef - PUSHW d0 - move.w #$00,d0 - bsr deref - move.l a0,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_c8: - ;; RET Z - HOLD_INTS - bsr f_norm_z - beq.s emu_op_c9 - CONTINUE_INTS - DONE ;nok - - START -emu_op_c9: - ;; RET - ;; PCl <- (SP) - ;; PCh <- (SP+1) POPW - ;; SP <- (SP+2) - HOLD_INTS - POPW d1 - bsr deref - movea.l a0,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_ca: - ;; JP Z,immed.w - ;; If Z, jump - HOLD_INTS - bsr f_norm_z - beq emu_op_c3 - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_cb: ; prefix - movea.w emu_op_undo_cb(pc),a2 - ;; nok - - START -emu_op_cc: - ;; CALL Z,immed.w - HOLD_INTS - bsr f_norm_z - beq.s emu_op_cd - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_cd: - ;; CALL immed.w - ;; (Like JSR on 68k) - ;; (SP-1) <- PCh - ;; (SP-2) <- PCl - ;; SP <- SP - 2 - ;; PC <- address - 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 - - START -emu_op_ce: - ;; ADC A,immed.b - HOLD_INTS - FETCHWI d1 - CONTINUE_INTS - F_ADC_B d1,eaf - DONE ;nok - - START -emu_op_cf: - ;; RST &08 - ;; == CALL 8 - 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 - DONE ;nok - - START -emu_op_d0: - ;; RET NC - HOLD_INTS - bsr f_norm_c - beq emu_op_c9 - CONTINUE_INTS - DONE ;nok - - START -emu_op_d1: - ;; POP DE - HOLD_INTS - POPW ede - CONTINUE_INTS - DONE ;nok - - START -emu_op_d2: - ;; JP NC,immed.w - HOLD_INTS - bsr f_norm_c - beq emu_op_c3 - add.l #2,epc - CONTINUE_INTS - DONE - - START -emu_op_d3: - ;; OUT immed.b,A - HOLD_INTS - move.b eaf,d1 - FETCHBI d0 - bsr port_out - CONTINUE_INTS - DONE ;nok - - START -emu_op_d4: - ;; CALL NC,immed.w - HOLD_INTS - bsr f_norm_c - beq emu_op_cd - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_d5: - ;; PUSH DE - HOLD_INTS - PUSHW ede - CONTINUE_INTS - DONE ;nok - - START -emu_op_d6: - ;; SUB A,immed.b - HOLD_INTS - FETCHBI d1 - CONTINUE_INTS - F_SUB_B eaf,d1 - DONE ;nok - - START -emu_op_d7: - ;; RST &10 - ;; == CALL 10 - HOLD_INTS - move.l epc,a0 - bsr underef - PUSHW d0 - move.w #$10,d0 - bsr deref - move.l a0,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_d8: - ;; RET C - HOLD_INTS - bsr f_norm_c - bne emu_op_c9 - CONTINUE_INTS - DONE ;nok - - START -emu_op_d9: - ;; EXX - swap ebc - swap ede - swap ehl - DONE ;nok - - START -emu_op_da: - ;; JP C,immed.w - HOLD_INTS - bsr f_norm_c - bne emu_op_c3 - CONTINUE_INTS - DONE ;nok - - START -emu_op_db: - ;; IN A,immed.b - HOLD_INTS - move.b eaf,d1 - FETCHBI d0 - CONTINUE_INTS - bsr port_in - DONE ;nok - - START -emu_op_dc: - ;; CALL C,immed.w - HOLD_INTS - bsr f_norm_c - bne emu_op_cd - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_dd: ; prefix - movea.w emu_op_undo_dd(pc),a2 - - START -emu_op_de: - ;; SBC A,immed.b - HOLD_INTS - FETCHWI d1 - CONTINUE_INTS - F_SBC_B d1,eaf - DONE ;nok - - START -emu_op_df: - ;; RST &18 - ;; == CALL 18 - HOLD_INTS - move.l epc,a0 - bsr underef - PUSHW d0 - move.w #$18,d0 - bsr deref - move.l a0,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_e0: - ;; RET PO - ;; If parity odd (P zero), return - HOLD_INTS - bsr f_norm_pv - beq emu_op_c9 - CONTINUE_INTS - DONE ;nok - - START -emu_op_e1: - ;; POP HL - POPW ehl - DONE ;nok - - START -emu_op_e2: - ;; JP PO,immed.w - HOLD_INTS - bsr f_norm_pv - beq emu_op_c3 - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_e3: - ;; EX (SP),HL - ;; Exchange - HOLD_INTS - POPW d1 - PUSHW ehl - CONTINUE_INTS - move.w d1,ehl - DONE ;nok - - START -emu_op_e4: - ;; CALL PO,immed.w - ;; if parity odd (P=0), call - HOLD_INTS - bsr f_norm_pv - beq emu_op_cd - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_e5: - ;; PUSH HL - HOLD_INTS - PUSHW ehl - CONTINUE_INTS - DONE ;nok - - START -emu_op_e6: - ;; AND immed.b - HOLD_INTS - FETCHBI d1 - CONTINUE_INTS - F_AND_B d1,eaf - DONE ;nok - - START -emu_op_e7: - ;; RST &20 - ;; == CALL 20 - HOLD_INTS - move.l epc,a0 - bsr underef - PUSHW d0 - move.w #$20,d0 - bsr deref - move.l a0,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_e8: - ;; RET PE - ;; If parity odd (P zero), return - HOLD_INTS - bsr f_norm_pv - bne emu_op_c9 - CONTINUE_INTS - DONE ;nok - - START -emu_op_e9: - ;; JP (HL) - HOLD_INTS - FETCHB ehl,d1 - bsr deref - movea.l a0,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_ea: - ;; JP PE,immed.w - HOLD_INTS - bsr f_norm_pv - bne emu_op_c3 - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_eb: - ;; EX DE,HL - exg.w ede,ehl - DONE ;nok - - START -emu_op_ec: - ;; CALL PE,immed.w - ;; If parity even (P=1), call - HOLD_INTS - bsr f_norm_c - bne emu_op_cd - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_ed: ; prefix - ;; XXX this probably ought to hold interrupts too - movea.w emu_op_undo_ed(pc),a2 - DONE ;nok - - START -emu_op_ee: - ;; XOR immed.b - HOLD_INTS - FETCHBI d1 - CONTINUE_INTS - F_XOR_B d1,eaf - DONE ;nok - - START -emu_op_ef: - ;; RST &28 - ;; == CALL 28 - HOLD_INTS - move.l epc,a0 - bsr underef - PUSHW d0 - move.w #$28,d0 - bsr deref - move.l a0,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_f0: - ;; RET P - ;; Return if Positive - HOLD_INTS - bsr f_norm_sign - beq emu_op_c9 ; RET - CONTINUE_INTS - DONE ;nok - - START -emu_op_f1: - ;; POP AF - ;; SPEED this can be made faster ... - ;; XXX AF - POPW eaf - move.w eaf,(flag_byte-flag_storage)(a3) - move.b #$ff,(flag_valid-flag_storage)(a3) - DONE ;nok - - START -emu_op_f2: - ;; JP P,immed.w - HOLD_INTS - bsr f_norm_sign - beq emu_op_c3 ; JP - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_f3: - ;; DI - bsr ints_stop - - START -emu_op_f4: - ;; CALL P,&0000 - ;; Call if positive (S=0) - HOLD_INTS - bsr f_norm_sign - beq emu_op_cd - CONTINUE_INTS - DONE ;nok - - START -emu_op_f5: - ;; PUSH AF - HOLD_INTS - bsr flags_normalize - LOHI eaf - move.b flag_byte(pc),eaf - ;; XXX wrong, af isn't normalized by flags_normalize? - CONTINUE_INTS - HILO eaf - PUSHW eaf - DONE ;nok - - START -emu_op_f6: - ;; OR immed.b - HOLD_INTS - FETCHBI d1 - CONTINUE_INTS - F_OR_B d1,eaf - DONE ;nok - - START -emu_op_f7: - ;; RST &30 - ;; == CALL 30 - HOLD_INTS - move.l epc,a0 - bsr underef - PUSHW d0 - move.w #$08,d0 - bsr deref - move.l a0,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_f8: - ;; RET M - ;; Return if Sign == 1, minus - HOLD_INTS - bsr f_norm_sign - bne emu_op_c9 ; RET - CONTINUE_INTS - DONE ;nok - - START -emu_op_f9: - ;; LD SP,HL - ;; SP <- HL - HOLD_INTS - move.w ehl,d1 - bsr deref - movea.l a0,esp - CONTINUE_INTS - DONE ;nok - - START -emu_op_fa: - ;; JP M,immed.w - HOLD_INTS - bsr f_norm_sign - bne emu_op_c3 ; JP - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_fb: - ;; EI - bsr ints_start - DONE ;nok - - START -emu_op_fc: - ;; CALL M,immed.w - ;; Call if minus (S=1) - HOLD_INTS - bsr f_norm_sign - bne emu_op_cd - add.l #2,epc - CONTINUE_INTS - DONE ;nok - - START -emu_op_fd: ; prefix - ;; swap IY, HL - movea.w emu_op_undo_fd(pc),a2 - - START -emu_op_fe: - ;; CP immed.b - HOLD_INTS - FETCHBI d1 - CONTINUE_INTS - F_CP_B d1,eaf - DONE ;nok - - START -emu_op_ff: - ;; RST &38 - ;; == CALL 38 - HOLD_INTS - move.l epc,a0 - bsr underef - PUSHW d0 - move.w #$08,d0 - bsr deref - move.l a0,epc - CONTINUE_INTS - DONE ;nok 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 diff --git a/opcodes.inc.m4 b/opcodes.inc.m4 new file mode 100644 index 0000000..d7343e8 --- /dev/null +++ b/opcodes.inc.m4 @@ -0,0 +1,8 @@ +dnl # change the comments to match the assembler. Prevents/reduces +dnl # confusion, since m4 likes to use ' as a quoting character. +changecom(;)dnl +define(`OPCODE',` START +`emu_op_'$1`:' +$2 + TIME $3 + DONE')dnl -- cgit v1.2.3