DAA & DAS algorithms in ARM assembly

This commit is contained in:
Aaron Culliney 2015-02-22 13:46:58 -08:00
parent d517339842
commit 792c0a0b08
2 changed files with 78 additions and 93 deletions

View File

@ -782,60 +782,48 @@
ADd memory to accumulator with Carry ADd memory to accumulator with Carry
---------------------------------- */ ---------------------------------- */
#define _AF r10 #define carry r9
#define hi_nib r0 #define lo_nyb r1
#define lo_nib r9
// Decimal mode // Decimal mode
ENTRY(op_ADC_dec) ENTRY(op_ADC_dec)
IncOpCycles IncOpCycles
GetFromEA_B GetFromEA_B
DebugBCDCheck DebugBCDCheck
// isolate lo nybbles
// initial addition with nybble carry check mov lo_nyb, A_Reg
and _AF, A_Reg, #0x10 mov r9, r0
bt and lo_nyb, lo_nyb, #0x0F
adcs r0, A_Reg, r0 and r9, r9, #0x0F
and r1, A_Reg, #0x10 // lo nybble addition with carry
eor _AF, _AF, r1 tst F_Reg, #C_Flag
addne r9, r9, #1
// DAA algorithm : http://www.ray.masmcode.com/BCDdaa.html add lo_nyb, lo_nyb, r9
// CF_old = CF // prep 65c02 flags
// IF (al AND 0Fh > 9) or (the Auxilliary Flag is set)
// al = al + 6
// CF = CF (automagically) or CF_old
// AF set (automagically)
// ENDIF
// IF (al > 99h) or (Carry Flag is set)
// al = al + 60h
// CF set
// ENDIF
lahf
bic F_Reg, #NVZC_Flags bic F_Reg, #NVZC_Flags
mov r1, r0 // lo nybble DAA (Decimal Adjustment after Addition), saving carry (+0, +1, +2)
and r1, r1, #0x0f cmp lo_nyb, #0x09
cmp r1, #0x09 addhi lo_nyb, lo_nyb, #6
bhi _daa_lo_nyb mov carry, lo_nyb, LSR #4
teq _AF, #0 and lo_nyb, lo_nyb, #0x0F
beq _daa_next0 // isolate hi nybbles
_daa_lo_nyb: mov r0, r0, LSL #24 mov A_Reg, A_Reg, LSR #4
adds r0, r0, #0x06000000 // adjust lo nybble mov r0, r0, LSR #4
mov r0, r0, LSR #24 // hi nybble addition with carry
bcs _daa_hi_nyb add r0, r0, carry
_daa_next0: tst arm_flags, #C_Flag add r0, A_Reg, r0
bne _daa_hi_nyb // hi nybble DAA
cmp r0, #0x9A cmp r0, #0x09
bmi _daa_next1 addhi r0, #6
_daa_hi_nyb: add r0, r0, #0x60 // adjust hi nybble orrhi F_Reg, #C_Flag
orr F_Reg, F_Reg, #C_Flag // FlagC // merge nybbles
_daa_next1: tst r0, #0x80 mov r0, r0, LSL #4
beq _daa_next2 orr A_Reg, r0, lo_nyb
orr F_Reg, F_Reg, #N_Flag // FlagN // NZ flags
_daa_next2: tst r0, #0xFF tst A_Reg, #0x80
bne _daa_finish orrne F_Reg, F_Reg, #N_Flag
orr F_Reg, F_Reg, #Z_Flag // FlagZ tst A_Reg, #0xFF
_daa_finish: mov A_Reg, r0 orreq F_Reg, F_Reg, #Z_Flag
Continue Continue
#define maybe_DoADC_d \ #define maybe_DoADC_d \
@ -1964,55 +1952,52 @@ ENTRY(op_RTS) // 0x60
SBC instructions SBC instructions
SuBtract memory from accumulator with Borrow SuBtract memory from accumulator with Borrow
---------------------------------- */ ---------------------------------- */
#define borrow carry
ENTRY(op_SBC_dec) ENTRY(op_SBC_dec)
IncOpCycles IncOpCycles
GetFromEA_B GetFromEA_B
DebugBCDCheck DebugBCDCheck
// isolate lo nybbles
// initial subtraction with nybble borrow check mov lo_nyb, A_Reg
and _AF, A_Reg, #0x10 mov r9, r0
btc and lo_nyb, lo_nyb, #0x0F
/*cmc*/ and r9, r9, #0x0F
sbcs r0, A_Reg, r0 // lo nybble subtraction with borrow
and r1, A_Reg, #0x10 sub lo_nyb, lo_nyb, r9
eor _AF, _AF, r1 and lo_nyb, lo_nyb, #0xFF
tst F_Reg, #C_Flag
// DAS algorithm : http://www.ray.masmcode.com/BCDdas.html subeq lo_nyb, lo_nyb, #1
// CF_old = CF andeq lo_nyb, lo_nyb, #0xFF
// IF (al AND 0Fh > 9) or (the Auxilliary Flag is set) // prep 65c02 flags
// al = al - 6 bic F_Reg, #NVZC_Flags
// CF = CF (automagically) or CF_old
// AF set (automagically)
// ENDIF
// IF (al > 99h) or (Carry Flag is set)
// al = al - 60h
// ^CF set
// ENDIF
lahf
bic F_Reg, F_Reg, #NVZ_Flags
orr F_Reg, #C_Flag orr F_Reg, #C_Flag
mov r1, r0 // lo nybble DAS (Decimal Adjustment after Subtraction), saving borrow
and r1, r1, #0x0f eor borrow, borrow, borrow
cmp r1, #0x09 cmp lo_nyb, #0x09
bhi _das_lo_nyb movhi borrow, #1
teq _AF, #0 subhi lo_nyb, lo_nyb, #6
beq _das_next0 andhi lo_nyb, lo_nyb, #0x0F
_das_lo_nyb: sbcs r0, r0, #0x06000000 // adjust lo nybble // isolate hi nybbles
bcs _das_hi_nyb mov A_Reg, A_Reg, LSR #4
_das_next0: tst arm_flags, #C_Flag mov r0, r0, LSR #4
bne _das_hi_nyb // hi nybble subtraction with borrow
cmp r0, #0x9A sub r0, A_Reg, r0
bmi _das_next1 and r0, r0, #0xFF
_das_hi_nyb: sub r0, r0, #0x60 // adjust hi nybble sub r0, r0, borrow
bic F_Reg, F_Reg, #C_Flag // !FlagC and r0, r0, #0xFF
_das_next1: tst r0, #0x80 // hi nybble DAS
beq _das_next2 cmp r0, #0x09
orr F_Reg, F_Reg, #N_Flag // FlagN subhi r0, #6
_das_next2: tst r0, #0xFF bichi F_Reg, #C_Flag
bne _das_finish andhi r0, r0, #0x0F
orr F_Reg, F_Reg, #Z_Flag // FlagZ // merge nybbles
_das_finish: mov A_Reg, r0 mov r0, r0, LSL #4
orr A_Reg, r0, lo_nyb
// NZ flags
tst A_Reg, #0x80
orrne F_Reg, F_Reg, #N_Flag
tst A_Reg, #0xFF
orreq F_Reg, F_Reg, #Z_Flag
Continue Continue
#define maybe_DoSBC_d \ #define maybe_DoSBC_d \

