From 541bce94a4d73e754ce522758dd25ecddb818f04 Mon Sep 17 00:00:00 2001 From: Astrid Smith Date: Fri, 21 Oct 2011 01:07:19 -0700 Subject: First stage of converting to be GAS-compliant I (think I) have converted all the A68k directives to their GAS equivalents. Still remaining are all the inline expressions. --- Makefile | 12 +- alu.asm | 93 -- alu.s | 95 ++ flags.asm | 309 ---- flags.s | 315 ++++ interrupts.asm.m4 | 113 -- interrupts.s.m4 | 115 ++ main.asm | 196 --- main.s | 200 +++ opcodes.asm.m4 | 4309 ----------------------------------------------------- opcodes.s.m4 | 4309 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ports.asm | 1188 --------------- ports.s | 1188 +++++++++++++++ 13 files changed, 6228 insertions(+), 6214 deletions(-) delete mode 100644 alu.asm create mode 100644 alu.s delete mode 100644 flags.asm create mode 100644 flags.s delete mode 100644 interrupts.asm.m4 create mode 100644 interrupts.s.m4 delete mode 100644 main.asm create mode 100644 main.s delete mode 100644 opcodes.asm.m4 create mode 100644 opcodes.s.m4 delete mode 100644 ports.asm create mode 100644 ports.s diff --git a/Makefile b/Makefile index e89fa38..9da723e 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ -# these files are written as .asm -ASM_FILES=alu.asm flags.asm ports.asm main.asm +# these files are written as .s +ASM_FILES=alu.s flags.s ports.s main.s -# these files are written as .asm.m4 and then preprocessed to .asm -M4_ASM_OUTPUT=opcodes.asm interrupts.asm +# these files are written as .s.m4 and then preprocessed to .s +M4_ASM_OUTPUT=opcodes.s interrupts.s M4_ASM_INCLUDES=opcodes.inc.m4 # this is the set of file(s) which is fed to the assembler, and uses # INCLUDE directives to include the rest of assembly source. -ASM=main.asm +ASM=main.s C_HEADERS=global.h asm_vars.h C_FILES=loader.c bankswap.c video.c misc.c debug.c @@ -53,7 +53,7 @@ packager: packager.c gcc $(CFLAGS) packager.c -o packager # preprocess asm files using m4 as necessary -%.asm: %.asm.m4 +%.s: %.s.m4 m4 $(M4_ASM_INCLUDES) $< > $@ # assemble z80 code diff --git a/alu.asm b/alu.asm deleted file mode 100644 index ec0e137..0000000 --- a/alu.asm +++ /dev/null @@ -1,93 +0,0 @@ - ;; Parting out the big math/logic routines from the - ;; instruction dispatch table. - -alu_add: - ;; ADD instruction - ;; ADD d1,d0 - ;; d1 + d0 -> d1 - move.b d0,f_tmp_src_b ; preserve operands for flag work - move.b d1,f_tmp_dst_b - move.b #1,f_tmp_byte - add d0,d1 - move sr,f_host_sr - move.w #0202,flag_byte - rts - -alu_adc: - ;; ADC instruction - ;; ADC d1,d0 - ;; d1 + d0 + carry -> d1 - bsr flags_normalize - move.b flag_byte(pc),d2 - andi.b #1,d2 - add.b d0,d2 - move.b d2,f_tmp_src_b - move.b d1,f_tmp_dst_b - add.b d2,d1 - move sr,f_host_ccr - move.w #$0202,flag_byte - rts - -alu_sbc: - ;; SBC instruction - ;; SBC d1,d0 - ;; d1 - (d0+C) -> d1 - ;; sets flags - - push.l d2 - bsr flags_normalize - move.b flag_byte(pc),d2 - andi.b #1,d2 - add.b d0,d2 - move.b d2,f_tmp_src_b - move.b d1,f_tmp_dst_b - sub.b d2,d1 - move sr,f_host_sr - move.b #$02,flag_byte - move.b #$02,flag_valid - pop.l d2 - rts - -alu_sub: - ;; SUB instruction - ;; SUB d1,d0 - ;; d1 - d0 -> d1 - ;; sets flags - - ;; XXX use lea and then d(an) if you have a spare register. - - ;; preserve operands for flagging - move.b d0,f_tmp_src_b - move.b d1,f_tmp_dst_b - move.b #1,f_tmp_byte - andi.b #%00000010,flag_valid - move.b #%00000010,flag_byte - sub d0,d1 - move sr,f_host_sr - rts - -alu_and: - ;; XXX do this - rts - -alu_xor: - ;; XXX do this - rts - -alu_or: - ;; XXX do this - rts - -alu_cp: - ;; Same as SUB but the macro that calls this doesn't save the - ;; result. - - ;; SPEED can hardcode one of the arguments to always be the A register. - move.b d0,f_tmp_src_b - move.b d1,f_tmp_dst_b - move.b #1,f_tmp_byte - andi.b #%00000010,flag_valid - move.b #%00000010,flag_byte - sub.b d0,d1 - move sr,f_host_sr - rts diff --git a/alu.s b/alu.s new file mode 100644 index 0000000..22594bd --- /dev/null +++ b/alu.s @@ -0,0 +1,95 @@ + ;; Parting out the big math/logic routines from the + ;; instruction dispatch table. + +.text + +alu_add: + ;; ADD instruction + ;; ADD d1,d0 + ;; d1 + d0 -> d1 + move.b d0,f_tmp_src_b ; preserve operands for flag work + move.b d1,f_tmp_dst_b + move.b #1,f_tmp_byte + add d0,d1 + move sr,f_host_sr + move.w #0202,flag_byte + rts + +alu_adc: + ;; ADC instruction + ;; ADC d1,d0 + ;; d1 + d0 + carry -> d1 + bsr flags_normalize + move.b flag_byte(pc),d2 + andi.b #1,d2 + add.b d0,d2 + move.b d2,f_tmp_src_b + move.b d1,f_tmp_dst_b + add.b d2,d1 + move sr,f_host_ccr + move.w #$0202,flag_byte + rts + +alu_sbc: + ;; SBC instruction + ;; SBC d1,d0 + ;; d1 - (d0+C) -> d1 + ;; sets flags + + push.l d2 + bsr flags_normalize + move.b flag_byte(pc),d2 + andi.b #1,d2 + add.b d0,d2 + move.b d2,f_tmp_src_b + move.b d1,f_tmp_dst_b + sub.b d2,d1 + move sr,f_host_sr + move.b #$02,flag_byte + move.b #$02,flag_valid + pop.l d2 + rts + +alu_sub: + ;; SUB instruction + ;; SUB d1,d0 + ;; d1 - d0 -> d1 + ;; sets flags + + ;; XXX use lea and then d(an) if you have a spare register. + + ;; preserve operands for flagging + move.b d0,f_tmp_src_b + move.b d1,f_tmp_dst_b + move.b #1,f_tmp_byte + andi.b #%00000010,flag_valid + move.b #%00000010,flag_byte + sub d0,d1 + move sr,f_host_sr + rts + +alu_and: + ;; XXX do this + rts + +alu_xor: + ;; XXX do this + rts + +alu_or: + ;; XXX do this + rts + +alu_cp: + ;; Same as SUB but the macro that calls this doesn't save the + ;; result. + + ;; SPEED can hardcode one of the arguments to always be the A register. + move.b d0,f_tmp_src_b + move.b d1,f_tmp_dst_b + move.b #1,f_tmp_byte + andi.b #%00000010,flag_valid + move.b #%00000010,flag_byte + sub.b d0,d1 + move sr,f_host_sr + rts diff --git a/flags.asm b/flags.asm deleted file mode 100644 index 6282336..0000000 --- a/flags.asm +++ /dev/null @@ -1,309 +0,0 @@ - ;; Routine to set the given flags - ;; Noted in \1 by a 1 bit -F_SET MACRO ; 32 cycles, 8 bytes - or.b \1,flag_byte-flag_storage(a3) - or.b \1,flag_valid-flag_storage(a3) - ENDM - - ;; Clear the given flags - ;; Noted in \1 (must be a reg) by a 1 bit -F_CLEAR MACRO ; 36 cycles, 10 bytes - or.b \1,flag_valid-flag_storage(a3) - not.b \1 - and.b \1,flag_byte-flag_storage(a3) - ENDM - - ;; Use this when an instruction uses the P/V bit as Parity. - ;; Sets or clears the bit explicitly. - ;; - ;; Byte for which parity is calculated must be in \1. High - ;; byte of \1.w must be zero, using d0 is suggested. (a0,d1 - ;; destroyed) - -F_PAR MACRO - ori.b #%00000100,flag_valid-flag_storage(a3) - move.b flag_byte(pc),d1 - andi.b #%11111011,d1 - lea lut_parity(pc),a0 - or.b 0(a0,\1.w),d1 - move.b d1,flag_byte-flag_storage(a3) - ENDM - - - ;; Use this when an instruction uses the P/V bit as Overflow. - ;; Leaves the bit itself implicit; simply marks it dirty. -F_OVFL MACRO ; 20 cycles, 6 bytes - andi.b #%11111011,flag_valid-flag_storage(a3) - ENDM - - ;; Save the two operands from ADD \1,\2 -F_ADD_SAVE MACRO - move.b \1,f_tmp_src_b-flag_storage(a3) - move.b \2,f_tmp_dst_b-flag_storage(a3) - move.b #$01,f_tmp_byte-flag_storage(a3) - F_SET #% - ENDM - - ;; Normalize and return inverse of emulated Carry bit (loaded - ;; into host zero flag) - - ;; Destroys d1 -f_norm_c: - move.b flag_valid-flag_storage(a3),d1 -; d1 is destroyed in all cases, so you can use lsr and the C bit (same speed, smaller) - lsr.b #1,d1 - bcs.s FNC_ok ; Bit is valid - move.b (f_host_sr+1)-flag_storage(a3),d1 - andi.b #%00000001,d1 - or.b d1,flag_byte-flag_storage(a3) - ori.b #%00000001,flag_valid-flag_storage(a3) -FNC_ok: - move.b flag_byte-flag_storage(a3),d1 - andi.b #%00000001,d1 - rts - - ;; Normalize and return **INVERSE** of emulated Zero bit - ;; (loaded into host's zero flag) - - ;; Destroys d1 -f_norm_z: - move.b flag_valid-flag_storage(a3),d1 - andi.b #%01000000,d1 - bne.s FNZ_ok ; Bit is valid - bsr flags_normalize -FNZ_ok: - move.b flag_byte-flag_storage(a3),d1 - andi.b #%01000000,d1 - rts - - ;; Normalize and return **INVERSE** of emulated Parity/oVerflow - ;; bit (loaded into host zero flag) - - ;; Destroys d1 -f_norm_pv: - move.b flag_valid-flag_storage(a3),d1 - andi.b #%00000100,d1 - bne.s FNPV_ok ; Bit is already valid - bsr flags_normalize -FNPV_ok: - move.b flag_byte-flag_storage(a3),d1 - andi.b #%00000100,d1 - rts - - ;; Calculate the P/V bit as Parity, for the byte in - ;; d1. Destroys d0,d1. -f_calc_parity: - andi.w #$ff,d1 - move.b lut_parity-flag_storage(a3,d1.w),d1 - move.b (flag_byte),d0 - and.b #%11110111,d0 - or.w #%0000100000000000,d0 - or.b d1,d0 - move.w d0,flag_byte-flag_storage(a3) - rts - - ;; Routine to make both the Carry and Half-Carry flags valid. - ;; Trashes d0, d1. -f_calc_carries: - ;; XXX do this - ;; if f_tmp_byte == 0 { - ;; return, shit is valid - ;; } else if f_tmp_byte == 2 { - ;; // it's a word - ;; add f_tmp_src_w to f_tmp_dst_w - ;; low bytes only, create a carry and save - ;; then high bytes, create a carry and output - ;; then 3rd nibble, create a half-carry and output - ;; } else if f_tmp_byte == 3 { - ;; // it's a byte - ;; add f_tmp_src_b to f_tmp_dst_b - ;; create a carry and output - ;; add low nybbles only - ;; create a half-carry and output - ;; } - ;; set f_tmp_byte = 0 - pushm d2-d5 ; how many registers do I need? - move.b f_tmp_byte(pc),d0 - bne f_cc_dirty - rts -f_cc_dirty: - cmpi.b #2,d0 - bne f_cc_byte - ;; it's a word! - move.w f_tmp_src_w(pc),d2 - move.w f_tmp_dst_w(pc),d3 - move.w d3,d4 - add.w d2,d3 - move sr,d5 - andi.w #1,d5 - rol #8,d5 - andi.w #$0fff,d2 - andi.w #$0fff,d4 - add.w d2,d4 - andi.l #$1000,d4 - ori.w #%00010001,d5 - or.w d4,d5 - or.w d5,flag_byte-flag_storage(a3) - clr.b f_tmp_byte-flag_storage(a3) - popm d2-d5 - rts -f_cc_byte: - move.b f_tmp_src_b(pc),d2 - move.b f_tmp_dst_b(pc),d3 - move.b d3,d4 - add.b d2,d3 - move sr,d5 - andi.b #1,d5 - andi.b #$0f,d2 - andi.b #$0f,d4 - add.b d2,d4 - andi.b #$10,d4 - or.b d4,d5 - or.b d5,flag_byte-flag_storage(a3) - clr.b f_tmp_byte-flag_storage(a3) - or.b #%00010001,flag_valid-flag_storage(a3) - popm d2-d5 - rts - - ;; Normalize and return inverse of emulated Sign bit (loaded - ;; into host zero flag). - - ;; Destroys d1 -f_norm_sign: - move.b flag_valid-flag_storage(a3),d1 - andi.b #%01000000,d1 - bne.s FNsign_ok ; Bit is already valid - bsr flags_normalize -FNsign_ok: - move.b flag_byte-flag_storage(a3),d1 - andi.b #%01000000,d1 - rts - - ;; Routine to turn 68k flags into z80 flags. -flags_normalize: - move.b (f_host_sr+1)(pc),d1 ; 8/4 - ;; .w keeps d1 clean - andi.w #%00011111,d1 ; 8/4 - - ;; doesn't this invalidate the previous contents of d1 - ;; entirely? - move.b lut_ccr(pc,d1.w),d1 ; 10/4 - move.b flag_valid(pc),d0 - not.b d0 - and.b d0,d1 ; Mask out all the unwanted bits - not.b d0 - ori.b #%11000101,d0 ; These are the z80 flag register bits that can be derived from the 68k CCR. - move.b d0,flag_valid-flag_storage(a3) - or.b d1,flag_byte-flag_storage(a3) - rts - - ;; Routine to completely fill the flags register -flags_all: - bsr flags_normalize - bsr f_calc_carries - rts - - EVEN -flag_storage: - ;; 0 if the flag is already valid - ;; 2 if tmp_???b is valid - ;; 3 if tmp_???w is valid -f_tmp_byte: dc.b 0 - - ;; 2 if P is 0 - ;; 3 if P is 1 - ;; 4 if P is uncalculated Parity - ;; 5 if P is uncalculated oVerflow -f_tmp_p_type: dc.b 0 - - ;; byte operands -f_tmp_src_b: dc.b 0 -f_tmp_dst_b: dc.b 0 -f_tmp_result_b: dc.b 0 - - EVEN -f_tmp_src_w: dc.w 0 -f_tmp_dst_w: dc.w 0 -f_tmp_result_w: dc.w 0 - - ;; 000XNZVC - EVEN - ;; DO NOT REARRANGE THESE -f_host_sr: dc.w 0 -f_host_ccr: dc.b 0 ;XXX make overlap somehow? - - EVEN - ;; DO NOT REARRANGE THESE. -flag_byte: dc.b 0 ; Byte of all flags -flag_valid: dc.b 0 ; Validity mask -- 1 if valid. - - - ;; LUT for the CCR -> F mapping -lut_ccr: - ;; N =S - ;; Z = Z - ;; V ~ P - ;; C= C - ;; - ;; =CCR= == z80== - ;; XNZVC SZ5H3PNC - dc.b %00000000 ;; 00000 00000000 - dc.b %00000001 ;; 00001 00000001 - dc.b %00000100 ;; 00010 00000100 - dc.b %00000101 ;; 00011 00000101 - dc.b %01000000 ;; 00100 01000000 - dc.b %01000001 ;; 00101 01000001 - dc.b %01000100 ;; 00110 01000100 - dc.b %01000101 ;; 00111 01000101 - dc.b %10000000 ;; 01000 10000000 - dc.b %10000001 ;; 01001 10000001 - dc.b %10000100 ;; 01010 10000100 - dc.b %10000101 ;; 01011 10000101 - dc.b %11000000 ;; 01100 11000000 - dc.b %11000001 ;; 01101 11000001 - dc.b %11000100 ;; 01110 11000100 - dc.b %11000101 ;; 01111 11000101 - dc.b %00000000 ;; 10000 00000000 - dc.b %00000001 ;; 10001 00000001 - dc.b %00000100 ;; 10010 00000100 - dc.b %00000101 ;; 10011 00000101 - dc.b %01000000 ;; 10100 01000000 - dc.b %01000001 ;; 10101 01000001 - dc.b %01000100 ;; 10110 01000100 - dc.b %01000101 ;; 10111 01000101 - dc.b %10000000 ;; 11000 10000000 - dc.b %10000001 ;; 11001 10000001 - dc.b %10000100 ;; 11010 10000100 - dc.b %10000101 ;; 11011 10000101 - dc.b %11000000 ;; 11100 11000000 - dc.b %11000001 ;; 11101 11000001 - dc.b %11000100 ;; 11110 11000100 - dc.b %11000101 ;; 11111 11000101 - - ;; 256-byte LUT for the Parity bit. - ;; Keep this last so all storage references require only one - ;; extension word. - ;; - ;; This table taken from another z80 emulator -lut_parity: - dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 - dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 - dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 - dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 - dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 - dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 - dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 - dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 - dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 - dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 - dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 - dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 - dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 - dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 - dc.b 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 - dc.b 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 - - ;; To save space I might be able to overlay the Parity table - ;; with the CCR table, or even interleave it in the opcodes. - - diff --git a/flags.s b/flags.s new file mode 100644 index 0000000..8fc2058 --- /dev/null +++ b/flags.s @@ -0,0 +1,315 @@ + ;; Routine to set the given flags + ;; Noted in \mask by a 1 bit +.macro F_SET mask ; 32 cycles, 8 bytes + or.b \mask,flag_byte-flag_storage(a3) + or.b \mask,flag_valid-flag_storage(a3) +.endm + + ;; Clear the given flags + ;; Noted in \mask (must be a reg) by a 1 bit +.macro F_CLEAR mask ; 36 cycles, 10 bytes + or.b \mask,flag_valid-flag_storage(a3) + not.b \mask + and.b \mask,flag_byte-flag_storage(a3) +.endm + + ;; Use this when an instruction uses the P/V bit as Parity. + ;; Sets or clears the bit explicitly. + ;; + ;; Byte for which parity is calculated must be in \byte. High + ;; byte of \byte.w must be zero, using d0 is suggested. (a0,d1 + ;; destroyed) + +.macro F_PAR byte + ori.b #%00000100,flag_valid-flag_storage(a3) + move.b flag_byte(pc),d1 + andi.b #%11111011,d1 + lea lut_parity(pc),a0 + or.b 0(a0,\byte.w),d1 + move.b d1,flag_byte-flag_storage(a3) +.endm + + + ;; Use this when an instruction uses the P/V bit as Overflow. + ;; Leaves the bit itself implicit; simply marks it dirty. +.macro F_OVFL ; 20 cycles, 6 bytes + andi.b #%11111011,flag_valid-flag_storage(a3) +.endm + + ;; Save the two operands from ADD \1,\2 +.macro F_ADD_SAVE src dst + move.b \src,f_tmp_src_b-flag_storage(a3) + move.b \dst,f_tmp_dst_b-flag_storage(a3) + move.b #$01,f_tmp_byte-flag_storage(a3) + F_SET #% +.endm + + + +.text + + ;; Normalize and return inverse of emulated Carry bit (loaded + ;; into host zero flag) + + ;; Destroys d1 +f_norm_c: + move.b flag_valid-flag_storage(a3),d1 +; d1 is destroyed in all cases, so you can use lsr and the C bit (same speed, smaller) + lsr.b #1,d1 + bcs.s FNC_ok ; Bit is valid + move.b (f_host_sr+1)-flag_storage(a3),d1 + andi.b #%00000001,d1 + or.b d1,flag_byte-flag_storage(a3) + ori.b #%00000001,flag_valid-flag_storage(a3) +FNC_ok: + move.b flag_byte-flag_storage(a3),d1 + andi.b #%00000001,d1 + rts + + ;; Normalize and return **INVERSE** of emulated Zero bit + ;; (loaded into host's zero flag) + + ;; Destroys d1 +f_norm_z: + move.b flag_valid-flag_storage(a3),d1 + andi.b #%01000000,d1 + bne.s FNZ_ok ; Bit is valid + bsr flags_normalize +FNZ_ok: + move.b flag_byte-flag_storage(a3),d1 + andi.b #%01000000,d1 + rts + + ;; Normalize and return **INVERSE** of emulated Parity/oVerflow + ;; bit (loaded into host zero flag) + + ;; Destroys d1 +f_norm_pv: + move.b flag_valid-flag_storage(a3),d1 + andi.b #%00000100,d1 + bne.s FNPV_ok ; Bit is already valid + bsr flags_normalize +FNPV_ok: + move.b flag_byte-flag_storage(a3),d1 + andi.b #%00000100,d1 + rts + + ;; Calculate the P/V bit as Parity, for the byte in + ;; d1. Destroys d0,d1. +f_calc_parity: + andi.w #$ff,d1 + move.b lut_parity-flag_storage(a3,d1.w),d1 + move.b (flag_byte),d0 + and.b #%11110111,d0 + or.w #%0000100000000000,d0 + or.b d1,d0 + move.w d0,flag_byte-flag_storage(a3) + rts + + ;; Routine to make both the Carry and Half-Carry flags valid. + ;; Trashes d0, d1. +f_calc_carries: + ;; XXX do this + ;; if f_tmp_byte == 0 { + ;; return, shit is valid + ;; } else if f_tmp_byte == 2 { + ;; // it's a word + ;; add f_tmp_src_w to f_tmp_dst_w + ;; low bytes only, create a carry and save + ;; then high bytes, create a carry and output + ;; then 3rd nibble, create a half-carry and output + ;; } else if f_tmp_byte == 3 { + ;; // it's a byte + ;; add f_tmp_src_b to f_tmp_dst_b + ;; create a carry and output + ;; add low nybbles only + ;; create a half-carry and output + ;; } + ;; set f_tmp_byte = 0 + pushm d2-d5 ; how many registers do I need? + move.b f_tmp_byte(pc),d0 + bne f_cc_dirty + rts +f_cc_dirty: + cmpi.b #2,d0 + bne f_cc_byte + ;; it's a word! + move.w f_tmp_src_w(pc),d2 + move.w f_tmp_dst_w(pc),d3 + move.w d3,d4 + add.w d2,d3 + move sr,d5 + andi.w #1,d5 + rol #8,d5 + andi.w #$0fff,d2 + andi.w #$0fff,d4 + add.w d2,d4 + andi.l #$1000,d4 + ori.w #%00010001,d5 + or.w d4,d5 + or.w d5,flag_byte-flag_storage(a3) + clr.b f_tmp_byte-flag_storage(a3) + popm d2-d5 + rts +f_cc_byte: + move.b f_tmp_src_b(pc),d2 + move.b f_tmp_dst_b(pc),d3 + move.b d3,d4 + add.b d2,d3 + move sr,d5 + andi.b #1,d5 + andi.b #$0f,d2 + andi.b #$0f,d4 + add.b d2,d4 + andi.b #$10,d4 + or.b d4,d5 + or.b d5,flag_byte-flag_storage(a3) + clr.b f_tmp_byte-flag_storage(a3) + or.b #%00010001,flag_valid-flag_storage(a3) + popm d2-d5 + rts + + ;; Normalize and return inverse of emulated Sign bit (loaded + ;; into host zero flag). + + ;; Destroys d1 +f_norm_sign: + move.b flag_valid-flag_storage(a3),d1 + andi.b #%01000000,d1 + bne.s FNsign_ok ; Bit is already valid + bsr flags_normalize +FNsign_ok: + move.b flag_byte-flag_storage(a3),d1 + andi.b #%01000000,d1 + rts + + ;; Routine to turn 68k flags into z80 flags. +flags_normalize: + move.b (f_host_sr+1)(pc),d1 ; 8/4 + ;; .w keeps d1 clean + andi.w #%00011111,d1 ; 8/4 + + ;; doesn't this invalidate the previous contents of d1 + ;; entirely? + move.b lut_ccr(pc,d1.w),d1 ; 10/4 + move.b flag_valid(pc),d0 + not.b d0 + and.b d0,d1 ; Mask out all the unwanted bits + not.b d0 + ori.b #%11000101,d0 ; These are the z80 flag register bits that can be derived from the 68k CCR. + move.b d0,flag_valid-flag_storage(a3) + or.b d1,flag_byte-flag_storage(a3) + rts + + ;; Routine to completely fill the flags register +flags_all: + bsr flags_normalize + bsr f_calc_carries + rts + + + +.data +flag_storage: + ;; 0 if the flag is already valid + ;; 2 if tmp_???b is valid + ;; 3 if tmp_???w is valid +f_tmp_byte: .byte 0 + + ;; 2 if P is 0 + ;; 3 if P is 1 + ;; 4 if P is uncalculated Parity + ;; 5 if P is uncalculated oVerflow +f_tmp_p_type: .byte 0 + + ;; byte operands +f_tmp_src_b: .byte 0 +f_tmp_dst_b: .byte 0 +f_tmp_result_b: .byte 0 + +.even +f_tmp_src_w: .word 0 +f_tmp_dst_w: .word 0 +f_tmp_result_w: .word 0 + + ;; 000XNZVC +.even + ;; DO NOT REARRANGE THESE +f_host_sr: .word 0 +f_host_ccr: .byte 0 ;XXX make overlap somehow? + +.even + ;; DO NOT REARRANGE THESE. +flag_byte: .byte 0 ; Byte of all flags +flag_valid: .byte 0 ; Validity mask -- 1 if valid. + + + ;; LUT for the CCR -> F mapping +lut_ccr: + ;; N =S + ;; Z = Z + ;; V ~ P + ;; C= C + ;; + ;; =CCR= == z80== + ;; XNZVC SZ5H3PNC + .byte %00000000 ;; 00000 00000000 + .byte %00000001 ;; 00001 00000001 + .byte %00000100 ;; 00010 00000100 + .byte %00000101 ;; 00011 00000101 + .byte %01000000 ;; 00100 01000000 + .byte %01000001 ;; 00101 01000001 + .byte %01000100 ;; 00110 01000100 + .byte %01000101 ;; 00111 01000101 + .byte %10000000 ;; 01000 10000000 + .byte %10000001 ;; 01001 10000001 + .byte %10000100 ;; 01010 10000100 + .byte %10000101 ;; 01011 10000101 + .byte %11000000 ;; 01100 11000000 + .byte %11000001 ;; 01101 11000001 + .byte %11000100 ;; 01110 11000100 + .byte %11000101 ;; 01111 11000101 + .byte %00000000 ;; 10000 00000000 + .byte %00000001 ;; 10001 00000001 + .byte %00000100 ;; 10010 00000100 + .byte %00000101 ;; 10011 00000101 + .byte %01000000 ;; 10100 01000000 + .byte %01000001 ;; 10101 01000001 + .byte %01000100 ;; 10110 01000100 + .byte %01000101 ;; 10111 01000101 + .byte %10000000 ;; 11000 10000000 + .byte %10000001 ;; 11001 10000001 + .byte %10000100 ;; 11010 10000100 + .byte %10000101 ;; 11011 10000101 + .byte %11000000 ;; 11100 11000000 + .byte %11000001 ;; 11101 11000001 + .byte %11000100 ;; 11110 11000100 + .byte %11000101 ;; 11111 11000101 + + ;; 256-byte LUT for the Parity bit. + ;; Keep this last so all storage references require only one + ;; extension word. + ;; + ;; This table taken from another z80 emulator +lut_parity: + .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 + .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 + .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 + .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 + .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 + .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 + .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 + .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 + .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 + .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 + .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 + .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 + .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 + .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 + .byte 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0 + .byte 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4 + + ;; To save space I might be able to overlay the Parity table + ;; with the CCR table, or even interleave it in the opcodes. + + diff --git a/interrupts.asm.m4 b/interrupts.asm.m4 deleted file mode 100644 index 7b4e522..0000000 --- a/interrupts.asm.m4 +++ /dev/null @@ -1,113 +0,0 @@ -;;; interrupt handling code, in -*- asm -*- - - ;; Current interrupt mode. IM 1 and friends will modify - ;; this. It can be any of 0, 1, 2. -int_mode: dc.b 0 - - ;; 0 if the emulated device doesn't want interrupts. - ;; 1 if interrupts are turned on. -int_enabled: dc.b 1 - - - ;; In interrupt mode 0, an interrupt will force a byte onto - ;; the data bus for the processor to execute. To handle - ;; those, the emulator will store the bus byte in int_opcode, - ;; which is followed by an absolute jump to the "next - ;; instruction". The value of int_jump will then be - ;; &int_opcode. - ;; - ;; This differs slightly from what I understand to be actual - ;; handling. The hardware will fetch an immediate argument to - ;; the interrupting instruction from the next location in - ;; memory. - ;; - ;; This emulator, on the other hand, will fetch the immediate - ;; argument from the JP instruction in the shim, and then - ;; dance off into la-la land. -int0_opcode: dc.b 0 - dc.b $c3 ; JP immed.w -int0_return: dc.w 0 ; the destination address - - - ;; This is the interrupt routine. It can come at any point - ;; during an instruction, though routines that use a5 (e.g. by - ;; calling C subroutines) will have to turn off or hold - ;; interrupts. - ;; - ;; Routines that call into TIOS will have to remove this - ;; interrupt handler. -int_handler: - sub.l #INT_OFFSET,a5 - rte - - -int_nevermind: - rts -do_interrupt: - add.l #INT_OFFSET,a5 ; clear the interrupt flag - pea 0(a5,d0.w) ; allows us to rts properly - - tst.b int_enabled ; 4 cycles - beq.b int_nevermind ; 8 cycles not taken - ;; Common case: interrupts enabled, fall through - - ;; Since this is an instruction all its own, we have D0, D1, - ;; and D2 available. - - ;; Interrupts are most often in mode 1, then mode 2, and - ;; almost never in mode 0. - move.b int_mode,d0 - cmpi.b #1,d0 - beq int_do_mode2 - cmpi.b #2,d0 - beq int_do_mode1 - cmpi.b #1,d0 - beq int_do_mode0 - rts - - ;; This routine emulates a mode 0 interrupt. - - ;; IM 0: A byte is placed on the bus and executed as if it - ;; were inline in the program. This emulator will put that - ;; byte into int0_opcode and set epc (or int_jump) to point - ;; there. -int_do_mode0: - move epc,int0_opcode - rts - - ;; This routine emulates a mode 1 interrupt. - - ;; IM 1: RST 38 is executed on every interrupt. This is what - ;; the TI-83+ uses almost all the time. -int_do_mode1: - jmp emu_op_ff - - - ;; This routine emulates a mode 2 interrupt. - - ;; IM 2: Vectored, the address jumped to is as follows: - ;; - ;; (I << 8) | (byte & 0xfe) - ;; - ;; where I is the I register, and byte is the byte that was - ;; found on the bus. -int_do_mode2: - rts - - ;; This routine emulates a non-maskable interrupt. -int_do_nmi: - rts - - - - - ;; This routine is used by the emulated DI instruction, which - ;; turns off emulator interrupts. -ints_stop: - rts - - ;; This routine is used by the emulated EI instruction, which - ;; turns on emulator interrupts. -ints_start: - rts - diff --git a/interrupts.s.m4 b/interrupts.s.m4 new file mode 100644 index 0000000..66b71d8 --- /dev/null +++ b/interrupts.s.m4 @@ -0,0 +1,115 @@ +;;; interrupt handling code, in -*- asm -*- + +.data + ;; Current interrupt mode. IM 1 and friends will modify + ;; this. It can be any of 0, 1, 2. +int_mode: dc.b 0 + + ;; 0 if the emulated device doesn't want interrupts. + ;; 1 if interrupts are turned on. +int_enabled: dc.b 1 + + + ;; In interrupt mode 0, an interrupt will force a byte onto + ;; the data bus for the processor to execute. To handle + ;; those, the emulator will store the bus byte in int_opcode, + ;; which is followed by an absolute jump to the "next + ;; instruction". The value of int_jump will then be + ;; &int_opcode. + ;; + ;; This differs slightly from what I understand to be actual + ;; handling. The hardware will fetch an immediate argument to + ;; the interrupting instruction from the next location in + ;; memory. + ;; + ;; This emulator, on the other hand, will fetch the immediate + ;; argument from the JP instruction in the shim, and then + ;; dance off into la-la land. +int0_opcode: dc.b 0 + dc.b $c3 ; JP immed.w +int0_return: dc.w 0 ; the destination address + + +.text + ;; This is the interrupt routine. It can come at any point + ;; during an instruction, though routines that use a5 (e.g. by + ;; calling C subroutines) will have to turn off or hold + ;; interrupts. + ;; + ;; Routines that call into TIOS will have to remove this + ;; interrupt handler. +int_handler: + sub.l #INT_OFFSET,a5 + rte + + +int_nevermind: + rts +do_interrupt: + add.l #INT_OFFSET,a5 ; clear the interrupt flag + pea 0(a5,d0.w) ; allows us to rts properly + + tst.b int_enabled ; 4 cycles + beq.b int_nevermind ; 8 cycles not taken + ;; Common case: interrupts enabled, fall through + + ;; Since this is an instruction all its own, we have D0, D1, + ;; and D2 available. + + ;; Interrupts are most often in mode 1, then mode 2, and + ;; almost never in mode 0. + move.b int_mode,d0 + cmpi.b #1,d0 + beq int_do_mode2 + cmpi.b #2,d0 + beq int_do_mode1 + cmpi.b #1,d0 + beq int_do_mode0 + rts + + ;; This routine emulates a mode 0 interrupt. + + ;; IM 0: A byte is placed on the bus and executed as if it + ;; were inline in the program. This emulator will put that + ;; byte into int0_opcode and set epc (or int_jump) to point + ;; there. +int_do_mode0: + move epc,int0_opcode + rts + + ;; This routine emulates a mode 1 interrupt. + + ;; IM 1: RST 38 is executed on every interrupt. This is what + ;; the TI-83+ uses almost all the time. +int_do_mode1: + jmp emu_op_ff + + + ;; This routine emulates a mode 2 interrupt. + + ;; IM 2: Vectored, the address jumped to is as follows: + ;; + ;; (I << 8) | (byte & 0xfe) + ;; + ;; where I is the I register, and byte is the byte that was + ;; found on the bus. +int_do_mode2: + rts + + ;; This routine emulates a non-maskable interrupt. +int_do_nmi: + rts + + + + + ;; This routine is used by the emulated DI instruction, which + ;; turns off emulator interrupts. +ints_stop: + rts + + ;; This routine is used by the emulated EI instruction, which + ;; turns on emulator interrupts. +ints_start: + rts + diff --git a/main.asm b/main.asm deleted file mode 100644 index 76b84fe..0000000 --- a/main.asm +++ /dev/null @@ -1,196 +0,0 @@ -;;; z80 emulator for 68k calculators - -;;; Astrid Smith -;;; Project started: 2010-06-06 -;;; GPL - -;;; Yes, I use lots of big ascii art. With this much code, you need -;;; something to catch your eye when scrolling through it. I suppose -;;; I'll split it into different files later. - -;;; Registers used: -;;; -;;; A7 68000 stack pointer -;;; A6/epc emulated PC -;;; A5 instruction table base pointer -;;; A4 emulated SP -;;; A3 pointer to flag_storage -;;; A2 -;;; A1 -;;; A0 -;;; -;;; D0 current instruction, scratch for macros -;;; D1 scratch for instructions -;;; D2 further scratch -;;; -;;; -;;; The following have their shadows in the top half of the register -;;; D3/eaf = AF A is in the low byte, F in the high byte (yeah ... speed) -;;; D4/ebc = BC B high, C low -;;; D5/ede = DE D high, E low -;;; D6/ehl = HL H high, L low -;;; -;;; IY is used more often so it's easier to get at. It can be slow -;;; but I don't really care to go to the effort to make it so. -;;; D7/eixy = IX (hi word), IY (low word) - - -;;; emulated I and R are both in RAM - - xdef _ti89 -; xdef _ti92plus - xdef __main -; xdef _tigcc_native - include "../tios.h" - - include "global.inc" - -__main: - movem.l d0-d7/a0-a6,-(sp) - bsr init_load - bsr display_setup - - bsr emu_setup - lea emu_plain_op,a5 - - ;; ... aaaaand we're off! - jsr emu_run - bsr emu_teardown - - bsr display_teardown - bsr unload - movem.l (sp)+,d0-d7/a0-a6 - rts - - include "ports.asm" - include "interrupts.asm" - include "flags.asm" - include "alu.asm" - -emu_setup: - movea.l emu_op_00,a5 - lea emu_run,a2 - lea flag_storage,a3 - move.w #$4000,d1 - bsr deref - move.l a0,epc - move.l a0,esp - - rts - -emu_teardown: - rts - - -;; |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -;; _ __ ___ ___ _ __ ___ ___ _ __ _ _ ||||||||||||||||||||||||||| -;; | '_ ` _ \ / _ \ '_ ` _ \ / _ \| '__| | | | \\\\\\\\\\\\\\\\\\\\\\\\\\\ -;; | | | | | | __/ | | | | | (_) | | | |_| | ||||||||||||||||||||||||||| -;; |_| |_| |_|\___|_| |_| |_|\___/|_| \__, | /////////////////////////// -;; of the virtual type |___/ ||||||||||||||||||||||||||| -;; =============================================JJJJJJJJJJJJJJJJJJJJJJJJJJJ - - ;; Take a virtual address in d1 and dereference it. Returns the - ;; host address in a0. Destroys a0, d0. -deref: ; 76 cycles + 18 cycles for bsr - ; 20 bytes to inline, saves 34 cycles per call - move.w d1,d0 - andi.w #$3FFF,d0 - movea.w d0,a0 - move.w d1,d0 - andi.w #$C000,d0 ; Can cut this out by pre-masking the table. - rol.w #4,d0 - adda.l deref_table(pc,d0.w),a0 - rts - - EVEN -deref_table: -mem_page_0: dc.l 0 ; bank 0 / 0x0000 -mem_page_1: dc.l 0 ; bank 1 / 0x4000 -mem_page_2: dc.l 0 ; bank 2 / 0x8000 -mem_page_3: dc.l 0 ; bank 3 / 0xc000 - - xdef mem_page_0 - xdef mem_page_1 - xdef mem_page_2 - xdef mem_page_3 - -mem_page_loc_0: dc.b 0 -mem_page_loc_1: dc.b 0 -mem_page_loc_2: dc.b 0 -mem_page_loc_3: dc.b 0 - - xdef mem_page_loc_0 - xdef mem_page_loc_1 - xdef mem_page_loc_2 - xdef mem_page_loc_3 - -pages: dc.l 0 - - xdef pages - - ;; Take a physical address in a0 and turn it into a virtual - ;; address in d0 - ;; Destroys d0 -; XXX AFAICS, a1 is currently a scratch address register, so you can load deref_table in it, and then save some space: -; But you may wish to use it for other purposes in the future, so you needn't integrate that immediately. - - ;; Guessing this is 300 cycles. -underef: - move.l d2,-(a7) - lea deref_table(pc),a1 - move.l a0,d0 - clr.w d2 - sub.l (a1)+,d0 - bmi.s underef_not0 - cmpi.l #$4000,d0 - bmi.s underef_thatsit -underef_not0: - move.l a0,d0 - move.w #$4000,d2 - sub.l (a1)+,d0 - bmi.s underef_not1 - cmpi.l #$4000,d0 - bmi.s underef_thatsit -underef_not1: - move.l a0,d0 - move.w #$8000,d2 - sub.l (a1)+,d0 - bmi.s underef_not2 - cmpi.l #$4000,d0 - bmi.s underef_thatsit -underef_not2: - move.w #$c000,d2 - suba.l (a1)+,a0 - ;; if that fails too, well shit man! - moveq #0,d0 -underef_thatsit: - add.w d2,d0 - move.l (a7)+,d2 - rts - - -;; ========================================================================= -;; instruction instruction instruction ================================ -;; _ _ _ _ ================================ -;; __| (_)___ _ __ __ _| |_ ___| |__ ================================ -;; / _` | / __| '_ \ / _` | __/ __| '_ \ ================================ -;; | (_| | \__ \ |_) | (_| | || (__| | | | ================================ -;; \__,_|_|___/ .__/ \__,_|\__\___|_| |_| ================================ -;; |_| ================================= -;; ========== ======================================================== -;; ========================================================================= - - include "opcodes.asm" - -emu_run: - ;; XXX: make this actually return - DONE - rts - -emu_op_undo_cb: -emu_op_undo_dd: -emu_op_undo_ed: -emu_op_undo_fd: - rts - diff --git a/main.s b/main.s new file mode 100644 index 0000000..a45950a --- /dev/null +++ b/main.s @@ -0,0 +1,200 @@ +||| -*- mode: gas; gas-comment-char: 124 -*- +||| z80 emulator for 68k calculators + +||| Astrid Smith +||| Project started: 2010-06-06 +||| GPL + +||| Yes, I use lots of big ascii art. With this much code, you need +||| something to catch your eye when scrolling through it. I suppose +||| I'll split it into different files later. + +||| Registers used: +||| +||| A7 68000 stack pointer +||| A6/epc emulated PC +||| A5 instruction table base pointer +||| A4 emulated SP +||| A3 pointer to flag_storage +||| A2 +||| A1 +||| A0 +||| +||| D0 current instruction, scratch for macros +||| D1 scratch for instructions +||| D2 further scratch +||| +||| +||| The following have their shadows in the top half of the register +||| D3/eaf = AF A is in the low byte, F in the high byte (yeah ... speed) +||| D4/ebc = BC B high, C low +||| D5/ede = DE D high, E low +||| D6/ehl = HL H high, L low +||| +||| IY is used more often so it's easier to get at. It can be slow +||| but I don't really care to go to the effort to make it so. +||| D7/eixy = IX (hi word), IY (low word) + + +||| emulated I and R are both in RAM + +.xdef _ti89 +|.xdef _ti92plus +.xdef __main +|.xdef _tigcc_native +.include "../tios.h" + +.include "global.inc" + +__main: + movem.l d0-d7/a0-a6,-(sp) + bsr init_load + bsr display_setup + + bsr emu_setup + lea emu_plain_op,a5 + + || ... aaaaand we're off! + jsr emu_run + bsr emu_teardown + + bsr display_teardown + bsr unload + movem.l (sp)+,d0-d7/a0-a6 + rts + +.include "ports.s" +.include "interrupts.s" +.include "flags.s" +.include "alu.s" + +emu_setup: + movea.l emu_op_00,a5 + lea emu_run,a2 + lea flag_storage,a3 + move.w #$4000,d1 + bsr deref + move.l a0,epc + move.l a0,esp + + rts + +emu_teardown: + rts + + +|| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +|| _ __ ___ ___ _ __ ___ ___ _ __ _ _ ||||||||||||||||||||||||||| +|| | '_ ` _ \ / _ \ '_ ` _ \ / _ \| '__| | | | \\\\\\\\\\\\\\\\\\\\\\\\\\\ +|| | | | | | | __/ | | | | | (_) | | | |_| | ||||||||||||||||||||||||||| +|| |_| |_| |_|\___|_| |_| |_|\___/|_| \__, | /////////////////////////// +|| of the virtual type |___/ ||||||||||||||||||||||||||| +|| =============================================JJJJJJJJJJJJJJJJJJJJJJJJJJJ + + || Take a virtual address in d1 and dereference it. Returns the + || host address in a0. Destroys a0, d0. +deref: | 76 cycles + 18 cycles for bsr + | 20 bytes to inline, saves 34 cycles per call + move.w d1,d0 + andi.w #$3FFF,d0 + movea.w d0,a0 + move.w d1,d0 + andi.w #$C000,d0 | Can cut this out by pre-masking the table. + rol.w #4,d0 + adda.l deref_table(pc,d0.w),a0 + rts + +.even +.data +deref_table: +mem_page_0: .long 0 | bank 0 / 0x0000 +mem_page_1: .long 0 | bank 1 / 0x4000 +mem_page_2: .long 0 | bank 2 / 0x8000 +mem_page_3: .long 0 | bank 3 / 0xc000 + +.xdef mem_page_0 +.xdef mem_page_1 +.xdef mem_page_2 +.xdef mem_page_3 + +mem_page_loc_0: .byte 0 +mem_page_loc_1: .byte 0 +mem_page_loc_2: .byte 0 +mem_page_loc_3: .byte 0 + +.xdef mem_page_loc_0 +.xdef mem_page_loc_1 +.xdef mem_page_loc_2 +.xdef mem_page_loc_3 + +pages: .long 0 + +.xdef pages + +.text + + || Take a physical address in a0 and turn it into a virtual + || address in d0 + || Destroys d0 +| XXX AFAICS, a1 is currently a scratch address register, so you can load deref_table in it, and then save some space: +| But you may wish to use it for other purposes in the future, so you needn't integrate that immediately. + + || Guessing this is 300 cycles. +underef: + move.l d2,-(a7) + lea deref_table(pc),a1 + move.l a0,d0 + clr.w d2 + sub.l (a1)+,d0 + bmi.s underef_not0 + cmpi.l #$4000,d0 + bmi.s underef_thatsit +underef_not0: + move.l a0,d0 + move.w #$4000,d2 + sub.l (a1)+,d0 + bmi.s underef_not1 + cmpi.l #$4000,d0 + bmi.s underef_thatsit +underef_not1: + move.l a0,d0 + move.w #$8000,d2 + sub.l (a1)+,d0 + bmi.s underef_not2 + cmpi.l #$4000,d0 + bmi.s underef_thatsit +underef_not2: + move.w #$c000,d2 + suba.l (a1)+,a0 + || if that fails too, well shit man! + moveq #0,d0 +underef_thatsit: + add.w d2,d0 + move.l (a7)+,d2 + rts + + +|| ========================================================================= +|| instruction instruction instruction ================================ +|| _ _ _ _ ================================ +|| __| (_)___ _ __ __ _| |_ ___| |__ ================================ +|| / _` | / __| '_ \ / _` | __/ __| '_ \ ================================ +|| | (_| | \__ \ |_) | (_| | || (__| | | | ================================ +|| \__,_|_|___/ .__/ \__,_|\__\___|_| |_| ================================ +|| |_| ================================= +|| ========== ======================================================== +|| ========================================================================= + +.include "opcodes.s" + +emu_run: + || XXX: make this actually return + DONE + rts + +emu_op_undo_cb: +emu_op_undo_dd: +emu_op_undo_ed: +emu_op_undo_fd: + rts + diff --git a/opcodes.asm.m4 b/opcodes.asm.m4 deleted file mode 100644 index c88f728..0000000 --- a/opcodes.asm.m4 +++ /dev/null @@ -1,4309 +0,0 @@ -;;; == -*- asm -*- ========================================================= -;;; ======================================================================== -;;; ___ ___ ======= ============================== -;;; ___( _ ) / _ \ 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 ; 106 cycles, 8 bytes - move.w \1,d1 - jsr deref - move.b (a0),\2 - ENDM - - ;; Macro to write a byte in \1 to main memory at \2 -PUTB MACRO ; 106 cycles, 8 bytes - move.w \2,d1 - jsr 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 ; 140 cycles, 16 bytes - move.w \1,d1 - jsr deref - ;; 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 ; 140 cycles, 14 bytes - move.w \2,d1 - jsr 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 esp. - ;; 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 ; 42 cycles, 8 bytes - move.w \1,d2 - LOHI d2 ;slow - move.b d2,-(esp) ; high byte - move.b \1,-(esp) ; low byte - ENDM - - ;; Pop the word at the top of stack esp into \1. - ;; Destroys d0. - - ;; \1_h <- (SP+1) - ;; \1_l <- (SP) - ;; SP <- SP + 2 -POPW MACRO ; 60 cycles, 8 bytes - move.b (esp)+,\1 - LOHI \1 - move.b (esp)+,\1 ; high byte - HILO \1 - ENDM - - ;; == Immediate Memory Macros == - - ;; Macro to read an immediate byte into \1. -FETCHBI MACRO ; 8 cycles, 2 bytes - move.b (epc)+,\1 - 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+$100 ; opcode routine length - jmp do_interrupt ; for interrupt routines - ENDM - -START_DD MACRO - ORG emu_plain_op+_align+$40 - ENDM - -START_CB MACRO - ORG emu_plain_op+_align+$42 - ENDM - -START_DDCB MACRO - ORG emu_plain_op+_align+$44 - ENDM - -START_FD MACRO - ORG emu_plain_op+_align+$46 - ENDM - -START_FDCB MACRO - ORG emu_plain_op+_align+$48 - ENDM - -START_ED MACRO - ORG emu_plain_op+_align+$4A - ENDM - - ;; LOHI/HILO are hideously slow for instructions used often. - ;; Consider interleaving 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 - 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 ; 52 cycles, 14 bytes - move.l \1,-(sp) - movep.w 0(sp),\1 - swap \1 - movep.w 1(sp),\1 - addq #4,sp - ENDM - - ;; == Special Opcode Macros ======================================== - - ;; Do an ADD \1,\2 -F_ADD_W MACRO ; ? cycles, ? bytes - ;; XXX - ENDM - ;; Do an SUB \1,\2 -F_SUB_W MACRO ; ? cycles, ? bytes - ;; XXX - ENDM - - ;; INC and DEC macros -F_INC_B MACRO ; 108 cycles, 34 bytes - 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 ; 80 cycles, 26 bytes - 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 ; 4 cycles, 2 bytes - addq.w #1,\1 - ENDM - -F_DEC_W MACRO ; 4 cycles, 2 bytes - 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 - 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 - 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 - - ;; I would like to thank the State of Washington for - ;; supporting the initial development of this file, by giving - ;; me a job doing nothing with no oversight for hours at a - ;; time. - - ;; NOP -OPCODE(00,«»,4) - - ;; -OP_DD(00,«») - - ;; RLC B -OP_CB(00,«») - - ;; -OP_DDCB(00,«») - - ;; -OP_FD(00,«») - - ;; -OP_FDCB(00,«») - - ;; -OP_ED(00,«») - - ;; LD BC,immed.w - ;; Read a word and put it in BC - ;; No flags - ;; 42 cycles -OPCODE(01,« - FETCHWI ebc - »,36,,12) - -OP_DD(01,«») -OP_CB(01,«») -OP_DDCB(01,«») -OP_FD(01,«») -OP_FDCB(01,«») -OP_ED(01,«») - - - ;; LD (BC),A - ;; (BC) <- A - ;; No flags - ;; 106 cycles -OPCODE(02,« - PUTB eaf,ebc - »,14,,4) - -OP_DD(02,«») -OP_CB(02,«») -OP_DDCB(02,«») -OP_FD(02,«») -OP_FDCB(02,«») -OP_ED(02,«») - - ;; INC BC - ;; BC <- BC+1 - ;; No flags - ;; 4 cycles -OPCODE(03,« - F_INC_W ebc - »,4,,2) - -OP_DD(03,«») -OP_CB(03,«») -OP_DDCB(03,«») -OP_FD(03,«») -OP_FDCB(03,«») -OP_ED(03,«») - - ;; INC B - ;; B <- B+1 - ;; 152 cycles -OPCODE(04,« - LOHI ebc - F_INC_B ebc - HILO ebc - ») - -OP_DD(04,«») -OP_CB(04,«») -OP_DDCB(04,«») -OP_FD(04,«») -OP_FDCB(04,«») -OP_ED(04,«») - - ;; DEC B - ;; B <- B-1 - ;; 124 cycles -OPCODE(05,« - LOHI ebc - F_DEC_B ebc - HILO ebc - ») - ;nok - -OP_DD(05,«») -OP_CB(05,«») -OP_DDCB(05,«») -OP_FD(05,«») -OP_FDCB(05,«») -OP_ED(05,«») - - ;; LD B,immed.b - ;; Read a byte and put it in B - ;; B <- immed.b - ;; No flags - ;; 52 cycles -OPCODE(06,« - LOHI ebc - FETCHBI ebc - HILO ebc - »,26,,10) - ;nok - -OP_DD(06,«») -OP_CB(06,«») -OP_DDCB(06,«») -OP_FD(06,«») -OP_FDCB(06,«») -OP_ED(06,«») - - ;; RLCA - ;; Rotate A left, carry bit gets top bit - ;; Flags: H,N=0; C aff. - ;; XXX flags - ;; ? cycles -OPCODE(07,« - rol.b #1,eaf - »,4,,2) - ;nok - -OP_DD(07,«») -OP_CB(07,«») -OP_DDCB(07,«») -OP_FD(07,«») -OP_FDCB(07,«») -OP_ED(07,«») - - ;; EX AF,AF' - ;; No flags - ;; XXX AF - ;; 4 cycles, 2 bytes -OPCODE(08,« - swap eaf - »,4,,2) - ;nok - -OP_DD(08,«») -OP_CB(08,«») -OP_DDCB(08,«») -OP_FD(08,«») -OP_FDCB(08,«») -OP_ED(08,«») - - ;; ADD HL,BC - ;; HL <- HL+BC - ;; Flags: H, C aff.; N=0 - ;; ? cycles -OPCODE(09,« - F_ADD_W ebc,ehl - ») - ;nok - -OP_DD(09,«») -OP_CB(09,«») -OP_DDCB(09,«») -OP_FD(09,«») -OP_FDCB(09,«») -OP_ED(09,«») - - ;; LD A,(BC) - ;; A <- (BC) - ;; No flags - ;; 106 cycles, 8 bytes -OPCODE(0a,« - FETCHB ebc,eaf - »,14,,4) - -OP_DD(0a,«») -OP_CB(0a,«») -OP_DDCB(0a,«») -OP_FD(0a,«») -OP_FDCB(0a,«») -OP_ED(0a,«») - - ;; DEC BC - ;; BC <- BC-1 - ;; No flags - ;; 4 cycles, 2 bytes -OPCODE(0b,« - F_DEC_W ebc - »,4,,2) - ;nok - -OP_DD(0b,«») -OP_CB(0b,«») -OP_DDCB(0b,«») -OP_FD(0b,«») -OP_FDCB(0b,«») -OP_ED(0b,«») - - ;; INC C - ;; C <- C+1 - ;; Flags: S,Z,H aff.; P=overflow, N=0 - ;; 108 cycles, 34 bytes -OPCODE(0c,« - F_INC_B ebc - ») - ;nok - -OP_DD(0c,«») -OP_CB(0c,«») -OP_DDCB(0c,«») -OP_FD(0c,«») -OP_FDCB(0c,«») -OP_ED(0c,«») - - ;; DEC C - ;; C <- C-1 - ;; Flags: S,Z,H aff., P=overflow, N=1 - ;; 80 cycles, 26 bytes -OPCODE(0d,« - F_DEC_B ebc - ») - ;nok - -OP_DD(0d,«») -OP_CB(0d,«») -OP_DDCB(0d,«») -OP_FD(0d,«») -OP_FDCB(0d,«») -OP_ED(0d,«») - - ;; LD C,immed.b - ;; C <- immed.b - ;; No flags - ;; 8 cycles, 2 bytes -OPCODE(0e,« - FETCHBI ebc - »,18,,6) - ;nok - -OP_DD(0e,«») -OP_CB(0e,«») -OP_DDCB(0e,«») -OP_FD(0e,«») -OP_FDCB(0e,«») -OP_ED(0e,«») - - ;; RRCA - ;; Rotate A right, carry bit gets top bit - ;; Flags: H,N=0; C aff. - ;; XXX FLAGS - ;; ? cycles -OPCODE(0f,« - ror.b #1,eaf - ») - ;nok - -OP_DD(0f,«») -OP_CB(0f,«») -OP_DDCB(0f,«») -OP_FD(0f,«») -OP_FDCB(0f,«») -OP_ED(0f,«») - - ;; DJNZ immed.w - ;; Decrement B - ;; and branch by immed.b - ;; if B not zero - ;; No flags - ;; 24 bytes - ;; take: 22+4+ 8+8+4+8+22 = 76 - ;; skip: 22+4+10+ 22 = 58 -OPCODE(10,« - LOHI ebc - subq.b #1,ebc - beq.s local(end) ; slooooow - FETCHBI d1 - ext.w d1 - add.w d1,epc -local(end): - HILO ebc - »,,,32) - ;nok - -OP_DD(10,«») -OP_CB(10,«») -OP_DDCB(10,«») -OP_FD(10,«») -OP_FDCB(10,«») -OP_ED(10,«») - - ;; LD DE,immed.w - ;; DE <- immed.w - ;; No flags - ;; 42 cycles, 8 bytes -OPCODE(11,« - FETCHWI ede - ») - ;nok - -OP_DD(11,«») -OP_CB(11,«») -OP_DDCB(11,«») -OP_FD(11,«») -OP_FDCB(11,«») -OP_ED(11,«») - - ;; LD (DE),A - ;; (DE) <- A - ;; No flags - ;; 106 cycles, 8 bytes -OPCODE(12,« - PUTB eaf,ede - ») - ;nok - -OP_DD(12,«») -OP_CB(12,«») -OP_DDCB(12,«») -OP_FD(12,«») -OP_FDCB(12,«») -OP_ED(12,«») - - ;; INC DE - ;; No flags - ;; 4 cycles, 2 bytes -OPCODE(13,« - F_INC_W ede - ») - ;nok - -OP_DD(13,«») -OP_CB(13,«») -OP_DDCB(13,«») -OP_FD(13,«») -OP_FDCB(13,«») -OP_ED(13,«») - - ;; INC D - ;; Flags: S,Z,H aff.; P=overflow, N=0 - ;; 152 cycles -OPCODE(14,« - LOHI ede - F_INC_B ede - HILO ede - ») - ;nok - -OP_DD(14,«») -OP_CB(14,«») -OP_DDCB(14,«») -OP_FD(14,«») -OP_FDCB(14,«») -OP_ED(14,«») - - ;; DEC D - ;; Flags: S,Z,H aff.; P=overflow, N=1 - ;; 124 cycles -OPCODE(15,« - LOHI ede - F_DEC_B ede - HILO ede - ») - ;nok - -OP_DD(15,«») -OP_CB(15,«») -OP_DDCB(15,«») -OP_FD(15,«») -OP_FDCB(15,«») -OP_ED(15,«») - - ;; LD D,immed.b - ;; No flags - ;; 52 cycles -OPCODE(16,« - LOHI ede - FETCHBI ede - HILO ede - ») - ;nok - -OP_DD(16,«») -OP_CB(16,«») -OP_DDCB(16,«») -OP_FD(16,«») -OP_FDCB(16,«») -OP_ED(16,«») - - ;; RLA - ;; Flags: P,N=0; C aff. - ;; XXX flags - ;; ? cycles -OPCODE(17,« - roxl.b #1,eaf - ») - ;nok - -OP_DD(17,«») -OP_CB(17,«») -OP_DDCB(17,«») -OP_FD(17,«») -OP_FDCB(17,«») -OP_ED(17,«») - - ;; JR immed.b - ;; PC <- immed.b - ;; Branch relative by a signed immediate byte - ;; No flags - ;; 20 cycles - - ;; XXX - ;; Yes, I can avoid the underef/deref cycle. To do so, put a - ;; sled of emulator trap instructions on either side of each - ;; 16k page. When that trap is executed, undo the shortcut - ;; and redo it by the book. - -OPCODE(18,« - clr.w d1 - FETCHBI d1 - add.w d1,epc - ») - ;nok - -OP_DD(18,«») -OP_CB(18,«») -OP_DDCB(18,«») -OP_FD(18,«») -OP_FDCB(18,«») -OP_ED(18,«») - - ;; ADD HL,DE - ;; HL <- HL+DE - ;; Flags: H,C aff,; N=0 - ;; ? cycles -OPCODE(19,« - F_ADD_W ede,ehl - ») - ;nok - -OP_DD(19,«») -OP_CB(19,«») -OP_DDCB(19,«») -OP_FD(19,«») -OP_FDCB(19,«») -OP_ED(19,«») - - ;; LD A,(DE) - ;; A <- (DE) - ;; No flags - ;; 106 cycles, 8 bytes -OPCODE(1a,« - FETCHB ede,eaf - ») - ;nok - -OP_DD(1a,«») -OP_CB(1a,«») -OP_DDCB(1a,«») -OP_FD(1a,«») -OP_FDCB(1a,«») -OP_ED(1a,«») - - ;; DEC DE - ;; No flags - ;; 4 cycles, 2 bytes -OPCODE(1b,« - subq.w #1,ede - ») - ;nok - -OP_DD(1b,«») -OP_CB(1b,«») -OP_DDCB(1b,«») -OP_FD(1b,«») -OP_FDCB(1b,«») -OP_ED(1b,«») - - ;; INC E - ;; Flags: S,Z,H aff.; P=overflow; N=0 - ;; 108 cycles, 34 bytes -OPCODE(1c,« - F_INC_B ede - ») - ;nok - -OP_DD(1c,«») -OP_CB(1c,«») -OP_DDCB(1c,«») -OP_FD(1c,«») -OP_FDCB(1c,«») -OP_ED(1c,«») - - ;; DEC E - ;; Flags: S,Z,H aff.; P=overflow, N=1 - ;; 80 cycles, 26 bytes -OPCODE(1d,« - F_DEC_B ede - ») - ;nok - -OP_DD(1d,«») -OP_CB(1d,«») -OP_DDCB(1d,«») -OP_FD(1d,«») -OP_FDCB(1d,«») -OP_ED(1d,«») - - ;; LD E,immed.b - ;; No flags - ;; 8 cycles, 2 bytes -OPCODE(1e,« - FETCHBI ede - ») - ;nok - -OP_DD(1e,«») -OP_CB(1e,«») -OP_DDCB(1e,«») -OP_FD(1e,«») -OP_FDCB(1e,«») -OP_ED(1e,«») - - ;; RRA - ;; Flags: H,N=0; C aff. - ;; XXX FLAGS - ;; ? cycles -OPCODE(1f,« - roxr.b #1,eaf - ») - ;nok - -OP_DD(1f,«») -OP_CB(1f,«») -OP_DDCB(1f,«») -OP_FD(1f,«») -OP_FDCB(1f,«») -OP_ED(1f,«») - - ;; JR NZ,immed.b - ;; if ~Z, - ;; PC <- PC+immed.b - ;; No flags - ;; 10 bytes - ;; take: 40+10+20(=JR immed.b) = 70 - ;; skip: 40+12+12 = 64 -OPCODE(20,« - jsr 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 - ») - -OP_DD(20,«») -OP_CB(20,«») -OP_DDCB(20,«») -OP_FD(20,«») -OP_FDCB(20,«») -OP_ED(20,«») - - ;; LD HL,immed.w - ;; No flags - ;; 42 cycles -OPCODE(21,« - FETCHWI ehl - ») - ;nok - -OP_DD(21,«») -OP_CB(21,«») -OP_DDCB(21,«») -OP_FD(21,«») -OP_FDCB(21,«») -OP_ED(21,«») - - ;; LD immed.w,HL - ;; (address) <- HL - ;; No flags - ;; 182 cycles -OPCODE(22,« - FETCHWI d1 - PUTW ehl,d1 - ») - ;nok - -OP_DD(22,«») -OP_CB(22,«») -OP_DDCB(22,«») -OP_FD(22,«») -OP_FDCB(22,«») -OP_ED(22,«») - - ;; INC HL - ;; No flags - ;; 4 cycles -OPCODE(23,« - addq.w #1,ehl - ») - ;nok - -OP_DD(23,«») -OP_CB(23,«») -OP_DDCB(23,«») -OP_FD(23,«») -OP_FDCB(23,«») -OP_ED(23,«») - - ;; INC H - ;; Flags: S,Z,H aff.; P=overflow, N=0 - ;; 152 cycles -OPCODE(24,« - LOHI ehl - F_INC_B ehl - HILO ehl - ») - ;nok - -OP_DD(24,«») -OP_CB(24,«») -OP_DDCB(24,«») -OP_FD(24,«») -OP_FDCB(24,«») -OP_ED(24,«») - - ;; DEC H - ;; Flags: S,Z,H aff.; P=overflow, N=1 - ;; 124 cycles -OPCODE(25,« - LOHI ehl - F_DEC_B ehl - HILO ehl - ») - ;nok - -OP_DD(25,«») -OP_CB(25,«») -OP_DDCB(25,«») -OP_FD(25,«») -OP_FDCB(25,«») -OP_ED(25,«») - - ;; LD H,immed.b - ;; No flags - ;; 52 cycles -OPCODE(26,« - LOHI ehl - FETCHBI ehl - HILO ehl - ») - ;nok - -OP_DD(26,«») -OP_CB(26,«») -OP_DDCB(26,«») -OP_FD(26,«») -OP_FDCB(26,«») -OP_ED(26,«») - - ;; DAA - ;; Decrement, adjust accum - ;; http://www.z80.info/z80syntx.htm#DAA - ;; Flags: ummm, go find a manual. - ;; XXX - ;; ? cycles -OPCODE(27,« - F_PAR eaf - ») - ;nok - -OP_DD(27,«») -OP_CB(27,«») -OP_DDCB(27,«») -OP_FD(27,«») -OP_FDCB(27,«») -OP_ED(27,«») - - ;; JR Z,immed.b - ;; If zero - ;; PC <- PC+immed.b - ;; SPEED can be made faster - ;; No flags - ;; ~130 cycles -OPCODE(28,« - jsr f_norm_z - bne emu_op_18 - add.l #1,epc - ») - ;nok - -OP_DD(28,«») -OP_CB(28,«») -OP_DDCB(28,«») -OP_FD(28,«») -OP_FDCB(28,«») -OP_ED(28,«») - - ;; ADD HL,HL - ;; No flags - ;; ? cycles -OPCODE(29,« - F_ADD_W ehl,ehl - ») - ;nok - -OP_DD(29,«») -OP_CB(29,«») -OP_DDCB(29,«») -OP_FD(29,«») -OP_FDCB(29,«») -OP_ED(29,«») - - ;; LD HL,(immed.w) - ;; address is absolute - ;; 172 cycles -OPCODE(2a,« - FETCHWI d1 - FETCHW d1,ehl - ») - ;nok - -OP_DD(2a,«») -OP_CB(2a,«») -OP_DDCB(2a,«») -OP_FD(2a,«») -OP_FDCB(2a,«») -OP_ED(2a,«») - - ;; XXX TOO LONG - ;; DEC HL - ;; ? cycles -OPCODE(2b,« - F_DEC_W ehl - ») - ;nok - -OP_DD(2b,«») -OP_CB(2b,«») -OP_DDCB(2b,«») -OP_FD(2b,«») -OP_FDCB(2b,«») -OP_ED(2b,«») - - ;; INC L - ;; 108 cycles -OPCODE(2c,« - F_INC_B ehl - ») - ;nok - -OP_DD(2c,«») -OP_CB(2c,«») -OP_DDCB(2c,«») -OP_FD(2c,«») -OP_FDCB(2c,«») -OP_ED(2c,«») - - ;; DEC L - ;; 80 cycles -OPCODE(2d,« - F_DEC_B ehl - ») - ;nok - -OP_DD(2d,«») -OP_CB(2d,«») -OP_DDCB(2d,«») -OP_FD(2d,«») -OP_FDCB(2d,«») -OP_ED(2d,«») - - ;; LD L,immed.b - ;; 8 cycles -OPCODE(2e,« - FETCHBI ehl - ») - ;nok - -OP_DD(2e,«») -OP_CB(2e,«») -OP_DDCB(2e,«») -OP_FD(2e,«») -OP_FDCB(2e,«») -OP_ED(2e,«») - - ;; CPL - ;; A <- NOT A - ;; XXX flags - ;; ? cycles -OPCODE(2f,« - not.b eaf - ») - ;nok - -OP_DD(2f,«») -OP_CB(2f,«») -OP_DDCB(2f,«») -OP_FD(2f,«») -OP_FDCB(2f,«») -OP_ED(2f,«») - - ;; JR NC,immed.b - ;; If carry clear - ;; PC <- PC+immed.b - ;; ? cycles -OPCODE(30,« - jsr f_norm_c - beq emu_op_18 ; branch taken: carry clear - add.l #1,epc - ») - -OP_DD(30,«») -OP_CB(30,«») -OP_DDCB(30,«») -OP_FD(30,«») -OP_FDCB(30,«») -OP_ED(30,«») - - ;; LD SP,immed.w - ;; 140 cycles -OPCODE(31,« - FETCHWI d1 - jsr deref - movea.l a0,esp - ») - ;nok - -OP_DD(31,«») -OP_CB(31,«») -OP_DDCB(31,«») -OP_FD(31,«») -OP_FDCB(31,«») -OP_ED(31,«») - - ;; LD (immed.w),A - ;; store indirect - ;; 170 cycles -OPCODE(32,« - FETCHWI d1 - rol.w #8,d1 - PUTB eaf,d1 - ») - ;nok - -OP_DD(32,«») -OP_CB(32,«») -OP_DDCB(32,«») -OP_FD(32,«») -OP_FDCB(32,«») -OP_ED(32,«») - - ;; INC SP - ;; No flags - ;; - ;; FYI: Do not have to deref because this will never cross a - ;; page boundary. So sayeth BrandonW. - ;; 4 cycles -OPCODE(33,« - addq.w #1,esp - ») - ;nok - -OP_DD(33,«») -OP_CB(33,«») -OP_DDCB(33,«») -OP_FD(33,«») -OP_FDCB(33,«») -OP_ED(33,«») - - ;; INC (HL) - ;; Increment byte - ;; SPEED can be made faster - ;; 320 cycles -OPCODE(34,« - FETCHB ehl,d1 - F_INC_B d1 - PUTB d1,ehl - ») - ;nok - -OP_DD(34,«») -OP_CB(34,«») -OP_DDCB(34,«») -OP_FD(34,«») -OP_FDCB(34,«») -OP_ED(34,«») - - ;; DEC (HL) - ;; Decrement byte - ;; SPEED can be made faster - ;; 292 cycles -OPCODE(35,« - FETCHB ehl,d1 - F_DEC_B d1 - PUTB d1,ehl - ») - ;nok - -OP_DD(35,«») -OP_CB(35,«») -OP_DDCB(35,«») -OP_FD(35,«») -OP_FDCB(35,«») -OP_ED(35,«») - - ;; LD (HL),immed.b - ;; 114 cycles -OPCODE(36,« - FETCHBI d1 - PUTB ehl,d1 - ») - ;nok - -OP_DD(36,«») -OP_CB(36,«») -OP_DDCB(36,«») -OP_FD(36,«») -OP_FDCB(36,«») -OP_ED(36,«») - - ;; SCF - ;; Set Carry Flag - ;; XXX flags are more complicated than this :( - ;; ? cycles -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 - -OP_DD(37,«») -OP_CB(37,«») -OP_DDCB(37,«») -OP_FD(37,«») -OP_FDCB(37,«») -OP_ED(37,«») - - ;; JR C,immed.b - ;; If carry set - ;; PC <- PC+immed.b - ;; ? cycles -OPCODE(38,« - jsr f_norm_c - bne emu_op_18 - add.l #1,epc - ») - -OP_DD(38,«») -OP_CB(38,«») -OP_DDCB(38,«») -OP_FD(38,«») -OP_FDCB(38,«») -OP_ED(38,«») - - ;; ADD HL,SP - ;; HL <- HL+SP -OPCODE(39,« - move.l esp,a0 - jsr underef - F_ADD_W d0,ehl - ») - ;nok - -OP_DD(39,«») -OP_CB(39,«») -OP_DDCB(39,«») -OP_FD(39,«») -OP_FDCB(39,«») -OP_ED(39,«») - - ;; LD A,(immed.w) -OPCODE(3a,« - FETCHWI d1 - FETCHB d1,eaf - ») - ;nok - -OP_DD(3a,«») -OP_CB(3a,«») -OP_DDCB(3a,«») -OP_FD(3a,«») -OP_FDCB(3a,«») -OP_ED(3a,«») - - ;; DEC SP - ;; No flags -OPCODE(3b,« - subq.l #1,esp - ») - ;nok - -OP_DD(3b,«») -OP_CB(3b,«») -OP_DDCB(3b,«») -OP_FD(3b,«») -OP_FDCB(3b,«») -OP_ED(3b,«») - - ;; INC A -OPCODE(3c,« - F_INC_B eaf - ») - -OP_DD(3c,«») -OP_CB(3c,«») -OP_DDCB(3c,«») -OP_FD(3c,«») -OP_FDCB(3c,«») -OP_ED(3c,«») - - ;; DEC A -OPCODE(3d,« - F_DEC_B eaf - ») - ;nok - -OP_DD(3d,«») -OP_CB(3d,«») -OP_DDCB(3d,«») -OP_FD(3d,«») -OP_FDCB(3d,«») -OP_ED(3d,«») - - ;; LD A,immed.b -OPCODE(3e,« - FETCHBI eaf - ») - - ;; CCF - ;; Clear carry flag - ;; XXX fuck flags - -OP_DD(3e,«») -OP_CB(3e,«») -OP_DDCB(3e,«») -OP_FD(3e,«») -OP_FDCB(3e,«») -OP_ED(3e,«») - -OPCODE(3f,« - jsr flags_normalize - ;; SZ5H3PNC - ori.b #%00000001,flag_valid-flag_storage(a3) - andi.b #%11111110,flag_byte-flag_storage(a3) - ») - ;nok - -OP_DD(3f,«») -OP_CB(3f,«») -OP_DDCB(3f,«») -OP_FD(3f,«») -OP_FDCB(3f,«») -OP_ED(3f,«») - - ;; LD B,B - ;; SPEED -OPCODE(40,« - LOHI ebc - move.b ebc,ebc - HILO ebc - ») - ;nok - -OP_DD(40,«») - - ;; BIT 0,A -OP_CB(40,«») - -OP_DDCB(40,«») -OP_FD(40,«») -OP_FDCB(40,«») - - ;; IN B,(C) -OP_ED(40,« - move.b ebc,d0 - jsr port_in - LOHI ebc - move.b d1,ebc - HILO ebc - ») - ;nok - - ;; LD B,C -OPCODE(41,« - move.w ebc,d1 - LOHI d1 ; deliberate trickery - move.b d1,ebc - ») - ;nok - -OP_DD(41,«») -OP_CB(41,«») -OP_DDCB(41,«») -OP_FD(41,«») -OP_FDCB(41,«») - - ;; OUT (C),B -OP_ED(41,« - move.b ebc,d0 - LOHI ebc - move.b ebc,d1 - HILO ebc - jsr port_out - ») - - ;; LD B,D - ;; B <- D - ;; SPEED -OPCODE(42,« - LOHI ebc - LOHI ede - move.b ede,ebc - HILO ebc - HILO ede - ») - ;nok - -OP_DD(42,«») -OP_CB(42,«») -OP_DDCB(42,«») -OP_FD(42,«») -OP_FDCB(42,«») -OP_ED(42,«») - - ;; LD B,E - ;; B <- E -OPCODE(43,« - LOHI ebc - move.b ebc,ede ; 4 - HILO ebc - ») - ;nok - -OP_DD(43,«») -OP_CB(43,«») -OP_DDCB(43,«») -OP_FD(43,«») -OP_FDCB(43,«») -OP_ED(43,«») - - ;; LD B,H - ;; B <- H - ;; SPEED -OPCODE(44,« - LOHI ebc - LOHI ehl - move.b ehl,ebc - HILO ebc - HILO ehl - ») - ;nok - -OP_DD(44,«») -OP_CB(44,«») -OP_DDCB(44,«») -OP_FD(44,«») -OP_FDCB(44,«») -OP_ED(44,«») - - ;; LD B,L - ;; B <- L -OPCODE(45,« - LOHI ebc - move.b ehl,ebc - HILO ebc - ») - ;nok - -OP_DD(45,«») -OP_CB(45,«») -OP_DDCB(45,«») -OP_FD(45,«») -OP_FDCB(45,«») -OP_ED(45,«») - - ;; LD B,(HL) - ;; B <- (HL) -OPCODE(46,« - LOHI ebc - FETCHB ehl,ebc - HILO ebc - ») - ;nok - -OP_DD(46,«») -OP_CB(46,«») -OP_DDCB(46,«») -OP_FD(46,«») -OP_FDCB(46,«») -OP_ED(46,«») - - ;; LD B,A - ;; B <- A -OPCODE(47,« - LOHI ebc - move.b eaf,ebc - HILO ebc - ») - ;nok - -OP_DD(47,«») -OP_CB(47,«») -OP_DDCB(47,«») -OP_FD(47,«») -OP_FDCB(47,«») -OP_ED(47,«») - - ;; LD C,B - ;; C <- B -OPCODE(48,« - move.w ebc,-(sp) - move.b (sp),ebc - ;; XXX emfasten? - addq.l #2,sp - ») - ;nok - -OP_DD(48,«») -OP_CB(48,«») -OP_DDCB(48,«») -OP_FD(48,«») -OP_FDCB(48,«») - - ;; IN C,(C) -OP_ED(48,« - move.b ebc,d0 - jsr port_in - move.b d1,ebc - ») - - ;; LD C,C -OPCODE(49,« - move.b ebc,ebc - ») - ;nok - -OP_DD(49,«») -OP_CB(49,«») -OP_DDCB(49,«») -OP_FD(49,«») -OP_FDCB(49,«») - - ;; OUT (C),C -OP_ED(49,« - move.b ebc,d0 - move.b ebc,d1 - jsr port_out - ») - ;nok - - ;; LD C,D -OPCODE(4a,« - move.w ede,-(sp) - move.b (sp),ebc - ;; XXX emfasten? - addq.l #2,sp - ») - ;nok - -OP_DD(4a,«») -OP_CB(4a,«») -OP_DDCB(4a,«») -OP_FD(4a,«») -OP_FDCB(4a,«») -OP_ED(4a,«») - - ;; LD C,E -OPCODE(4b,« - move.b ebc,ede - ») - ;nok - -OP_DD(4b,«») -OP_CB(4b,«») -OP_DDCB(4b,«») -OP_FD(4b,«») -OP_FDCB(4b,«») -OP_ED(4b,«») - - ;; LD C,H -OPCODE(4c,« - LOHI ehl - move.b ebc,ehl - HILO ehl - ») - ;nok - -OP_DD(4c,«») -OP_CB(4c,«») -OP_DDCB(4c,«») -OP_FD(4c,«») -OP_FDCB(4c,«») -OP_ED(4c,«») - - ;; LD C,L -OPCODE(4d,« - move.b ebc,ehl - ») - ;nok - -OP_DD(4d,«») -OP_CB(4d,«») -OP_DDCB(4d,«») -OP_FD(4d,«») -OP_FDCB(4d,«») -OP_ED(4d,«») - - ;; LD C,(HL) - ;; C <- (HL) -OPCODE(4e,« - FETCHB ehl,ebc - ») - ;nok - -OP_DD(4e,«») -OP_CB(4e,«») -OP_DDCB(4e,«») -OP_FD(4e,«») -OP_FDCB(4e,«») -OP_ED(4e,«») - - ;; LD C,A -OPCODE(4f,« - move.b eaf,ebc - ») - ;nok - -OP_DD(4f,«») -OP_CB(4f,«») -OP_DDCB(4f,«») -OP_FD(4f,«») -OP_FDCB(4f,«») -OP_ED(4f,«») - -; 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 - -OP_DD(50,«») -OP_CB(50,«») -OP_DDCB(50,«») -OP_FD(50,«») -OP_FDCB(50,«») - - ;; IN D,(C) -OP_ED(50,« - move.b ebc,d0 - jsr port_in - LOHI ede - move.b d1,ede - HILO ede - ») - - ;; LD D,C -OPCODE(51,« - LOHI ede - move.b ebc,ede - HILO ede - ») - ;nok - -OP_DD(51,«») -OP_CB(51,«») -OP_DDCB(51,«») -OP_FD(51,«») -OP_FDCB(51,«») - - ;; OUT (C),D -OP_ED(51,« - move.b ebc,d0 - LOHI ede - move.b ede,d1 - HILO ede - jsr port_out - ») - - ;; LD D,D -OPCODE(52,« - ») - ;nok - -OP_DD(52,«») -OP_CB(52,«») -OP_DDCB(52,«») -OP_FD(52,«») -OP_FDCB(52,«») -OP_ED(52,«») - - ;; LD D,E -OPCODE(53,« - andi.w #$00ff,ede - move.b ede,d1 - lsl #8,d1 - or.w d1,ede - ») - ;nok - -OP_DD(53,«») -OP_CB(53,«») -OP_DDCB(53,«») -OP_FD(53,«») -OP_FDCB(53,«») -OP_ED(53,«») - - ;; LD D,H -OPCODE(54,« - LOHI ede ; 4 - LOHI ehl ; 4 - move.b ehl,ede ; 4 - HILO ede ; 4 - HILO ehl ; 4 - »,20) - ;nok - ;20 cycles - -OP_DD(54,«») -OP_CB(54,«») -OP_DDCB(54,«») -OP_FD(54,«») -OP_FDCB(54,«») -OP_ED(54,«») - - ;; LD D,L -OPCODE(55,« - LOHI ede - move.b ehl,ede - HILO ede - ») - ;nok - -OP_DD(55,«») -OP_CB(55,«») -OP_DDCB(55,«») -OP_FD(55,«») -OP_FDCB(55,«») -OP_ED(55,«») - - ;; LD D,(HL) - ;; D <- (HL) -OPCODE(56,« - LOHI ede - FETCHB ehl,ede - HILO ede - ») - ;nok - -OP_DD(56,«») -OP_CB(56,«») -OP_DDCB(56,«») -OP_FD(56,«») -OP_FDCB(56,«») -OP_ED(56,«») - - ;; LD D,A -OPCODE(57,« - LOHI ede - move.b eaf,ede - HILO ede - ») - ;nok - -OP_DD(57,«») -OP_CB(57,«») -OP_DDCB(57,«») -OP_FD(57,«») -OP_FDCB(57,«») -OP_ED(57,«») - - ;; LD E,B -OPCODE(58,« - LOHI ebc - move.b ebc,ede - HILO ebc - ») - ;nok - -OP_DD(58,«») -OP_CB(58,«») -OP_DDCB(58,«») -OP_FD(58,«») -OP_FDCB(58,«») - - ;; IN E,(C) -OP_ED(58,« - move.b ebc,d0 - jsr port_in - move.b d1,ede - ») - - ;; LD E,C -OPCODE(59,« - move.b ebc,ede - ») - ;nok - -OP_DD(59,«») -OP_CB(59,«») -OP_DDCB(59,«») -OP_FD(59,«») -OP_FDCB(59,«») - - ;; OUT (C),E -OP_ED(59,« - move.b ebc,d0 - move.b ede,d1 - jsr port_out - ») - ;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 - »,38,,2) - ;nok - -OP_DD(5a,«») -OP_CB(5a,«») -OP_DDCB(5a,«») -OP_FD(5a,«») -OP_FDCB(5a,«») -OP_ED(5a,«») - - ;; LD E,E -OPCODE(5b,« - move.b ede,ede - ») - ;nok - -OP_DD(5b,«») -OP_CB(5b,«») -OP_DDCB(5b,«») -OP_FD(5b,«») -OP_FDCB(5b,«») -OP_ED(5b,«») - - ;; LD E,H -OPCODE(5c,« - LOHI ehl - move.b ede,ehl - HILO ehl - ») - ;nok - -OP_DD(5c,«») -OP_CB(5c,«») -OP_DDCB(5c,«») -OP_FD(5c,«») -OP_FDCB(5c,«») -OP_ED(5c,«») - - ;; LD E,L -OPCODE(5d,« - move.b ede,ehl - ») - ;nok - -OP_DD(5d,«») -OP_CB(5d,«») -OP_DDCB(5d,«») -OP_FD(5d,«») -OP_FDCB(5d,«») -OP_ED(5d,«») - - ;; LD E,(HL) -OPCODE(5e,« - FETCHB ehl,d1 - ») - ;nok - -OP_DD(5e,«») -OP_CB(5e,«») -OP_DDCB(5e,«») -OP_FD(5e,«») -OP_FDCB(5e,«») -OP_ED(5e,«») - - ;; LD E,A -OPCODE(5f,« - move.b ede,eaf - ») - ;nok - -OP_DD(5f,«») -OP_CB(5f,«») -OP_DDCB(5f,«») -OP_FD(5f,«») -OP_FDCB(5f,«») -OP_ED(5f,«») - - ;; LD H,B -OPCODE(60,« - LOHI ebc - LOHI ehl - move.b ehl,ebc - HILO ebc - HILO ehl - ») - ;nok - -OP_DD(60,«») -OP_CB(60,«») -OP_DDCB(60,«») -OP_FD(60,«») -OP_FDCB(60,«») - - ;; IN H,(C) -OP_ED(60,« - move.b ebc,d0 - jsr port_in - LOHI ehl - move.b d1,ehl - HILO ehl - ») - - ;; LD H,C -OPCODE(61,« - LOHI ehl - move.b ebc,ehl - HILO ehl - ») - ;nok - -OP_DD(61,«») -OP_CB(61,«») -OP_DDCB(61,«») -OP_FD(61,«») -OP_FDCB(61,«») - - ;; OUT (C),H -OP_ED(61,« - move.b ebc,d0 - LOHI ehl - move.b ehl,d1 - HILO ehl - jsr port_out - ») - - ;; LD H,D -OPCODE(62,« - LOHI ede - LOHI ehl - move.b ede,ehl - HILO ede - HILO ehl - ») - ;nok - -OP_DD(62,«») -OP_CB(62,«») -OP_DDCB(62,«») -OP_FD(62,«») -OP_FDCB(62,«») -OP_ED(62,«») - - ;; LD H,E -OPCODE(63,« - LOHI ehl - move.b ede,ehl - HILO ehl - ») - ;nok - -OP_DD(63,«») -OP_CB(63,«») -OP_DDCB(63,«») -OP_FD(63,«») -OP_FDCB(63,«») -OP_ED(63,«») - - ;; LD H,H -OPCODE(64,« - LOHI ehl - move.b ehl,ehl - HILO ehl - ») - ;nok - -OP_DD(64,«») -OP_CB(64,«») -OP_DDCB(64,«») -OP_FD(64,«») -OP_FDCB(64,«») -OP_ED(64,«») - - ;; LD H,L - ;; H <- L -OPCODE(65,« - move.b ehl,d1 - LOHI ehl - move.b d1,ehl - HILO ehl - ») - ;nok - -OP_DD(65,«») -OP_CB(65,«») -OP_DDCB(65,«») -OP_FD(65,«») -OP_FDCB(65,«») -OP_ED(65,«») - - ;; LD H,(HL) -OPCODE(66,« - FETCHB ehl,d1 - LOHI ehl - move.b d1,ehl - HILO ehl - ») - ;nok - -OP_DD(66,«») -OP_CB(66,«») -OP_DDCB(66,«») -OP_FD(66,«») -OP_FDCB(66,«») -OP_ED(66,«») - - ;; LD H,A -OPCODE(67,« - LOHI ehl - move.b eaf,ehl - HILO ehl - ») - ;nok - -OP_DD(67,«») -OP_CB(67,«») -OP_DDCB(67,«») -OP_FD(67,«») -OP_FDCB(67,«») -OP_ED(67,«») - - ;; LD L,B -OPCODE(68,« - LOHI ebc - move.b ebc,ehl - HILO ebc - ») - ;nok - -OP_DD(68,«») -OP_CB(68,«») -OP_DDCB(68,«») -OP_FD(68,«») -OP_FDCB(68,«») - - ;; IN L,(C) -OP_ED(68,« - move.b ebc,d0 - jsr port_in - move.b d1,ehl - ») - - ;; LD L,C -OPCODE(69,« - move.b ebc,ehl - ») - ;nok - -OP_DD(69,«») -OP_CB(69,«») -OP_DDCB(69,«») -OP_FD(69,«») -OP_FDCB(69,«») - - ;; OUT (C),L -OP_ED(69,« - move.b ebc,d0 - move.b ehl,d1 - jsr port_out - ») - - ;; LD L,D -OPCODE(6a,« - LOHI ede - move.b ede,ehl - HILO ede - ») - ;nok - -OP_DD(6a,«») -OP_CB(6a,«») -OP_DDCB(6a,«») -OP_FD(6a,«») -OP_FDCB(6a,«») -OP_ED(6a,«») - - ;; LD L,E -OPCODE(6b,« - move.b ede,ehl - ») - ;nok - -OP_DD(6b,«») -OP_CB(6b,«») -OP_DDCB(6b,«») -OP_FD(6b,«») -OP_FDCB(6b,«») -OP_ED(6b,«») - - ;; LD L,H -OPCODE(6c,« - move.b ehl,d1 - LOHI d1 - move.b d1,ehl - ») - ;nok - -OP_DD(6c,«») -OP_CB(6c,«») -OP_DDCB(6c,«») -OP_FD(6c,«») -OP_FDCB(6c,«») -OP_ED(6c,«») - - ;; LD L,L -OPCODE(6d,« - move.b ehl,ehl - ») - ;nok - -OP_DD(6d,«») -OP_CB(6d,«») -OP_DDCB(6d,«») -OP_FD(6d,«») -OP_FDCB(6d,«») -OP_ED(6d,«») - - ;; LD L,(HL) - ;; L <- (HL) -OPCODE(6e,« - FETCHB ehl,ehl - ») - ;nok - -OP_DD(6e,«») -OP_CB(6e,«») -OP_DDCB(6e,«») -OP_FD(6e,«») -OP_FDCB(6e,«») -OP_ED(6e,«») - - ;; LD L,A -OPCODE(6f,« - move.b eaf,ehl - ») - ;nok - -OP_DD(6f,«») -OP_CB(6f,«») -OP_DDCB(6f,«») -OP_FD(6f,«») -OP_FDCB(6f,«») -OP_ED(6f,«») - - ;; LD (HL),B -OPCODE(70,« - LOHI ebc - PUTB ehl,ebc - HILO ebc - ») - ;nok - -OP_DD(70,«») -OP_CB(70,«») -OP_DDCB(70,«») -OP_FD(70,«») -OP_FDCB(70,«») -OP_ED(70,«») - - ;; LD (HL),C -OPCODE(71,« - PUTB ehl,ebc - ») - ;nok - -OP_DD(71,«») -OP_CB(71,«») -OP_DDCB(71,«») -OP_FD(71,«») -OP_FDCB(71,«») -OP_ED(71,«») - - ;; LD (HL),D -OPCODE(72,« - LOHI ede - PUTB ehl,ede - HILO ede - ») - ;nok - -OP_DD(72,«») -OP_CB(72,«») -OP_DDCB(72,«») -OP_FD(72,«») -OP_FDCB(72,«») -OP_ED(72,«») - - ;; LD (HL),E -OPCODE(73,« - PUTB ehl,ede - ») - ;nok - -OP_DD(73,«») -OP_CB(73,«») -OP_DDCB(73,«») -OP_FD(73,«») -OP_FDCB(73,«») -OP_ED(73,«») - - ;; LD (HL),H -OPCODE(74,« - move.w ehl,d1 - HILO d1 - PUTB d1,ehl - ») - ;nok - -OP_DD(74,«») -OP_CB(74,«») -OP_DDCB(74,«») -OP_FD(74,«») -OP_FDCB(74,«») -OP_ED(74,«») - - ;; LD (HL),L -OPCODE(75,« - move.b ehl,d1 - PUTB d1,ehl - ») - ;nok - -OP_DD(75,«») -OP_CB(75,«») -OP_DDCB(75,«») -OP_FD(75,«») -OP_FDCB(75,«») -OP_ED(75,«») - - ;; HALT - ;; XXX do this -OPCODE(76,« - bra emu_op_76 - ») - ;nok - -OP_DD(76,«») -OP_CB(76,«») -OP_DDCB(76,«») -OP_FD(76,«») -OP_FDCB(76,«») -OP_ED(76,«») - - ;; LD (HL),A -OPCODE(77,« - PUTB eaf,ehl - ») - ;nok - -OP_DD(77,«») -OP_CB(77,«») -OP_DDCB(77,«») -OP_FD(77,«») -OP_FDCB(77,«») -OP_ED(77,«») - - ;; LD A,B -OPCODE(78,« - move.w ebc,d1 - LOHI d1 - move.b d1,eaf - ») - ;nok - -OP_DD(78,«») -OP_CB(78,«») -OP_DDCB(78,«») -OP_FD(78,«») -OP_FDCB(78,«») - - ;; IN A,(C) -OP_ED(78,« - move.b ebc,d0 - jsr port_in - move.b d1,eaf - ») - ;nok - - ;; LD A,C -OPCODE(79,« - move.b ebc,eaf - ») - ;nok - -OP_DD(79,«») -OP_CB(79,«») -OP_DDCB(79,«») -OP_FD(79,«») -OP_FDCB(79,«») - - ;; OUT (C),A -OP_ED(79,« - move.b ebc,d0 - move.b eaf,d1 - jsr port_out - ») - ;nok - - ;; LD A,D -OPCODE(7a,« - move.w ede,d1 - LOHI d1 - move.b d1,eaf - ») - ;nok - -OP_DD(7a,«») -OP_CB(7a,«») -OP_DDCB(7a,«») -OP_FD(7a,«») -OP_FDCB(7a,«») -OP_ED(7a,«») - - ;; LD A,E -OPCODE(7b,« - move.b ede,eaf - ») - ;nok - -OP_DD(7b,«») -OP_CB(7b,«») -OP_DDCB(7b,«») -OP_FD(7b,«») -OP_FDCB(7b,«») -OP_ED(7b,«») - - ;; LD A,H -OPCODE(7c,« - move.w ehl,d1 - LOHI d1 - move.b d1,eaf - ») - ;nok - -OP_DD(7c,«») -OP_CB(7c,«») -OP_DDCB(7c,«») -OP_FD(7c,«») -OP_FDCB(7c,«») -OP_ED(7c,«») - - ;; LD A,L -OPCODE(7d,« - move.b ehl,eaf - ») - ;nok - -OP_DD(7d,«») -OP_CB(7d,«») -OP_DDCB(7d,«») -OP_FD(7d,«») -OP_FDCB(7d,«») -OP_ED(7d,«») - - ;; LD A,(HL) - ;; A <- (HL) -OPCODE(7e,« - FETCHB ehl,eaf - ») - -OP_DD(7e,«») -OP_CB(7e,«») -OP_DDCB(7e,«») -OP_FD(7e,«») -OP_FDCB(7e,«») -OP_ED(7e,«») - - ;; LD A,A -OPCODE(7f,« - ») - ;nok - -OP_DD(7f,«») -OP_CB(7f,«») -OP_DDCB(7f,«») -OP_FD(7f,«») -OP_FDCB(7f,«») -OP_ED(7f,«») - - - - ;; Do an ADD \2,\1 -F_ADD_B MACRO ; 14 bytes? - move.b \2,d1 - move.b \1,d0 - jsr alu_add - move.b d1,\2 - ENDM - - ;; ADD A,B -OPCODE(80,« - LOHI ebc - F_ADD_B ebc,eaf - HILO ebc - ») - ;nok - -OP_DD(80,«») -OP_CB(80,«») -OP_DDCB(80,«») -OP_FD(80,«») -OP_FDCB(80,«») -OP_ED(80,«») - - ;; ADD A,C -OPCODE(81,« - F_ADD_B ebc,eaf - ») - ;nok - -OP_DD(81,«») -OP_CB(81,«») -OP_DDCB(81,«») -OP_FD(81,«») -OP_FDCB(81,«») -OP_ED(81,«») - - ;; ADD A,D -OPCODE(82,« - LOHI ede - F_ADD_B ede,eaf - HILO ede - ») - ;nok - -OP_DD(82,«») -OP_CB(82,«») -OP_DDCB(82,«») -OP_FD(82,«») -OP_FDCB(82,«») -OP_ED(82,«») - - ;; ADD A,E -OPCODE(83,« - F_ADD_B ede,eaf - ») - ;nok - -OP_DD(83,«») -OP_CB(83,«») -OP_DDCB(83,«») -OP_FD(83,«») -OP_FDCB(83,«») -OP_ED(83,«») - - ;; ADD A,H -OPCODE(84,« - LOHI ehl - F_ADD_B ehl,eaf - HILO ehl - ») - ;nok - -OP_DD(84,«») -OP_CB(84,«») -OP_DDCB(84,«») -OP_FD(84,«») -OP_FDCB(84,«») -OP_ED(84,«») - - ;; ADD A,L -OPCODE(85,« - F_ADD_B ehl,eaf - ») - ;nok - -OP_DD(85,«») -OP_CB(85,«») -OP_DDCB(85,«») -OP_FD(85,«») -OP_FDCB(85,«») -OP_ED(85,«») - - ;; ADD A,(HL) - ;; XXX size? -OPCODE(86,« - FETCHB ehl,d2 - F_ADD_B d2,eaf - PUTB d2,ehl - ») - ;nok - -OP_DD(86,«») -OP_CB(86,«») -OP_DDCB(86,«») -OP_FD(86,«») -OP_FDCB(86,«») -OP_ED(86,«») - - ;; ADD A,A -OPCODE(87,« - F_ADD_B eaf,eaf - ») - ;nok - -OP_DD(87,«») -OP_CB(87,«») -OP_DDCB(87,«») -OP_FD(87,«») -OP_FDCB(87,«») -OP_ED(87,«») - - - - ;; Do an ADC \2,\1 -F_ADC_B MACRO ; S34 - move.b \2,d1 - move.b \1,d0 - jsr 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 - -OP_DD(88,«») -OP_CB(88,«») -OP_DDCB(88,«») -OP_FD(88,«») -OP_FDCB(88,«») -OP_ED(88,«») - - ;; ADC A,C - ;; A <- A + C + (carry) -OPCODE(89,« - F_ADC_B ebc,eaf - ») - ;nok - -OP_DD(89,«») -OP_CB(89,«») -OP_DDCB(89,«») -OP_FD(89,«») -OP_FDCB(89,«») -OP_ED(89,«») - - ;; ADC A,D -OPCODE(8a,« - LOHI ede - F_ADC_B ede,eaf - HILO ede - ») - ;nok - -OP_DD(8a,«») -OP_CB(8a,«») -OP_DDCB(8a,«») -OP_FD(8a,«») -OP_FDCB(8a,«») -OP_ED(8a,«») - - ;; ADC A,E - ;; A <- A + E + carry -OPCODE(8b,« - F_ADC_B ede,eaf - ») - ;nok - -OP_DD(8b,«») -OP_CB(8b,«») -OP_DDCB(8b,«») -OP_FD(8b,«») -OP_FDCB(8b,«») -OP_ED(8b,«») - - ;; ADC A,H -OPCODE(8c,« - LOHI eaf - F_ADC_B ehl,eaf - HILO eaf - ») - ;nok - -OP_DD(8c,«») -OP_CB(8c,«») -OP_DDCB(8c,«») -OP_FD(8c,«») -OP_FDCB(8c,«») -OP_ED(8c,«») - - ;; ADC A,L -OPCODE(8d,« - F_ADC_B ehl,eaf - ») - ;nok - -OP_DD(8d,«») -OP_CB(8d,«») -OP_DDCB(8d,«») -OP_FD(8d,«») -OP_FDCB(8d,«») -OP_ED(8d,«») - - ;; ADC A,(HL) -OPCODE(8e,« - FETCHB ehl,d2 - F_ADC_B d2,eaf - PUTB d2,ehl - ») - ;nok - -OP_DD(8e,«») -OP_CB(8e,«») -OP_DDCB(8e,«») -OP_FD(8e,«») -OP_FDCB(8e,«») -OP_ED(8e,«») - - ;; ADC A,A -OPCODE(8f,« - F_ADC_B eaf,eaf - ») - ;nok - -OP_DD(8f,«») -OP_CB(8f,«») -OP_DDCB(8f,«») -OP_FD(8f,«») -OP_FDCB(8f,«») -OP_ED(8f,«») - - - - - - ;; Do a SUB \2,\1 -F_SUB_B MACRO - move.b \2,d1 - move.b \1,d0 - jsr alu_sub - move.b d1,\2 - ENDM - - ;; SUB A,B -OPCODE(90,« - LOHI ebc - F_SUB_B ebc,eaf - HILO ebc - ») - ;nok - -OP_DD(90,«») -OP_CB(90,«») -OP_DDCB(90,«») -OP_FD(90,«») -OP_FDCB(90,«») -OP_ED(90,«») - - ;; SUB A,C -OPCODE(91,« - F_SUB_B ebc,eaf - ») - ;nok - -OP_DD(91,«») -OP_CB(91,«») -OP_DDCB(91,«») -OP_FD(91,«») -OP_FDCB(91,«») -OP_ED(91,«») - - ;; SUB A,D -OPCODE(92,« - LOHI ede - F_SUB_B ede,eaf - HILO ede - ») - ;nok - -OP_DD(92,«») -OP_CB(92,«») -OP_DDCB(92,«») -OP_FD(92,«») -OP_FDCB(92,«») -OP_ED(92,«») - - ;; SUB A,E -OPCODE(93,« - F_SUB_B ede,eaf - ») - ;nok - -OP_DD(93,«») -OP_CB(93,«») -OP_DDCB(93,«») -OP_FD(93,«») -OP_FDCB(93,«») -OP_ED(93,«») - - ;; SUB A,H -OPCODE(94,« - LOHI ehl - F_SUB_B ehl,eaf - HILO ehl - ») - ;nok - -OP_DD(94,«») -OP_CB(94,«») -OP_DDCB(94,«») -OP_FD(94,«») -OP_FDCB(94,«») -OP_ED(94,«») - - ;; SUB A,L -OPCODE(95,« - F_SUB_B ehl,eaf - ») - -OP_DD(95,«») -OP_CB(95,«») -OP_DDCB(95,«») -OP_FD(95,«») -OP_FDCB(95,«») -OP_ED(95,«») - - ;; SUB A,(HL) -OPCODE(96,« - FETCHB ehl,d2 - F_SUB_B d2,eaf - PUTB d2,ehl - ») - ;nok - -OP_DD(96,«») -OP_CB(96,«») -OP_DDCB(96,«») -OP_FD(96,«») -OP_FDCB(96,«») -OP_ED(96,«») - - ;; SUB A,A -OPCODE(97,« - F_SUB_B eaf,eaf - ») - ;nok - -OP_DD(97,«») -OP_CB(97,«») -OP_DDCB(97,«») -OP_FD(97,«») -OP_FDCB(97,«») -OP_ED(97,«») - - - - - ;; Do a SBC \2,\1 -F_SBC_B MACRO - move.b \2,d1 - move.b \1,d0 - jsr alu_sbc - move.b d1,\2 - ENDM - - ;; SBC A,B -OPCODE(98,« - LOHI ebc - F_SBC_B ebc,eaf - HILO ebc - ») - ;nok - -OP_DD(98,«») -OP_CB(98,«») -OP_DDCB(98,«») -OP_FD(98,«») -OP_FDCB(98,«») -OP_ED(98,«») - - ;; SBC A,C -OPCODE(99,« - F_SBC_B ebc,eaf - ») - ;nok - -OP_DD(99,«») -OP_CB(99,«») -OP_DDCB(99,«») -OP_FD(99,«») -OP_FDCB(99,«») -OP_ED(99,«») - - ;; SBC A,D -OPCODE(9a,« - LOHI ede - F_SBC_B ede,eaf - HILO ede - ») - ;nok - -OP_DD(9a,«») -OP_CB(9a,«») -OP_DDCB(9a,«») -OP_FD(9a,«») -OP_FDCB(9a,«») -OP_ED(9a,«») - - ;; SBC A,E -OPCODE(9b,« - F_SBC_B ede,eaf - ») - ;nok - -OP_DD(9b,«») -OP_CB(9b,«») -OP_DDCB(9b,«») -OP_FD(9b,«») -OP_FDCB(9b,«») -OP_ED(9b,«») - - ;; SBC A,H -OPCODE(9c,« - LOHI ehl - F_SBC_B ehl,eaf - HILO ehl - ») - ;nok - -OP_DD(9c,«») -OP_CB(9c,«») -OP_DDCB(9c,«») -OP_FD(9c,«») -OP_FDCB(9c,«») -OP_ED(9c,«») - - ;; SBC A,L -OPCODE(9d,« - F_SBC_B ehl,eaf - ») - ;nok - -OP_DD(9d,«») -OP_CB(9d,«») -OP_DDCB(9d,«») -OP_FD(9d,«») -OP_FDCB(9d,«») -OP_ED(9d,«») - - ;; SBC A,(HL) -OPCODE(9e,« - FETCHB ehl,d2 - F_SBC_B d2,eaf - PUTB d2,ehl - ») - ;nok - -OP_DD(9e,«») -OP_CB(9e,«») -OP_DDCB(9e,«») -OP_FD(9e,«») -OP_FDCB(9e,«») -OP_ED(9e,«») - - ;; SBC A,A -OPCODE(9f,« - F_SBC_B eaf,eaf - ») - ;nok - - - - - -F_AND_B MACRO - move.b \2,d1 - move.b \1,d0 - jsr alu_and - move.b d1,\2 - ENDM - -OP_DD(9f,«») -OP_CB(9f,«») -OP_DDCB(9f,«») -OP_FD(9f,«») -OP_FDCB(9f,«») -OP_ED(9f,«») - - ;; AND B -OPCODE(a0,« - LOHI ebc - F_AND_B ebc,eaf - HILO ebc - ») - ;nok - -OP_DD(a0,«») -OP_CB(a0,«») -OP_DDCB(a0,«») -OP_FD(a0,«») -OP_FDCB(a0,«») -OP_ED(a0,«») - - ;; AND C -OPCODE(a1,« - F_AND_B ebc,eaf - ») - -OP_DD(a1,«») -OP_CB(a1,«») -OP_DDCB(a1,«») -OP_FD(a1,«») -OP_FDCB(a1,«») -OP_ED(a1,«») - - ;; AND D -OPCODE(a2,« - LOHI ede - F_AND_B ede,eaf - HILO ede - ») - ;nok - -OP_DD(a2,«») -OP_CB(a2,«») -OP_DDCB(a2,«») -OP_FD(a2,«») -OP_FDCB(a2,«») -OP_ED(a2,«») - - ;; AND E -OPCODE(a3,« - F_AND_B ede,eaf - ») - ;nok - -OP_DD(a3,«») -OP_CB(a3,«») -OP_DDCB(a3,«») -OP_FD(a3,«») -OP_FDCB(a3,«») -OP_ED(a3,«») - - ;; AND H -OPCODE(a4,« - LOHI ehl - F_AND_B ehl,eaf - HILO ehl - ») - ;nok - -OP_DD(a4,«») -OP_CB(a4,«») -OP_DDCB(a4,«») -OP_FD(a4,«») -OP_FDCB(a4,«») -OP_ED(a4,«») - - ;; AND L -OPCODE(a5,« - F_AND_B ehl,eaf - ») - ;nok - -OP_DD(a5,«») -OP_CB(a5,«») -OP_DDCB(a5,«») -OP_FD(a5,«») -OP_FDCB(a5,«») -OP_ED(a5,«») - - ;; AND (HL) -OPCODE(a6,« - FETCHB ehl,d2 - F_AND_B d2,eaf - PUTB d2,ehl - ») - ;nok - -OP_DD(a6,«») -OP_CB(a6,«») -OP_DDCB(a6,«») -OP_FD(a6,«») -OP_FDCB(a6,«») -OP_ED(a6,«») - - ;; 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 - jsr alu_xor - move.b d1,\2 - ENDM - -OP_DD(a7,«») -OP_CB(a7,«») -OP_DDCB(a7,«») -OP_FD(a7,«») -OP_FDCB(a7,«») -OP_ED(a7,«») - - ;; XOR B -OPCODE(a8,« - LOHI ebc - F_XOR_B ebc,eaf - HILO ebc - ») - ;nok - -OP_DD(a8,«») -OP_CB(a8,«») -OP_DDCB(a8,«») -OP_FD(a8,«») -OP_FDCB(a8,«») -OP_ED(a8,«») - - ;; XOR C -OPCODE(a9,« - F_XOR_B ebc,eaf - ») - ;nok - -OP_DD(a9,«») -OP_CB(a9,«») -OP_DDCB(a9,«») -OP_FD(a9,«») -OP_FDCB(a9,«») -OP_ED(a9,«») - - ;; XOR D -OPCODE(aa,« - LOHI ede - F_XOR_B ede,eaf - HILO ede - ») - ;nok - -OP_DD(aa,«») -OP_CB(aa,«») -OP_DDCB(aa,«») -OP_FD(aa,«») -OP_FDCB(aa,«») -OP_ED(aa,«») - - ;; XOR E -OPCODE(ab,« - F_XOR_B ede,eaf - ») - ;nok - -OP_DD(ab,«») -OP_CB(ab,«») -OP_DDCB(ab,«») -OP_FD(ab,«») -OP_FDCB(ab,«») -OP_ED(ab,«») - - ;; XOR H -OPCODE(ac,« - LOHI ehl - F_XOR_B ehl,eaf - HILO ehl - ») - ;nok - -OP_DD(ac,«») -OP_CB(ac,«») -OP_DDCB(ac,«») -OP_FD(ac,«») -OP_FDCB(ac,«») -OP_ED(ac,«») - - ;; XOR L -OPCODE(ad,« - F_XOR_B ehl,eaf - ») - ;nok - -OP_DD(ad,«») -OP_CB(ad,«») -OP_DDCB(ad,«») -OP_FD(ad,«») -OP_FDCB(ad,«») -OP_ED(ad,«») - - ;; XOR (HL) -OPCODE(ae,« - FETCHB ehl,d2 - F_XOR_B d2,eaf - PUTB d2,ehl - ») - ;nok - -OP_DD(ae,«») -OP_CB(ae,«») -OP_DDCB(ae,«») -OP_FD(ae,«») -OP_FDCB(ae,«») -OP_ED(ae,«») - - ;; XOR A -OPCODE(af,« - F_XOR_B eaf,eaf - ;; XXX - ») - ;nok - - - - - -F_OR_B MACRO - move.b \2,d1 - move.b \1,d0 - jsr alu_or - move.b d1,\2 - ENDM - -OP_DD(af,«») -OP_CB(af,«») -OP_DDCB(af,«») -OP_FD(af,«») -OP_FDCB(af,«») -OP_ED(af,«») - - ;; OR B -OPCODE(b0,« - LOHI ebc - F_OR_B ebc,eaf - HILO ebc - ») - ;nok - -OP_DD(b0,«») -OP_CB(b0,«») -OP_DDCB(b0,«») -OP_FD(b0,«») -OP_FDCB(b0,«») -OP_ED(b0,«») - - ;; OR C -OPCODE(b1,« - F_OR_B ebc,eaf - ») - ;nok - -OP_DD(b1,«») -OP_CB(b1,«») -OP_DDCB(b1,«») -OP_FD(b1,«») -OP_FDCB(b1,«») -OP_ED(b1,«») - - ;; OR D -OPCODE(b2,« - LOHI ede - F_OR_B ede,eaf - HILO ede - ») - ;nok - -OP_DD(b2,«») -OP_CB(b2,«») -OP_DDCB(b2,«») -OP_FD(b2,«») -OP_FDCB(b2,«») -OP_ED(b2,«») - - ;; OR E -OPCODE(b3,« - F_OR_B ede,eaf - ») - ;nok - -OP_DD(b3,«») -OP_CB(b3,«») -OP_DDCB(b3,«») -OP_FD(b3,«») -OP_FDCB(b3,«») -OP_ED(b3,«») - - ;; OR H -OPCODE(b4,« - LOHI ehl - F_OR_B ehl,eaf - HILO ehl - ») - ;nok - -OP_DD(b4,«») -OP_CB(b4,«») -OP_DDCB(b4,«») -OP_FD(b4,«») -OP_FDCB(b4,«») -OP_ED(b4,«») - - ;; OR L -OPCODE(b5,« - F_OR_B ehl,eaf - ») - ;nok - -OP_DD(b5,«») -OP_CB(b5,«») -OP_DDCB(b5,«») -OP_FD(b5,«») -OP_FDCB(b5,«») -OP_ED(b5,«») - - ;; OR (HL) -OPCODE(b6,« - ;; SPEED unnecessary move - FETCHB ehl,d2 - F_OR_B d2,eaf - ») - ;nok - -OPCODE(b7,« -OP_DD(b6,«») -OP_CB(b6,«») -OP_DDCB(b6,«») -OP_FD(b6,«») -OP_FDCB(b6,«») -OP_ED(b6,«») - - ;; OR A - F_OR_B eaf,eaf - ») - ;nok - - - - - - ;; COMPARE instruction - ;; Tests the argument against A -F_CP_B MACRO - ;; XXX deal with \2 or \1 being d1 or d0 - move.b \2,d1 - move.b \1,d0 - jsr alu_cp - ;; no result to save - ENDM - -OP_DD(b7,«») -OP_CB(b7,«») -OP_DDCB(b7,«») -OP_FD(b7,«») -OP_FDCB(b7,«») -OP_ED(b7,«») - - ;; CP B -OPCODE(b8,« - move.w ebc,d2 - LOHI d2 - F_CP_B d2,eaf - ») - ;nok - -OP_DD(b8,«») -OP_CB(b8,«») -OP_DDCB(b8,«») -OP_FD(b8,«») -OP_FDCB(b8,«») -OP_ED(b8,«») - - ;; CP C -OPCODE(b9,« - F_CP_B ebc,eaf - ») - ;nok - -OP_DD(b9,«») -OP_CB(b9,«») -OP_DDCB(b9,«») -OP_FD(b9,«») -OP_FDCB(b9,«») -OP_ED(b9,«») - - ;; CP D -OPCODE(ba,« - move.w ede,d2 - LOHI d2 - F_CP_B d2,eaf - ») - ;nok - -OP_DD(ba,«») -OP_CB(ba,«») -OP_DDCB(ba,«») -OP_FD(ba,«») -OP_FDCB(ba,«») -OP_ED(ba,«») - - ;; CP E -OPCODE(bb,« - F_CP_B ede,eaf - ») - ;nok - -OP_DD(bb,«») -OP_CB(bb,«») -OP_DDCB(bb,«») -OP_FD(bb,«») -OP_FDCB(bb,«») -OP_ED(bb,«») - - ;; CP H -OPCODE(bc,« - move.w ehl,d2 - LOHI d2 - F_CP_B d2,eaf - ») - ;nok - -OP_DD(bc,«») -OP_CB(bc,«») -OP_DDCB(bc,«») -OP_FD(bc,«») -OP_FDCB(bc,«») -OP_ED(bc,«») - - ;; CP L -OPCODE(bd,« - F_CP_B ehl,eaf - ») - ;nok - -OP_DD(bd,«») -OP_CB(bd,«») -OP_DDCB(bd,«») -OP_FD(bd,«») -OP_FDCB(bd,«») -OP_ED(bd,«») - - ;; CP (HL) -OPCODE(be,« - FETCHB ehl,d2 - F_CP_B d2,eaf - ;; no result to store - ») - ;nok - -OP_DD(be,«») -OP_CB(be,«») -OP_DDCB(be,«») -OP_FD(be,«») -OP_FDCB(be,«») -OP_ED(be,«») - - ;; CP A -OPCODE(bf,« - F_CP_B eaf,eaf - ») - -OP_DD(bf,«») -OP_CB(bf,«») -OP_DDCB(bf,«») -OP_FD(bf,«») -OP_FDCB(bf,«») -OP_ED(bf,«») - - ;; RET NZ - ;; if ~Z - ;; PCl <- (SP) - ;; PCh <- (SP+1) - ;; SP <- (SP+2) -OPCODE(c0,« - jsr f_norm_z - ;; SPEED inline RET - beq emu_op_c9 ; RET - ») - ;nok - -OP_DD(c0,«») -OP_CB(c0,«») -OP_DDCB(c0,«») -OP_FD(c0,«») -OP_FDCB(c0,«») -OP_ED(c0,«») - - ;; POP BC - ;; Pops a word into BC -OPCODE(c1,« ; S10 T - POPW ebc - ») - ;nok - -OP_DD(c1,«») -OP_CB(c1,«») -OP_DDCB(c1,«») -OP_FD(c1,«») -OP_FDCB(c1,«») -OP_ED(c1,«») - - ;; JP NZ,immed.w - ;; if ~Z - ;; PC <- immed.w -OPCODE(c2,« - jsr f_norm_z - bne local(continue) - jmp emu_op_c3 ; shame this has to be a long jump -local(continue): - add.l #2,epc - ») - ;nok - -OP_DD(c2,«») -OP_CB(c2,«») -OP_DDCB(c2,«») -OP_FD(c2,«») -OP_FDCB(c2,«») -OP_ED(c2,«») - - ;; JP immed.w - ;; PC <- immed.w -OPCODE(c3,« - FETCHWI d1 - jsr deref - movea.l a0,epc - »,36,,12) - -OP_DD(c3,«») -OP_CB(c3,«») -OP_DDCB(c3,«») -OP_FD(c3,«») -OP_FDCB(c3,«») -OP_ED(c3,«») - - ;; CALL NZ,immed.w - ;; If ~Z, CALL immed.w -OPCODE(c4,« - jsr 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. - beq emu_op_cd - add.l #2,epc - ») - ;nok - -OP_DD(c4,«») -OP_CB(c4,«») -OP_DDCB(c4,«») -OP_FD(c4,«») -OP_FDCB(c4,«») -OP_ED(c4,«») - - ;; PUSH BC -OPCODE(c5,« - PUSHW ebc - ») - ;nok - -OP_DD(c5,«») -OP_CB(c5,«») -OP_DDCB(c5,«») -OP_FD(c5,«») -OP_FDCB(c5,«») -OP_ED(c5,«») - - ;; ADD A,immed.b -OPCODE(c6,« - FETCHBI d1 - F_ADD_B d1,eaf - ») - ;nok - -OP_DD(c6,«») -OP_CB(c6,«») -OP_DDCB(c6,«») -OP_FD(c6,«») -OP_FDCB(c6,«») -OP_ED(c6,«») - - ;; RST &0 - ;; == CALL 0 - ;; XXX check -OPCODE(c7,« - move.l epc,a0 - jsr underef - PUSHW d0 - move.w #$00,d0 - jsr deref - move.l a0,epc - ») - ;nok - -OP_DD(c7,«») -OP_CB(c7,«») -OP_DDCB(c7,«») -OP_FD(c7,«») -OP_FDCB(c7,«») -OP_ED(c7,«») - - ;; RET Z -OPCODE(c8,« - jsr f_norm_z - beq local(continue) - jmp emu_op_c9 ; shame this has to be a long jump -local(continue): - ») - ;nok - -OP_DD(c8,«») -OP_CB(c8,«») -OP_DDCB(c8,«») -OP_FD(c8,«») -OP_FDCB(c8,«») -OP_ED(c8,«») - - ;; RET - ;; PCl <- (SP) - ;; PCh <- (SP+1) POPW - ;; SP <- (SP+2) -OPCODE(c9,« - POPW d1 - jsr deref - movea.l a0,epc - ») - ;nok - -OP_DD(c9,«») -OP_CB(c9,«») -OP_DDCB(c9,«») -OP_FD(c9,«») -OP_FDCB(c9,«») -OP_ED(c9,«») - - ;; JP Z,immed.w - ;; If Z, jump -OPCODE(ca,« - jsr f_norm_z - bne emu_op_c3 - add.l #2,epc - ») - ;nok -OP_DD(ca,«») -OP_CB(ca,«») -OP_DDCB(ca,«») -OP_FD(ca,«») -OP_FDCB(ca,«») -OP_ED(ca,«») - - ;; prefix -OPCODE(cb,« - movea.w emu_op_undo_cb(pc),a2 - ») - ;nok - -OP_DD(cb,«») -OP_CB(cb,«») -OP_DDCB(cb,«») -OP_FD(cb,«») -OP_FDCB(cb,«») -OP_ED(cb,«») - - ;; CALL Z,immed.w -OPCODE(cc,« - jsr f_norm_z - beq local(continue) - jmp emu_op_cd -local(continue): - add.l #2,epc - ») - ;nok - -OP_DD(cc,«») -OP_CB(cc,«») -OP_DDCB(cc,«») -OP_FD(cc,«») -OP_FDCB(cc,«») -OP_ED(cc,«») - - ;; CALL immed.w - ;; (Like JSR on 68k) - ;; (SP-1) <- PCh - ;; (SP-2) <- PCl - ;; SP <- SP - 2 - ;; PC <- address -OPCODE(cd,« - move.l epc,a0 - jsr underef ; d0 has PC - add.w #2,d0 - PUSHW d0 - bra emu_op_c3 ; JP - ») - -OP_DD(cd,«») -OP_CB(cd,«») -OP_DDCB(cd,«») -OP_FD(cd,«») -OP_FDCB(cd,«») -OP_ED(cd,«») - - ;; ADC A,immed.b -OPCODE(ce,« - FETCHWI d1 - F_ADC_B d1,eaf - ») - ;nok - -OP_DD(ce,«») -OP_CB(ce,«») -OP_DDCB(ce,«») -OP_FD(ce,«») -OP_FDCB(ce,«») -OP_ED(ce,«») - - ;; RST &08 - ;; == CALL 8 -OPCODE(cf,« - move.l epc,a0 - jsr underef ; d0 has PC - PUSHW d0 - move.w #$08,d0 - jsr deref - move.l a0,epc - ») - ;nok - -OP_DD(cf,«») -OP_CB(cf,«») -OP_DDCB(cf,«») -OP_FD(cf,«») -OP_FDCB(cf,«») -OP_ED(cf,«») - - ;; RET NC -OPCODE(d0,« - jsr f_norm_c - beq emu_op_c9 - ») - ;nok - -OP_DD(d0,«») -OP_CB(d0,«») -OP_DDCB(d0,«») -OP_FD(d0,«») -OP_FDCB(d0,«») -OP_ED(d0,«») - - ;; POP DE -OPCODE(d1,« - POPW ede - ») - ;nok - -OP_DD(d1,«») -OP_CB(d1,«») -OP_DDCB(d1,«») -OP_FD(d1,«») -OP_FDCB(d1,«») -OP_ED(d1,«») - - ;; JP NC,immed.w -OPCODE(d2,« - jsr f_norm_c - beq emu_op_c3 - add.l #2,epc - ») - -OP_DD(d2,«») -OP_CB(d2,«») -OP_DDCB(d2,«») -OP_FD(d2,«») -OP_FDCB(d2,«») -OP_ED(d2,«») - - ;; OUT immed.b,A -OPCODE(d3,« - move.b eaf,d1 - FETCHBI d0 - jsr port_out - ») - ;nok - -OP_DD(d3,«») -OP_CB(d3,«») -OP_DDCB(d3,«») -OP_FD(d3,«») -OP_FDCB(d3,«») -OP_ED(d3,«») - - ;; CALL NC,immed.w -OPCODE(d4,« - jsr f_norm_c - beq emu_op_cd - add.l #2,epc - ») - ;nok - -OP_DD(d4,«») -OP_CB(d4,«») -OP_DDCB(d4,«») -OP_FD(d4,«») -OP_FDCB(d4,«») -OP_ED(d4,«») - - ;; PUSH DE -OPCODE(d5,« - PUSHW ede - ») - ;nok - -OP_DD(d5,«») -OP_CB(d5,«») -OP_DDCB(d5,«») -OP_FD(d5,«») -OP_FDCB(d5,«») -OP_ED(d5,«») - - ;; SUB A,immed.b -OPCODE(d6,« - FETCHBI d1 - F_SUB_B eaf,d1 - ») - ;nok - -OP_DD(d6,«») -OP_CB(d6,«») -OP_DDCB(d6,«») -OP_FD(d6,«») -OP_FDCB(d6,«») -OP_ED(d6,«») - - ;; RST &10 - ;; == CALL 10 -OPCODE(d7,« - move.l epc,a0 - jsr underef - PUSHW d0 - move.w #$10,d0 - jsr deref - move.l a0,epc - ») - ;nok - -OP_DD(d7,«») -OP_CB(d7,«») -OP_DDCB(d7,«») -OP_FD(d7,«») -OP_FDCB(d7,«») -OP_ED(d7,«») - - ;; RET C -OPCODE(d8,« - jsr f_norm_c - bne emu_op_c9 - ») - ;nok - -OP_DD(d8,«») -OP_CB(d8,«») -OP_DDCB(d8,«») -OP_FD(d8,«») -OP_FDCB(d8,«») -OP_ED(d8,«») - - ;; EXX -OPCODE(d9,« - swap ebc - swap ede - swap ehl - ») - ;nok - -OP_DD(d9,«») -OP_CB(d9,«») -OP_DDCB(d9,«») -OP_FD(d9,«») -OP_FDCB(d9,«») -OP_ED(d9,«») - - ;; JP C,immed.w -OPCODE(da,« - jsr f_norm_c - bne emu_op_c3 - ») - ;nok - -OP_DD(da,«») -OP_CB(da,«») -OP_DDCB(da,«») -OP_FD(da,«») -OP_FDCB(da,«») -OP_ED(da,«») - - ;; IN A,immed.b -OPCODE(db,« - move.b eaf,d1 - FETCHBI d0 - jsr port_in - ») - ;nok - -OP_DD(db,«») -OP_CB(db,«») -OP_DDCB(db,«») -OP_FD(db,«») -OP_FDCB(db,«») -OP_ED(db,«») - - ;; CALL C,immed.w -OPCODE(dc,« - jsr f_norm_c - bne emu_op_cd - add.l #2,epc - ») - ;nok - -OPCODE(dd,« ; prefix - movea.w emu_op_undo_dd(pc),a2 - ») - -OP_DD(dc,«») -OP_CB(dc,«») -OP_DDCB(dc,«») -OP_FD(dc,«») -OP_FDCB(dc,«») -OP_ED(dc,«») - - ;; SBC A,immed.b -OPCODE(de,« - FETCHWI d1 - F_SBC_B d1,eaf - ») - ;nok - -OP_DD(dd,«») -OP_CB(dd,«») -OP_DDCB(dd,«») -OP_FD(dd,«») -OP_FDCB(dd,«») -OP_ED(dd,«») - - ;; RST &18 - ;; == CALL 18 -OPCODE(df,« - move.l epc,a0 - jsr underef - PUSHW d0 - move.w #$18,d0 - jsr deref - move.l a0,epc - ») - ;nok - -OP_DD(de,«») -OP_CB(de,«») -OP_DDCB(de,«») -OP_FD(de,«») -OP_FDCB(de,«») -OP_ED(de,«») - - ;; RET PO - ;; If parity odd (P zero), return -OPCODE(e0,« - jsr f_norm_pv - beq emu_op_c9 - ») - ;nok - -OP_DD(df,«») -OP_CB(df,«») -OP_DDCB(df,«») -OP_FD(df,«») -OP_FDCB(df,«») -OP_ED(df,«») - - ;; POP HL -OPCODE(e1,« - POPW ehl - ») - ;nok - -OP_DD(e0,«») -OP_CB(e0,«») -OP_DDCB(e0,«») -OP_FD(e0,«») -OP_FDCB(e0,«») -OP_ED(e0,«») - - ;; JP PO,immed.w -OPCODE(e2,« - jsr f_norm_pv - beq emu_op_c3 - add.l #2,epc - ») - ;nok - -OP_DD(e1,«») -OP_CB(e1,«») -OP_DDCB(e1,«») -OP_FD(e1,«») -OP_FDCB(e1,«») -OP_ED(e1,«») - - ;; EX (SP),HL - ;; Exchange -OPCODE(e3,« - POPW d1 - PUSHW ehl - move.w d1,ehl - ») - ;nok - -OP_DD(e2,«») -OP_CB(e2,«») -OP_DDCB(e2,«») -OP_FD(e2,«») -OP_FDCB(e2,«») -OP_ED(e2,«») - - ;; CALL PO,immed.w - ;; if parity odd (P=0), call -OPCODE(e4,« - jsr f_norm_pv - beq emu_op_cd - add.l #2,epc - ») - ;nok - -OP_DD(e3,«») -OP_CB(e3,«») -OP_DDCB(e3,«») -OP_FD(e3,«») -OP_FDCB(e3,«») -OP_ED(e3,«») - - ;; PUSH HL -OPCODE(e5,« - PUSHW ehl - ») - ;nok - -OP_DD(e4,«») -OP_CB(e4,«») -OP_DDCB(e4,«») -OP_FD(e4,«») -OP_FDCB(e4,«») -OP_ED(e4,«») - - ;; AND immed.b -OPCODE(e6,« - FETCHBI d1 - F_AND_B d1,eaf - ») - ;nok - -OP_DD(e5,«») -OP_CB(e5,«») -OP_DDCB(e5,«») -OP_FD(e5,«») -OP_FDCB(e5,«») -OP_ED(e5,«») - - ;; RST &20 - ;; == CALL 20 -OPCODE(e7,« - move.l epc,a0 - jsr underef - PUSHW d0 - move.w #$20,d0 - jsr deref - move.l a0,epc - ») - ;nok - -OP_DD(e6,«») -OP_CB(e6,«») -OP_DDCB(e6,«») -OP_FD(e6,«») -OP_FDCB(e6,«») -OP_ED(e6,«») - - ;; RET PE - ;; If parity odd (P zero), return -OPCODE(e8,« - jsr f_norm_pv - bne emu_op_c9 - ») - ;nok - -OP_DD(e7,«») -OP_CB(e7,«») -OP_DDCB(e7,«») -OP_FD(e7,«») -OP_FDCB(e7,«») -OP_ED(e7,«») - - ;; JP (HL) -OPCODE(e9,« - FETCHB ehl,d1 - jsr deref - movea.l a0,epc - ») - ;nok - -OP_DD(e8,«») -OP_CB(e8,«») -OP_DDCB(e8,«») -OP_FD(e8,«») -OP_FDCB(e8,«») -OP_ED(e8,«») - - ;; JP PE,immed.w -OPCODE(ea,« - jsr f_norm_pv - bne emu_op_c3 - add.l #2,epc - ») - ;nok - -OP_DD(e9,«») -OP_CB(e9,«») -OP_DDCB(e9,«») -OP_FD(e9,«») -OP_FDCB(e9,«») -OP_ED(e9,«») - - ;; EX DE,HL -OPCODE(eb,« - exg.w ede,ehl - ») - ;nok - -OP_DD(ea,«») -OP_CB(ea,«») -OP_DDCB(ea,«») -OP_FD(ea,«») -OP_FDCB(ea,«») -OP_ED(ea,«») - - ;; CALL PE,immed.w - ;; If parity even (P=1), call -OPCODE(ec,« - jsr f_norm_c - bne emu_op_cd - add.l #2,epc - ») - ;nok - -OP_DD(eb,«») -OP_CB(eb,«») -OP_DDCB(eb,«») -OP_FD(eb,«») -OP_FDCB(eb,«») -OP_ED(eb,«») - - ;; XXX this probably ought to hold interrupts too -OPCODE(ed,« ; prefix - movea.w emu_op_undo_ed(pc),a2 - ») - ;nok - -OP_DD(ec,«») -OP_CB(ec,«») -OP_DDCB(ec,«») -OP_FD(ec,«») -OP_FDCB(ec,«») -OP_ED(ec,«») - - ;; XOR immed.b -OPCODE(ee,« - FETCHBI d1 - F_XOR_B d1,eaf - ») - ;nok - -OP_DD(ed,«») -OP_CB(ed,«») -OP_DDCB(ed,«») -OP_FD(ed,«») -OP_FDCB(ed,«») -OP_ED(ed,«») - - ;; RST &28 - ;; == CALL 28 -OPCODE(ef,« - move.l epc,a0 - jsr underef - PUSHW d0 - move.w #$28,d0 - jsr deref - move.l a0,epc - ») - ;nok - -OP_DD(ee,«») -OP_CB(ee,«») -OP_DDCB(ee,«») -OP_FD(ee,«») -OP_FDCB(ee,«») -OP_ED(ee,«») - - ;; RET P - ;; Return if Positive -OPCODE(f0,« - jsr f_norm_sign - beq emu_op_c9 ; RET - ») - ;nok - -OP_DD(ef,«») -OP_CB(ef,«») -OP_DDCB(ef,«») -OP_FD(ef,«») -OP_FDCB(ef,«») -OP_ED(ef,«») - - ;; 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 - -OP_DD(f0,«») -OP_CB(f0,«») -OP_DDCB(f0,«») -OP_FD(f0,«») -OP_FDCB(f0,«») -OP_ED(f0,«») - - ;; JP P,immed.w -OPCODE(f2,« - jsr f_norm_sign - beq emu_op_c3 ; JP - add.l #2,epc - ») - ;nok - -OPCODE(f3,« -OP_DD(f1,«») -OP_CB(f1,«») -OP_DDCB(f1,«») -OP_FD(f1,«») -OP_FDCB(f1,«») -OP_ED(f1,«») - - ;; DI - jsr ints_stop - ») - -OP_DD(f2,«») -OP_CB(f2,«») -OP_DDCB(f2,«») -OP_FD(f2,«») -OP_FDCB(f2,«») -OP_ED(f2,«») - - ;; CALL P,&0000 - ;; Call if positive (S=0) -OPCODE(f4,« - jsr f_norm_sign - beq emu_op_cd - ») - ;nok - -OP_DD(f3,«») -OP_CB(f3,«») -OP_DDCB(f3,«») -OP_FD(f3,«») -OP_FDCB(f3,«») -OP_ED(f3,«») - - ;; PUSH AF -OPCODE(f5,« - jsr flags_normalize - LOHI eaf - move.b (flag_byte),eaf - ;; XXX wrong, af is not normalized by flags_normalize? - HILO eaf - PUSHW eaf - ») - ;nok - -OP_DD(f5,«») -OP_CB(f5,«») -OP_DDCB(f5,«») -OP_FD(f5,«») -OP_FDCB(f5,«») -OP_ED(f5,«») - - ;; OR immed.b -OPCODE(f6,« - FETCHBI d1 - F_OR_B d1,eaf - ») - ;nok - -OP_DD(f6,«») -OP_CB(f6,«») -OP_DDCB(f6,«») -OP_FD(f6,«») -OP_FDCB(f6,«») -OP_ED(f6,«») - - ;; RST &30 - ;; == CALL 30 -OPCODE(f7,« - move.l epc,a0 - jsr underef - PUSHW d0 - move.w #$30,d0 - jsr deref - move.l a0,epc - ») - ;nok - -OP_DD(f7,«») -OP_CB(f7,«») -OP_DDCB(f7,«») -OP_FD(f7,«») -OP_FDCB(f7,«») -OP_ED(f7,«») - - ;; RET M - ;; Return if Sign == 1, minus -OPCODE(f8,« - jsr f_norm_sign - bne emu_op_c9 ; RET - ») - ;nok - -OP_DD(f8,«») -OP_CB(f8,«») -OP_DDCB(f8,«») -OP_FD(f8,«») -OP_FDCB(f8,«») -OP_ED(f8,«») - - ;; LD SP,HL - ;; SP <- HL -OPCODE(f9,« - move.w ehl,d1 - jsr deref - movea.l a0,esp - ») - ;nok - -OP_DD(f9,«») -OP_CB(f9,«») -OP_DDCB(f9,«») -OP_FD(f9,«») -OP_FDCB(f9,«») -OP_ED(f9,«») - - ;; JP M,immed.w -OPCODE(fa,« - jsr f_norm_sign - bne emu_op_c3 ; JP - add.l #2,epc - ») - ;nok - -OP_DD(fa,«») -OP_CB(fa,«») -OP_DDCB(fa,«») -OP_FD(fa,«») -OP_FDCB(fa,«») -OP_ED(fa,«») - - ;; EI -OPCODE(fb,« - jsr ints_start - ») - ;nok - -OP_DD(fb,«») -OP_CB(fb,«») -OP_DDCB(fb,«») -OP_FD(fb,«») -OP_FDCB(fb,«») -OP_ED(fb,«») - - ;; CALL M,immed.w - ;; Call if minus (S=1) -OPCODE(fc,« - jsr f_norm_sign - bne emu_op_cd - add.l #2,epc - ») - ;nok - -OP_DD(fc,«») -OP_CB(fc,«») -OP_DDCB(fc,«») -OP_FD(fc,«») -OP_FDCB(fc,«») -OP_ED(fc,«») - - ;; swap IY, HL -OPCODE(fd,« ; prefix - movea.w emu_op_undo_fd(pc),a2 - ») - -OP_DD(fd,«») -OP_CB(fd,«») -OP_DDCB(fd,«») -OP_FD(fd,«») -OP_FDCB(fd,«») -OP_ED(fd,«») - - ;; CP immed.b -OPCODE(fe,« - FETCHBI d1 - F_CP_B d1,eaf - ») - ;nok - -OP_DD(fe,«») -OP_CB(fe,«») -OP_DDCB(fe,«») -OP_FD(fe,«») -OP_FDCB(fe,«») -OP_ED(fe,«») - - ;; RST &38 - ;; == CALL 38 -OPCODE(ff,« - move.l epc,a0 - jsr underef - PUSHW d0 - move.w #$38,d0 - jsr deref - move.l a0,epc - ») - ;nok - -OP_DD(ff,«») -OP_CB(ff,«») -OP_DDCB(ff,«») -OP_FD(ff,«») -OP_FDCB(ff,«») -OP_ED(ff,«») - diff --git a/opcodes.s.m4 b/opcodes.s.m4 new file mode 100644 index 0000000..522b539 --- /dev/null +++ b/opcodes.s.m4 @@ -0,0 +1,4309 @@ +;;; == -*- asm -*- ========================================================= +;;; ======================================================================== +;;; ___ ___ ======= ============================== +;;; ___( _ ) / _ \ 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 \addr. Puts + ;; the byte read in \dest. +.macro FETCHB src dest ; 106 cycles, 8 bytes + move.w \addr,d1 + jsr deref + move.b (a0),\dest +.endm + + ;; Macro to write a byte in \val to main memory at \addr +.macro PUTB val addr ; 106 cycles, 8 bytes + move.w \addr,d1 + jsr deref + move.b \val,(a0) +.endm + + ;; Macro to read a word from main memory at register \addr + ;; (unaligned). Puts the word read in \dest. +.macro FETCHW addr dest ; 140 cycles, 16 bytes + move.w \addr,d1 + jsr deref + ;; XXX SPEED + move.b (a0)+,d2 + move.b (a0),\dest + rol.w #8,\dest + move.b d2,\dest +.endm + + ;; Macro to write a word in \val to main memory at \addr (regs only) +.macro PUTW val addr ; 140 cycles, 14 bytes + move.w \addr,d1 + jsr deref + move.w \val,d0 + move.b d0,(a0)+ + LOHI d0 + move.b d0,(a0) +.endm + + ;; Push the word in \val (register) using stack register esp. + ;; Sadly, I can't trust the stack register to be aligned. + ;; Destroys d2. + + ;; (SP-2) <- \1_l + ;; (SP-1) <- \1_h + ;; SP <- SP - 2 +.macro PUSHW val ; 42 cycles, 8 bytes + move.w \val,d2 + LOHI d2 ;slow + move.b d2,-(esp) ; high byte + move.b \val,-(esp) ; low byte +.endm + + ;; Pop the word at the top of stack esp into \dest. + ;; Destroys d0. + + ;; \1_h <- (SP+1) + ;; \1_l <- (SP) + ;; SP <- SP + 2 +.macro POPW dest ; 60 cycles, 8 bytes + move.b (esp)+,\dest + LOHI \dest + move.b (esp)+,\dest ; high byte + HILO \dest +.endm + + ;; == Immediate Memory Macros == + + ;; Macro to read an immediate byte into \dest. +.macro FETCHBI dest ; 8 cycles, 2 bytes + move.b (epc)+,\dest +.endm + + ;; Macro to read an immediate word (unaligned) into \dest. +.macro FETCHWI dest ; 42 cycles, 8 bytes + ;; XXX SPEED + move.b (epc)+,d2 + move.b (epc)+,\dest + rol.w #8,\dest + move.b d2,\dest +.endm + + ;; == Common Opcode Macros ========================================= + + ;; To align opcode routines. +.set _align,0 + +.macro start + .org emu_plain_op+_align +.set _align,_align+$100 ; opcode routine length + jmp do_interrupt ; for interrupt routines +.endm + +.macro START_DD + .org emu_plain_op+_align+$40 +.endm + +.macro START_CB + .org emu_plain_op+_align+$42 +.endm + +.macro START_DDCB + .org emu_plain_op+_align+$44 +.endm + +.macro START_FD + .org emu_plain_op+_align+$46 +.endm + +.macro START_FDCB + .org emu_plain_op+_align+$48 +.endm + +.macro START_ED + .org emu_plain_op+_align+$4A +.endm + + ;; LOHI/HILO are hideously slow for instructions used often. + ;; Consider interleaving 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 +.macro LOHI reg ; 22 cycles, 2 bytes + ror.w #8,\reg +.endm + + ;; Then do your shit and finish with this +.macro HILO reg ; 22 cycles, 2 bytes + rol.w #8,\reg +.endm + + ;; Rearrange a register: ABCD -> ACBD. +.macro WORD reg ; 52 cycles, 14 bytes + move.l \reg,-(sp) + movep.w 0(sp),\reg + swap \reg + movep.w 1(sp),\reg + addq #4,sp +.endm + + ;; == Special Opcode Macros ======================================== + + ;; Do an ADD \1,\2 +.macro F_ADD_W ; ? cycles, ? bytes + ;; XXX +.endm + ;; Do an SUB \1,\2 +.macro F_SUB_W ; ? cycles, ? bytes + ;; XXX +.endm + + ;; INC and DEC macros +.macro F_INC_B reg ; 108 cycles, 34 bytes + move.b #1,f_tmp_byte-flag_storage(a3) + move.b #1,f_tmp_src_b-flag_storage(a3) + move.b \reg,f_tmp_dst_b-flag_storage(a3) + addq #1,\reg + moveq #2,d0 + F_CLEAR d0 + F_OVFL +.endm + +.macro F_DEC_B reg ; 80 cycles, 26 bytes + move.b #1,f_tmp_byte-flag_storage(a3) + st f_tmp_src_b-flag_storage(a3) ;; why did I do this? + move.b \reg,f_tmp_dst_b-flag_storage(a3) + subq #1,\reg + F_SET #2 +.endm + +.macro F_INC_W regpr ; 4 cycles, 2 bytes + addq.w #1,\regpr + ENDM + +.macro F_DEC_W regpr ; 4 cycles, 2 bytes + subq.w #1,\regpr + 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 + + +.macro 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 +.endm + + ;; Timing correction for more precise emulation + ;; + ;; \1 is number of tstates the current instruction should take + ;; \2 is number of cycles taken already +.macro TIME +.endm + + CNOP 0,32 + +emu_plain_op: ; Size(bytes) Time(cycles) + ; S0 T0 + + ;; I would like to thank the State of Washington for + ;; supporting the initial development of this file, by giving + ;; me a job doing nothing with no oversight for hours at a + ;; time. + + ;; NOP +OPCODE(00,«»,4) + + ;; +OP_DD(00,«») + + ;; RLC B +OP_CB(00,«») + + ;; +OP_DDCB(00,«») + + ;; +OP_FD(00,«») + + ;; +OP_FDCB(00,«») + + ;; +OP_ED(00,«») + + ;; LD BC,immed.w + ;; Read a word and put it in BC + ;; No flags + ;; 42 cycles +OPCODE(01,« + FETCHWI ebc + »,36,,12) + +OP_DD(01,«») +OP_CB(01,«») +OP_DDCB(01,«») +OP_FD(01,«») +OP_FDCB(01,«») +OP_ED(01,«») + + + ;; LD (BC),A + ;; (BC) <- A + ;; No flags + ;; 106 cycles +OPCODE(02,« + PUTB eaf,ebc + »,14,,4) + +OP_DD(02,«») +OP_CB(02,«») +OP_DDCB(02,«») +OP_FD(02,«») +OP_FDCB(02,«») +OP_ED(02,«») + + ;; INC BC + ;; BC <- BC+1 + ;; No flags + ;; 4 cycles +OPCODE(03,« + F_INC_W ebc + »,4,,2) + +OP_DD(03,«») +OP_CB(03,«») +OP_DDCB(03,«») +OP_FD(03,«») +OP_FDCB(03,«») +OP_ED(03,«») + + ;; INC B + ;; B <- B+1 + ;; 152 cycles +OPCODE(04,« + LOHI ebc + F_INC_B ebc + HILO ebc + ») + +OP_DD(04,«») +OP_CB(04,«») +OP_DDCB(04,«») +OP_FD(04,«») +OP_FDCB(04,«») +OP_ED(04,«») + + ;; DEC B + ;; B <- B-1 + ;; 124 cycles +OPCODE(05,« + LOHI ebc + F_DEC_B ebc + HILO ebc + ») + ;nok + +OP_DD(05,«») +OP_CB(05,«») +OP_DDCB(05,«») +OP_FD(05,«») +OP_FDCB(05,«») +OP_ED(05,«») + + ;; LD B,immed.b + ;; Read a byte and put it in B + ;; B <- immed.b + ;; No flags + ;; 52 cycles +OPCODE(06,« + LOHI ebc + FETCHBI ebc + HILO ebc + »,26,,10) + ;nok + +OP_DD(06,«») +OP_CB(06,«») +OP_DDCB(06,«») +OP_FD(06,«») +OP_FDCB(06,«») +OP_ED(06,«») + + ;; RLCA + ;; Rotate A left, carry bit gets top bit + ;; Flags: H,N=0; C aff. + ;; XXX flags + ;; ? cycles +OPCODE(07,« + rol.b #1,eaf + »,4,,2) + ;nok + +OP_DD(07,«») +OP_CB(07,«») +OP_DDCB(07,«») +OP_FD(07,«») +OP_FDCB(07,«») +OP_ED(07,«») + + ;; EX AF,AF' + ;; No flags + ;; XXX AF + ;; 4 cycles, 2 bytes +OPCODE(08,« + swap eaf + »,4,,2) + ;nok + +OP_DD(08,«») +OP_CB(08,«») +OP_DDCB(08,«») +OP_FD(08,«») +OP_FDCB(08,«») +OP_ED(08,«») + + ;; ADD HL,BC + ;; HL <- HL+BC + ;; Flags: H, C aff.; N=0 + ;; ? cycles +OPCODE(09,« + F_ADD_W ebc,ehl + ») + ;nok + +OP_DD(09,«») +OP_CB(09,«») +OP_DDCB(09,«») +OP_FD(09,«») +OP_FDCB(09,«») +OP_ED(09,«») + + ;; LD A,(BC) + ;; A <- (BC) + ;; No flags + ;; 106 cycles, 8 bytes +OPCODE(0a,« + FETCHB ebc,eaf + »,14,,4) + +OP_DD(0a,«») +OP_CB(0a,«») +OP_DDCB(0a,«») +OP_FD(0a,«») +OP_FDCB(0a,«») +OP_ED(0a,«») + + ;; DEC BC + ;; BC <- BC-1 + ;; No flags + ;; 4 cycles, 2 bytes +OPCODE(0b,« + F_DEC_W ebc + »,4,,2) + ;nok + +OP_DD(0b,«») +OP_CB(0b,«») +OP_DDCB(0b,«») +OP_FD(0b,«») +OP_FDCB(0b,«») +OP_ED(0b,«») + + ;; INC C + ;; C <- C+1 + ;; Flags: S,Z,H aff.; P=overflow, N=0 + ;; 108 cycles, 34 bytes +OPCODE(0c,« + F_INC_B ebc + ») + ;nok + +OP_DD(0c,«») +OP_CB(0c,«») +OP_DDCB(0c,«») +OP_FD(0c,«») +OP_FDCB(0c,«») +OP_ED(0c,«») + + ;; DEC C + ;; C <- C-1 + ;; Flags: S,Z,H aff., P=overflow, N=1 + ;; 80 cycles, 26 bytes +OPCODE(0d,« + F_DEC_B ebc + ») + ;nok + +OP_DD(0d,«») +OP_CB(0d,«») +OP_DDCB(0d,«») +OP_FD(0d,«») +OP_FDCB(0d,«») +OP_ED(0d,«») + + ;; LD C,immed.b + ;; C <- immed.b + ;; No flags + ;; 8 cycles, 2 bytes +OPCODE(0e,« + FETCHBI ebc + »,18,,6) + ;nok + +OP_DD(0e,«») +OP_CB(0e,«») +OP_DDCB(0e,«») +OP_FD(0e,«») +OP_FDCB(0e,«») +OP_ED(0e,«») + + ;; RRCA + ;; Rotate A right, carry bit gets top bit + ;; Flags: H,N=0; C aff. + ;; XXX FLAGS + ;; ? cycles +OPCODE(0f,« + ror.b #1,eaf + ») + ;nok + +OP_DD(0f,«») +OP_CB(0f,«») +OP_DDCB(0f,«») +OP_FD(0f,«») +OP_FDCB(0f,«») +OP_ED(0f,«») + + ;; DJNZ immed.w + ;; Decrement B + ;; and branch by immed.b + ;; if B not zero + ;; No flags + ;; 24 bytes + ;; take: 22+4+ 8+8+4+8+22 = 76 + ;; skip: 22+4+10+ 22 = 58 +OPCODE(10,« + LOHI ebc + subq.b #1,ebc + beq.s local(end) ; slooooow + FETCHBI d1 + ext.w d1 + add.w d1,epc +local(end): + HILO ebc + »,,,32) + ;nok + +OP_DD(10,«») +OP_CB(10,«») +OP_DDCB(10,«») +OP_FD(10,«») +OP_FDCB(10,«») +OP_ED(10,«») + + ;; LD DE,immed.w + ;; DE <- immed.w + ;; No flags + ;; 42 cycles, 8 bytes +OPCODE(11,« + FETCHWI ede + ») + ;nok + +OP_DD(11,«») +OP_CB(11,«») +OP_DDCB(11,«») +OP_FD(11,«») +OP_FDCB(11,«») +OP_ED(11,«») + + ;; LD (DE),A + ;; (DE) <- A + ;; No flags + ;; 106 cycles, 8 bytes +OPCODE(12,« + PUTB eaf,ede + ») + ;nok + +OP_DD(12,«») +OP_CB(12,«») +OP_DDCB(12,«») +OP_FD(12,«») +OP_FDCB(12,«») +OP_ED(12,«») + + ;; INC DE + ;; No flags + ;; 4 cycles, 2 bytes +OPCODE(13,« + F_INC_W ede + ») + ;nok + +OP_DD(13,«») +OP_CB(13,«») +OP_DDCB(13,«») +OP_FD(13,«») +OP_FDCB(13,«») +OP_ED(13,«») + + ;; INC D + ;; Flags: S,Z,H aff.; P=overflow, N=0 + ;; 152 cycles +OPCODE(14,« + LOHI ede + F_INC_B ede + HILO ede + ») + ;nok + +OP_DD(14,«») +OP_CB(14,«») +OP_DDCB(14,«») +OP_FD(14,«») +OP_FDCB(14,«») +OP_ED(14,«») + + ;; DEC D + ;; Flags: S,Z,H aff.; P=overflow, N=1 + ;; 124 cycles +OPCODE(15,« + LOHI ede + F_DEC_B ede + HILO ede + ») + ;nok + +OP_DD(15,«») +OP_CB(15,«») +OP_DDCB(15,«») +OP_FD(15,«») +OP_FDCB(15,«») +OP_ED(15,«») + + ;; LD D,immed.b + ;; No flags + ;; 52 cycles +OPCODE(16,« + LOHI ede + FETCHBI ede + HILO ede + ») + ;nok + +OP_DD(16,«») +OP_CB(16,«») +OP_DDCB(16,«») +OP_FD(16,«») +OP_FDCB(16,«») +OP_ED(16,«») + + ;; RLA + ;; Flags: P,N=0; C aff. + ;; XXX flags + ;; ? cycles +OPCODE(17,« + roxl.b #1,eaf + ») + ;nok + +OP_DD(17,«») +OP_CB(17,«») +OP_DDCB(17,«») +OP_FD(17,«») +OP_FDCB(17,«») +OP_ED(17,«») + + ;; JR immed.b + ;; PC <- immed.b + ;; Branch relative by a signed immediate byte + ;; No flags + ;; 20 cycles + + ;; XXX + ;; Yes, I can avoid the underef/deref cycle. To do so, put a + ;; sled of emulator trap instructions on either side of each + ;; 16k page. When that trap is executed, undo the shortcut + ;; and redo it by the book. + +OPCODE(18,« + clr.w d1 + FETCHBI d1 + add.w d1,epc + ») + ;nok + +OP_DD(18,«») +OP_CB(18,«») +OP_DDCB(18,«») +OP_FD(18,«») +OP_FDCB(18,«») +OP_ED(18,«») + + ;; ADD HL,DE + ;; HL <- HL+DE + ;; Flags: H,C aff,; N=0 + ;; ? cycles +OPCODE(19,« + F_ADD_W ede,ehl + ») + ;nok + +OP_DD(19,«») +OP_CB(19,«») +OP_DDCB(19,«») +OP_FD(19,«») +OP_FDCB(19,«») +OP_ED(19,«») + + ;; LD A,(DE) + ;; A <- (DE) + ;; No flags + ;; 106 cycles, 8 bytes +OPCODE(1a,« + FETCHB ede,eaf + ») + ;nok + +OP_DD(1a,«») +OP_CB(1a,«») +OP_DDCB(1a,«») +OP_FD(1a,«») +OP_FDCB(1a,«») +OP_ED(1a,«») + + ;; DEC DE + ;; No flags + ;; 4 cycles, 2 bytes +OPCODE(1b,« + subq.w #1,ede + ») + ;nok + +OP_DD(1b,«») +OP_CB(1b,«») +OP_DDCB(1b,«») +OP_FD(1b,«») +OP_FDCB(1b,«») +OP_ED(1b,«») + + ;; INC E + ;; Flags: S,Z,H aff.; P=overflow; N=0 + ;; 108 cycles, 34 bytes +OPCODE(1c,« + F_INC_B ede + ») + ;nok + +OP_DD(1c,«») +OP_CB(1c,«») +OP_DDCB(1c,«») +OP_FD(1c,«») +OP_FDCB(1c,«») +OP_ED(1c,«») + + ;; DEC E + ;; Flags: S,Z,H aff.; P=overflow, N=1 + ;; 80 cycles, 26 bytes +OPCODE(1d,« + F_DEC_B ede + ») + ;nok + +OP_DD(1d,«») +OP_CB(1d,«») +OP_DDCB(1d,«») +OP_FD(1d,«») +OP_FDCB(1d,«») +OP_ED(1d,«») + + ;; LD E,immed.b + ;; No flags + ;; 8 cycles, 2 bytes +OPCODE(1e,« + FETCHBI ede + ») + ;nok + +OP_DD(1e,«») +OP_CB(1e,«») +OP_DDCB(1e,«») +OP_FD(1e,«») +OP_FDCB(1e,«») +OP_ED(1e,«») + + ;; RRA + ;; Flags: H,N=0; C aff. + ;; XXX FLAGS + ;; ? cycles +OPCODE(1f,« + roxr.b #1,eaf + ») + ;nok + +OP_DD(1f,«») +OP_CB(1f,«») +OP_DDCB(1f,«») +OP_FD(1f,«») +OP_FDCB(1f,«») +OP_ED(1f,«») + + ;; JR NZ,immed.b + ;; if ~Z, + ;; PC <- PC+immed.b + ;; No flags + ;; 10 bytes + ;; take: 40+10+20(=JR immed.b) = 70 + ;; skip: 40+12+12 = 64 +OPCODE(20,« + jsr 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 + ») + +OP_DD(20,«») +OP_CB(20,«») +OP_DDCB(20,«») +OP_FD(20,«») +OP_FDCB(20,«») +OP_ED(20,«») + + ;; LD HL,immed.w + ;; No flags + ;; 42 cycles +OPCODE(21,« + FETCHWI ehl + ») + ;nok + +OP_DD(21,«») +OP_CB(21,«») +OP_DDCB(21,«») +OP_FD(21,«») +OP_FDCB(21,«») +OP_ED(21,«») + + ;; LD immed.w,HL + ;; (address) <- HL + ;; No flags + ;; 182 cycles +OPCODE(22,« + FETCHWI d1 + PUTW ehl,d1 + ») + ;nok + +OP_DD(22,«») +OP_CB(22,«») +OP_DDCB(22,«») +OP_FD(22,«») +OP_FDCB(22,«») +OP_ED(22,«») + + ;; INC HL + ;; No flags + ;; 4 cycles +OPCODE(23,« + addq.w #1,ehl + ») + ;nok + +OP_DD(23,«») +OP_CB(23,«») +OP_DDCB(23,«») +OP_FD(23,«») +OP_FDCB(23,«») +OP_ED(23,«») + + ;; INC H + ;; Flags: S,Z,H aff.; P=overflow, N=0 + ;; 152 cycles +OPCODE(24,« + LOHI ehl + F_INC_B ehl + HILO ehl + ») + ;nok + +OP_DD(24,«») +OP_CB(24,«») +OP_DDCB(24,«») +OP_FD(24,«») +OP_FDCB(24,«») +OP_ED(24,«») + + ;; DEC H + ;; Flags: S,Z,H aff.; P=overflow, N=1 + ;; 124 cycles +OPCODE(25,« + LOHI ehl + F_DEC_B ehl + HILO ehl + ») + ;nok + +OP_DD(25,«») +OP_CB(25,«») +OP_DDCB(25,«») +OP_FD(25,«») +OP_FDCB(25,«») +OP_ED(25,«») + + ;; LD H,immed.b + ;; No flags + ;; 52 cycles +OPCODE(26,« + LOHI ehl + FETCHBI ehl + HILO ehl + ») + ;nok + +OP_DD(26,«») +OP_CB(26,«») +OP_DDCB(26,«») +OP_FD(26,«») +OP_FDCB(26,«») +OP_ED(26,«») + + ;; DAA + ;; Decrement, adjust accum + ;; http://www.z80.info/z80syntx.htm#DAA + ;; Flags: ummm, go find a manual. + ;; XXX + ;; ? cycles +OPCODE(27,« + F_PAR eaf + ») + ;nok + +OP_DD(27,«») +OP_CB(27,«») +OP_DDCB(27,«») +OP_FD(27,«») +OP_FDCB(27,«») +OP_ED(27,«») + + ;; JR Z,immed.b + ;; If zero + ;; PC <- PC+immed.b + ;; SPEED can be made faster + ;; No flags + ;; ~130 cycles +OPCODE(28,« + jsr f_norm_z + bne emu_op_18 + add.l #1,epc + ») + ;nok + +OP_DD(28,«») +OP_CB(28,«») +OP_DDCB(28,«») +OP_FD(28,«») +OP_FDCB(28,«») +OP_ED(28,«») + + ;; ADD HL,HL + ;; No flags + ;; ? cycles +OPCODE(29,« + F_ADD_W ehl,ehl + ») + ;nok + +OP_DD(29,«») +OP_CB(29,«») +OP_DDCB(29,«») +OP_FD(29,«») +OP_FDCB(29,«») +OP_ED(29,«») + + ;; LD HL,(immed.w) + ;; address is absolute + ;; 172 cycles +OPCODE(2a,« + FETCHWI d1 + FETCHW d1,ehl + ») + ;nok + +OP_DD(2a,«») +OP_CB(2a,«») +OP_DDCB(2a,«») +OP_FD(2a,«») +OP_FDCB(2a,«») +OP_ED(2a,«») + + ;; XXX TOO LONG + ;; DEC HL + ;; ? cycles +OPCODE(2b,« + F_DEC_W ehl + ») + ;nok + +OP_DD(2b,«») +OP_CB(2b,«») +OP_DDCB(2b,«») +OP_FD(2b,«») +OP_FDCB(2b,«») +OP_ED(2b,«») + + ;; INC L + ;; 108 cycles +OPCODE(2c,« + F_INC_B ehl + ») + ;nok + +OP_DD(2c,«») +OP_CB(2c,«») +OP_DDCB(2c,«») +OP_FD(2c,«») +OP_FDCB(2c,«») +OP_ED(2c,«») + + ;; DEC L + ;; 80 cycles +OPCODE(2d,« + F_DEC_B ehl + ») + ;nok + +OP_DD(2d,«») +OP_CB(2d,«») +OP_DDCB(2d,«») +OP_FD(2d,«») +OP_FDCB(2d,«») +OP_ED(2d,«») + + ;; LD L,immed.b + ;; 8 cycles +OPCODE(2e,« + FETCHBI ehl + ») + ;nok + +OP_DD(2e,«») +OP_CB(2e,«») +OP_DDCB(2e,«») +OP_FD(2e,«») +OP_FDCB(2e,«») +OP_ED(2e,«») + + ;; CPL + ;; A <- NOT A + ;; XXX flags + ;; ? cycles +OPCODE(2f,« + not.b eaf + ») + ;nok + +OP_DD(2f,«») +OP_CB(2f,«») +OP_DDCB(2f,«») +OP_FD(2f,«») +OP_FDCB(2f,«») +OP_ED(2f,«») + + ;; JR NC,immed.b + ;; If carry clear + ;; PC <- PC+immed.b + ;; ? cycles +OPCODE(30,« + jsr f_norm_c + beq emu_op_18 ; branch taken: carry clear + add.l #1,epc + ») + +OP_DD(30,«») +OP_CB(30,«») +OP_DDCB(30,«») +OP_FD(30,«») +OP_FDCB(30,«») +OP_ED(30,«») + + ;; LD SP,immed.w + ;; 140 cycles +OPCODE(31,« + FETCHWI d1 + jsr deref + movea.l a0,esp + ») + ;nok + +OP_DD(31,«») +OP_CB(31,«») +OP_DDCB(31,«») +OP_FD(31,«») +OP_FDCB(31,«») +OP_ED(31,«») + + ;; LD (immed.w),A + ;; store indirect + ;; 170 cycles +OPCODE(32,« + FETCHWI d1 + rol.w #8,d1 + PUTB eaf,d1 + ») + ;nok + +OP_DD(32,«») +OP_CB(32,«») +OP_DDCB(32,«») +OP_FD(32,«») +OP_FDCB(32,«») +OP_ED(32,«») + + ;; INC SP + ;; No flags + ;; + ;; FYI: Do not have to deref because this will never cross a + ;; page boundary. So sayeth BrandonW. + ;; 4 cycles +OPCODE(33,« + addq.w #1,esp + ») + ;nok + +OP_DD(33,«») +OP_CB(33,«») +OP_DDCB(33,«») +OP_FD(33,«») +OP_FDCB(33,«») +OP_ED(33,«») + + ;; INC (HL) + ;; Increment byte + ;; SPEED can be made faster + ;; 320 cycles +OPCODE(34,« + FETCHB ehl,d1 + F_INC_B d1 + PUTB d1,ehl + ») + ;nok + +OP_DD(34,«») +OP_CB(34,«») +OP_DDCB(34,«») +OP_FD(34,«») +OP_FDCB(34,«») +OP_ED(34,«») + + ;; DEC (HL) + ;; Decrement byte + ;; SPEED can be made faster + ;; 292 cycles +OPCODE(35,« + FETCHB ehl,d1 + F_DEC_B d1 + PUTB d1,ehl + ») + ;nok + +OP_DD(35,«») +OP_CB(35,«») +OP_DDCB(35,«») +OP_FD(35,«») +OP_FDCB(35,«») +OP_ED(35,«») + + ;; LD (HL),immed.b + ;; 114 cycles +OPCODE(36,« + FETCHBI d1 + PUTB ehl,d1 + ») + ;nok + +OP_DD(36,«») +OP_CB(36,«») +OP_DDCB(36,«») +OP_FD(36,«») +OP_FDCB(36,«») +OP_ED(36,«») + + ;; SCF + ;; Set Carry Flag + ;; XXX flags are more complicated than this :( + ;; ? cycles +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 + +OP_DD(37,«») +OP_CB(37,«») +OP_DDCB(37,«») +OP_FD(37,«») +OP_FDCB(37,«») +OP_ED(37,«») + + ;; JR C,immed.b + ;; If carry set + ;; PC <- PC+immed.b + ;; ? cycles +OPCODE(38,« + jsr f_norm_c + bne emu_op_18 + add.l #1,epc + ») + +OP_DD(38,«») +OP_CB(38,«») +OP_DDCB(38,«») +OP_FD(38,«») +OP_FDCB(38,«») +OP_ED(38,«») + + ;; ADD HL,SP + ;; HL <- HL+SP +OPCODE(39,« + move.l esp,a0 + jsr underef + F_ADD_W d0,ehl + ») + ;nok + +OP_DD(39,«») +OP_CB(39,«») +OP_DDCB(39,«») +OP_FD(39,«») +OP_FDCB(39,«») +OP_ED(39,«») + + ;; LD A,(immed.w) +OPCODE(3a,« + FETCHWI d1 + FETCHB d1,eaf + ») + ;nok + +OP_DD(3a,«») +OP_CB(3a,«») +OP_DDCB(3a,«») +OP_FD(3a,«») +OP_FDCB(3a,«») +OP_ED(3a,«») + + ;; DEC SP + ;; No flags +OPCODE(3b,« + subq.l #1,esp + ») + ;nok + +OP_DD(3b,«») +OP_CB(3b,«») +OP_DDCB(3b,«») +OP_FD(3b,«») +OP_FDCB(3b,«») +OP_ED(3b,«») + + ;; INC A +OPCODE(3c,« + F_INC_B eaf + ») + +OP_DD(3c,«») +OP_CB(3c,«») +OP_DDCB(3c,«») +OP_FD(3c,«») +OP_FDCB(3c,«») +OP_ED(3c,«») + + ;; DEC A +OPCODE(3d,« + F_DEC_B eaf + ») + ;nok + +OP_DD(3d,«») +OP_CB(3d,«») +OP_DDCB(3d,«») +OP_FD(3d,«») +OP_FDCB(3d,«») +OP_ED(3d,«») + + ;; LD A,immed.b +OPCODE(3e,« + FETCHBI eaf + ») + + ;; CCF + ;; Clear carry flag + ;; XXX fuck flags + +OP_DD(3e,«») +OP_CB(3e,«») +OP_DDCB(3e,«») +OP_FD(3e,«») +OP_FDCB(3e,«») +OP_ED(3e,«») + +OPCODE(3f,« + jsr flags_normalize + ;; SZ5H3PNC + ori.b #%00000001,flag_valid-flag_storage(a3) + andi.b #%11111110,flag_byte-flag_storage(a3) + ») + ;nok + +OP_DD(3f,«») +OP_CB(3f,«») +OP_DDCB(3f,«») +OP_FD(3f,«») +OP_FDCB(3f,«») +OP_ED(3f,«») + + ;; LD B,B + ;; SPEED +OPCODE(40,« + LOHI ebc + move.b ebc,ebc + HILO ebc + ») + ;nok + +OP_DD(40,«») + + ;; BIT 0,A +OP_CB(40,«») + +OP_DDCB(40,«») +OP_FD(40,«») +OP_FDCB(40,«») + + ;; IN B,(C) +OP_ED(40,« + move.b ebc,d0 + jsr port_in + LOHI ebc + move.b d1,ebc + HILO ebc + ») + ;nok + + ;; LD B,C +OPCODE(41,« + move.w ebc,d1 + LOHI d1 ; deliberate trickery + move.b d1,ebc + ») + ;nok + +OP_DD(41,«») +OP_CB(41,«») +OP_DDCB(41,«») +OP_FD(41,«») +OP_FDCB(41,«») + + ;; OUT (C),B +OP_ED(41,« + move.b ebc,d0 + LOHI ebc + move.b ebc,d1 + HILO ebc + jsr port_out + ») + + ;; LD B,D + ;; B <- D + ;; SPEED +OPCODE(42,« + LOHI ebc + LOHI ede + move.b ede,ebc + HILO ebc + HILO ede + ») + ;nok + +OP_DD(42,«») +OP_CB(42,«») +OP_DDCB(42,«») +OP_FD(42,«») +OP_FDCB(42,«») +OP_ED(42,«») + + ;; LD B,E + ;; B <- E +OPCODE(43,« + LOHI ebc + move.b ebc,ede ; 4 + HILO ebc + ») + ;nok + +OP_DD(43,«») +OP_CB(43,«») +OP_DDCB(43,«») +OP_FD(43,«») +OP_FDCB(43,«») +OP_ED(43,«») + + ;; LD B,H + ;; B <- H + ;; SPEED +OPCODE(44,« + LOHI ebc + LOHI ehl + move.b ehl,ebc + HILO ebc + HILO ehl + ») + ;nok + +OP_DD(44,«») +OP_CB(44,«») +OP_DDCB(44,«») +OP_FD(44,«») +OP_FDCB(44,«») +OP_ED(44,«») + + ;; LD B,L + ;; B <- L +OPCODE(45,« + LOHI ebc + move.b ehl,ebc + HILO ebc + ») + ;nok + +OP_DD(45,«») +OP_CB(45,«») +OP_DDCB(45,«») +OP_FD(45,«») +OP_FDCB(45,«») +OP_ED(45,«») + + ;; LD B,(HL) + ;; B <- (HL) +OPCODE(46,« + LOHI ebc + FETCHB ehl,ebc + HILO ebc + ») + ;nok + +OP_DD(46,«») +OP_CB(46,«») +OP_DDCB(46,«») +OP_FD(46,«») +OP_FDCB(46,«») +OP_ED(46,«») + + ;; LD B,A + ;; B <- A +OPCODE(47,« + LOHI ebc + move.b eaf,ebc + HILO ebc + ») + ;nok + +OP_DD(47,«») +OP_CB(47,«») +OP_DDCB(47,«») +OP_FD(47,«») +OP_FDCB(47,«») +OP_ED(47,«») + + ;; LD C,B + ;; C <- B +OPCODE(48,« + move.w ebc,-(sp) + move.b (sp),ebc + ;; XXX emfasten? + addq.l #2,sp + ») + ;nok + +OP_DD(48,«») +OP_CB(48,«») +OP_DDCB(48,«») +OP_FD(48,«») +OP_FDCB(48,«») + + ;; IN C,(C) +OP_ED(48,« + move.b ebc,d0 + jsr port_in + move.b d1,ebc + ») + + ;; LD C,C +OPCODE(49,« + move.b ebc,ebc + ») + ;nok + +OP_DD(49,«») +OP_CB(49,«») +OP_DDCB(49,«») +OP_FD(49,«») +OP_FDCB(49,«») + + ;; OUT (C),C +OP_ED(49,« + move.b ebc,d0 + move.b ebc,d1 + jsr port_out + ») + ;nok + + ;; LD C,D +OPCODE(4a,« + move.w ede,-(sp) + move.b (sp),ebc + ;; XXX emfasten? + addq.l #2,sp + ») + ;nok + +OP_DD(4a,«») +OP_CB(4a,«») +OP_DDCB(4a,«») +OP_FD(4a,«») +OP_FDCB(4a,«») +OP_ED(4a,«») + + ;; LD C,E +OPCODE(4b,« + move.b ebc,ede + ») + ;nok + +OP_DD(4b,«») +OP_CB(4b,«») +OP_DDCB(4b,«») +OP_FD(4b,«») +OP_FDCB(4b,«») +OP_ED(4b,«») + + ;; LD C,H +OPCODE(4c,« + LOHI ehl + move.b ebc,ehl + HILO ehl + ») + ;nok + +OP_DD(4c,«») +OP_CB(4c,«») +OP_DDCB(4c,«») +OP_FD(4c,«») +OP_FDCB(4c,«») +OP_ED(4c,«») + + ;; LD C,L +OPCODE(4d,« + move.b ebc,ehl + ») + ;nok + +OP_DD(4d,«») +OP_CB(4d,«») +OP_DDCB(4d,«») +OP_FD(4d,«») +OP_FDCB(4d,«») +OP_ED(4d,«») + + ;; LD C,(HL) + ;; C <- (HL) +OPCODE(4e,« + FETCHB ehl,ebc + ») + ;nok + +OP_DD(4e,«») +OP_CB(4e,«») +OP_DDCB(4e,«») +OP_FD(4e,«») +OP_FDCB(4e,«») +OP_ED(4e,«») + + ;; LD C,A +OPCODE(4f,« + move.b eaf,ebc + ») + ;nok + +OP_DD(4f,«») +OP_CB(4f,«») +OP_DDCB(4f,«») +OP_FD(4f,«») +OP_FDCB(4f,«») +OP_ED(4f,«») + +; 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 + +OP_DD(50,«») +OP_CB(50,«») +OP_DDCB(50,«») +OP_FD(50,«») +OP_FDCB(50,«») + + ;; IN D,(C) +OP_ED(50,« + move.b ebc,d0 + jsr port_in + LOHI ede + move.b d1,ede + HILO ede + ») + + ;; LD D,C +OPCODE(51,« + LOHI ede + move.b ebc,ede + HILO ede + ») + ;nok + +OP_DD(51,«») +OP_CB(51,«») +OP_DDCB(51,«») +OP_FD(51,«») +OP_FDCB(51,«») + + ;; OUT (C),D +OP_ED(51,« + move.b ebc,d0 + LOHI ede + move.b ede,d1 + HILO ede + jsr port_out + ») + + ;; LD D,D +OPCODE(52,« + ») + ;nok + +OP_DD(52,«») +OP_CB(52,«») +OP_DDCB(52,«») +OP_FD(52,«») +OP_FDCB(52,«») +OP_ED(52,«») + + ;; LD D,E +OPCODE(53,« + andi.w #$00ff,ede + move.b ede,d1 + lsl #8,d1 + or.w d1,ede + ») + ;nok + +OP_DD(53,«») +OP_CB(53,«») +OP_DDCB(53,«») +OP_FD(53,«») +OP_FDCB(53,«») +OP_ED(53,«») + + ;; LD D,H +OPCODE(54,« + LOHI ede ; 4 + LOHI ehl ; 4 + move.b ehl,ede ; 4 + HILO ede ; 4 + HILO ehl ; 4 + »,20) + ;nok + ;20 cycles + +OP_DD(54,«») +OP_CB(54,«») +OP_DDCB(54,«») +OP_FD(54,«») +OP_FDCB(54,«») +OP_ED(54,«») + + ;; LD D,L +OPCODE(55,« + LOHI ede + move.b ehl,ede + HILO ede + ») + ;nok + +OP_DD(55,«») +OP_CB(55,«») +OP_DDCB(55,«») +OP_FD(55,«») +OP_FDCB(55,«») +OP_ED(55,«») + + ;; LD D,(HL) + ;; D <- (HL) +OPCODE(56,« + LOHI ede + FETCHB ehl,ede + HILO ede + ») + ;nok + +OP_DD(56,«») +OP_CB(56,«») +OP_DDCB(56,«») +OP_FD(56,«») +OP_FDCB(56,«») +OP_ED(56,«») + + ;; LD D,A +OPCODE(57,« + LOHI ede + move.b eaf,ede + HILO ede + ») + ;nok + +OP_DD(57,«») +OP_CB(57,«») +OP_DDCB(57,«») +OP_FD(57,«») +OP_FDCB(57,«») +OP_ED(57,«») + + ;; LD E,B +OPCODE(58,« + LOHI ebc + move.b ebc,ede + HILO ebc + ») + ;nok + +OP_DD(58,«») +OP_CB(58,«») +OP_DDCB(58,«») +OP_FD(58,«») +OP_FDCB(58,«») + + ;; IN E,(C) +OP_ED(58,« + move.b ebc,d0 + jsr port_in + move.b d1,ede + ») + + ;; LD E,C +OPCODE(59,« + move.b ebc,ede + ») + ;nok + +OP_DD(59,«») +OP_CB(59,«») +OP_DDCB(59,«») +OP_FD(59,«») +OP_FDCB(59,«») + + ;; OUT (C),E +OP_ED(59,« + move.b ebc,d0 + move.b ede,d1 + jsr port_out + ») + ;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 + »,38,,2) + ;nok + +OP_DD(5a,«») +OP_CB(5a,«») +OP_DDCB(5a,«») +OP_FD(5a,«») +OP_FDCB(5a,«») +OP_ED(5a,«») + + ;; LD E,E +OPCODE(5b,« + move.b ede,ede + ») + ;nok + +OP_DD(5b,«») +OP_CB(5b,«») +OP_DDCB(5b,«») +OP_FD(5b,«») +OP_FDCB(5b,«») +OP_ED(5b,«») + + ;; LD E,H +OPCODE(5c,« + LOHI ehl + move.b ede,ehl + HILO ehl + ») + ;nok + +OP_DD(5c,«») +OP_CB(5c,«») +OP_DDCB(5c,«») +OP_FD(5c,«») +OP_FDCB(5c,«») +OP_ED(5c,«») + + ;; LD E,L +OPCODE(5d,« + move.b ede,ehl + ») + ;nok + +OP_DD(5d,«») +OP_CB(5d,«») +OP_DDCB(5d,«») +OP_FD(5d,«») +OP_FDCB(5d,«») +OP_ED(5d,«») + + ;; LD E,(HL) +OPCODE(5e,« + FETCHB ehl,d1 + ») + ;nok + +OP_DD(5e,«») +OP_CB(5e,«») +OP_DDCB(5e,«») +OP_FD(5e,«») +OP_FDCB(5e,«») +OP_ED(5e,«») + + ;; LD E,A +OPCODE(5f,« + move.b ede,eaf + ») + ;nok + +OP_DD(5f,«») +OP_CB(5f,«») +OP_DDCB(5f,«») +OP_FD(5f,«») +OP_FDCB(5f,«») +OP_ED(5f,«») + + ;; LD H,B +OPCODE(60,« + LOHI ebc + LOHI ehl + move.b ehl,ebc + HILO ebc + HILO ehl + ») + ;nok + +OP_DD(60,«») +OP_CB(60,«») +OP_DDCB(60,«») +OP_FD(60,«») +OP_FDCB(60,«») + + ;; IN H,(C) +OP_ED(60,« + move.b ebc,d0 + jsr port_in + LOHI ehl + move.b d1,ehl + HILO ehl + ») + + ;; LD H,C +OPCODE(61,« + LOHI ehl + move.b ebc,ehl + HILO ehl + ») + ;nok + +OP_DD(61,«») +OP_CB(61,«») +OP_DDCB(61,«») +OP_FD(61,«») +OP_FDCB(61,«») + + ;; OUT (C),H +OP_ED(61,« + move.b ebc,d0 + LOHI ehl + move.b ehl,d1 + HILO ehl + jsr port_out + ») + + ;; LD H,D +OPCODE(62,« + LOHI ede + LOHI ehl + move.b ede,ehl + HILO ede + HILO ehl + ») + ;nok + +OP_DD(62,«») +OP_CB(62,«») +OP_DDCB(62,«») +OP_FD(62,«») +OP_FDCB(62,«») +OP_ED(62,«») + + ;; LD H,E +OPCODE(63,« + LOHI ehl + move.b ede,ehl + HILO ehl + ») + ;nok + +OP_DD(63,«») +OP_CB(63,«») +OP_DDCB(63,«») +OP_FD(63,«») +OP_FDCB(63,«») +OP_ED(63,«») + + ;; LD H,H +OPCODE(64,« + LOHI ehl + move.b ehl,ehl + HILO ehl + ») + ;nok + +OP_DD(64,«») +OP_CB(64,«») +OP_DDCB(64,«») +OP_FD(64,«») +OP_FDCB(64,«») +OP_ED(64,«») + + ;; LD H,L + ;; H <- L +OPCODE(65,« + move.b ehl,d1 + LOHI ehl + move.b d1,ehl + HILO ehl + ») + ;nok + +OP_DD(65,«») +OP_CB(65,«») +OP_DDCB(65,«») +OP_FD(65,«») +OP_FDCB(65,«») +OP_ED(65,«») + + ;; LD H,(HL) +OPCODE(66,« + FETCHB ehl,d1 + LOHI ehl + move.b d1,ehl + HILO ehl + ») + ;nok + +OP_DD(66,«») +OP_CB(66,«») +OP_DDCB(66,«») +OP_FD(66,«») +OP_FDCB(66,«») +OP_ED(66,«») + + ;; LD H,A +OPCODE(67,« + LOHI ehl + move.b eaf,ehl + HILO ehl + ») + ;nok + +OP_DD(67,«») +OP_CB(67,«») +OP_DDCB(67,«») +OP_FD(67,«») +OP_FDCB(67,«») +OP_ED(67,«») + + ;; LD L,B +OPCODE(68,« + LOHI ebc + move.b ebc,ehl + HILO ebc + ») + ;nok + +OP_DD(68,«») +OP_CB(68,«») +OP_DDCB(68,«») +OP_FD(68,«») +OP_FDCB(68,«») + + ;; IN L,(C) +OP_ED(68,« + move.b ebc,d0 + jsr port_in + move.b d1,ehl + ») + + ;; LD L,C +OPCODE(69,« + move.b ebc,ehl + ») + ;nok + +OP_DD(69,«») +OP_CB(69,«») +OP_DDCB(69,«») +OP_FD(69,«») +OP_FDCB(69,«») + + ;; OUT (C),L +OP_ED(69,« + move.b ebc,d0 + move.b ehl,d1 + jsr port_out + ») + + ;; LD L,D +OPCODE(6a,« + LOHI ede + move.b ede,ehl + HILO ede + ») + ;nok + +OP_DD(6a,«») +OP_CB(6a,«») +OP_DDCB(6a,«») +OP_FD(6a,«») +OP_FDCB(6a,«») +OP_ED(6a,«») + + ;; LD L,E +OPCODE(6b,« + move.b ede,ehl + ») + ;nok + +OP_DD(6b,«») +OP_CB(6b,«») +OP_DDCB(6b,«») +OP_FD(6b,«») +OP_FDCB(6b,«») +OP_ED(6b,«») + + ;; LD L,H +OPCODE(6c,« + move.b ehl,d1 + LOHI d1 + move.b d1,ehl + ») + ;nok + +OP_DD(6c,«») +OP_CB(6c,«») +OP_DDCB(6c,«») +OP_FD(6c,«») +OP_FDCB(6c,«») +OP_ED(6c,«») + + ;; LD L,L +OPCODE(6d,« + move.b ehl,ehl + ») + ;nok + +OP_DD(6d,«») +OP_CB(6d,«») +OP_DDCB(6d,«») +OP_FD(6d,«») +OP_FDCB(6d,«») +OP_ED(6d,«») + + ;; LD L,(HL) + ;; L <- (HL) +OPCODE(6e,« + FETCHB ehl,ehl + ») + ;nok + +OP_DD(6e,«») +OP_CB(6e,«») +OP_DDCB(6e,«») +OP_FD(6e,«») +OP_FDCB(6e,«») +OP_ED(6e,«») + + ;; LD L,A +OPCODE(6f,« + move.b eaf,ehl + ») + ;nok + +OP_DD(6f,«») +OP_CB(6f,«») +OP_DDCB(6f,«») +OP_FD(6f,«») +OP_FDCB(6f,«») +OP_ED(6f,«») + + ;; LD (HL),B +OPCODE(70,« + LOHI ebc + PUTB ehl,ebc + HILO ebc + ») + ;nok + +OP_DD(70,«») +OP_CB(70,«») +OP_DDCB(70,«») +OP_FD(70,«») +OP_FDCB(70,«») +OP_ED(70,«») + + ;; LD (HL),C +OPCODE(71,« + PUTB ehl,ebc + ») + ;nok + +OP_DD(71,«») +OP_CB(71,«») +OP_DDCB(71,«») +OP_FD(71,«») +OP_FDCB(71,«») +OP_ED(71,«») + + ;; LD (HL),D +OPCODE(72,« + LOHI ede + PUTB ehl,ede + HILO ede + ») + ;nok + +OP_DD(72,«») +OP_CB(72,«») +OP_DDCB(72,«») +OP_FD(72,«») +OP_FDCB(72,«») +OP_ED(72,«») + + ;; LD (HL),E +OPCODE(73,« + PUTB ehl,ede + ») + ;nok + +OP_DD(73,«») +OP_CB(73,«») +OP_DDCB(73,«») +OP_FD(73,«») +OP_FDCB(73,«») +OP_ED(73,«») + + ;; LD (HL),H +OPCODE(74,« + move.w ehl,d1 + HILO d1 + PUTB d1,ehl + ») + ;nok + +OP_DD(74,«») +OP_CB(74,«») +OP_DDCB(74,«») +OP_FD(74,«») +OP_FDCB(74,«») +OP_ED(74,«») + + ;; LD (HL),L +OPCODE(75,« + move.b ehl,d1 + PUTB d1,ehl + ») + ;nok + +OP_DD(75,«») +OP_CB(75,«») +OP_DDCB(75,«») +OP_FD(75,«») +OP_FDCB(75,«») +OP_ED(75,«») + + ;; HALT + ;; XXX do this +OPCODE(76,« + bra emu_op_76 + ») + ;nok + +OP_DD(76,«») +OP_CB(76,«») +OP_DDCB(76,«») +OP_FD(76,«») +OP_FDCB(76,«») +OP_ED(76,«») + + ;; LD (HL),A +OPCODE(77,« + PUTB eaf,ehl + ») + ;nok + +OP_DD(77,«») +OP_CB(77,«») +OP_DDCB(77,«») +OP_FD(77,«») +OP_FDCB(77,«») +OP_ED(77,«») + + ;; LD A,B +OPCODE(78,« + move.w ebc,d1 + LOHI d1 + move.b d1,eaf + ») + ;nok + +OP_DD(78,«») +OP_CB(78,«») +OP_DDCB(78,«») +OP_FD(78,«») +OP_FDCB(78,«») + + ;; IN A,(C) +OP_ED(78,« + move.b ebc,d0 + jsr port_in + move.b d1,eaf + ») + ;nok + + ;; LD A,C +OPCODE(79,« + move.b ebc,eaf + ») + ;nok + +OP_DD(79,«») +OP_CB(79,«») +OP_DDCB(79,«») +OP_FD(79,«») +OP_FDCB(79,«») + + ;; OUT (C),A +OP_ED(79,« + move.b ebc,d0 + move.b eaf,d1 + jsr port_out + ») + ;nok + + ;; LD A,D +OPCODE(7a,« + move.w ede,d1 + LOHI d1 + move.b d1,eaf + ») + ;nok + +OP_DD(7a,«») +OP_CB(7a,«») +OP_DDCB(7a,«») +OP_FD(7a,«») +OP_FDCB(7a,«») +OP_ED(7a,«») + + ;; LD A,E +OPCODE(7b,« + move.b ede,eaf + ») + ;nok + +OP_DD(7b,«») +OP_CB(7b,«») +OP_DDCB(7b,«») +OP_FD(7b,«») +OP_FDCB(7b,«») +OP_ED(7b,«») + + ;; LD A,H +OPCODE(7c,« + move.w ehl,d1 + LOHI d1 + move.b d1,eaf + ») + ;nok + +OP_DD(7c,«») +OP_CB(7c,«») +OP_DDCB(7c,«») +OP_FD(7c,«») +OP_FDCB(7c,«») +OP_ED(7c,«») + + ;; LD A,L +OPCODE(7d,« + move.b ehl,eaf + ») + ;nok + +OP_DD(7d,«») +OP_CB(7d,«») +OP_DDCB(7d,«») +OP_FD(7d,«») +OP_FDCB(7d,«») +OP_ED(7d,«») + + ;; LD A,(HL) + ;; A <- (HL) +OPCODE(7e,« + FETCHB ehl,eaf + ») + +OP_DD(7e,«») +OP_CB(7e,«») +OP_DDCB(7e,«») +OP_FD(7e,«») +OP_FDCB(7e,«») +OP_ED(7e,«») + + ;; LD A,A +OPCODE(7f,« + ») + ;nok + +OP_DD(7f,«») +OP_CB(7f,«») +OP_DDCB(7f,«») +OP_FD(7f,«») +OP_FDCB(7f,«») +OP_ED(7f,«») + + + + ;; Do an ADD \2,\1 +.macro F_ADD_B src dest ; 14 bytes? + move.b \dest,d1 + move.b \src,d0 + jsr alu_add + move.b d1,\dest + ENDM + + ;; ADD A,B +OPCODE(80,« + LOHI ebc + F_ADD_B ebc,eaf + HILO ebc + ») + ;nok + +OP_DD(80,«») +OP_CB(80,«») +OP_DDCB(80,«») +OP_FD(80,«») +OP_FDCB(80,«») +OP_ED(80,«») + + ;; ADD A,C +OPCODE(81,« + F_ADD_B ebc,eaf + ») + ;nok + +OP_DD(81,«») +OP_CB(81,«») +OP_DDCB(81,«») +OP_FD(81,«») +OP_FDCB(81,«») +OP_ED(81,«») + + ;; ADD A,D +OPCODE(82,« + LOHI ede + F_ADD_B ede,eaf + HILO ede + ») + ;nok + +OP_DD(82,«») +OP_CB(82,«») +OP_DDCB(82,«») +OP_FD(82,«») +OP_FDCB(82,«») +OP_ED(82,«») + + ;; ADD A,E +OPCODE(83,« + F_ADD_B ede,eaf + ») + ;nok + +OP_DD(83,«») +OP_CB(83,«») +OP_DDCB(83,«») +OP_FD(83,«») +OP_FDCB(83,«») +OP_ED(83,«») + + ;; ADD A,H +OPCODE(84,« + LOHI ehl + F_ADD_B ehl,eaf + HILO ehl + ») + ;nok + +OP_DD(84,«») +OP_CB(84,«») +OP_DDCB(84,«») +OP_FD(84,«») +OP_FDCB(84,«») +OP_ED(84,«») + + ;; ADD A,L +OPCODE(85,« + F_ADD_B ehl,eaf + ») + ;nok + +OP_DD(85,«») +OP_CB(85,«») +OP_DDCB(85,«») +OP_FD(85,«») +OP_FDCB(85,«») +OP_ED(85,«») + + ;; ADD A,(HL) + ;; XXX size? +OPCODE(86,« + FETCHB ehl,d2 + F_ADD_B d2,eaf + PUTB d2,ehl + ») + ;nok + +OP_DD(86,«») +OP_CB(86,«») +OP_DDCB(86,«») +OP_FD(86,«») +OP_FDCB(86,«») +OP_ED(86,«») + + ;; ADD A,A +OPCODE(87,« + F_ADD_B eaf,eaf + ») + ;nok + +OP_DD(87,«») +OP_CB(87,«») +OP_DDCB(87,«») +OP_FD(87,«») +OP_FDCB(87,«») +OP_ED(87,«») + + + + ;; Do an ADC \2,\1 +.macro F_ADC_B src dest ; S34 + move.b \dest,d1 + move.b \src,d0 + jsr alu_adc + move.b d1,\dest + ENDM + + ;; ADC A,B + ;; A <- A + B + (carry) +OPCODE(88,« + LOHI ebc + F_ADC_B ebc,eaf + HILO ebc + ») + ;nok + +OP_DD(88,«») +OP_CB(88,«») +OP_DDCB(88,«») +OP_FD(88,«») +OP_FDCB(88,«») +OP_ED(88,«») + + ;; ADC A,C + ;; A <- A + C + (carry) +OPCODE(89,« + F_ADC_B ebc,eaf + ») + ;nok + +OP_DD(89,«») +OP_CB(89,«») +OP_DDCB(89,«») +OP_FD(89,«») +OP_FDCB(89,«») +OP_ED(89,«») + + ;; ADC A,D +OPCODE(8a,« + LOHI ede + F_ADC_B ede,eaf + HILO ede + ») + ;nok + +OP_DD(8a,«») +OP_CB(8a,«») +OP_DDCB(8a,«») +OP_FD(8a,«») +OP_FDCB(8a,«») +OP_ED(8a,«») + + ;; ADC A,E + ;; A <- A + E + carry +OPCODE(8b,« + F_ADC_B ede,eaf + ») + ;nok + +OP_DD(8b,«») +OP_CB(8b,«») +OP_DDCB(8b,«») +OP_FD(8b,«») +OP_FDCB(8b,«») +OP_ED(8b,«») + + ;; ADC A,H +OPCODE(8c,« + LOHI eaf + F_ADC_B ehl,eaf + HILO eaf + ») + ;nok + +OP_DD(8c,«») +OP_CB(8c,«») +OP_DDCB(8c,«») +OP_FD(8c,«») +OP_FDCB(8c,«») +OP_ED(8c,«») + + ;; ADC A,L +OPCODE(8d,« + F_ADC_B ehl,eaf + ») + ;nok + +OP_DD(8d,«») +OP_CB(8d,«») +OP_DDCB(8d,«») +OP_FD(8d,«») +OP_FDCB(8d,«») +OP_ED(8d,«») + + ;; ADC A,(HL) +OPCODE(8e,« + FETCHB ehl,d2 + F_ADC_B d2,eaf + PUTB d2,ehl + ») + ;nok + +OP_DD(8e,«») +OP_CB(8e,«») +OP_DDCB(8e,«») +OP_FD(8e,«») +OP_FDCB(8e,«») +OP_ED(8e,«») + + ;; ADC A,A +OPCODE(8f,« + F_ADC_B eaf,eaf + ») + ;nok + +OP_DD(8f,«») +OP_CB(8f,«») +OP_DDCB(8f,«») +OP_FD(8f,«») +OP_FDCB(8f,«») +OP_ED(8f,«») + + + + + + ;; Do a SUB \2,\1 +.macro F_SUB_B src dest + move.b \dest,d1 + move.b \src,d0 + jsr alu_sub + move.b d1,\dest + ENDM + + ;; SUB A,B +OPCODE(90,« + LOHI ebc + F_SUB_B ebc,eaf + HILO ebc + ») + ;nok + +OP_DD(90,«») +OP_CB(90,«») +OP_DDCB(90,«») +OP_FD(90,«») +OP_FDCB(90,«») +OP_ED(90,«») + + ;; SUB A,C +OPCODE(91,« + F_SUB_B ebc,eaf + ») + ;nok + +OP_DD(91,«») +OP_CB(91,«») +OP_DDCB(91,«») +OP_FD(91,«») +OP_FDCB(91,«») +OP_ED(91,«») + + ;; SUB A,D +OPCODE(92,« + LOHI ede + F_SUB_B ede,eaf + HILO ede + ») + ;nok + +OP_DD(92,«») +OP_CB(92,«») +OP_DDCB(92,«») +OP_FD(92,«») +OP_FDCB(92,«») +OP_ED(92,«») + + ;; SUB A,E +OPCODE(93,« + F_SUB_B ede,eaf + ») + ;nok + +OP_DD(93,«») +OP_CB(93,«») +OP_DDCB(93,«») +OP_FD(93,«») +OP_FDCB(93,«») +OP_ED(93,«») + + ;; SUB A,H +OPCODE(94,« + LOHI ehl + F_SUB_B ehl,eaf + HILO ehl + ») + ;nok + +OP_DD(94,«») +OP_CB(94,«») +OP_DDCB(94,«») +OP_FD(94,«») +OP_FDCB(94,«») +OP_ED(94,«») + + ;; SUB A,L +OPCODE(95,« + F_SUB_B ehl,eaf + ») + +OP_DD(95,«») +OP_CB(95,«») +OP_DDCB(95,«») +OP_FD(95,«») +OP_FDCB(95,«») +OP_ED(95,«») + + ;; SUB A,(HL) +OPCODE(96,« + FETCHB ehl,d2 + F_SUB_B d2,eaf + PUTB d2,ehl + ») + ;nok + +OP_DD(96,«») +OP_CB(96,«») +OP_DDCB(96,«») +OP_FD(96,«») +OP_FDCB(96,«») +OP_ED(96,«») + + ;; SUB A,A +OPCODE(97,« + F_SUB_B eaf,eaf + ») + ;nok + +OP_DD(97,«») +OP_CB(97,«») +OP_DDCB(97,«») +OP_FD(97,«») +OP_FDCB(97,«») +OP_ED(97,«») + + + + + ;; Do a SBC \2,\1 +.macro F_SBC_B src dest + move.b \dest,d1 + move.b \src,d0 + jsr alu_sbc + move.b d1,\dest +.endm + + ;; SBC A,B +OPCODE(98,« + LOHI ebc + F_SBC_B ebc,eaf + HILO ebc + ») + ;nok + +OP_DD(98,«») +OP_CB(98,«») +OP_DDCB(98,«») +OP_FD(98,«») +OP_FDCB(98,«») +OP_ED(98,«») + + ;; SBC A,C +OPCODE(99,« + F_SBC_B ebc,eaf + ») + ;nok + +OP_DD(99,«») +OP_CB(99,«») +OP_DDCB(99,«») +OP_FD(99,«») +OP_FDCB(99,«») +OP_ED(99,«») + + ;; SBC A,D +OPCODE(9a,« + LOHI ede + F_SBC_B ede,eaf + HILO ede + ») + ;nok + +OP_DD(9a,«») +OP_CB(9a,«») +OP_DDCB(9a,«») +OP_FD(9a,«») +OP_FDCB(9a,«») +OP_ED(9a,«») + + ;; SBC A,E +OPCODE(9b,« + F_SBC_B ede,eaf + ») + ;nok + +OP_DD(9b,«») +OP_CB(9b,«») +OP_DDCB(9b,«») +OP_FD(9b,«») +OP_FDCB(9b,«») +OP_ED(9b,«») + + ;; SBC A,H +OPCODE(9c,« + LOHI ehl + F_SBC_B ehl,eaf + HILO ehl + ») + ;nok + +OP_DD(9c,«») +OP_CB(9c,«») +OP_DDCB(9c,«») +OP_FD(9c,«») +OP_FDCB(9c,«») +OP_ED(9c,«») + + ;; SBC A,L +OPCODE(9d,« + F_SBC_B ehl,eaf + ») + ;nok + +OP_DD(9d,«») +OP_CB(9d,«») +OP_DDCB(9d,«») +OP_FD(9d,«») +OP_FDCB(9d,«») +OP_ED(9d,«») + + ;; SBC A,(HL) +OPCODE(9e,« + FETCHB ehl,d2 + F_SBC_B d2,eaf + PUTB d2,ehl + ») + ;nok + +OP_DD(9e,«») +OP_CB(9e,«») +OP_DDCB(9e,«») +OP_FD(9e,«») +OP_FDCB(9e,«») +OP_ED(9e,«») + + ;; SBC A,A +OPCODE(9f,« + F_SBC_B eaf,eaf + ») + ;nok + + + + + +.macro F_AND_B src dest + move.b \dest,d1 + move.b \src,d0 + jsr alu_and + move.b d1,\dest +.endm + +OP_DD(9f,«») +OP_CB(9f,«») +OP_DDCB(9f,«») +OP_FD(9f,«») +OP_FDCB(9f,«») +OP_ED(9f,«») + + ;; AND B +OPCODE(a0,« + LOHI ebc + F_AND_B ebc,eaf + HILO ebc + ») + ;nok + +OP_DD(a0,«») +OP_CB(a0,«») +OP_DDCB(a0,«») +OP_FD(a0,«») +OP_FDCB(a0,«») +OP_ED(a0,«») + + ;; AND C +OPCODE(a1,« + F_AND_B ebc,eaf + ») + +OP_DD(a1,«») +OP_CB(a1,«») +OP_DDCB(a1,«») +OP_FD(a1,«») +OP_FDCB(a1,«») +OP_ED(a1,«») + + ;; AND D +OPCODE(a2,« + LOHI ede + F_AND_B ede,eaf + HILO ede + ») + ;nok + +OP_DD(a2,«») +OP_CB(a2,«») +OP_DDCB(a2,«») +OP_FD(a2,«») +OP_FDCB(a2,«») +OP_ED(a2,«») + + ;; AND E +OPCODE(a3,« + F_AND_B ede,eaf + ») + ;nok + +OP_DD(a3,«») +OP_CB(a3,«») +OP_DDCB(a3,«») +OP_FD(a3,«») +OP_FDCB(a3,«») +OP_ED(a3,«») + + ;; AND H +OPCODE(a4,« + LOHI ehl + F_AND_B ehl,eaf + HILO ehl + ») + ;nok + +OP_DD(a4,«») +OP_CB(a4,«») +OP_DDCB(a4,«») +OP_FD(a4,«») +OP_FDCB(a4,«») +OP_ED(a4,«») + + ;; AND L +OPCODE(a5,« + F_AND_B ehl,eaf + ») + ;nok + +OP_DD(a5,«») +OP_CB(a5,«») +OP_DDCB(a5,«») +OP_FD(a5,«») +OP_FDCB(a5,«») +OP_ED(a5,«») + + ;; AND (HL) +OPCODE(a6,« + FETCHB ehl,d2 + F_AND_B d2,eaf + PUTB d2,ehl + ») + ;nok + +OP_DD(a6,«») +OP_CB(a6,«») +OP_DDCB(a6,«») +OP_FD(a6,«») +OP_FDCB(a6,«») +OP_ED(a6,«») + + ;; AND A + ;; SPEED ... It's probably not necessary to run this faster. +OPCODE(a7,« + F_AND_B eaf,eaf + ») + ;nok + + + + + +.macro F_XOR_B src dest + move.b \dest,d1 + move.b \src,d0 + jsr alu_xor + move.b d1,\dest + ENDM + +OP_DD(a7,«») +OP_CB(a7,«») +OP_DDCB(a7,«») +OP_FD(a7,«») +OP_FDCB(a7,«») +OP_ED(a7,«») + + ;; XOR B +OPCODE(a8,« + LOHI ebc + F_XOR_B ebc,eaf + HILO ebc + ») + ;nok + +OP_DD(a8,«») +OP_CB(a8,«») +OP_DDCB(a8,«») +OP_FD(a8,«») +OP_FDCB(a8,«») +OP_ED(a8,«») + + ;; XOR C +OPCODE(a9,« + F_XOR_B ebc,eaf + ») + ;nok + +OP_DD(a9,«») +OP_CB(a9,«») +OP_DDCB(a9,«») +OP_FD(a9,«») +OP_FDCB(a9,«») +OP_ED(a9,«») + + ;; XOR D +OPCODE(aa,« + LOHI ede + F_XOR_B ede,eaf + HILO ede + ») + ;nok + +OP_DD(aa,«») +OP_CB(aa,«») +OP_DDCB(aa,«») +OP_FD(aa,«») +OP_FDCB(aa,«») +OP_ED(aa,«») + + ;; XOR E +OPCODE(ab,« + F_XOR_B ede,eaf + ») + ;nok + +OP_DD(ab,«») +OP_CB(ab,«») +OP_DDCB(ab,«») +OP_FD(ab,«») +OP_FDCB(ab,«») +OP_ED(ab,«») + + ;; XOR H +OPCODE(ac,« + LOHI ehl + F_XOR_B ehl,eaf + HILO ehl + ») + ;nok + +OP_DD(ac,«») +OP_CB(ac,«») +OP_DDCB(ac,«») +OP_FD(ac,«») +OP_FDCB(ac,«») +OP_ED(ac,«») + + ;; XOR L +OPCODE(ad,« + F_XOR_B ehl,eaf + ») + ;nok + +OP_DD(ad,«») +OP_CB(ad,«») +OP_DDCB(ad,«») +OP_FD(ad,«») +OP_FDCB(ad,«») +OP_ED(ad,«») + + ;; XOR (HL) +OPCODE(ae,« + FETCHB ehl,d2 + F_XOR_B d2,eaf + PUTB d2,ehl + ») + ;nok + +OP_DD(ae,«») +OP_CB(ae,«») +OP_DDCB(ae,«») +OP_FD(ae,«») +OP_FDCB(ae,«») +OP_ED(ae,«») + + ;; XOR A +OPCODE(af,« + F_XOR_B eaf,eaf + ;; XXX + ») + ;nok + + + + + +.macro F_OR_B src dest + move.b \dest,d1 + move.b \src,d0 + jsr alu_or + move.b d1,\dest +.endm + +OP_DD(af,«») +OP_CB(af,«») +OP_DDCB(af,«») +OP_FD(af,«») +OP_FDCB(af,«») +OP_ED(af,«») + + ;; OR B +OPCODE(b0,« + LOHI ebc + F_OR_B ebc,eaf + HILO ebc + ») + ;nok + +OP_DD(b0,«») +OP_CB(b0,«») +OP_DDCB(b0,«») +OP_FD(b0,«») +OP_FDCB(b0,«») +OP_ED(b0,«») + + ;; OR C +OPCODE(b1,« + F_OR_B ebc,eaf + ») + ;nok + +OP_DD(b1,«») +OP_CB(b1,«») +OP_DDCB(b1,«») +OP_FD(b1,«») +OP_FDCB(b1,«») +OP_ED(b1,«») + + ;; OR D +OPCODE(b2,« + LOHI ede + F_OR_B ede,eaf + HILO ede + ») + ;nok + +OP_DD(b2,«») +OP_CB(b2,«») +OP_DDCB(b2,«») +OP_FD(b2,«») +OP_FDCB(b2,«») +OP_ED(b2,«») + + ;; OR E +OPCODE(b3,« + F_OR_B ede,eaf + ») + ;nok + +OP_DD(b3,«») +OP_CB(b3,«») +OP_DDCB(b3,«») +OP_FD(b3,«») +OP_FDCB(b3,«») +OP_ED(b3,«») + + ;; OR H +OPCODE(b4,« + LOHI ehl + F_OR_B ehl,eaf + HILO ehl + ») + ;nok + +OP_DD(b4,«») +OP_CB(b4,«») +OP_DDCB(b4,«») +OP_FD(b4,«») +OP_FDCB(b4,«») +OP_ED(b4,«») + + ;; OR L +OPCODE(b5,« + F_OR_B ehl,eaf + ») + ;nok + +OP_DD(b5,«») +OP_CB(b5,«») +OP_DDCB(b5,«») +OP_FD(b5,«») +OP_FDCB(b5,«») +OP_ED(b5,«») + + ;; OR (HL) +OPCODE(b6,« + ;; SPEED unnecessary move + FETCHB ehl,d2 + F_OR_B d2,eaf + ») + ;nok + +OPCODE(b7,« +OP_DD(b6,«») +OP_CB(b6,«») +OP_DDCB(b6,«») +OP_FD(b6,«») +OP_FDCB(b6,«») +OP_ED(b6,«») + + ;; OR A + F_OR_B eaf,eaf + ») + ;nok + + + + + + ;; COMPARE instruction + ;; Tests the argument against A +.macro F_CP_B src dest + ;; XXX deal with \2 or \1 being d1 or d0 + move.b \dest,d1 + move.b \src,d0 + jsr alu_cp + ;; no result to save +.endm + +OP_DD(b7,«») +OP_CB(b7,«») +OP_DDCB(b7,«») +OP_FD(b7,«») +OP_FDCB(b7,«») +OP_ED(b7,«») + + ;; CP B +OPCODE(b8,« + move.w ebc,d2 + LOHI d2 + F_CP_B d2,eaf + ») + ;nok + +OP_DD(b8,«») +OP_CB(b8,«») +OP_DDCB(b8,«») +OP_FD(b8,«») +OP_FDCB(b8,«») +OP_ED(b8,«») + + ;; CP C +OPCODE(b9,« + F_CP_B ebc,eaf + ») + ;nok + +OP_DD(b9,«») +OP_CB(b9,«») +OP_DDCB(b9,«») +OP_FD(b9,«») +OP_FDCB(b9,«») +OP_ED(b9,«») + + ;; CP D +OPCODE(ba,« + move.w ede,d2 + LOHI d2 + F_CP_B d2,eaf + ») + ;nok + +OP_DD(ba,«») +OP_CB(ba,«») +OP_DDCB(ba,«») +OP_FD(ba,«») +OP_FDCB(ba,«») +OP_ED(ba,«») + + ;; CP E +OPCODE(bb,« + F_CP_B ede,eaf + ») + ;nok + +OP_DD(bb,«») +OP_CB(bb,«») +OP_DDCB(bb,«») +OP_FD(bb,«») +OP_FDCB(bb,«») +OP_ED(bb,«») + + ;; CP H +OPCODE(bc,« + move.w ehl,d2 + LOHI d2 + F_CP_B d2,eaf + ») + ;nok + +OP_DD(bc,«») +OP_CB(bc,«») +OP_DDCB(bc,«») +OP_FD(bc,«») +OP_FDCB(bc,«») +OP_ED(bc,«») + + ;; CP L +OPCODE(bd,« + F_CP_B ehl,eaf + ») + ;nok + +OP_DD(bd,«») +OP_CB(bd,«») +OP_DDCB(bd,«») +OP_FD(bd,«») +OP_FDCB(bd,«») +OP_ED(bd,«») + + ;; CP (HL) +OPCODE(be,« + FETCHB ehl,d2 + F_CP_B d2,eaf + ;; no result to store + ») + ;nok + +OP_DD(be,«») +OP_CB(be,«») +OP_DDCB(be,«») +OP_FD(be,«») +OP_FDCB(be,«») +OP_ED(be,«») + + ;; CP A +OPCODE(bf,« + F_CP_B eaf,eaf + ») + +OP_DD(bf,«») +OP_CB(bf,«») +OP_DDCB(bf,«») +OP_FD(bf,«») +OP_FDCB(bf,«») +OP_ED(bf,«») + + ;; RET NZ + ;; if ~Z + ;; PCl <- (SP) + ;; PCh <- (SP+1) + ;; SP <- (SP+2) +OPCODE(c0,« + jsr f_norm_z + ;; SPEED inline RET + beq emu_op_c9 ; RET + ») + ;nok + +OP_DD(c0,«») +OP_CB(c0,«») +OP_DDCB(c0,«») +OP_FD(c0,«») +OP_FDCB(c0,«») +OP_ED(c0,«») + + ;; POP BC + ;; Pops a word into BC +OPCODE(c1,« ; S10 T + POPW ebc + ») + ;nok + +OP_DD(c1,«») +OP_CB(c1,«») +OP_DDCB(c1,«») +OP_FD(c1,«») +OP_FDCB(c1,«») +OP_ED(c1,«») + + ;; JP NZ,immed.w + ;; if ~Z + ;; PC <- immed.w +OPCODE(c2,« + jsr f_norm_z + bne local(continue) + jmp emu_op_c3 ; shame this has to be a long jump +local(continue): + add.l #2,epc + ») + ;nok + +OP_DD(c2,«») +OP_CB(c2,«») +OP_DDCB(c2,«») +OP_FD(c2,«») +OP_FDCB(c2,«») +OP_ED(c2,«») + + ;; JP immed.w + ;; PC <- immed.w +OPCODE(c3,« + FETCHWI d1 + jsr deref + movea.l a0,epc + »,36,,12) + +OP_DD(c3,«») +OP_CB(c3,«») +OP_DDCB(c3,«») +OP_FD(c3,«») +OP_FDCB(c3,«») +OP_ED(c3,«») + + ;; CALL NZ,immed.w + ;; If ~Z, CALL immed.w +OPCODE(c4,« + jsr 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. + beq emu_op_cd + add.l #2,epc + ») + ;nok + +OP_DD(c4,«») +OP_CB(c4,«») +OP_DDCB(c4,«») +OP_FD(c4,«») +OP_FDCB(c4,«») +OP_ED(c4,«») + + ;; PUSH BC +OPCODE(c5,« + PUSHW ebc + ») + ;nok + +OP_DD(c5,«») +OP_CB(c5,«») +OP_DDCB(c5,«») +OP_FD(c5,«») +OP_FDCB(c5,«») +OP_ED(c5,«») + + ;; ADD A,immed.b +OPCODE(c6,« + FETCHBI d1 + F_ADD_B d1,eaf + ») + ;nok + +OP_DD(c6,«») +OP_CB(c6,«») +OP_DDCB(c6,«») +OP_FD(c6,«») +OP_FDCB(c6,«») +OP_ED(c6,«») + + ;; RST &0 + ;; == CALL 0 + ;; XXX check +OPCODE(c7,« + move.l epc,a0 + jsr underef + PUSHW d0 + move.w #$00,d0 + jsr deref + move.l a0,epc + ») + ;nok + +OP_DD(c7,«») +OP_CB(c7,«») +OP_DDCB(c7,«») +OP_FD(c7,«») +OP_FDCB(c7,«») +OP_ED(c7,«») + + ;; RET Z +OPCODE(c8,« + jsr f_norm_z + beq local(continue) + jmp emu_op_c9 ; shame this has to be a long jump +local(continue): + ») + ;nok + +OP_DD(c8,«») +OP_CB(c8,«») +OP_DDCB(c8,«») +OP_FD(c8,«») +OP_FDCB(c8,«») +OP_ED(c8,«») + + ;; RET + ;; PCl <- (SP) + ;; PCh <- (SP+1) POPW + ;; SP <- (SP+2) +OPCODE(c9,« + POPW d1 + jsr deref + movea.l a0,epc + ») + ;nok + +OP_DD(c9,«») +OP_CB(c9,«») +OP_DDCB(c9,«») +OP_FD(c9,«») +OP_FDCB(c9,«») +OP_ED(c9,«») + + ;; JP Z,immed.w + ;; If Z, jump +OPCODE(ca,« + jsr f_norm_z + bne emu_op_c3 + add.l #2,epc + ») + ;nok +OP_DD(ca,«») +OP_CB(ca,«») +OP_DDCB(ca,«») +OP_FD(ca,«») +OP_FDCB(ca,«») +OP_ED(ca,«») + + ;; prefix +OPCODE(cb,« + movea.w emu_op_undo_cb(pc),a2 + ») + ;nok + +OP_DD(cb,«») +OP_CB(cb,«») +OP_DDCB(cb,«») +OP_FD(cb,«») +OP_FDCB(cb,«») +OP_ED(cb,«») + + ;; CALL Z,immed.w +OPCODE(cc,« + jsr f_norm_z + beq local(continue) + jmp emu_op_cd +local(continue): + add.l #2,epc + ») + ;nok + +OP_DD(cc,«») +OP_CB(cc,«») +OP_DDCB(cc,«») +OP_FD(cc,«») +OP_FDCB(cc,«») +OP_ED(cc,«») + + ;; CALL immed.w + ;; (Like JSR on 68k) + ;; (SP-1) <- PCh + ;; (SP-2) <- PCl + ;; SP <- SP - 2 + ;; PC <- address +OPCODE(cd,« + move.l epc,a0 + jsr underef ; d0 has PC + add.w #2,d0 + PUSHW d0 + bra emu_op_c3 ; JP + ») + +OP_DD(cd,«») +OP_CB(cd,«») +OP_DDCB(cd,«») +OP_FD(cd,«») +OP_FDCB(cd,«») +OP_ED(cd,«») + + ;; ADC A,immed.b +OPCODE(ce,« + FETCHWI d1 + F_ADC_B d1,eaf + ») + ;nok + +OP_DD(ce,«») +OP_CB(ce,«») +OP_DDCB(ce,«») +OP_FD(ce,«») +OP_FDCB(ce,«») +OP_ED(ce,«») + + ;; RST &08 + ;; == CALL 8 +OPCODE(cf,« + move.l epc,a0 + jsr underef ; d0 has PC + PUSHW d0 + move.w #$08,d0 + jsr deref + move.l a0,epc + ») + ;nok + +OP_DD(cf,«») +OP_CB(cf,«») +OP_DDCB(cf,«») +OP_FD(cf,«») +OP_FDCB(cf,«») +OP_ED(cf,«») + + ;; RET NC +OPCODE(d0,« + jsr f_norm_c + beq emu_op_c9 + ») + ;nok + +OP_DD(d0,«») +OP_CB(d0,«») +OP_DDCB(d0,«») +OP_FD(d0,«») +OP_FDCB(d0,«») +OP_ED(d0,«») + + ;; POP DE +OPCODE(d1,« + POPW ede + ») + ;nok + +OP_DD(d1,«») +OP_CB(d1,«») +OP_DDCB(d1,«») +OP_FD(d1,«») +OP_FDCB(d1,«») +OP_ED(d1,«») + + ;; JP NC,immed.w +OPCODE(d2,« + jsr f_norm_c + beq emu_op_c3 + add.l #2,epc + ») + +OP_DD(d2,«») +OP_CB(d2,«») +OP_DDCB(d2,«») +OP_FD(d2,«») +OP_FDCB(d2,«») +OP_ED(d2,«») + + ;; OUT immed.b,A +OPCODE(d3,« + move.b eaf,d1 + FETCHBI d0 + jsr port_out + ») + ;nok + +OP_DD(d3,«») +OP_CB(d3,«») +OP_DDCB(d3,«») +OP_FD(d3,«») +OP_FDCB(d3,«») +OP_ED(d3,«») + + ;; CALL NC,immed.w +OPCODE(d4,« + jsr f_norm_c + beq emu_op_cd + add.l #2,epc + ») + ;nok + +OP_DD(d4,«») +OP_CB(d4,«») +OP_DDCB(d4,«») +OP_FD(d4,«») +OP_FDCB(d4,«») +OP_ED(d4,«») + + ;; PUSH DE +OPCODE(d5,« + PUSHW ede + ») + ;nok + +OP_DD(d5,«») +OP_CB(d5,«») +OP_DDCB(d5,«») +OP_FD(d5,«») +OP_FDCB(d5,«») +OP_ED(d5,«») + + ;; SUB A,immed.b +OPCODE(d6,« + FETCHBI d1 + F_SUB_B eaf,d1 + ») + ;nok + +OP_DD(d6,«») +OP_CB(d6,«») +OP_DDCB(d6,«») +OP_FD(d6,«») +OP_FDCB(d6,«») +OP_ED(d6,«») + + ;; RST &10 + ;; == CALL 10 +OPCODE(d7,« + move.l epc,a0 + jsr underef + PUSHW d0 + move.w #$10,d0 + jsr deref + move.l a0,epc + ») + ;nok + +OP_DD(d7,«») +OP_CB(d7,«») +OP_DDCB(d7,«») +OP_FD(d7,«») +OP_FDCB(d7,«») +OP_ED(d7,«») + + ;; RET C +OPCODE(d8,« + jsr f_norm_c + bne emu_op_c9 + ») + ;nok + +OP_DD(d8,«») +OP_CB(d8,«») +OP_DDCB(d8,«») +OP_FD(d8,«») +OP_FDCB(d8,«») +OP_ED(d8,«») + + ;; EXX +OPCODE(d9,« + swap ebc + swap ede + swap ehl + ») + ;nok + +OP_DD(d9,«») +OP_CB(d9,«») +OP_DDCB(d9,«») +OP_FD(d9,«») +OP_FDCB(d9,«») +OP_ED(d9,«») + + ;; JP C,immed.w +OPCODE(da,« + jsr f_norm_c + bne emu_op_c3 + ») + ;nok + +OP_DD(da,«») +OP_CB(da,«») +OP_DDCB(da,«») +OP_FD(da,«») +OP_FDCB(da,«») +OP_ED(da,«») + + ;; IN A,immed.b +OPCODE(db,« + move.b eaf,d1 + FETCHBI d0 + jsr port_in + ») + ;nok + +OP_DD(db,«») +OP_CB(db,«») +OP_DDCB(db,«») +OP_FD(db,«») +OP_FDCB(db,«») +OP_ED(db,«») + + ;; CALL C,immed.w +OPCODE(dc,« + jsr f_norm_c + bne emu_op_cd + add.l #2,epc + ») + ;nok + +OPCODE(dd,« ; prefix + movea.w emu_op_undo_dd(pc),a2 + ») + +OP_DD(dc,«») +OP_CB(dc,«») +OP_DDCB(dc,«») +OP_FD(dc,«») +OP_FDCB(dc,«») +OP_ED(dc,«») + + ;; SBC A,immed.b +OPCODE(de,« + FETCHWI d1 + F_SBC_B d1,eaf + ») + ;nok + +OP_DD(dd,«») +OP_CB(dd,«») +OP_DDCB(dd,«») +OP_FD(dd,«») +OP_FDCB(dd,«») +OP_ED(dd,«») + + ;; RST &18 + ;; == CALL 18 +OPCODE(df,« + move.l epc,a0 + jsr underef + PUSHW d0 + move.w #$18,d0 + jsr deref + move.l a0,epc + ») + ;nok + +OP_DD(de,«») +OP_CB(de,«») +OP_DDCB(de,«») +OP_FD(de,«») +OP_FDCB(de,«») +OP_ED(de,«») + + ;; RET PO + ;; If parity odd (P zero), return +OPCODE(e0,« + jsr f_norm_pv + beq emu_op_c9 + ») + ;nok + +OP_DD(df,«») +OP_CB(df,«») +OP_DDCB(df,«») +OP_FD(df,«») +OP_FDCB(df,«») +OP_ED(df,«») + + ;; POP HL +OPCODE(e1,« + POPW ehl + ») + ;nok + +OP_DD(e0,«») +OP_CB(e0,«») +OP_DDCB(e0,«») +OP_FD(e0,«») +OP_FDCB(e0,«») +OP_ED(e0,«») + + ;; JP PO,immed.w +OPCODE(e2,« + jsr f_norm_pv + beq emu_op_c3 + add.l #2,epc + ») + ;nok + +OP_DD(e1,«») +OP_CB(e1,«») +OP_DDCB(e1,«») +OP_FD(e1,«») +OP_FDCB(e1,«») +OP_ED(e1,«») + + ;; EX (SP),HL + ;; Exchange +OPCODE(e3,« + POPW d1 + PUSHW ehl + move.w d1,ehl + ») + ;nok + +OP_DD(e2,«») +OP_CB(e2,«») +OP_DDCB(e2,«») +OP_FD(e2,«») +OP_FDCB(e2,«») +OP_ED(e2,«») + + ;; CALL PO,immed.w + ;; if parity odd (P=0), call +OPCODE(e4,« + jsr f_norm_pv + beq emu_op_cd + add.l #2,epc + ») + ;nok + +OP_DD(e3,«») +OP_CB(e3,«») +OP_DDCB(e3,«») +OP_FD(e3,«») +OP_FDCB(e3,«») +OP_ED(e3,«») + + ;; PUSH HL +OPCODE(e5,« + PUSHW ehl + ») + ;nok + +OP_DD(e4,«») +OP_CB(e4,«») +OP_DDCB(e4,«») +OP_FD(e4,«») +OP_FDCB(e4,«») +OP_ED(e4,«») + + ;; AND immed.b +OPCODE(e6,« + FETCHBI d1 + F_AND_B d1,eaf + ») + ;nok + +OP_DD(e5,«») +OP_CB(e5,«») +OP_DDCB(e5,«») +OP_FD(e5,«») +OP_FDCB(e5,«») +OP_ED(e5,«») + + ;; RST &20 + ;; == CALL 20 +OPCODE(e7,« + move.l epc,a0 + jsr underef + PUSHW d0 + move.w #$20,d0 + jsr deref + move.l a0,epc + ») + ;nok + +OP_DD(e6,«») +OP_CB(e6,«») +OP_DDCB(e6,«») +OP_FD(e6,«») +OP_FDCB(e6,«») +OP_ED(e6,«») + + ;; RET PE + ;; If parity odd (P zero), return +OPCODE(e8,« + jsr f_norm_pv + bne emu_op_c9 + ») + ;nok + +OP_DD(e7,«») +OP_CB(e7,«») +OP_DDCB(e7,«») +OP_FD(e7,«») +OP_FDCB(e7,«») +OP_ED(e7,«») + + ;; JP (HL) +OPCODE(e9,« + FETCHB ehl,d1 + jsr deref + movea.l a0,epc + ») + ;nok + +OP_DD(e8,«») +OP_CB(e8,«») +OP_DDCB(e8,«») +OP_FD(e8,«») +OP_FDCB(e8,«») +OP_ED(e8,«») + + ;; JP PE,immed.w +OPCODE(ea,« + jsr f_norm_pv + bne emu_op_c3 + add.l #2,epc + ») + ;nok + +OP_DD(e9,«») +OP_CB(e9,«») +OP_DDCB(e9,«») +OP_FD(e9,«») +OP_FDCB(e9,«») +OP_ED(e9,«») + + ;; EX DE,HL +OPCODE(eb,« + exg.w ede,ehl + ») + ;nok + +OP_DD(ea,«») +OP_CB(ea,«») +OP_DDCB(ea,«») +OP_FD(ea,«») +OP_FDCB(ea,«») +OP_ED(ea,«») + + ;; CALL PE,immed.w + ;; If parity even (P=1), call +OPCODE(ec,« + jsr f_norm_c + bne emu_op_cd + add.l #2,epc + ») + ;nok + +OP_DD(eb,«») +OP_CB(eb,«») +OP_DDCB(eb,«») +OP_FD(eb,«») +OP_FDCB(eb,«») +OP_ED(eb,«») + + ;; XXX this probably ought to hold interrupts too +OPCODE(ed,« ; prefix + movea.w emu_op_undo_ed(pc),a2 + ») + ;nok + +OP_DD(ec,«») +OP_CB(ec,«») +OP_DDCB(ec,«») +OP_FD(ec,«») +OP_FDCB(ec,«») +OP_ED(ec,«») + + ;; XOR immed.b +OPCODE(ee,« + FETCHBI d1 + F_XOR_B d1,eaf + ») + ;nok + +OP_DD(ed,«») +OP_CB(ed,«») +OP_DDCB(ed,«») +OP_FD(ed,«») +OP_FDCB(ed,«») +OP_ED(ed,«») + + ;; RST &28 + ;; == CALL 28 +OPCODE(ef,« + move.l epc,a0 + jsr underef + PUSHW d0 + move.w #$28,d0 + jsr deref + move.l a0,epc + ») + ;nok + +OP_DD(ee,«») +OP_CB(ee,«») +OP_DDCB(ee,«») +OP_FD(ee,«») +OP_FDCB(ee,«») +OP_ED(ee,«») + + ;; RET P + ;; Return if Positive +OPCODE(f0,« + jsr f_norm_sign + beq emu_op_c9 ; RET + ») + ;nok + +OP_DD(ef,«») +OP_CB(ef,«») +OP_DDCB(ef,«») +OP_FD(ef,«») +OP_FDCB(ef,«») +OP_ED(ef,«») + + ;; 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 + +OP_DD(f0,«») +OP_CB(f0,«») +OP_DDCB(f0,«») +OP_FD(f0,«») +OP_FDCB(f0,«») +OP_ED(f0,«») + + ;; JP P,immed.w +OPCODE(f2,« + jsr f_norm_sign + beq emu_op_c3 ; JP + add.l #2,epc + ») + ;nok + +OPCODE(f3,« +OP_DD(f1,«») +OP_CB(f1,«») +OP_DDCB(f1,«») +OP_FD(f1,«») +OP_FDCB(f1,«») +OP_ED(f1,«») + + ;; DI + jsr ints_stop + ») + +OP_DD(f2,«») +OP_CB(f2,«») +OP_DDCB(f2,«») +OP_FD(f2,«») +OP_FDCB(f2,«») +OP_ED(f2,«») + + ;; CALL P,&0000 + ;; Call if positive (S=0) +OPCODE(f4,« + jsr f_norm_sign + beq emu_op_cd + ») + ;nok + +OP_DD(f3,«») +OP_CB(f3,«») +OP_DDCB(f3,«») +OP_FD(f3,«») +OP_FDCB(f3,«») +OP_ED(f3,«») + + ;; PUSH AF +OPCODE(f5,« + jsr flags_normalize + LOHI eaf + move.b (flag_byte),eaf + ;; XXX wrong, af is not normalized by flags_normalize? + HILO eaf + PUSHW eaf + ») + ;nok + +OP_DD(f5,«») +OP_CB(f5,«») +OP_DDCB(f5,«») +OP_FD(f5,«») +OP_FDCB(f5,«») +OP_ED(f5,«») + + ;; OR immed.b +OPCODE(f6,« + FETCHBI d1 + F_OR_B d1,eaf + ») + ;nok + +OP_DD(f6,«») +OP_CB(f6,«») +OP_DDCB(f6,«») +OP_FD(f6,«») +OP_FDCB(f6,«») +OP_ED(f6,«») + + ;; RST &30 + ;; == CALL 30 +OPCODE(f7,« + move.l epc,a0 + jsr underef + PUSHW d0 + move.w #$30,d0 + jsr deref + move.l a0,epc + ») + ;nok + +OP_DD(f7,«») +OP_CB(f7,«») +OP_DDCB(f7,«») +OP_FD(f7,«») +OP_FDCB(f7,«») +OP_ED(f7,«») + + ;; RET M + ;; Return if Sign == 1, minus +OPCODE(f8,« + jsr f_norm_sign + bne emu_op_c9 ; RET + ») + ;nok + +OP_DD(f8,«») +OP_CB(f8,«») +OP_DDCB(f8,«») +OP_FD(f8,«») +OP_FDCB(f8,«») +OP_ED(f8,«») + + ;; LD SP,HL + ;; SP <- HL +OPCODE(f9,« + move.w ehl,d1 + jsr deref + movea.l a0,esp + ») + ;nok + +OP_DD(f9,«») +OP_CB(f9,«») +OP_DDCB(f9,«») +OP_FD(f9,«») +OP_FDCB(f9,«») +OP_ED(f9,«») + + ;; JP M,immed.w +OPCODE(fa,« + jsr f_norm_sign + bne emu_op_c3 ; JP + add.l #2,epc + ») + ;nok + +OP_DD(fa,«») +OP_CB(fa,«») +OP_DDCB(fa,«») +OP_FD(fa,«») +OP_FDCB(fa,«») +OP_ED(fa,«») + + ;; EI +OPCODE(fb,« + jsr ints_start + ») + ;nok + +OP_DD(fb,«») +OP_CB(fb,«») +OP_DDCB(fb,«») +OP_FD(fb,«») +OP_FDCB(fb,«») +OP_ED(fb,«») + + ;; CALL M,immed.w + ;; Call if minus (S=1) +OPCODE(fc,« + jsr f_norm_sign + bne emu_op_cd + add.l #2,epc + ») + ;nok + +OP_DD(fc,«») +OP_CB(fc,«») +OP_DDCB(fc,«») +OP_FD(fc,«») +OP_FDCB(fc,«») +OP_ED(fc,«») + + ;; swap IY, HL +OPCODE(fd,« ; prefix + movea.w emu_op_undo_fd(pc),a2 + ») + +OP_DD(fd,«») +OP_CB(fd,«») +OP_DDCB(fd,«») +OP_FD(fd,«») +OP_FDCB(fd,«») +OP_ED(fd,«») + + ;; CP immed.b +OPCODE(fe,« + FETCHBI d1 + F_CP_B d1,eaf + ») + ;nok + +OP_DD(fe,«») +OP_CB(fe,«») +OP_DDCB(fe,«») +OP_FD(fe,«») +OP_FDCB(fe,«») +OP_ED(fe,«») + + ;; RST &38 + ;; == CALL 38 +OPCODE(ff,« + move.l epc,a0 + jsr underef + PUSHW d0 + move.w #$38,d0 + jsr deref + move.l a0,epc + ») + ;nok + +OP_DD(ff,«») +OP_CB(ff,«») +OP_DDCB(ff,«») +OP_FD(ff,«») +OP_FDCB(ff,«») +OP_ED(ff,«») + diff --git a/ports.asm b/ports.asm deleted file mode 100644 index 1a6b47e..0000000 --- a/ports.asm +++ /dev/null @@ -1,1188 +0,0 @@ - ;; Routines to process OUT and IN instructions. This is the - ;; bit that's unique to TI calculators. - - ;; Port is in d0, byte is in d1 - ;; Destroys a0 -port_in: - andi.w #$ff,d0 - add.w d0,d0 - add.w d0,d0 - movea.l lut_ports_in(pc,d0),a0 - jmp (a0) - rts - -lut_ports_in: - dc.l port_in_00 - dc.l port_in_01 - dc.l port_in_02 - dc.l port_in_03 - dc.l port_in_04 - dc.l port_in_05 - dc.l port_in_06 - dc.l port_in_07 - dc.l port_in_08 - dc.l port_in_09 - dc.l port_in_0a - dc.l port_in_0b - dc.l port_in_0c - dc.l port_in_0d - dc.l port_in_0e - dc.l port_in_0f - dc.l port_in_10 - dc.l port_in_11 - dc.l port_in_12 - dc.l port_in_13 - dc.l port_in_14 - dc.l port_in_15 - dc.l port_in_16 - dc.l port_in_17 - dc.l port_in_18 - dc.l port_in_19 - dc.l port_in_1a - dc.l port_in_1b - dc.l port_in_1c - dc.l port_in_1d - dc.l port_in_1e - dc.l port_in_1f - dc.l port_in_20 - dc.l port_in_21 - dc.l port_in_22 - dc.l port_in_23 - dc.l port_in_24 - dc.l port_in_25 - dc.l port_in_26 - dc.l port_in_27 - dc.l port_in_28 - dc.l port_in_29 - dc.l port_in_2a - dc.l port_in_2b - dc.l port_in_2c - dc.l port_in_2d - dc.l port_in_2e - dc.l port_in_2f - dc.l port_in_30 - dc.l port_in_31 - dc.l port_in_32 - dc.l port_in_33 - dc.l port_in_34 - dc.l port_in_35 - dc.l port_in_36 - dc.l port_in_37 - dc.l port_in_38 - dc.l port_in_39 - dc.l port_in_3a - dc.l port_in_3b - dc.l port_in_3c - dc.l port_in_3d - dc.l port_in_3e - dc.l port_in_3f - dc.l port_in_40 - dc.l port_in_41 - dc.l port_in_42 - dc.l port_in_43 - dc.l port_in_44 - dc.l port_in_45 - dc.l port_in_46 - dc.l port_in_47 - dc.l port_in_48 - dc.l port_in_49 - dc.l port_in_4a - dc.l port_in_4b - dc.l port_in_4c - dc.l port_in_4d - dc.l port_in_4e - dc.l port_in_4f - dc.l port_in_50 - dc.l port_in_51 - dc.l port_in_52 - dc.l port_in_53 - dc.l port_in_54 - dc.l port_in_55 - dc.l port_in_56 - dc.l port_in_57 - dc.l port_in_58 - dc.l port_in_59 - dc.l port_in_5a - dc.l port_in_5b - dc.l port_in_5c - dc.l port_in_5d - dc.l port_in_5e - dc.l port_in_5f - dc.l port_in_60 - dc.l port_in_61 - dc.l port_in_62 - dc.l port_in_63 - dc.l port_in_64 - dc.l port_in_65 - dc.l port_in_66 - dc.l port_in_67 - dc.l port_in_68 - dc.l port_in_69 - dc.l port_in_6a - dc.l port_in_6b - dc.l port_in_6c - dc.l port_in_6d - dc.l port_in_6e - dc.l port_in_6f - dc.l port_in_70 - dc.l port_in_71 - dc.l port_in_72 - dc.l port_in_73 - dc.l port_in_74 - dc.l port_in_75 - dc.l port_in_76 - dc.l port_in_77 - dc.l port_in_78 - dc.l port_in_79 - dc.l port_in_7a - dc.l port_in_7b - dc.l port_in_7c - dc.l port_in_7d - dc.l port_in_7e - dc.l port_in_7f - dc.l port_in_80 - dc.l port_in_81 - dc.l port_in_82 - dc.l port_in_83 - dc.l port_in_84 - dc.l port_in_85 - dc.l port_in_86 - dc.l port_in_87 - dc.l port_in_88 - dc.l port_in_89 - dc.l port_in_8a - dc.l port_in_8b - dc.l port_in_8c - dc.l port_in_8d - dc.l port_in_8e - dc.l port_in_8f - dc.l port_in_90 - dc.l port_in_91 - dc.l port_in_92 - dc.l port_in_93 - dc.l port_in_94 - dc.l port_in_95 - dc.l port_in_96 - dc.l port_in_97 - dc.l port_in_98 - dc.l port_in_99 - dc.l port_in_9a - dc.l port_in_9b - dc.l port_in_9c - dc.l port_in_9d - dc.l port_in_9e - dc.l port_in_9f - dc.l port_in_a0 - dc.l port_in_a1 - dc.l port_in_a2 - dc.l port_in_a3 - dc.l port_in_a4 - dc.l port_in_a5 - dc.l port_in_a6 - dc.l port_in_a7 - dc.l port_in_a8 - dc.l port_in_a9 - dc.l port_in_aa - dc.l port_in_ab - dc.l port_in_ac - dc.l port_in_ad - dc.l port_in_ae - dc.l port_in_af - dc.l port_in_b0 - dc.l port_in_b1 - dc.l port_in_b2 - dc.l port_in_b3 - dc.l port_in_b4 - dc.l port_in_b5 - dc.l port_in_b6 - dc.l port_in_b7 - dc.l port_in_b8 - dc.l port_in_b9 - dc.l port_in_ba - dc.l port_in_bb - dc.l port_in_bc - dc.l port_in_bd - dc.l port_in_be - dc.l port_in_bf - dc.l port_in_c0 - dc.l port_in_c1 - dc.l port_in_c2 - dc.l port_in_c3 - dc.l port_in_c4 - dc.l port_in_c5 - dc.l port_in_c6 - dc.l port_in_c7 - dc.l port_in_c8 - dc.l port_in_c9 - dc.l port_in_ca - dc.l port_in_cb - dc.l port_in_cc - dc.l port_in_cd - dc.l port_in_ce - dc.l port_in_cf - dc.l port_in_d0 - dc.l port_in_d1 - dc.l port_in_d2 - dc.l port_in_d3 - dc.l port_in_d4 - dc.l port_in_d5 - dc.l port_in_d6 - dc.l port_in_d7 - dc.l port_in_d8 - dc.l port_in_d9 - dc.l port_in_da - dc.l port_in_db - dc.l port_in_dc - dc.l port_in_dd - dc.l port_in_de - dc.l port_in_df - dc.l port_in_e0 - dc.l port_in_e1 - dc.l port_in_e2 - dc.l port_in_e3 - dc.l port_in_e4 - dc.l port_in_e5 - dc.l port_in_e6 - dc.l port_in_e7 - dc.l port_in_e8 - dc.l port_in_e9 - dc.l port_in_ea - dc.l port_in_eb - dc.l port_in_ec - dc.l port_in_ed - dc.l port_in_ee - dc.l port_in_ef - dc.l port_in_f0 - dc.l port_in_f1 - dc.l port_in_f2 - dc.l port_in_f3 - dc.l port_in_f4 - dc.l port_in_f5 - dc.l port_in_f6 - dc.l port_in_f7 - dc.l port_in_f8 - dc.l port_in_f9 - dc.l port_in_fa - dc.l port_in_fb - dc.l port_in_fc - dc.l port_in_fd - dc.l port_in_fe - dc.l port_in_ff - -port_out: - andi.w #$ff,d0 - ;; This is the fastest way to shift left 2 bits. :S - add.w d0,d0 - add.w d0,d0 - movea.l lut_ports_out(pc,d0.w),a0 - jmp (a0) - -lut_ports_out: - dc.l port_out_00 - dc.l port_out_01 - dc.l port_out_02 - dc.l port_out_03 - dc.l port_out_04 - dc.l port_out_05 - dc.l port_out_06 - dc.l port_out_07 - dc.l port_out_08 - dc.l port_out_09 - dc.l port_out_0a - dc.l port_out_0b - dc.l port_out_0c - dc.l port_out_0d - dc.l port_out_0e - dc.l port_out_0f - dc.l port_out_10 - dc.l port_out_11 - dc.l port_out_12 - dc.l port_out_13 - dc.l port_out_14 - dc.l port_out_15 - dc.l port_out_16 - dc.l port_out_17 - dc.l port_out_18 - dc.l port_out_19 - dc.l port_out_1a - dc.l port_out_1b - dc.l port_out_1c - dc.l port_out_1d - dc.l port_out_1e - dc.l port_out_1f - dc.l port_out_20 - dc.l port_out_21 - dc.l port_out_22 - dc.l port_out_23 - dc.l port_out_24 - dc.l port_out_25 - dc.l port_out_26 - dc.l port_out_27 - dc.l port_out_28 - dc.l port_out_29 - dc.l port_out_2a - dc.l port_out_2b - dc.l port_out_2c - dc.l port_out_2d - dc.l port_out_2e - dc.l port_out_2f - dc.l port_out_30 - dc.l port_out_31 - dc.l port_out_32 - dc.l port_out_33 - dc.l port_out_34 - dc.l port_out_35 - dc.l port_out_36 - dc.l port_out_37 - dc.l port_out_38 - dc.l port_out_39 - dc.l port_out_3a - dc.l port_out_3b - dc.l port_out_3c - dc.l port_out_3d - dc.l port_out_3e - dc.l port_out_3f - dc.l port_out_40 - dc.l port_out_41 - dc.l port_out_42 - dc.l port_out_43 - dc.l port_out_44 - dc.l port_out_45 - dc.l port_out_46 - dc.l port_out_47 - dc.l port_out_48 - dc.l port_out_49 - dc.l port_out_4a - dc.l port_out_4b - dc.l port_out_4c - dc.l port_out_4d - dc.l port_out_4e - dc.l port_out_4f - dc.l port_out_50 - dc.l port_out_51 - dc.l port_out_52 - dc.l port_out_53 - dc.l port_out_54 - dc.l port_out_55 - dc.l port_out_56 - dc.l port_out_57 - dc.l port_out_58 - dc.l port_out_59 - dc.l port_out_5a - dc.l port_out_5b - dc.l port_out_5c - dc.l port_out_5d - dc.l port_out_5e - dc.l port_out_5f - dc.l port_out_60 - dc.l port_out_61 - dc.l port_out_62 - dc.l port_out_63 - dc.l port_out_64 - dc.l port_out_65 - dc.l port_out_66 - dc.l port_out_67 - dc.l port_out_68 - dc.l port_out_69 - dc.l port_out_6a - dc.l port_out_6b - dc.l port_out_6c - dc.l port_out_6d - dc.l port_out_6e - dc.l port_out_6f - dc.l port_out_70 - dc.l port_out_71 - dc.l port_out_72 - dc.l port_out_73 - dc.l port_out_74 - dc.l port_out_75 - dc.l port_out_76 - dc.l port_out_77 - dc.l port_out_78 - dc.l port_out_79 - dc.l port_out_7a - dc.l port_out_7b - dc.l port_out_7c - dc.l port_out_7d - dc.l port_out_7e - dc.l port_out_7f - dc.l port_out_80 - dc.l port_out_81 - dc.l port_out_82 - dc.l port_out_83 - dc.l port_out_84 - dc.l port_out_85 - dc.l port_out_86 - dc.l port_out_87 - dc.l port_out_88 - dc.l port_out_89 - dc.l port_out_8a - dc.l port_out_8b - dc.l port_out_8c - dc.l port_out_8d - dc.l port_out_8e - dc.l port_out_8f - dc.l port_out_90 - dc.l port_out_91 - dc.l port_out_92 - dc.l port_out_93 - dc.l port_out_94 - dc.l port_out_95 - dc.l port_out_96 - dc.l port_out_97 - dc.l port_out_98 - dc.l port_out_99 - dc.l port_out_9a - dc.l port_out_9b - dc.l port_out_9c - dc.l port_out_9d - dc.l port_out_9e - dc.l port_out_9f - dc.l port_out_a0 - dc.l port_out_a1 - dc.l port_out_a2 - dc.l port_out_a3 - dc.l port_out_a4 - dc.l port_out_a5 - dc.l port_out_a6 - dc.l port_out_a7 - dc.l port_out_a8 - dc.l port_out_a9 - dc.l port_out_aa - dc.l port_out_ab - dc.l port_out_ac - dc.l port_out_ad - dc.l port_out_ae - dc.l port_out_af - dc.l port_out_b0 - dc.l port_out_b1 - dc.l port_out_b2 - dc.l port_out_b3 - dc.l port_out_b4 - dc.l port_out_b5 - dc.l port_out_b6 - dc.l port_out_b7 - dc.l port_out_b8 - dc.l port_out_b9 - dc.l port_out_ba - dc.l port_out_bb - dc.l port_out_bc - dc.l port_out_bd - dc.l port_out_be - dc.l port_out_bf - dc.l port_out_c0 - dc.l port_out_c1 - dc.l port_out_c2 - dc.l port_out_c3 - dc.l port_out_c4 - dc.l port_out_c5 - dc.l port_out_c6 - dc.l port_out_c7 - dc.l port_out_c8 - dc.l port_out_c9 - dc.l port_out_ca - dc.l port_out_cb - dc.l port_out_cc - dc.l port_out_cd - dc.l port_out_ce - dc.l port_out_cf - dc.l port_out_d0 - dc.l port_out_d1 - dc.l port_out_d2 - dc.l port_out_d3 - dc.l port_out_d4 - dc.l port_out_d5 - dc.l port_out_d6 - dc.l port_out_d7 - dc.l port_out_d8 - dc.l port_out_d9 - dc.l port_out_da - dc.l port_out_db - dc.l port_out_dc - dc.l port_out_dd - dc.l port_out_de - dc.l port_out_df - dc.l port_out_e0 - dc.l port_out_e1 - dc.l port_out_e2 - dc.l port_out_e3 - dc.l port_out_e4 - dc.l port_out_e5 - dc.l port_out_e6 - dc.l port_out_e7 - dc.l port_out_e8 - dc.l port_out_e9 - dc.l port_out_ea - dc.l port_out_eb - dc.l port_out_ec - dc.l port_out_ed - dc.l port_out_ee - dc.l port_out_ef - dc.l port_out_f0 - dc.l port_out_f1 - dc.l port_out_f2 - dc.l port_out_f3 - dc.l port_out_f4 - dc.l port_out_f5 - dc.l port_out_f6 - dc.l port_out_f7 - dc.l port_out_f8 - dc.l port_out_f9 - dc.l port_out_fa - dc.l port_out_fb - dc.l port_out_fc - dc.l port_out_fd - dc.l port_out_fe - dc.l port_out_ff - -port_in_00: -port_out_00: - ;; Temporary test harness. Writing to this port writes a - ;; character to the screen. - SAVEREG - andi.w #$ff,d1 - move.w d1,-(sp) - jsr char_draw - addq #2,sp - RESTREG - rts - -port_in_01: -port_out_01: -port_in_02: -port_out_02: -port_in_03: -port_out_03: -port_in_04: -port_out_04: - ;; Bank B paging, among other things - SAVEREG - move.b d1,-(a7) - jsr bankswap_b_write - addq #2,a7 - RESTREG - rts - -port_in_05: -port_out_05: -port_in_06: -port_out_06: - ;; Bank A paging - SAVEREG - move.b d1,-(a7) - jsr bankswap_a_write - addq #2,a7 - RESTREG - rts - -port_in_07: -port_out_07: -port_in_08: -port_out_08: -port_in_09: -port_out_09: -port_in_0a: -port_out_0a: -port_in_0b: -port_out_0b: -port_in_0c: -port_out_0c: -port_in_0d: -port_out_0d: -port_in_0e: -port_out_0e: -port_in_0f: -port_out_0f: -port_in_10: - xref video_row - xref video_increment - xref video_enabled - xref video_6bit - xref video_busy - xref video_cur_row - xref video_cur_col - xref video_write - xref video_read - - ;; LCD status - clr.b d1 - or.b video_increment,d1 - or.b video_row,d1 - or.b video_enabled,d1 - or.b video_6bit,d1 - or.b video_busy,d1 - rts - -port_out_10: - ;; LCD command - tst.b d1 - beq port_out_10_00 - subq.b #1,d1 - beq port_out_10_01 - subq.b #1,d1 - beq port_out_10_02 - subq.b #1,d1 - beq port_out_10_03 - subq.b #1,d1 - beq port_out_10_04 - subq.b #1,d1 - beq port_out_10_05 - subq.b #1,d1 - beq port_out_10_06 - subq.b #1,d1 - beq port_out_10_07 - addq.b #7,d1 - cmpi.b #$0b,d1 ; power supply enhancement - ble port_out_10_undef - cmpi.b #$13,d1 ; power supply level - ble port_out_10_undef - cmpi.b #$17,d1 ; undefined - ble port_out_10_undef - cmpi.b #$18,d1 ; cancel test mode - beq port_out_10_undef - cmpi.b #$1b,d1 ; undefined - beq port_out_10_undef - cmpi.b #$1f,d1 ; enter test mode - ble port_out_10_undef - cmpi.b #$3f,d1 ; set column - ble port_out_10_set_col - cmpi.b #$7f,d1 ; z-addressing - ble port_out_10_undef ; XXX? - cmpi.b #$df,d1 ; set row - ble port_out_10_set_row - ;; fallthrough: set contrast (unimplemented) - rts - ;; ... -port_out_10_00: ; 6-bit mode - move.b #$00,video_6bit - rts -port_out_10_01: ; 8-bit mode - move.b #$40,video_6bit - rts -port_out_10_02: ; screen off - move.b #$20,video_enabled - rts -port_out_10_03: ; screen on - move.b #$00,video_enabled - rts -port_out_10_04: ; x-- - move.b #$01,video_row - move.b #$00,video_increment - rts -port_out_10_05: ; x++ - move.b #$01,video_row - move.b #$02,video_increment - rts -port_out_10_06: ; y-- - move.b #$00,video_row - move.b #$00,video_increment - rts -port_out_10_07: ; y++ - move.b #$00,video_row - move.b #$02,video_increment - rts -port_out_10_undef: - rts -port_out_10_set_col: - sub.b #$20,d1 - move.b d1,video_cur_col - rts -port_out_10_set_row: - sub.b #$80,d1 - move.b d1,video_cur_row - rts - - -port_in_11: - ;; LCD data - SAVEREG - jsr video_read - move.b d0,d1 ; return value - RESTREG - rts - -port_out_11: - ;; LCD data - SAVEREG - move.b d1,-(a7) - jsr video_write - addq #2,a7 - RESTREG - rts - -port_in_12: -port_out_12: -port_in_13: -port_out_13: -port_in_14: -port_out_14: -port_in_15: -port_out_15: -port_in_16: -port_out_16: -port_in_17: -port_out_17: -port_in_18: -port_out_18: -port_in_19: -port_out_19: -port_in_1a: -port_out_1a: -port_in_1b: -port_out_1b: -port_in_1c: -port_out_1c: -port_in_1d: -port_out_1d: -port_in_1e: -port_out_1e: -port_in_1f: -port_out_1f: -port_in_20: -port_out_20: -port_in_21: -port_out_21: -port_in_22: -port_out_22: -port_in_23: -port_out_23: -port_in_24: -port_out_24: -port_in_25: -port_out_25: -port_in_26: -port_out_26: -port_in_27: -port_out_27: -port_in_28: -port_out_28: -port_in_29: -port_out_29: -port_in_2a: -port_out_2a: -port_in_2b: -port_out_2b: -port_in_2c: -port_out_2c: -port_in_2d: -port_out_2d: -port_in_2e: -port_out_2e: -port_in_2f: -port_out_2f: -port_in_30: -port_out_30: -port_in_31: -port_out_31: -port_in_32: -port_out_32: -port_in_33: -port_out_33: -port_in_34: -port_out_34: -port_in_35: -port_out_35: -port_in_36: -port_out_36: -port_in_37: -port_out_37: -port_in_38: -port_out_38: -port_in_39: -port_out_39: -port_in_3a: -port_out_3a: -port_in_3b: -port_out_3b: -port_in_3c: -port_out_3c: -port_in_3d: -port_out_3d: -port_in_3e: -port_out_3e: -port_in_3f: -port_out_3f: -port_in_40: -port_out_40: -port_in_41: -port_out_41: -port_in_42: -port_out_42: -port_in_43: -port_out_43: -port_in_44: -port_out_44: -port_in_45: -port_out_45: -port_in_46: -port_out_46: -port_in_47: -port_out_47: -port_in_48: -port_out_48: -port_in_49: -port_out_49: -port_in_4a: -port_out_4a: -port_in_4b: -port_out_4b: -port_in_4c: -port_out_4c: -port_in_4d: -port_out_4d: -port_in_4e: -port_out_4e: -port_in_4f: -port_out_4f: -port_in_50: -port_out_50: -port_in_51: -port_out_51: -port_in_52: -port_out_52: -port_in_53: -port_out_53: -port_in_54: -port_out_54: -port_in_55: -port_out_55: -port_in_56: -port_out_56: -port_in_57: -port_out_57: -port_in_58: -port_out_58: -port_in_59: -port_out_59: -port_in_5a: -port_out_5a: -port_in_5b: -port_out_5b: -port_in_5c: -port_out_5c: -port_in_5d: -port_out_5d: -port_in_5e: -port_out_5e: -port_in_5f: -port_out_5f: -port_in_60: -port_out_60: -port_in_61: -port_out_61: -port_in_62: -port_out_62: -port_in_63: -port_out_63: -port_in_64: -port_out_64: -port_in_65: -port_out_65: -port_in_66: -port_out_66: -port_in_67: -port_out_67: -port_in_68: -port_out_68: -port_in_69: -port_out_69: -port_in_6a: -port_out_6a: -port_in_6b: -port_out_6b: -port_in_6c: -port_out_6c: -port_in_6d: -port_out_6d: -port_in_6e: -port_out_6e: -port_in_6f: -port_out_6f: -port_in_70: -port_out_70: -port_in_71: -port_out_71: -port_in_72: -port_out_72: -port_in_73: -port_out_73: -port_in_74: -port_out_74: -port_in_75: -port_out_75: -port_in_76: -port_out_76: -port_in_77: -port_out_77: -port_in_78: -port_out_78: -port_in_79: -port_out_79: -port_in_7a: -port_out_7a: -port_in_7b: -port_out_7b: -port_in_7c: -port_out_7c: -port_in_7d: -port_out_7d: -port_in_7e: -port_out_7e: -port_in_7f: -port_out_7f: -port_in_80: -port_out_80: -port_in_81: -port_out_81: -port_in_82: -port_out_82: -port_in_83: -port_out_83: -port_in_84: -port_out_84: -port_in_85: -port_out_85: -port_in_86: -port_out_86: -port_in_87: -port_out_87: -port_in_88: -port_out_88: -port_in_89: -port_out_89: -port_in_8a: -port_out_8a: -port_in_8b: -port_out_8b: -port_in_8c: -port_out_8c: -port_in_8d: -port_out_8d: -port_in_8e: -port_out_8e: -port_in_8f: -port_out_8f: -port_in_90: -port_out_90: -port_in_91: -port_out_91: -port_in_92: -port_out_92: -port_in_93: -port_out_93: -port_in_94: -port_out_94: -port_in_95: -port_out_95: -port_in_96: -port_out_96: -port_in_97: -port_out_97: -port_in_98: -port_out_98: -port_in_99: -port_out_99: -port_in_9a: -port_out_9a: -port_in_9b: -port_out_9b: -port_in_9c: -port_out_9c: -port_in_9d: -port_out_9d: -port_in_9e: -port_out_9e: -port_in_9f: -port_out_9f: -port_in_a0: -port_out_a0: -port_in_a1: -port_out_a1: -port_in_a2: -port_out_a2: -port_in_a3: -port_out_a3: -port_in_a4: -port_out_a4: -port_in_a5: -port_out_a5: -port_in_a6: -port_out_a6: -port_in_a7: -port_out_a7: -port_in_a8: -port_out_a8: -port_in_a9: -port_out_a9: -port_in_aa: -port_out_aa: -port_in_ab: -port_out_ab: -port_in_ac: -port_out_ac: -port_in_ad: -port_out_ad: -port_in_ae: -port_out_ae: -port_in_af: -port_out_af: -port_in_b0: -port_out_b0: -port_in_b1: -port_out_b1: -port_in_b2: -port_out_b2: -port_in_b3: -port_out_b3: -port_in_b4: -port_out_b4: -port_in_b5: -port_out_b5: -port_in_b6: -port_out_b6: -port_in_b7: -port_out_b7: -port_in_b8: -port_out_b8: -port_in_b9: -port_out_b9: -port_in_ba: -port_out_ba: -port_in_bb: -port_out_bb: -port_in_bc: -port_out_bc: -port_in_bd: -port_out_bd: -port_in_be: -port_out_be: -port_in_bf: -port_out_bf: -port_in_c0: -port_out_c0: -port_in_c1: -port_out_c1: -port_in_c2: -port_out_c2: -port_in_c3: -port_out_c3: -port_in_c4: -port_out_c4: -port_in_c5: -port_out_c5: -port_in_c6: -port_out_c6: -port_in_c7: -port_out_c7: -port_in_c8: -port_out_c8: -port_in_c9: -port_out_c9: -port_in_ca: -port_out_ca: -port_in_cb: -port_out_cb: -port_in_cc: -port_out_cc: -port_in_cd: -port_out_cd: -port_in_ce: -port_out_ce: -port_in_cf: -port_out_cf: -port_in_d0: -port_out_d0: -port_in_d1: -port_out_d1: -port_in_d2: -port_out_d2: -port_in_d3: -port_out_d3: -port_in_d4: -port_out_d4: -port_in_d5: -port_out_d5: -port_in_d6: -port_out_d6: -port_in_d7: -port_out_d7: -port_in_d8: -port_out_d8: -port_in_d9: -port_out_d9: -port_in_da: -port_out_da: -port_in_db: -port_out_db: -port_in_dc: -port_out_dc: -port_in_dd: -port_out_dd: -port_in_de: -port_out_de: -port_in_df: -port_out_df: -port_in_e0: -port_out_e0: -port_in_e1: -port_out_e1: -port_in_e2: -port_out_e2: -port_in_e3: -port_out_e3: -port_in_e4: -port_out_e4: -port_in_e5: -port_out_e5: -port_in_e6: -port_out_e6: -port_in_e7: -port_out_e7: -port_in_e8: -port_out_e8: -port_in_e9: -port_out_e9: -port_in_ea: -port_out_ea: -port_in_eb: -port_out_eb: -port_in_ec: -port_out_ec: -port_in_ed: -port_out_ed: -port_in_ee: -port_out_ee: -port_in_ef: -port_out_ef: -port_in_f0: -port_out_f0: -port_in_f1: -port_out_f1: -port_in_f2: -port_out_f2: -port_in_f3: -port_out_f3: -port_in_f4: -port_out_f4: -port_in_f5: -port_out_f5: -port_in_f6: -port_out_f6: -port_in_f7: -port_out_f7: -port_in_f8: -port_out_f8: -port_in_f9: -port_out_f9: -port_in_fa: -port_out_fa: -port_in_fb: -port_out_fb: -port_in_fc: -port_out_fc: -port_in_fd: -port_out_fd: -port_in_fe: -port_out_fe: -port_in_ff: -port_out_ff: diff --git a/ports.s b/ports.s new file mode 100644 index 0000000..2c7a93e --- /dev/null +++ b/ports.s @@ -0,0 +1,1188 @@ + ;; Routines to process OUT and IN instructions. This is the + ;; bit that's unique to TI calculators. + + ;; Port is in d0, byte is in d1 + ;; Destroys a0 +port_in: + andi.w #$ff,d0 + add.w d0,d0 + add.w d0,d0 + movea.l lut_ports_in(pc,d0),a0 + jmp (a0) + rts + +lut_ports_in: + .int port_in_00 + .int port_in_01 + .int port_in_02 + .int port_in_03 + .int port_in_04 + .int port_in_05 + .int port_in_06 + .int port_in_07 + .int port_in_08 + .int port_in_09 + .int port_in_0a + .int port_in_0b + .int port_in_0c + .int port_in_0d + .int port_in_0e + .int port_in_0f + .int port_in_10 + .int port_in_11 + .int port_in_12 + .int port_in_13 + .int port_in_14 + .int port_in_15 + .int port_in_16 + .int port_in_17 + .int port_in_18 + .int port_in_19 + .int port_in_1a + .int port_in_1b + .int port_in_1c + .int port_in_1d + .int port_in_1e + .int port_in_1f + .int port_in_20 + .int port_in_21 + .int port_in_22 + .int port_in_23 + .int port_in_24 + .int port_in_25 + .int port_in_26 + .int port_in_27 + .int port_in_28 + .int port_in_29 + .int port_in_2a + .int port_in_2b + .int port_in_2c + .int port_in_2d + .int port_in_2e + .int port_in_2f + .int port_in_30 + .int port_in_31 + .int port_in_32 + .int port_in_33 + .int port_in_34 + .int port_in_35 + .int port_in_36 + .int port_in_37 + .int port_in_38 + .int port_in_39 + .int port_in_3a + .int port_in_3b + .int port_in_3c + .int port_in_3d + .int port_in_3e + .int port_in_3f + .int port_in_40 + .int port_in_41 + .int port_in_42 + .int port_in_43 + .int port_in_44 + .int port_in_45 + .int port_in_46 + .int port_in_47 + .int port_in_48 + .int port_in_49 + .int port_in_4a + .int port_in_4b + .int port_in_4c + .int port_in_4d + .int port_in_4e + .int port_in_4f + .int port_in_50 + .int port_in_51 + .int port_in_52 + .int port_in_53 + .int port_in_54 + .int port_in_55 + .int port_in_56 + .int port_in_57 + .int port_in_58 + .int port_in_59 + .int port_in_5a + .int port_in_5b + .int port_in_5c + .int port_in_5d + .int port_in_5e + .int port_in_5f + .int port_in_60 + .int port_in_61 + .int port_in_62 + .int port_in_63 + .int port_in_64 + .int port_in_65 + .int port_in_66 + .int port_in_67 + .int port_in_68 + .int port_in_69 + .int port_in_6a + .int port_in_6b + .int port_in_6c + .int port_in_6d + .int port_in_6e + .int port_in_6f + .int port_in_70 + .int port_in_71 + .int port_in_72 + .int port_in_73 + .int port_in_74 + .int port_in_75 + .int port_in_76 + .int port_in_77 + .int port_in_78 + .int port_in_79 + .int port_in_7a + .int port_in_7b + .int port_in_7c + .int port_in_7d + .int port_in_7e + .int port_in_7f + .int port_in_80 + .int port_in_81 + .int port_in_82 + .int port_in_83 + .int port_in_84 + .int port_in_85 + .int port_in_86 + .int port_in_87 + .int port_in_88 + .int port_in_89 + .int port_in_8a + .int port_in_8b + .int port_in_8c + .int port_in_8d + .int port_in_8e + .int port_in_8f + .int port_in_90 + .int port_in_91 + .int port_in_92 + .int port_in_93 + .int port_in_94 + .int port_in_95 + .int port_in_96 + .int port_in_97 + .int port_in_98 + .int port_in_99 + .int port_in_9a + .int port_in_9b + .int port_in_9c + .int port_in_9d + .int port_in_9e + .int port_in_9f + .int port_in_a0 + .int port_in_a1 + .int port_in_a2 + .int port_in_a3 + .int port_in_a4 + .int port_in_a5 + .int port_in_a6 + .int port_in_a7 + .int port_in_a8 + .int port_in_a9 + .int port_in_aa + .int port_in_ab + .int port_in_ac + .int port_in_ad + .int port_in_ae + .int port_in_af + .int port_in_b0 + .int port_in_b1 + .int port_in_b2 + .int port_in_b3 + .int port_in_b4 + .int port_in_b5 + .int port_in_b6 + .int port_in_b7 + .int port_in_b8 + .int port_in_b9 + .int port_in_ba + .int port_in_bb + .int port_in_bc + .int port_in_bd + .int port_in_be + .int port_in_bf + .int port_in_c0 + .int port_in_c1 + .int port_in_c2 + .int port_in_c3 + .int port_in_c4 + .int port_in_c5 + .int port_in_c6 + .int port_in_c7 + .int port_in_c8 + .int port_in_c9 + .int port_in_ca + .int port_in_cb + .int port_in_cc + .int port_in_cd + .int port_in_ce + .int port_in_cf + .int port_in_d0 + .int port_in_d1 + .int port_in_d2 + .int port_in_d3 + .int port_in_d4 + .int port_in_d5 + .int port_in_d6 + .int port_in_d7 + .int port_in_d8 + .int port_in_d9 + .int port_in_da + .int port_in_db + .int port_in_dc + .int port_in_dd + .int port_in_de + .int port_in_df + .int port_in_e0 + .int port_in_e1 + .int port_in_e2 + .int port_in_e3 + .int port_in_e4 + .int port_in_e5 + .int port_in_e6 + .int port_in_e7 + .int port_in_e8 + .int port_in_e9 + .int port_in_ea + .int port_in_eb + .int port_in_ec + .int port_in_ed + .int port_in_ee + .int port_in_ef + .int port_in_f0 + .int port_in_f1 + .int port_in_f2 + .int port_in_f3 + .int port_in_f4 + .int port_in_f5 + .int port_in_f6 + .int port_in_f7 + .int port_in_f8 + .int port_in_f9 + .int port_in_fa + .int port_in_fb + .int port_in_fc + .int port_in_fd + .int port_in_fe + .int port_in_ff + +port_out: + andi.w #$ff,d0 + ;; This is the fastest way to shift left 2 bits. :S + add.w d0,d0 + add.w d0,d0 + movea.l lut_ports_out(pc,d0.w),a0 + jmp (a0) + +lut_ports_out: + .int port_out_00 + .int port_out_01 + .int port_out_02 + .int port_out_03 + .int port_out_04 + .int port_out_05 + .int port_out_06 + .int port_out_07 + .int port_out_08 + .int port_out_09 + .int port_out_0a + .int port_out_0b + .int port_out_0c + .int port_out_0d + .int port_out_0e + .int port_out_0f + .int port_out_10 + .int port_out_11 + .int port_out_12 + .int port_out_13 + .int port_out_14 + .int port_out_15 + .int port_out_16 + .int port_out_17 + .int port_out_18 + .int port_out_19 + .int port_out_1a + .int port_out_1b + .int port_out_1c + .int port_out_1d + .int port_out_1e + .int port_out_1f + .int port_out_20 + .int port_out_21 + .int port_out_22 + .int port_out_23 + .int port_out_24 + .int port_out_25 + .int port_out_26 + .int port_out_27 + .int port_out_28 + .int port_out_29 + .int port_out_2a + .int port_out_2b + .int port_out_2c + .int port_out_2d + .int port_out_2e + .int port_out_2f + .int port_out_30 + .int port_out_31 + .int port_out_32 + .int port_out_33 + .int port_out_34 + .int port_out_35 + .int port_out_36 + .int port_out_37 + .int port_out_38 + .int port_out_39 + .int port_out_3a + .int port_out_3b + .int port_out_3c + .int port_out_3d + .int port_out_3e + .int port_out_3f + .int port_out_40 + .int port_out_41 + .int port_out_42 + .int port_out_43 + .int port_out_44 + .int port_out_45 + .int port_out_46 + .int port_out_47 + .int port_out_48 + .int port_out_49 + .int port_out_4a + .int port_out_4b + .int port_out_4c + .int port_out_4d + .int port_out_4e + .int port_out_4f + .int port_out_50 + .int port_out_51 + .int port_out_52 + .int port_out_53 + .int port_out_54 + .int port_out_55 + .int port_out_56 + .int port_out_57 + .int port_out_58 + .int port_out_59 + .int port_out_5a + .int port_out_5b + .int port_out_5c + .int port_out_5d + .int port_out_5e + .int port_out_5f + .int port_out_60 + .int port_out_61 + .int port_out_62 + .int port_out_63 + .int port_out_64 + .int port_out_65 + .int port_out_66 + .int port_out_67 + .int port_out_68 + .int port_out_69 + .int port_out_6a + .int port_out_6b + .int port_out_6c + .int port_out_6d + .int port_out_6e + .int port_out_6f + .int port_out_70 + .int port_out_71 + .int port_out_72 + .int port_out_73 + .int port_out_74 + .int port_out_75 + .int port_out_76 + .int port_out_77 + .int port_out_78 + .int port_out_79 + .int port_out_7a + .int port_out_7b + .int port_out_7c + .int port_out_7d + .int port_out_7e + .int port_out_7f + .int port_out_80 + .int port_out_81 + .int port_out_82 + .int port_out_83 + .int port_out_84 + .int port_out_85 + .int port_out_86 + .int port_out_87 + .int port_out_88 + .int port_out_89 + .int port_out_8a + .int port_out_8b + .int port_out_8c + .int port_out_8d + .int port_out_8e + .int port_out_8f + .int port_out_90 + .int port_out_91 + .int port_out_92 + .int port_out_93 + .int port_out_94 + .int port_out_95 + .int port_out_96 + .int port_out_97 + .int port_out_98 + .int port_out_99 + .int port_out_9a + .int port_out_9b + .int port_out_9c + .int port_out_9d + .int port_out_9e + .int port_out_9f + .int port_out_a0 + .int port_out_a1 + .int port_out_a2 + .int port_out_a3 + .int port_out_a4 + .int port_out_a5 + .int port_out_a6 + .int port_out_a7 + .int port_out_a8 + .int port_out_a9 + .int port_out_aa + .int port_out_ab + .int port_out_ac + .int port_out_ad + .int port_out_ae + .int port_out_af + .int port_out_b0 + .int port_out_b1 + .int port_out_b2 + .int port_out_b3 + .int port_out_b4 + .int port_out_b5 + .int port_out_b6 + .int port_out_b7 + .int port_out_b8 + .int port_out_b9 + .int port_out_ba + .int port_out_bb + .int port_out_bc + .int port_out_bd + .int port_out_be + .int port_out_bf + .int port_out_c0 + .int port_out_c1 + .int port_out_c2 + .int port_out_c3 + .int port_out_c4 + .int port_out_c5 + .int port_out_c6 + .int port_out_c7 + .int port_out_c8 + .int port_out_c9 + .int port_out_ca + .int port_out_cb + .int port_out_cc + .int port_out_cd + .int port_out_ce + .int port_out_cf + .int port_out_d0 + .int port_out_d1 + .int port_out_d2 + .int port_out_d3 + .int port_out_d4 + .int port_out_d5 + .int port_out_d6 + .int port_out_d7 + .int port_out_d8 + .int port_out_d9 + .int port_out_da + .int port_out_db + .int port_out_dc + .int port_out_dd + .int port_out_de + .int port_out_df + .int port_out_e0 + .int port_out_e1 + .int port_out_e2 + .int port_out_e3 + .int port_out_e4 + .int port_out_e5 + .int port_out_e6 + .int port_out_e7 + .int port_out_e8 + .int port_out_e9 + .int port_out_ea + .int port_out_eb + .int port_out_ec + .int port_out_ed + .int port_out_ee + .int port_out_ef + .int port_out_f0 + .int port_out_f1 + .int port_out_f2 + .int port_out_f3 + .int port_out_f4 + .int port_out_f5 + .int port_out_f6 + .int port_out_f7 + .int port_out_f8 + .int port_out_f9 + .int port_out_fa + .int port_out_fb + .int port_out_fc + .int port_out_fd + .int port_out_fe + .int port_out_ff + +port_in_00: +port_out_00: + ;; Temporary test harness. Writing to this port writes a + ;; character to the screen. + SAVEREG + andi.w #$ff,d1 + move.w d1,-(sp) + jsr char_draw + addq #2,sp + RESTREG + rts + +port_in_01: +port_out_01: +port_in_02: +port_out_02: +port_in_03: +port_out_03: +port_in_04: +port_out_04: + ;; Bank B paging, among other things + SAVEREG + move.b d1,-(a7) + jsr bankswap_b_write + addq #2,a7 + RESTREG + rts + +port_in_05: +port_out_05: +port_in_06: +port_out_06: + ;; Bank A paging + SAVEREG + move.b d1,-(a7) + jsr bankswap_a_write + addq #2,a7 + RESTREG + rts + +port_in_07: +port_out_07: +port_in_08: +port_out_08: +port_in_09: +port_out_09: +port_in_0a: +port_out_0a: +port_in_0b: +port_out_0b: +port_in_0c: +port_out_0c: +port_in_0d: +port_out_0d: +port_in_0e: +port_out_0e: +port_in_0f: +port_out_0f: +port_in_10: +.xref video_row +.xref video_increment +.xref video_enabled +.xref video_6bit +.xref video_busy +.xref video_cur_row +.xref video_cur_col +.xref video_write +.xref video_read + + ;; LCD status + clr.b d1 + or.b video_increment,d1 + or.b video_row,d1 + or.b video_enabled,d1 + or.b video_6bit,d1 + or.b video_busy,d1 + rts + +port_out_10: + ;; LCD command + tst.b d1 + beq port_out_10_00 + subq.b #1,d1 + beq port_out_10_01 + subq.b #1,d1 + beq port_out_10_02 + subq.b #1,d1 + beq port_out_10_03 + subq.b #1,d1 + beq port_out_10_04 + subq.b #1,d1 + beq port_out_10_05 + subq.b #1,d1 + beq port_out_10_06 + subq.b #1,d1 + beq port_out_10_07 + addq.b #7,d1 + cmpi.b #$0b,d1 ; power supply enhancement + ble port_out_10_undef + cmpi.b #$13,d1 ; power supply level + ble port_out_10_undef + cmpi.b #$17,d1 ; undefined + ble port_out_10_undef + cmpi.b #$18,d1 ; cancel test mode + beq port_out_10_undef + cmpi.b #$1b,d1 ; undefined + beq port_out_10_undef + cmpi.b #$1f,d1 ; enter test mode + ble port_out_10_undef + cmpi.b #$3f,d1 ; set column + ble port_out_10_set_col + cmpi.b #$7f,d1 ; z-addressing + ble port_out_10_undef ; XXX? + cmpi.b #$df,d1 ; set row + ble port_out_10_set_row + ;; fallthrough: set contrast (unimplemented) + rts + ;; ... +port_out_10_00: ; 6-bit mode + move.b #$00,video_6bit + rts +port_out_10_01: ; 8-bit mode + move.b #$40,video_6bit + rts +port_out_10_02: ; screen off + move.b #$20,video_enabled + rts +port_out_10_03: ; screen on + move.b #$00,video_enabled + rts +port_out_10_04: ; x-- + move.b #$01,video_row + move.b #$00,video_increment + rts +port_out_10_05: ; x++ + move.b #$01,video_row + move.b #$02,video_increment + rts +port_out_10_06: ; y-- + move.b #$00,video_row + move.b #$00,video_increment + rts +port_out_10_07: ; y++ + move.b #$00,video_row + move.b #$02,video_increment + rts +port_out_10_undef: + rts +port_out_10_set_col: + sub.b #$20,d1 + move.b d1,video_cur_col + rts +port_out_10_set_row: + sub.b #$80,d1 + move.b d1,video_cur_row + rts + + +port_in_11: + ;; LCD data + SAVEREG + jsr video_read + move.b d0,d1 ; return value + RESTREG + rts + +port_out_11: + ;; LCD data + SAVEREG + move.b d1,-(a7) + jsr video_write + addq #2,a7 + RESTREG + rts + +port_in_12: +port_out_12: +port_in_13: +port_out_13: +port_in_14: +port_out_14: +port_in_15: +port_out_15: +port_in_16: +port_out_16: +port_in_17: +port_out_17: +port_in_18: +port_out_18: +port_in_19: +port_out_19: +port_in_1a: +port_out_1a: +port_in_1b: +port_out_1b: +port_in_1c: +port_out_1c: +port_in_1d: +port_out_1d: +port_in_1e: +port_out_1e: +port_in_1f: +port_out_1f: +port_in_20: +port_out_20: +port_in_21: +port_out_21: +port_in_22: +port_out_22: +port_in_23: +port_out_23: +port_in_24: +port_out_24: +port_in_25: +port_out_25: +port_in_26: +port_out_26: +port_in_27: +port_out_27: +port_in_28: +port_out_28: +port_in_29: +port_out_29: +port_in_2a: +port_out_2a: +port_in_2b: +port_out_2b: +port_in_2c: +port_out_2c: +port_in_2d: +port_out_2d: +port_in_2e: +port_out_2e: +port_in_2f: +port_out_2f: +port_in_30: +port_out_30: +port_in_31: +port_out_31: +port_in_32: +port_out_32: +port_in_33: +port_out_33: +port_in_34: +port_out_34: +port_in_35: +port_out_35: +port_in_36: +port_out_36: +port_in_37: +port_out_37: +port_in_38: +port_out_38: +port_in_39: +port_out_39: +port_in_3a: +port_out_3a: +port_in_3b: +port_out_3b: +port_in_3c: +port_out_3c: +port_in_3d: +port_out_3d: +port_in_3e: +port_out_3e: +port_in_3f: +port_out_3f: +port_in_40: +port_out_40: +port_in_41: +port_out_41: +port_in_42: +port_out_42: +port_in_43: +port_out_43: +port_in_44: +port_out_44: +port_in_45: +port_out_45: +port_in_46: +port_out_46: +port_in_47: +port_out_47: +port_in_48: +port_out_48: +port_in_49: +port_out_49: +port_in_4a: +port_out_4a: +port_in_4b: +port_out_4b: +port_in_4c: +port_out_4c: +port_in_4d: +port_out_4d: +port_in_4e: +port_out_4e: +port_in_4f: +port_out_4f: +port_in_50: +port_out_50: +port_in_51: +port_out_51: +port_in_52: +port_out_52: +port_in_53: +port_out_53: +port_in_54: +port_out_54: +port_in_55: +port_out_55: +port_in_56: +port_out_56: +port_in_57: +port_out_57: +port_in_58: +port_out_58: +port_in_59: +port_out_59: +port_in_5a: +port_out_5a: +port_in_5b: +port_out_5b: +port_in_5c: +port_out_5c: +port_in_5d: +port_out_5d: +port_in_5e: +port_out_5e: +port_in_5f: +port_out_5f: +port_in_60: +port_out_60: +port_in_61: +port_out_61: +port_in_62: +port_out_62: +port_in_63: +port_out_63: +port_in_64: +port_out_64: +port_in_65: +port_out_65: +port_in_66: +port_out_66: +port_in_67: +port_out_67: +port_in_68: +port_out_68: +port_in_69: +port_out_69: +port_in_6a: +port_out_6a: +port_in_6b: +port_out_6b: +port_in_6c: +port_out_6c: +port_in_6d: +port_out_6d: +port_in_6e: +port_out_6e: +port_in_6f: +port_out_6f: +port_in_70: +port_out_70: +port_in_71: +port_out_71: +port_in_72: +port_out_72: +port_in_73: +port_out_73: +port_in_74: +port_out_74: +port_in_75: +port_out_75: +port_in_76: +port_out_76: +port_in_77: +port_out_77: +port_in_78: +port_out_78: +port_in_79: +port_out_79: +port_in_7a: +port_out_7a: +port_in_7b: +port_out_7b: +port_in_7c: +port_out_7c: +port_in_7d: +port_out_7d: +port_in_7e: +port_out_7e: +port_in_7f: +port_out_7f: +port_in_80: +port_out_80: +port_in_81: +port_out_81: +port_in_82: +port_out_82: +port_in_83: +port_out_83: +port_in_84: +port_out_84: +port_in_85: +port_out_85: +port_in_86: +port_out_86: +port_in_87: +port_out_87: +port_in_88: +port_out_88: +port_in_89: +port_out_89: +port_in_8a: +port_out_8a: +port_in_8b: +port_out_8b: +port_in_8c: +port_out_8c: +port_in_8d: +port_out_8d: +port_in_8e: +port_out_8e: +port_in_8f: +port_out_8f: +port_in_90: +port_out_90: +port_in_91: +port_out_91: +port_in_92: +port_out_92: +port_in_93: +port_out_93: +port_in_94: +port_out_94: +port_in_95: +port_out_95: +port_in_96: +port_out_96: +port_in_97: +port_out_97: +port_in_98: +port_out_98: +port_in_99: +port_out_99: +port_in_9a: +port_out_9a: +port_in_9b: +port_out_9b: +port_in_9c: +port_out_9c: +port_in_9d: +port_out_9d: +port_in_9e: +port_out_9e: +port_in_9f: +port_out_9f: +port_in_a0: +port_out_a0: +port_in_a1: +port_out_a1: +port_in_a2: +port_out_a2: +port_in_a3: +port_out_a3: +port_in_a4: +port_out_a4: +port_in_a5: +port_out_a5: +port_in_a6: +port_out_a6: +port_in_a7: +port_out_a7: +port_in_a8: +port_out_a8: +port_in_a9: +port_out_a9: +port_in_aa: +port_out_aa: +port_in_ab: +port_out_ab: +port_in_ac: +port_out_ac: +port_in_ad: +port_out_ad: +port_in_ae: +port_out_ae: +port_in_af: +port_out_af: +port_in_b0: +port_out_b0: +port_in_b1: +port_out_b1: +port_in_b2: +port_out_b2: +port_in_b3: +port_out_b3: +port_in_b4: +port_out_b4: +port_in_b5: +port_out_b5: +port_in_b6: +port_out_b6: +port_in_b7: +port_out_b7: +port_in_b8: +port_out_b8: +port_in_b9: +port_out_b9: +port_in_ba: +port_out_ba: +port_in_bb: +port_out_bb: +port_in_bc: +port_out_bc: +port_in_bd: +port_out_bd: +port_in_be: +port_out_be: +port_in_bf: +port_out_bf: +port_in_c0: +port_out_c0: +port_in_c1: +port_out_c1: +port_in_c2: +port_out_c2: +port_in_c3: +port_out_c3: +port_in_c4: +port_out_c4: +port_in_c5: +port_out_c5: +port_in_c6: +port_out_c6: +port_in_c7: +port_out_c7: +port_in_c8: +port_out_c8: +port_in_c9: +port_out_c9: +port_in_ca: +port_out_ca: +port_in_cb: +port_out_cb: +port_in_cc: +port_out_cc: +port_in_cd: +port_out_cd: +port_in_ce: +port_out_ce: +port_in_cf: +port_out_cf: +port_in_d0: +port_out_d0: +port_in_d1: +port_out_d1: +port_in_d2: +port_out_d2: +port_in_d3: +port_out_d3: +port_in_d4: +port_out_d4: +port_in_d5: +port_out_d5: +port_in_d6: +port_out_d6: +port_in_d7: +port_out_d7: +port_in_d8: +port_out_d8: +port_in_d9: +port_out_d9: +port_in_da: +port_out_da: +port_in_db: +port_out_db: +port_in_dc: +port_out_dc: +port_in_dd: +port_out_dd: +port_in_de: +port_out_de: +port_in_df: +port_out_df: +port_in_e0: +port_out_e0: +port_in_e1: +port_out_e1: +port_in_e2: +port_out_e2: +port_in_e3: +port_out_e3: +port_in_e4: +port_out_e4: +port_in_e5: +port_out_e5: +port_in_e6: +port_out_e6: +port_in_e7: +port_out_e7: +port_in_e8: +port_out_e8: +port_in_e9: +port_out_e9: +port_in_ea: +port_out_ea: +port_in_eb: +port_out_eb: +port_in_ec: +port_out_ec: +port_in_ed: +port_out_ed: +port_in_ee: +port_out_ee: +port_in_ef: +port_out_ef: +port_in_f0: +port_out_f0: +port_in_f1: +port_out_f1: +port_in_f2: +port_out_f2: +port_in_f3: +port_out_f3: +port_in_f4: +port_out_f4: +port_in_f5: +port_out_f5: +port_in_f6: +port_out_f6: +port_in_f7: +port_out_f7: +port_in_f8: +port_out_f8: +port_in_f9: +port_out_f9: +port_in_fa: +port_out_fa: +port_in_fb: +port_out_fb: +port_in_fc: +port_out_fc: +port_in_fd: +port_out_fd: +port_in_fe: +port_out_fe: +port_in_ff: +port_out_ff: -- cgit v1.2.3