diff options
| author | Astrid Smith | 2011-10-22 00:48:25 -0700 |
|---|---|---|
| committer | Astrid Smith | 2011-10-22 00:48:25 -0700 |
| commit | 3c802cbedc1f5e5f07afb837efcc160c11336e83 (patch) | |
| tree | 671a540f93f5d910594119eb7e40b438facf49bb /flags.s | |
| parent | b9be2d76a48409e1b5053338cd5f51f22b6e5b2f (diff) | |
Now gas eats it all happily
With the exception of the final binary being too large to link ...
Diffstat (limited to 'flags.s')
| -rw-r--r-- | flags.s | 309 |
1 files changed, 156 insertions, 153 deletions
@@ -1,139 +1,142 @@ - ;; Routine to set the given flags - ;; Noted in \mask by a 1 bit -.macro F_SET mask ; 32 cycles, 8 bytes +||| -*- gas -*- +||| Code and variables to emulate z80 CPU flags + + || 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 + || 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) + || 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) + ori.b #0b00000100,flag_valid-flag_storage(a3) move.b flag_byte(pc),d1 - andi.b #%11111011,d1 + andi.b #0b11111011,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) + || 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 #0b11111011,flag_valid-flag_storage(a3) .endm - ;; Save the two operands from ADD \1,\2 + || 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 #% + move.b #0x01,f_tmp_byte-flag_storage(a3) + F_SET #0b .endm .text - ;; Normalize and return inverse of emulated Carry bit (loaded - ;; into host zero flag) + || Normalize and return inverse of emulated Carry bit (loaded + || into host zero flag) - ;; Destroys d1 + || 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) +| 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 + bcs.s FNC_ok | Bit is valid move.b (f_host_sr+1)-flag_storage(a3),d1 - andi.b #%00000001,d1 + andi.b #0b00000001,d1 or.b d1,flag_byte-flag_storage(a3) - ori.b #%00000001,flag_valid-flag_storage(a3) + ori.b #0b00000001,flag_valid-flag_storage(a3) FNC_ok: move.b flag_byte-flag_storage(a3),d1 - andi.b #%00000001,d1 + andi.b #0b00000001,d1 rts - ;; Normalize and return **INVERSE** of emulated Zero bit - ;; (loaded into host's zero flag) + || Normalize and return **INVERSE** of emulated Zero bit + || (loaded into host's zero flag) - ;; Destroys d1 + || Destroys d1 f_norm_z: move.b flag_valid-flag_storage(a3),d1 - andi.b #%01000000,d1 - bne.s FNZ_ok ; Bit is valid + andi.b #0b01000000,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 + andi.b #0b01000000,d1 rts - ;; Normalize and return **INVERSE** of emulated Parity/oVerflow - ;; bit (loaded into host zero flag) + || Normalize and return **INVERSE** of emulated Parity/oVerflow + || bit (loaded into host zero flag) - ;; Destroys d1 + || 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 + andi.b #0b00000100,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 + andi.b #0b00000100,d1 rts - ;; Calculate the P/V bit as Parity, for the byte in - ;; d1. Destroys d0,d1. + || Calculate the P/V bit as Parity, for the byte in + || d1. Destroys d0,d1. f_calc_parity: - andi.w #$ff,d1 + andi.w #0xff,d1 move.b lut_parity-flag_storage(a3,d1.w),d1 move.b (flag_byte),d0 - and.b #%11110111,d0 - or.w #%0000100000000000,d0 + and.b #0b11110111,d0 + or.w #0b0000100000000000,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. + || 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? + || 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! + || it's a word! move.w f_tmp_src_w(pc),d2 move.w f_tmp_dst_w(pc),d3 move.w d3,d4 @@ -141,11 +144,11 @@ f_cc_dirty: move sr,d5 andi.w #1,d5 rol #8,d5 - andi.w #$0fff,d2 - andi.w #$0fff,d4 + andi.w #0x0fff,d2 + andi.w #0x0fff,d4 add.w d2,d4 - andi.l #$1000,d4 - ori.w #%00010001,d5 + andi.l #0x1000,d4 + ori.w #0b00010001,d5 or.w d4,d5 or.w d5,flag_byte-flag_storage(a3) clr.b f_tmp_byte-flag_storage(a3) @@ -158,50 +161,50 @@ f_cc_byte: add.b d2,d3 move sr,d5 andi.b #1,d5 - andi.b #$0f,d2 - andi.b #$0f,d4 + andi.b #0x0f,d2 + andi.b #0x0f,d4 add.b d2,d4 - andi.b #$10,d4 + andi.b #0x10,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) + or.b #0b00010001,flag_valid-flag_storage(a3) popm d2-d5 rts - ;; Normalize and return inverse of emulated Sign bit (loaded - ;; into host zero flag). + || Normalize and return inverse of emulated Sign bit (loaded + || into host zero flag). - ;; Destroys d1 + || 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 + andi.b #0b01000000,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 + andi.b #0b01000000,d1 rts - ;; Routine to turn 68k flags into z80 flags. + || 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 + move.b (f_host_sr+1)(pc),d1 | 8/4 + || .w keeps d1 clean + andi.w #0b00011111,d1 | 8/4 - ;; doesn't this invalidate the previous contents of d1 - ;; entirely? - move.b lut_ccr(pc,d1.w),d1 ; 10/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 + 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. + ori.b #0b11000101,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 + || Routine to completely fill the flags register flags_all: bsr flags_normalize bsr f_calc_carries @@ -211,18 +214,18 @@ flags_all: .data flag_storage: - ;; 0 if the flag is already valid - ;; 2 if tmp_???b is valid - ;; 3 if tmp_???w is valid + || 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 + || 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 + || byte operands f_tmp_src_b: .byte 0 f_tmp_dst_b: .byte 0 f_tmp_result_b: .byte 0 @@ -232,65 +235,65 @@ f_tmp_src_w: .word 0 f_tmp_dst_w: .word 0 f_tmp_result_w: .word 0 - ;; 000XNZVC + || 000XNZVC .even - ;; DO NOT REARRANGE THESE + || DO NOT REARRANGE THESE f_host_sr: .word 0 -f_host_ccr: .byte 0 ;XXX make overlap somehow? +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. + || 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 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 + || N =S + || Z = Z + || V ~ P + || C= C + || + || =CCR= == z80== + || XNZVC SZ5H3PNC + .byte 0b00000000 || 00000 00000000 + .byte 0b00000001 || 00001 00000001 + .byte 0b00000100 || 00010 00000100 + .byte 0b00000101 || 00011 00000101 + .byte 0b01000000 || 00100 01000000 + .byte 0b01000001 || 00101 01000001 + .byte 0b01000100 || 00110 01000100 + .byte 0b01000101 || 00111 01000101 + .byte 0b10000000 || 01000 10000000 + .byte 0b10000001 || 01001 10000001 + .byte 0b10000100 || 01010 10000100 + .byte 0b10000101 || 01011 10000101 + .byte 0b11000000 || 01100 11000000 + .byte 0b11000001 || 01101 11000001 + .byte 0b11000100 || 01110 11000100 + .byte 0b11000101 || 01111 11000101 + .byte 0b00000000 || 10000 00000000 + .byte 0b00000001 || 10001 00000001 + .byte 0b00000100 || 10010 00000100 + .byte 0b00000101 || 10011 00000101 + .byte 0b01000000 || 10100 01000000 + .byte 0b01000001 || 10101 01000001 + .byte 0b01000100 || 10110 01000100 + .byte 0b01000101 || 10111 01000101 + .byte 0b10000000 || 11000 10000000 + .byte 0b10000001 || 11001 10000001 + .byte 0b10000100 || 11010 10000100 + .byte 0b10000101 || 11011 10000101 + .byte 0b11000000 || 11100 11000000 + .byte 0b11000001 || 11101 11000001 + .byte 0b11000100 || 11110 11000100 + .byte 0b11000101 || 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 @@ -309,7 +312,7 @@ lut_parity: .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. + || To save space I might be able to overlay the Parity table + || with the CCR table, or even interleave it in the opcodes. |