View File

@ -539,7 +539,7 @@ ENTRY(op_ADC_dec)
#else #else
// DAA algorithm : http://www.ray.masmcode.com/BCDdaa.html // DAA algorithm : http://www.ray.masmcode.com/BCDdaa.html
// CF_old = CF // CF_old = CF
// IF (al AND 0Fh > 9) or (the Auxilliary Flag is set) // IF (al AND 0Fh > 9) or (the Auxiliary Flag is set)
// al = al + 6 // al = al + 6
// CF = CF (automagically) or CF_old // CF = CF (automagically) or CF_old
// AF set (automagically) // AF set (automagically)
@ -1727,7 +1727,7 @@ ENTRY(op_SBC_dec)
sbbb A_Reg, %al sbbb A_Reg, %al
// DAS algorithm : http://www.ray.masmcode.com/BCDdas.html // DAS algorithm : http://www.ray.masmcode.com/BCDdas.html
// CF_old = CF // CF_old = CF
// IF (al AND 0Fh > 9) or (the Auxilliary Flag is set) // IF (al AND 0Fh > 9) or (the Auxiliary Flag is set)
// al = al - 6 // al = al - 6
// CF = CF (automagically) or CF_old // CF = CF (automagically) or CF_old
// AF set (automagically) // AF set (automagically)