summaryrefslogtreecommitdiff
path: root/flags.asm
diff options
context:
space:
mode:
authorAstrid Smith2010-06-12 11:06:51 -0700
committerAstrid Smith2010-06-12 11:06:51 -0700
commitf0882c0b92b01a290c62d3a3044bb027014b56c6 (patch)
treee359688d9ee995e04423ecdff23da5273e31ac38 /flags.asm
parente0167a8639b80aa0f54b48cb605996f1dcc16bb9 (diff)
Worked in Lionel's changes to flags.asm, patched up main.asm slightly to fit
Diffstat (limited to 'flags.asm')
-rw-r--r--flags.asm196
1 files changed, 86 insertions, 110 deletions
diff --git a/flags.asm b/flags.asm
index 0b85267..9c25dd7 100644
--- a/flags.asm
+++ b/flags.asm
@@ -1,43 +1,3 @@
-;; N =S
-;; Z = Z
-;; V ~ P
-;; C= C
-;;
-;; =CCR= == z80==
-;; XNZVC SZ5H3PNC
-;; 00000 00000000
-;; 00001 00000001
-;; 00010 00000100
-;; 00011 00000101
-;; 00100 01000000
-;; 00101 01000001
-;; 00110 01000100
-;; 00111 01000101
-;; 01000 10000000
-;; 01001 10000001
-;; 01010 10000100
-;; 01011 10000101
-;; 01100 11000000
-;; 01101 11000001
-;; 01110 11000100
-;; 01111 11000101
-;; 10000 00000000
-;; 10001 00000001
-;; 10010 00000100
-;; 10011 00000101
-;; 10100 01000000
-;; 10101 01000001
-;; 10110 01000100
-;; 10111 01000101
-;; 11000 10000000
-;; 11001 10000001
-;; 11010 10000100
-;; 11011 10000101
-;; 11100 11000000
-;; 11101 11000001
-;; 11110 11000100
-;; 11111 11000101
-
;; Routine to set the given flags
;; Noted in \1 by a 1 bit
F_SET MACRO
@@ -56,28 +16,17 @@ F_CLEAR MACRO
;; 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. (d1
+ ;; Byte for which parity is calculated must be in \1. High
+ ;; byte of \1.w must be zero, using d0 is suggested. (d1
;; destroyed)
-;; XXX that's expensive. After making this a subroutine, to speed up parity computation, maybe you could use a 256-byte lookup table accessed by d(pc,ix.w).
-;; And if you have a spare address register, since xxx.l addressing mode is expensive speed-wise and size-wise (4 bytes + relocation),
-;; you should use lea d(pc) to preload the address of flag_valid into an address register,
-;; and then use (an) and d(an) to write to flag_valid and flag_byte.
+
F_PAR MACRO
- move.b \1,d1 ; 4 2
- lsr.w #4,d1 ; 14 2
- eor.b \1,d1 ; 4 2
- lsr.w #2,d1 ; 10 2
- eor.b \1,d1 ; 4 2
- lsr.w #1,d1 ; 8 2
- eor.b \1,d1 ; 4 2
- andi.b #$01,d1 ; 8 4
- ;; odd parity is now in d1
- ori.b #%00000100,flag_valid ; 20 8
- andi.b #%11111011,flag_byte ; 20 8
- rol.b #2,d1 ; 6 2
- or.b d1,flag_byte ; 16 4
+ ori.b #%00000100,flag_valid-flag_storage(a3) ; ??/4
+ move.b flag_byte-flag_storage(a3),d1 ; ??/2
+ andi.b #%11111011,d1 ; ??/4
+ or.b lut_parity-flag_storage(a3,\1.w),d1 ; ??/4
+ move.b d1,flag_byte-flag_storage(a3) ; ??/2
ENDM ;xxx cycles (!)
- ; xx bytes (make this a subroutine)
;; Use this when an instruction uses the P/V bit as Overflow.
@@ -88,42 +37,41 @@ F_OVFL MACRO
;; Save the two operands from ADD \1,\2
F_ADD_SAVE MACRO
- move.b \1,f_tmp_src_b
- move.b \2,f_tmp_dst_b
- move.b #$01,f_tmp_byte
+ 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 carry bit (is loaded into Z bit)
;; Destroys d1
f_norm_c:
- move.b flag_valid(pc),d1
-;; XXX you could use lsr #1 (same number of cycles, smaller) + bcc.s or bcs.s here.
+ move.b flag_valid-flag_storage(a3),d1
andi.b #%00000001,d1
bne.s FNC_ok ; Bit is valid
- move.b f_host_ccr(pc),d1
+ move.b f_host_ccr-flag_storage(a3),d1
andi.b #%00000001,d1
;; XXX see above comment for using lea and then d(an) if you have a spare register.
- or.b d1,flag_byte
+ or.b d1,flag_byte-flag_storage(a3)
ori.b #%00000001,flag_valid
FNC_ok:
- move.b flag_byte(pc),d1
+ move.b flag_byte-flag_storage(a3),d1
andi.b #%00000001,d1
rts
;; Normalize and return zero bit (loaded into Z bit)
;; Destroys d1
f_norm_z:
- move.b flag_valid(pc),d1
+ move.b flag_valid-flag_storage(a3),d1
andi.b #%01000000,d1
bne.s FNZ_ok ; Bit is valid
- move.b f_host_ccr(pc),d1
+ move.b f_host_ccr-flag_storage(a3),d1
andi.b #%01000000,d1
;; XXX see above comment for using lea and then d(an) if you have a spare register.
- or.b d1,flag_byte
- ori.b #%01000000,flag_valid
+ or.b d1,flag_byte-flag_storage(a3)
+ ori.b #%01000000,flag_valid-flag_storage(a3)
FNZ_ok:
- move.b flag_byte(pc),d1
+ move.b flag_byte-flag_storage(a3),d1
andi.b #%01000000,d1
rts
@@ -132,15 +80,14 @@ FNZ_ok:
;; Preconditions:
;; Flags to change are noted in d0 by a 1 bit
flags_normalize:
- move.b f_host_ccr(pc),d1
-;; XXX .w because you don't want garbage in bits 8-15 when using d(pc,ix.w) or d(an,ix.w) ea mode.
- andi.w #%00011111,d1 ; Maybe TI uses the reserved bits for
- ; something ...
- move.b lut_ccr(pc,d1.w),d1
+ move.b f_host_ccr-flag_storage(a3),d1 ; 8/4
+ ;; .w keeps d1 clean
+ andi.w #%00011111,d1 ; 8/4
+ move.b lut_ccr(pc,d1.w),d1 ; 10/4
;; XXX do this
rts
-storage:
+flag_storage:
;; 1 if tmp_???b is valid, 0 if tmp_???w is valid
f_tmp_byte: ds.b 0
;; 2 if P is 0, 3 if P is 1, 4 if P is Parity, 5 if P is oVerflow
@@ -169,36 +116,65 @@ flag_valid: ds.b 0 ; Validity mask -- 1 if valid.
;; LUT for the CCR -> F mapping
lut_ccr:
- dc.b %00000000
- dc.b %00000001
- dc.b %00000100
- dc.b %00000101
- dc.b %01000000
- dc.b %01000001
- dc.b %01000100
- dc.b %01000101
- dc.b %10000000
- dc.b %10000001
- dc.b %10000100
- dc.b %10000101
- dc.b %11000000
- dc.b %11000001
- dc.b %11000100
- dc.b %11000101
- dc.b %00000000
- dc.b %00000001
- dc.b %00000100
- dc.b %00000101
- dc.b %01000000
- dc.b %01000001
- dc.b %01000100
- dc.b %01000101
- dc.b %10000000
- dc.b %10000001
- dc.b %10000100
- dc.b %10000101
- dc.b %11000000
- dc.b %11000001
- dc.b %11000100
- dc.b %11000101
+ ;; 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.
+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
+