summaryrefslogtreecommitdiff
path: root/flags.s
diff options
context:
space:
mode:
authorAstrid Smith2011-10-22 00:48:25 -0700
committerAstrid Smith2011-10-22 00:48:25 -0700
commit3c802cbedc1f5e5f07afb837efcc160c11336e83 (patch)
tree671a540f93f5d910594119eb7e40b438facf49bb /flags.s
parentb9be2d76a48409e1b5053338cd5f51f22b6e5b2f (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.s309
1 files changed, 156 insertions, 153 deletions
diff --git a/flags.s b/flags.s
index 8fc2058..4f837a1 100644
--- a/flags.s
+++ b/flags.s
@@ -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.