diff --git a/py65/tests/devices/bcd/6502_decimal_test.bin b/py65/tests/devices/bcd/6502_decimal_test.bin index 9f95942..b99d8d9 100644 Binary files a/py65/tests/devices/bcd/6502_decimal_test.bin and b/py65/tests/devices/bcd/6502_decimal_test.bin differ diff --git a/py65/tests/devices/bcd/6502_decimal_test.a65 b/py65/tests/devices/bcd/6502_decimal_test.c65 similarity index 77% rename from py65/tests/devices/bcd/6502_decimal_test.a65 rename to py65/tests/devices/bcd/6502_decimal_test.c65 index 0d076bf..9868914 100644 --- a/py65/tests/devices/bcd/6502_decimal_test.a65 +++ b/py65/tests/devices/bcd/6502_decimal_test.c65 @@ -33,99 +33,100 @@ chk_v = 1 ; check overflow flag chk_z = 1 ; check zero flag chk_c = 1 ; check carry flag -end_of_test macro - db $db ;execute 65C02 stop instruction - endm +.macro end_of_test + BRK + ; .byte $db ;execute 65C02 stop instruction +.endmacro - bss - org 0 + .ZEROPAGE + .org 0 ; operands - register Y = carry in -N1 ds 1 -N2 ds 1 +N1: .res 1,0 +N2: .res 1,0 ; binary result -HA ds 1 -HNVZC ds 1 +HA: .res 1,0 +HNVZC: .res 1,0 ;04 ; decimal result -DA ds 1 -DNVZC ds 1 +DA: .res 1,0 +DNVZC: .res 1,0 ; predicted results -AR ds 1 -NF ds 1 +AR: .res 1,0 +NF: .res 1,0 ;08 -VF ds 1 -ZF ds 1 -CF ds 1 -ERROR ds 1 +VF: .res 1,0 +ZF: .res 1,0 +CF: .res 1,0 +ERROR: .res 1,0 ;0C ; workspace -N1L ds 1 -N1H ds 1 -N2L ds 1 -N2H ds 2 +N1L: .res 1,0 +N1H: .res 1,0 +N2L: .res 1,0 +N2H: .res 2,0 - code - org $200 -TEST ldy #1 ; initialize Y (used to loop through carry flag values) + .CODE + .org $200 +TEST: ldy #1 ; initialize Y (used to loop through carry flag values) sty ERROR ; store 1 in ERROR until the test passes lda #0 ; initialize N1 and N2 sta N1 sta N2 -LOOP1 lda N2 ; N2L = N2 & $0F +LOOP1: lda N2 ; N2L = N2 & $0F and #$0F ; [1] see text - if vld_bcd = 1 + .if vld_bcd = 1 cmp #$0a bcs NEXT2 - endif + .endif sta N2L lda N2 ; N2H = N2 & $F0 and #$F0 ; [2] see text - if vld_bcd = 1 + .if vld_bcd = 1 cmp #$a0 bcs NEXT2 - endif + .endif sta N2H ora #$0F ; N2H+1 = (N2 & $F0) + $0F sta N2H+1 -LOOP2 lda N1 ; N1L = N1 & $0F +LOOP2: lda N1 ; N1L = N1 & $0F and #$0F ; [3] see text - if vld_bcd = 1 + .if vld_bcd = 1 cmp #$0a bcs NEXT1 - endif + .endif sta N1L lda N1 ; N1H = N1 & $F0 and #$F0 ; [4] see text - if vld_bcd = 1 + .if vld_bcd = 1 cmp #$a0 bcs NEXT1 - endif + .endif sta N1H jsr ADD jsr A6502 jsr COMPARE - bne * + bne DONE jsr SUB jsr S6502 jsr COMPARE - bne * -NEXT1 inc N1 ; [5] see text + bne DONE +NEXT1: inc N1 ; [5] see text bne LOOP2 ; loop through all 256 values of N1 -NEXT2 inc N2 ; [6] see text +NEXT2: inc N2 ; [6] see text bne LOOP1 ; loop through all 256 values of N2 dey bpl LOOP1 ; loop through both values of the carry flag lda #0 ; test passed, so store 0 in ERROR sta ERROR -DONE +DONE: end_of_test - + ; Calculate the actual decimal mode accumulator and flags, the accumulator ; and flag results when N1 is added to N2 using binary arithmetic, the ; predicted accumulator result, the predicted carry flag, and the predicted -; V flag -; -ADD sed ; decimal mode +; V flag +; +ADD: sed ; decimal mode cpy #1 ; set carry if Y = 1, clear carry if Y = 0 lda N1 adc N2 @@ -138,7 +139,7 @@ ADD sed ; decimal mode lda N1 adc N2 sta HA ; accumulator result of N1+N2 using binary arithmetic - + php pla sta HNVZC ; flags result of N1+N2 using binary arithmetic @@ -152,34 +153,34 @@ ADD sed ; decimal mode adc #5 ; add 6 (carry is set) and #$0F sec -A1 ora N1H -; +A1: ora N1H +; ; if N1L + N2L < $0A, then add N2 & $F0 ; if N1L + N2L >= $0A, then add (N2 & $F0) + $0F + 1 (carry is set) -; +; adc N2H,x php bcs A2 cmp #$A0 bcc A3 -A2 adc #$5F ; add $60 (carry is set) +A2: adc #$5F ; add $60 (carry is set) sec -A3 sta AR ; predicted accumulator result +A3: sta AR ; predicted accumulator result php pla sta CF ; predicted carry result pla -; +; ; note that all 8 bits of the P register are stored in VF -; +; sta VF ; predicted V flags rts - + ; Calculate the actual decimal mode accumulator and flags, and the ; accumulator and flag results when N2 is subtracted from N1 using binary ; arithmetic -; -SUB sed ; decimal mode +; +SUB: sed ; decimal mode cpy #1 ; set carry if Y = 1, clear carry if Y = 0 lda N1 sbc N2 @@ -192,16 +193,16 @@ SUB sed ; decimal mode lda N1 sbc N2 sta HA ; accumulator result of N1-N2 using binary arithmetic - + php pla sta HNVZC ; flags result of N1-N2 using binary arithmetic rts - - if cputype != 1 + + .if cputype <> 1 ; Calculate the predicted SBC accumulator result for the 6502 and 65816 -; -SUB1 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +; +SUB1: cpy #1 ; set carry if Y = 1, clear carry if Y = 0 lda N1L sbc N2L ldx #0 @@ -210,22 +211,22 @@ SUB1 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 sbc #5 ; subtract 6 (carry is clear) and #$0F clc -S11 ora N1H -; +S11: ora N1H +; ; if N1L - N2L >= 0, then subtract N2 & $F0 ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) -; +; sbc N2H,x bcs S12 sbc #$5F ; subtract $60 (carry is clear) -S12 sta AR +S12: sta AR rts - endif - - if cputype = 1 + .endif + + .if cputype = 1 ; Calculate the predicted SBC accumulator result for the 6502 and 65C02 ; -SUB2 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +SUB2: cpy #1 ; set carry if Y = 1, clear carry if Y = 0 lda N1L sbc N2L ldx #0 @@ -233,74 +234,74 @@ SUB2 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 inx and #$0F clc -S21 ora N1H -; +S21: ora N1H +; ; if N1L - N2L >= 0, then subtract N2 & $F0 ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) -; +; sbc N2H,x bcs S22 sbc #$5F ; subtract $60 (carry is clear) -S22 cpx #0 +S22: cpx #0 beq S23 sbc #6 -S23 sta AR ; predicted accumulator result +S23: sta AR ; predicted accumulator result rts - endif - + .endif + ; Compare accumulator actual results to predicted results -; -; Return: +; +; Return: ; Z flag = 1 (BEQ branch) if same ; Z flag = 0 (BNE branch) if different -; -COMPARE - if chk_a = 1 +; +COMPARE: + .if chk_a = 1 lda DA cmp AR bne C1 - endif - if chk_n = 1 + .endif + .if chk_n = 1 lda DNVZC ; [7] see text eor NF and #$80 ; mask off N flag bne C1 - endif - if chk_v = 1 + .endif + .if chk_v = 1 lda DNVZC ; [8] see text eor VF and #$40 ; mask off V flag bne C1 ; [9] see text - endif - if chk_z = 1 + .endif + .if chk_z = 1 lda DNVZC eor ZF ; mask off Z flag and #2 bne C1 ; [10] see text - endif - if chk_c = 1 + .endif + .if chk_c = 1 lda DNVZC eor CF and #1 ; mask off C flag - endif -C1 rts - + .endif +C1: rts + ; These routines store the predicted values for ADC and SBC for the 6502, ; 65C02, and 65816 in AR, CF, NF, VF, and ZF - if cputype = 0 + .if cputype = 0 -A6502 lda VF ; 6502 -; +A6502: lda VF ; 6502 +; ; since all 8 bits of the P register were stored in VF, bit 7 of VF contains ; the N flag for NF -; +; sta NF lda HNVZC sta ZF rts - -S6502 jsr SUB1 + +S6502: jsr SUB1 lda HNVZC sta NF sta VF @@ -308,17 +309,17 @@ S6502 jsr SUB1 sta CF rts - endif - if cputype = 1 + .endif + .if cputype = 1 -A6502 lda AR ; 65C02 +A6502: lda AR ; 65C02 php pla sta NF sta ZF rts - -S6502 jsr SUB2 + +S6502: jsr SUB2 lda AR php pla @@ -329,17 +330,17 @@ S6502 jsr SUB2 sta CF rts - endif - if cputype = 2 + .endif + .if cputype = 2 -A6502 lda AR ; 65C816 +A6502: lda AR ; 65C816 php pla sta NF sta ZF rts - -S6502 jsr SUB1 + +S6502: jsr SUB1 lda AR php pla @@ -350,6 +351,4 @@ S6502 jsr SUB1 sta CF rts - endif - - end TEST + .endif \ No newline at end of file diff --git a/py65/tests/devices/bcd/6502_decimal_test.lst b/py65/tests/devices/bcd/6502_decimal_test.lst index 9d7190c..63581c2 100644 --- a/py65/tests/devices/bcd/6502_decimal_test.lst +++ b/py65/tests/devices/bcd/6502_decimal_test.lst @@ -1,367 +1,359 @@ -AS65 Assembler for R6502 [1.42]. Copyright 1994-2007, Frank A. Kingswood Page 1 ------------------------------------------------------ 6502_decimal_test.a65 ------------------------------------------------------ +ca65 V2.17 - Git N/A +Main file : 6502_decimal_test.c65 +Current file: 6502_decimal_test.c65 -355 lines read, no errors in pass 1. - ; Verify decimal mode behavior - ; Written by Bruce Clark. This code is public domain. - ; see http://www.6502.org/tutorials/decimal_mode.html - ; - ; Returns: - ; ERROR = 0 if the test passed - ; ERROR = 1 if the test failed - ; modify the code at the DONE label for desired program end - ; - ; This routine requires 17 bytes of RAM -- 1 byte each for: - ; AR, CF, DA, DNVZC, ERROR, HA, HNVZC, N1, N1H, N1L, N2, N2L, NF, VF, and ZF - ; and 2 bytes for N2H - ; - ; Variables: - ; N1 and N2 are the two numbers to be added or subtracted - ; N1H, N1L, N2H, and N2L are the upper 4 bits and lower 4 bits of N1 and N2 - ; DA and DNVZC are the actual accumulator and flag results in decimal mode - ; HA and HNVZC are the accumulator and flag results when N1 and N2 are - ; added or subtracted using binary arithmetic - ; AR, NF, VF, ZF, and CF are the predicted decimal mode accumulator and - ; flag results, calculated using binary arithmetic - ; - ; This program takes approximately 1 minute at 1 MHz (a few seconds more on - ; a 65C02 than a 6502 or 65816) - ; - - ; Configuration: -0000 = cputype = 0 ; 0 = 6502, 1 = 65C02, 2 = 65C816 -0000 = vld_bcd = 0 ; 0 = allow invalid bcd, 1 = valid bcd only -0001 = chk_a = 1 ; check accumulator -0001 = chk_n = 1 ; check sign (negative) flag -0001 = chk_v = 1 ; check overflow flag -0001 = chk_z = 1 ; check zero flag -0001 = chk_c = 1 ; check carry flag - - end_of_test macro - db $db ;execute 65C02 stop instruction - endm - - bss -0000 = org 0 - ; operands - register Y = carry in -0000 = N1 ds 1 -0001 = N2 ds 1 - ; binary result -0002 = HA ds 1 -0003 = HNVZC ds 1 - ;04 - ; decimal result -0004 = DA ds 1 -0005 = DNVZC ds 1 - ; predicted results -0006 = AR ds 1 -0007 = NF ds 1 - ;08 -0008 = VF ds 1 -0009 = ZF ds 1 -000a = CF ds 1 -000b = ERROR ds 1 - ;0C - ; workspace -000c = N1L ds 1 -000d = N1H ds 1 -000e = N2L ds 1 -000f = N2H ds 2 - - code -0200 = org $200 -0200 : a001 TEST ldy #1 ; initialize Y (used to loop through carry flag values) -0202 : 840b sty ERROR ; store 1 in ERROR until the test passes -0204 : a900 lda #0 ; initialize N1 and N2 -0206 : 8500 sta N1 -0208 : 8501 sta N2 -020a : a501 LOOP1 lda N2 ; N2L = N2 & $0F -020c : 290f and #$0F ; [1] see text - if vld_bcd = 1 - cmp #$0a - bcs NEXT2 - endif -020e : 850e sta N2L -0210 : a501 lda N2 ; N2H = N2 & $F0 -0212 : 29f0 and #$F0 ; [2] see text - if vld_bcd = 1 - cmp #$a0 - bcs NEXT2 - endif -0214 : 850f sta N2H -0216 : 090f ora #$0F ; N2H+1 = (N2 & $F0) + $0F -0218 : 8510 sta N2H+1 -021a : a500 LOOP2 lda N1 ; N1L = N1 & $0F -021c : 290f and #$0F ; [3] see text - if vld_bcd = 1 - cmp #$0a - bcs NEXT1 - endif -021e : 850c sta N1L -0220 : a500 lda N1 ; N1H = N1 & $F0 -0222 : 29f0 and #$F0 ; [4] see text - if vld_bcd = 1 - cmp #$a0 - bcs NEXT1 - endif -0224 : 850d sta N1H -0226 : 204c02 jsr ADD -0229 : 20eb02 jsr A6502 -022c : 20c602 jsr COMPARE -022f : d0fe bne * -0231 : 209002 jsr SUB -0234 : 20f402 jsr S6502 -0237 : 20c602 jsr COMPARE -023a : d0fe bne * -023c : e600 NEXT1 inc N1 ; [5] see text -023e : d0da bne LOOP2 ; loop through all 256 values of N1 -0240 : e601 NEXT2 inc N2 ; [6] see text -0242 : d0c6 bne LOOP1 ; loop through all 256 values of N2 -0244 : 88 dey -0245 : 10c3 bpl LOOP1 ; loop through both values of the carry flag -0247 : a900 lda #0 ; test passed, so store 0 in ERROR -0249 : 850b sta ERROR -024b : DONE - end_of_test -024b : db > db $db ;execute 65C02 stop instruction - - - ; Calculate the actual decimal mode accumulator and flags, the accumulator - ; and flag results when N1 is added to N2 using binary arithmetic, the - ; predicted accumulator result, the predicted carry flag, and the predicted - ; V flag - ; -024c : f8 ADD sed ; decimal mode -024d : c001 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 -024f : a500 lda N1 -0251 : 6501 adc N2 -0253 : 8504 sta DA ; actual accumulator result in decimal mode -0255 : 08 php -0256 : 68 pla -0257 : 8505 sta DNVZC ; actual flags result in decimal mode -0259 : d8 cld ; binary mode -025a : c001 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 -025c : a500 lda N1 -025e : 6501 adc N2 -0260 : 8502 sta HA ; accumulator result of N1+N2 using binary arithmetic - -0262 : 08 php -0263 : 68 pla -0264 : 8503 sta HNVZC ; flags result of N1+N2 using binary arithmetic -0266 : c001 cpy #1 -0268 : a50c lda N1L -026a : 650e adc N2L -026c : c90a cmp #$0A -026e : a200 ldx #0 -0270 : 9006 bcc A1 -0272 : e8 inx -0273 : 6905 adc #5 ; add 6 (carry is set) -0275 : 290f and #$0F -0277 : 38 sec -0278 : 050d A1 ora N1H - ; - ; if N1L + N2L < $0A, then add N2 & $F0 - ; if N1L + N2L >= $0A, then add (N2 & $F0) + $0F + 1 (carry is set) - ; -027a : 750f adc N2H,x -027c : 08 php -027d : b004 bcs A2 -027f : c9a0 cmp #$A0 -0281 : 9003 bcc A3 -0283 : 695f A2 adc #$5F ; add $60 (carry is set) -0285 : 38 sec -0286 : 8506 A3 sta AR ; predicted accumulator result -0288 : 08 php -0289 : 68 pla -028a : 850a sta CF ; predicted carry result -028c : 68 pla - ; - ; note that all 8 bits of the P register are stored in VF - ; -028d : 8508 sta VF ; predicted V flags -028f : 60 rts - - ; Calculate the actual decimal mode accumulator and flags, and the - ; accumulator and flag results when N2 is subtracted from N1 using binary - ; arithmetic - ; -0290 : f8 SUB sed ; decimal mode -0291 : c001 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 -0293 : a500 lda N1 -0295 : e501 sbc N2 -0297 : 8504 sta DA ; actual accumulator result in decimal mode -0299 : 08 php -029a : 68 pla -029b : 8505 sta DNVZC ; actual flags result in decimal mode -029d : d8 cld ; binary mode -029e : c001 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 -02a0 : a500 lda N1 -02a2 : e501 sbc N2 -02a4 : 8502 sta HA ; accumulator result of N1-N2 using binary arithmetic - -02a6 : 08 php -02a7 : 68 pla -02a8 : 8503 sta HNVZC ; flags result of N1-N2 using binary arithmetic -02aa : 60 rts - - if cputype != 1 - ; Calculate the predicted SBC accumulator result for the 6502 and 65816 - ; -02ab : c001 SUB1 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 -02ad : a50c lda N1L -02af : e50e sbc N2L -02b1 : a200 ldx #0 -02b3 : b006 bcs S11 -02b5 : e8 inx -02b6 : e905 sbc #5 ; subtract 6 (carry is clear) -02b8 : 290f and #$0F -02ba : 18 clc -02bb : 050d S11 ora N1H - ; - ; if N1L - N2L >= 0, then subtract N2 & $F0 - ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) - ; -02bd : f50f sbc N2H,x -02bf : b002 bcs S12 -02c1 : e95f sbc #$5F ; subtract $60 (carry is clear) -02c3 : 8506 S12 sta AR -02c5 : 60 rts - endif - - if cputype = 1 - ; Calculate the predicted SBC accumulator result for the 6502 and 65C02 - ; - SUB2 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 - lda N1L - sbc N2L - ldx #0 - bcs S21 - inx - and #$0F - clc - S21 ora N1H - ; - ; if N1L - N2L >= 0, then subtract N2 & $F0 - ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) - ; - sbc N2H,x - bcs S22 - sbc #$5F ; subtract $60 (carry is clear) - S22 cpx #0 - beq S23 - sbc #6 - S23 sta AR ; predicted accumulator result - rts - endif - - ; Compare accumulator actual results to predicted results - ; - ; Return: - ; Z flag = 1 (BEQ branch) if same - ; Z flag = 0 (BNE branch) if different - ; -02c6 : COMPARE - if chk_a = 1 -02c6 : a504 lda DA -02c8 : c506 cmp AR -02ca : d01e bne C1 - endif - if chk_n = 1 -02cc : a505 lda DNVZC ; [7] see text -02ce : 4507 eor NF -02d0 : 2980 and #$80 ; mask off N flag -02d2 : d016 bne C1 - endif - if chk_v = 1 -02d4 : a505 lda DNVZC ; [8] see text -02d6 : 4508 eor VF -02d8 : 2940 and #$40 ; mask off V flag -02da : d00e bne C1 ; [9] see text - endif - if chk_z = 1 -02dc : a505 lda DNVZC -02de : 4509 eor ZF ; mask off Z flag -02e0 : 2902 and #2 -02e2 : d006 bne C1 ; [10] see text - endif - if chk_c = 1 -02e4 : a505 lda DNVZC -02e6 : 450a eor CF -02e8 : 2901 and #1 ; mask off C flag - endif -02ea : 60 C1 rts - - ; These routines store the predicted values for ADC and SBC for the 6502, - ; 65C02, and 65816 in AR, CF, NF, VF, and ZF - - if cputype = 0 - -02eb : a508 A6502 lda VF ; 6502 - ; - ; since all 8 bits of the P register were stored in VF, bit 7 of VF contains - ; the N flag for NF - ; -02ed : 8507 sta NF -02ef : a503 lda HNVZC -02f1 : 8509 sta ZF -02f3 : 60 rts - -02f4 : 20ab02 S6502 jsr SUB1 -02f7 : a503 lda HNVZC -02f9 : 8507 sta NF -02fb : 8508 sta VF -02fd : 8509 sta ZF -02ff : 850a sta CF -0301 : 60 rts - - endif - if cputype = 1 - - A6502 lda AR ; 65C02 - php - pla - sta NF - sta ZF - rts - - S6502 jsr SUB2 - lda AR - php - pla - sta NF - sta ZF - lda HNVZC - sta VF - sta CF - rts - - endif - if cputype = 2 - - A6502 lda AR ; 65C816 - php - pla - sta NF - sta ZF - rts - - S6502 jsr SUB1 - lda AR - php - pla - sta NF - sta ZF - lda HNVZC - sta VF - sta CF - rts - - endif - -02f4 = end TEST - -No errors in pass 2. -Wrote binary from address $0200 through $0301. -Total size 258 bytes. -Program start address is at $0200 (512). - \ No newline at end of file +000000r 1 ; Verify decimal mode behavior +000000r 1 ; Written by Bruce Clark. This code is public domain. +000000r 1 ; see http://www.6502.org/tutorials/decimal_mode.html +000000r 1 ; +000000r 1 ; Returns: +000000r 1 ; ERROR = 0 if the test passed +000000r 1 ; ERROR = 1 if the test failed +000000r 1 ; modify the code at the DONE label for desired program end +000000r 1 ; +000000r 1 ; This routine requires 17 bytes of RAM -- 1 byte each for: +000000r 1 ; AR, CF, DA, DNVZC, ERROR, HA, HNVZC, N1, N1H, N1L, N2, N2L, NF, VF, and ZF +000000r 1 ; and 2 bytes for N2H +000000r 1 ; +000000r 1 ; Variables: +000000r 1 ; N1 and N2 are the two numbers to be added or subtracted +000000r 1 ; N1H, N1L, N2H, and N2L are the upper 4 bits and lower 4 bits of N1 and N2 +000000r 1 ; DA and DNVZC are the actual accumulator and flag results in decimal mode +000000r 1 ; HA and HNVZC are the accumulator and flag results when N1 and N2 are +000000r 1 ; added or subtracted using binary arithmetic +000000r 1 ; AR, NF, VF, ZF, and CF are the predicted decimal mode accumulator and +000000r 1 ; flag results, calculated using binary arithmetic +000000r 1 ; +000000r 1 ; This program takes approximately 1 minute at 1 MHz (a few seconds more on +000000r 1 ; a 65C02 than a 6502 or 65816) +000000r 1 ; +000000r 1 +000000r 1 ; Configuration: +000000r 1 cputype = 0 ; 0 = 6502, 1 = 65C02, 2 = 65C816 +000000r 1 vld_bcd = 0 ; 0 = allow invalid bcd, 1 = valid bcd only +000000r 1 chk_a = 1 ; check accumulator +000000r 1 chk_n = 1 ; check sign (negative) flag +000000r 1 chk_v = 1 ; check overflow flag +000000r 1 chk_z = 1 ; check zero flag +000000r 1 chk_c = 1 ; check carry flag +000000r 1 +000000r 1 .macro end_of_test +000000r 1 BRK +000000r 1 ; .byte $db ;execute 65C02 stop instruction +000000r 1 .endmacro +000000r 1 +000000r 1 .ZEROPAGE +000000r 1 .org 0 +000000 1 ; operands - register Y = carry in +000000 1 00 N1: .res 1,0 +000001 1 00 N2: .res 1,0 +000002 1 ; binary result +000002 1 00 HA: .res 1,0 +000003 1 00 HNVZC: .res 1,0 +000004 1 ;04 +000004 1 ; decimal result +000004 1 00 DA: .res 1,0 +000005 1 00 DNVZC: .res 1,0 +000006 1 ; predicted results +000006 1 00 AR: .res 1,0 +000007 1 00 NF: .res 1,0 +000008 1 ;08 +000008 1 00 VF: .res 1,0 +000009 1 00 ZF: .res 1,0 +00000A 1 00 CF: .res 1,0 +00000B 1 00 ERROR: .res 1,0 +00000C 1 ;0C +00000C 1 ; workspace +00000C 1 00 N1L: .res 1,0 +00000D 1 00 N1H: .res 1,0 +00000E 1 00 N2L: .res 1,0 +00000F 1 00 00 N2H: .res 2,0 +000011 1 +000011 1 .CODE +000011 1 .org $200 +000200 1 A0 01 TEST: ldy #1 ; initialize Y (used to loop through carry flag values) +000202 1 84 0B sty ERROR ; store 1 in ERROR until the test passes +000204 1 A9 00 lda #0 ; initialize N1 and N2 +000206 1 85 00 sta N1 +000208 1 85 01 sta N2 +00020A 1 A5 01 LOOP1: lda N2 ; N2L = N2 & $0F +00020C 1 29 0F and #$0F ; [1] see text +00020E 1 .if vld_bcd = 1 +00020E 1 cmp #$0a +00020E 1 bcs NEXT2 +00020E 1 .endif +00020E 1 85 0E sta N2L +000210 1 A5 01 lda N2 ; N2H = N2 & $F0 +000212 1 29 F0 and #$F0 ; [2] see text +000214 1 .if vld_bcd = 1 +000214 1 cmp #$a0 +000214 1 bcs NEXT2 +000214 1 .endif +000214 1 85 0F sta N2H +000216 1 09 0F ora #$0F ; N2H+1 = (N2 & $F0) + $0F +000218 1 85 10 sta N2H+1 +00021A 1 A5 00 LOOP2: lda N1 ; N1L = N1 & $0F +00021C 1 29 0F and #$0F ; [3] see text +00021E 1 .if vld_bcd = 1 +00021E 1 cmp #$0a +00021E 1 bcs NEXT1 +00021E 1 .endif +00021E 1 85 0C sta N1L +000220 1 A5 00 lda N1 ; N1H = N1 & $F0 +000222 1 29 F0 and #$F0 ; [4] see text +000224 1 .if vld_bcd = 1 +000224 1 cmp #$a0 +000224 1 bcs NEXT1 +000224 1 .endif +000224 1 85 0D sta N1H +000226 1 20 4C 02 jsr ADD +000229 1 20 EB 02 jsr A6502 +00022C 1 20 C6 02 jsr COMPARE +00022F 1 D0 1A bne DONE +000231 1 20 90 02 jsr SUB +000234 1 20 F4 02 jsr S6502 +000237 1 20 C6 02 jsr COMPARE +00023A 1 D0 0F bne DONE +00023C 1 E6 00 NEXT1: inc N1 ; [5] see text +00023E 1 D0 DA bne LOOP2 ; loop through all 256 values of N1 +000240 1 E6 01 NEXT2: inc N2 ; [6] see text +000242 1 D0 C6 bne LOOP1 ; loop through all 256 values of N2 +000244 1 88 dey +000245 1 10 C3 bpl LOOP1 ; loop through both values of the carry flag +000247 1 A9 00 lda #0 ; test passed, so store 0 in ERROR +000249 1 85 0B sta ERROR +00024B 1 DONE: +00024B 1 00 end_of_test +00024C 1 +00024C 1 ; Calculate the actual decimal mode accumulator and flags, the accumulator +00024C 1 ; and flag results when N1 is added to N2 using binary arithmetic, the +00024C 1 ; predicted accumulator result, the predicted carry flag, and the predicted +00024C 1 ; V flag +00024C 1 ; +00024C 1 F8 ADD: sed ; decimal mode +00024D 1 C0 01 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +00024F 1 A5 00 lda N1 +000251 1 65 01 adc N2 +000253 1 85 04 sta DA ; actual accumulator result in decimal mode +000255 1 08 php +000256 1 68 pla +000257 1 85 05 sta DNVZC ; actual flags result in decimal mode +000259 1 D8 cld ; binary mode +00025A 1 C0 01 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +00025C 1 A5 00 lda N1 +00025E 1 65 01 adc N2 +000260 1 85 02 sta HA ; accumulator result of N1+N2 using binary arithmetic +000262 1 +000262 1 08 php +000263 1 68 pla +000264 1 85 03 sta HNVZC ; flags result of N1+N2 using binary arithmetic +000266 1 C0 01 cpy #1 +000268 1 A5 0C lda N1L +00026A 1 65 0E adc N2L +00026C 1 C9 0A cmp #$0A +00026E 1 A2 00 ldx #0 +000270 1 90 06 bcc A1 +000272 1 E8 inx +000273 1 69 05 adc #5 ; add 6 (carry is set) +000275 1 29 0F and #$0F +000277 1 38 sec +000278 1 05 0D A1: ora N1H +00027A 1 ; +00027A 1 ; if N1L + N2L < $0A, then add N2 & $F0 +00027A 1 ; if N1L + N2L >= $0A, then add (N2 & $F0) + $0F + 1 (carry is set) +00027A 1 ; +00027A 1 75 0F adc N2H,x +00027C 1 08 php +00027D 1 B0 04 bcs A2 +00027F 1 C9 A0 cmp #$A0 +000281 1 90 03 bcc A3 +000283 1 69 5F A2: adc #$5F ; add $60 (carry is set) +000285 1 38 sec +000286 1 85 06 A3: sta AR ; predicted accumulator result +000288 1 08 php +000289 1 68 pla +00028A 1 85 0A sta CF ; predicted carry result +00028C 1 68 pla +00028D 1 ; +00028D 1 ; note that all 8 bits of the P register are stored in VF +00028D 1 ; +00028D 1 85 08 sta VF ; predicted V flags +00028F 1 60 rts +000290 1 +000290 1 ; Calculate the actual decimal mode accumulator and flags, and the +000290 1 ; accumulator and flag results when N2 is subtracted from N1 using binary +000290 1 ; arithmetic +000290 1 ; +000290 1 F8 SUB: sed ; decimal mode +000291 1 C0 01 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +000293 1 A5 00 lda N1 +000295 1 E5 01 sbc N2 +000297 1 85 04 sta DA ; actual accumulator result in decimal mode +000299 1 08 php +00029A 1 68 pla +00029B 1 85 05 sta DNVZC ; actual flags result in decimal mode +00029D 1 D8 cld ; binary mode +00029E 1 C0 01 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +0002A0 1 A5 00 lda N1 +0002A2 1 E5 01 sbc N2 +0002A4 1 85 02 sta HA ; accumulator result of N1-N2 using binary arithmetic +0002A6 1 +0002A6 1 08 php +0002A7 1 68 pla +0002A8 1 85 03 sta HNVZC ; flags result of N1-N2 using binary arithmetic +0002AA 1 60 rts +0002AB 1 +0002AB 1 .if cputype <> 1 +0002AB 1 ; Calculate the predicted SBC accumulator result for the 6502 and 65816 +0002AB 1 ; +0002AB 1 C0 01 SUB1: cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +0002AD 1 A5 0C lda N1L +0002AF 1 E5 0E sbc N2L +0002B1 1 A2 00 ldx #0 +0002B3 1 B0 06 bcs S11 +0002B5 1 E8 inx +0002B6 1 E9 05 sbc #5 ; subtract 6 (carry is clear) +0002B8 1 29 0F and #$0F +0002BA 1 18 clc +0002BB 1 05 0D S11: ora N1H +0002BD 1 ; +0002BD 1 ; if N1L - N2L >= 0, then subtract N2 & $F0 +0002BD 1 ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) +0002BD 1 ; +0002BD 1 F5 0F sbc N2H,x +0002BF 1 B0 02 bcs S12 +0002C1 1 E9 5F sbc #$5F ; subtract $60 (carry is clear) +0002C3 1 85 06 S12: sta AR +0002C5 1 60 rts +0002C6 1 .endif +0002C6 1 +0002C6 1 .if cputype = 1 +0002C6 1 ; Calculate the predicted SBC accumulator result for the 6502 and 65C02 +0002C6 1 ; +0002C6 1 SUB2: cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +0002C6 1 lda N1L +0002C6 1 sbc N2L +0002C6 1 ldx #0 +0002C6 1 bcs S21 +0002C6 1 inx +0002C6 1 and #$0F +0002C6 1 clc +0002C6 1 S21: ora N1H +0002C6 1 ; +0002C6 1 ; if N1L - N2L >= 0, then subtract N2 & $F0 +0002C6 1 ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) +0002C6 1 ; +0002C6 1 sbc N2H,x +0002C6 1 bcs S22 +0002C6 1 sbc #$5F ; subtract $60 (carry is clear) +0002C6 1 S22: cpx #0 +0002C6 1 beq S23 +0002C6 1 sbc #6 +0002C6 1 S23: sta AR ; predicted accumulator result +0002C6 1 rts +0002C6 1 .endif +0002C6 1 +0002C6 1 ; Compare accumulator actual results to predicted results +0002C6 1 ; +0002C6 1 ; Return: +0002C6 1 ; Z flag = 1 (BEQ branch) if same +0002C6 1 ; Z flag = 0 (BNE branch) if different +0002C6 1 ; +0002C6 1 COMPARE: +0002C6 1 .if chk_a = 1 +0002C6 1 A5 04 lda DA +0002C8 1 C5 06 cmp AR +0002CA 1 D0 1E bne C1 +0002CC 1 .endif +0002CC 1 .if chk_n = 1 +0002CC 1 A5 05 lda DNVZC ; [7] see text +0002CE 1 45 07 eor NF +0002D0 1 29 80 and #$80 ; mask off N flag +0002D2 1 D0 16 bne C1 +0002D4 1 .endif +0002D4 1 .if chk_v = 1 +0002D4 1 A5 05 lda DNVZC ; [8] see text +0002D6 1 45 08 eor VF +0002D8 1 29 40 and #$40 ; mask off V flag +0002DA 1 D0 0E bne C1 ; [9] see text +0002DC 1 .endif +0002DC 1 .if chk_z = 1 +0002DC 1 A5 05 lda DNVZC +0002DE 1 45 09 eor ZF ; mask off Z flag +0002E0 1 29 02 and #2 +0002E2 1 D0 06 bne C1 ; [10] see text +0002E4 1 .endif +0002E4 1 .if chk_c = 1 +0002E4 1 A5 05 lda DNVZC +0002E6 1 45 0A eor CF +0002E8 1 29 01 and #1 ; mask off C flag +0002EA 1 .endif +0002EA 1 60 C1: rts +0002EB 1 +0002EB 1 ; These routines store the predicted values for ADC and SBC for the 6502, +0002EB 1 ; 65C02, and 65816 in AR, CF, NF, VF, and ZF +0002EB 1 +0002EB 1 .if cputype = 0 +0002EB 1 +0002EB 1 A5 08 A6502: lda VF ; 6502 +0002ED 1 ; +0002ED 1 ; since all 8 bits of the P register were stored in VF, bit 7 of VF contains +0002ED 1 ; the N flag for NF +0002ED 1 ; +0002ED 1 85 07 sta NF +0002EF 1 A5 03 lda HNVZC +0002F1 1 85 09 sta ZF +0002F3 1 60 rts +0002F4 1 +0002F4 1 20 AB 02 S6502: jsr SUB1 +0002F7 1 A5 03 lda HNVZC +0002F9 1 85 07 sta NF +0002FB 1 85 08 sta VF +0002FD 1 85 09 sta ZF +0002FF 1 85 0A sta CF +000301 1 60 rts +000302 1 +000302 1 .endif +000302 1 .if cputype = 1 +000302 1 +000302 1 A6502: lda AR ; 65C02 +000302 1 php +000302 1 pla +000302 1 sta NF +000302 1 sta ZF +000302 1 rts +000302 1 +000302 1 S6502: jsr SUB2 +000302 1 lda AR +000302 1 php +000302 1 pla +000302 1 sta NF +000302 1 sta ZF +000302 1 lda HNVZC +000302 1 sta VF +000302 1 sta CF +000302 1 rts +000302 1 +000302 1 .endif +000302 1 .if cputype = 2 +000302 1 +000302 1 A6502: lda AR ; 65C816 +000302 1 php +000302 1 pla +000302 1 sta NF +000302 1 sta ZF +000302 1 rts +000302 1 +000302 1 S6502: jsr SUB1 +000302 1 lda AR +000302 1 php +000302 1 pla +000302 1 sta NF +000302 1 sta ZF +000302 1 lda HNVZC +000302 1 sta VF +000302 1 sta CF +000302 1 rts +000302 1 +000302 1 .endif +000302 1 diff --git a/py65/tests/devices/bcd/65C02_decimal_test.bin b/py65/tests/devices/bcd/65C02_decimal_test.bin index e4b80b1..e1ecc33 100644 Binary files a/py65/tests/devices/bcd/65C02_decimal_test.bin and b/py65/tests/devices/bcd/65C02_decimal_test.bin differ diff --git a/py65/tests/devices/bcd/65C02_decimal_test.a65 b/py65/tests/devices/bcd/65C02_decimal_test.c65 similarity index 77% rename from py65/tests/devices/bcd/65C02_decimal_test.a65 rename to py65/tests/devices/bcd/65C02_decimal_test.c65 index 37dfa4b..50e8d49 100644 --- a/py65/tests/devices/bcd/65C02_decimal_test.a65 +++ b/py65/tests/devices/bcd/65C02_decimal_test.c65 @@ -33,99 +33,100 @@ chk_v = 1 ; check overflow flag chk_z = 1 ; check zero flag chk_c = 1 ; check carry flag -end_of_test macro - db $db ;execute 65C02 stop instruction - endm +.macro end_of_test + BRK + ; .byte $db ;execute 65C02 stop instruction +.endmacro - bss - org 0 + .ZEROPAGE + .org 0 ; operands - register Y = carry in -N1 ds 1 -N2 ds 1 +N1: .res 1,0 +N2: .res 1,0 ; binary result -HA ds 1 -HNVZC ds 1 +HA: .res 1,0 +HNVZC: .res 1,0 ;04 ; decimal result -DA ds 1 -DNVZC ds 1 +DA: .res 1,0 +DNVZC: .res 1,0 ; predicted results -AR ds 1 -NF ds 1 +AR: .res 1,0 +NF: .res 1,0 ;08 -VF ds 1 -ZF ds 1 -CF ds 1 -ERROR ds 1 +VF: .res 1,0 +ZF: .res 1,0 +CF: .res 1,0 +ERROR: .res 1,0 ;0C ; workspace -N1L ds 1 -N1H ds 1 -N2L ds 1 -N2H ds 2 +N1L: .res 1,0 +N1H: .res 1,0 +N2L: .res 1,0 +N2H: .res 2,0 - code - org $200 -TEST ldy #1 ; initialize Y (used to loop through carry flag values) + .CODE + .org $200 +TEST: ldy #1 ; initialize Y (used to loop through carry flag values) sty ERROR ; store 1 in ERROR until the test passes lda #0 ; initialize N1 and N2 sta N1 sta N2 -LOOP1 lda N2 ; N2L = N2 & $0F +LOOP1: lda N2 ; N2L = N2 & $0F and #$0F ; [1] see text - if vld_bcd = 1 + .if vld_bcd = 1 cmp #$0a bcs NEXT2 - endif + .endif sta N2L lda N2 ; N2H = N2 & $F0 and #$F0 ; [2] see text - if vld_bcd = 1 + .if vld_bcd = 1 cmp #$a0 bcs NEXT2 - endif + .endif sta N2H ora #$0F ; N2H+1 = (N2 & $F0) + $0F sta N2H+1 -LOOP2 lda N1 ; N1L = N1 & $0F +LOOP2: lda N1 ; N1L = N1 & $0F and #$0F ; [3] see text - if vld_bcd = 1 + .if vld_bcd = 1 cmp #$0a bcs NEXT1 - endif + .endif sta N1L lda N1 ; N1H = N1 & $F0 and #$F0 ; [4] see text - if vld_bcd = 1 + .if vld_bcd = 1 cmp #$a0 bcs NEXT1 - endif + .endif sta N1H jsr ADD jsr A6502 jsr COMPARE - bne * + bne DONE jsr SUB jsr S6502 jsr COMPARE - bne * -NEXT1 inc N1 ; [5] see text + bne DONE +NEXT1: inc N1 ; [5] see text bne LOOP2 ; loop through all 256 values of N1 -NEXT2 inc N2 ; [6] see text +NEXT2: inc N2 ; [6] see text bne LOOP1 ; loop through all 256 values of N2 dey bpl LOOP1 ; loop through both values of the carry flag lda #0 ; test passed, so store 0 in ERROR sta ERROR -DONE +DONE: end_of_test - + ; Calculate the actual decimal mode accumulator and flags, the accumulator ; and flag results when N1 is added to N2 using binary arithmetic, the ; predicted accumulator result, the predicted carry flag, and the predicted -; V flag -; -ADD sed ; decimal mode +; V flag +; +ADD: sed ; decimal mode cpy #1 ; set carry if Y = 1, clear carry if Y = 0 lda N1 adc N2 @@ -138,7 +139,7 @@ ADD sed ; decimal mode lda N1 adc N2 sta HA ; accumulator result of N1+N2 using binary arithmetic - + php pla sta HNVZC ; flags result of N1+N2 using binary arithmetic @@ -152,34 +153,34 @@ ADD sed ; decimal mode adc #5 ; add 6 (carry is set) and #$0F sec -A1 ora N1H -; +A1: ora N1H +; ; if N1L + N2L < $0A, then add N2 & $F0 ; if N1L + N2L >= $0A, then add (N2 & $F0) + $0F + 1 (carry is set) -; +; adc N2H,x php bcs A2 cmp #$A0 bcc A3 -A2 adc #$5F ; add $60 (carry is set) +A2: adc #$5F ; add $60 (carry is set) sec -A3 sta AR ; predicted accumulator result +A3: sta AR ; predicted accumulator result php pla sta CF ; predicted carry result pla -; +; ; note that all 8 bits of the P register are stored in VF -; +; sta VF ; predicted V flags rts - + ; Calculate the actual decimal mode accumulator and flags, and the ; accumulator and flag results when N2 is subtracted from N1 using binary ; arithmetic -; -SUB sed ; decimal mode +; +SUB: sed ; decimal mode cpy #1 ; set carry if Y = 1, clear carry if Y = 0 lda N1 sbc N2 @@ -192,16 +193,16 @@ SUB sed ; decimal mode lda N1 sbc N2 sta HA ; accumulator result of N1-N2 using binary arithmetic - + php pla sta HNVZC ; flags result of N1-N2 using binary arithmetic rts - - if cputype != 1 + + .if cputype <> 1 ; Calculate the predicted SBC accumulator result for the 6502 and 65816 -; -SUB1 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +; +SUB1: cpy #1 ; set carry if Y = 1, clear carry if Y = 0 lda N1L sbc N2L ldx #0 @@ -210,22 +211,22 @@ SUB1 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 sbc #5 ; subtract 6 (carry is clear) and #$0F clc -S11 ora N1H -; +S11: ora N1H +; ; if N1L - N2L >= 0, then subtract N2 & $F0 ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) -; +; sbc N2H,x bcs S12 sbc #$5F ; subtract $60 (carry is clear) -S12 sta AR +S12: sta AR rts - endif - - if cputype = 1 + .endif + + .if cputype = 1 ; Calculate the predicted SBC accumulator result for the 6502 and 65C02 ; -SUB2 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +SUB2: cpy #1 ; set carry if Y = 1, clear carry if Y = 0 lda N1L sbc N2L ldx #0 @@ -233,74 +234,74 @@ SUB2 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 inx and #$0F clc -S21 ora N1H -; +S21: ora N1H +; ; if N1L - N2L >= 0, then subtract N2 & $F0 ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) -; +; sbc N2H,x bcs S22 sbc #$5F ; subtract $60 (carry is clear) -S22 cpx #0 +S22: cpx #0 beq S23 sbc #6 -S23 sta AR ; predicted accumulator result +S23: sta AR ; predicted accumulator result rts - endif - + .endif + ; Compare accumulator actual results to predicted results -; -; Return: +; +; Return: ; Z flag = 1 (BEQ branch) if same ; Z flag = 0 (BNE branch) if different -; -COMPARE - if chk_a = 1 +; +COMPARE: + .if chk_a = 1 lda DA cmp AR bne C1 - endif - if chk_n = 1 + .endif + .if chk_n = 1 lda DNVZC ; [7] see text eor NF and #$80 ; mask off N flag bne C1 - endif - if chk_v = 1 + .endif + .if chk_v = 1 lda DNVZC ; [8] see text eor VF and #$40 ; mask off V flag bne C1 ; [9] see text - endif - if chk_z = 1 + .endif + .if chk_z = 1 lda DNVZC eor ZF ; mask off Z flag and #2 bne C1 ; [10] see text - endif - if chk_c = 1 + .endif + .if chk_c = 1 lda DNVZC eor CF and #1 ; mask off C flag - endif -C1 rts - + .endif +C1: rts + ; These routines store the predicted values for ADC and SBC for the 6502, ; 65C02, and 65816 in AR, CF, NF, VF, and ZF - if cputype = 0 + .if cputype = 0 -A6502 lda VF ; 6502 -; +A6502: lda VF ; 6502 +; ; since all 8 bits of the P register were stored in VF, bit 7 of VF contains ; the N flag for NF -; +; sta NF lda HNVZC sta ZF rts - -S6502 jsr SUB1 + +S6502: jsr SUB1 lda HNVZC sta NF sta VF @@ -308,17 +309,17 @@ S6502 jsr SUB1 sta CF rts - endif - if cputype = 1 + .endif + .if cputype = 1 -A6502 lda AR ; 65C02 +A6502: lda AR ; 65C02 php pla sta NF sta ZF rts - -S6502 jsr SUB2 + +S6502: jsr SUB2 lda AR php pla @@ -329,17 +330,17 @@ S6502 jsr SUB2 sta CF rts - endif - if cputype = 2 + .endif + .if cputype = 2 -A6502 lda AR ; 65C816 +A6502: lda AR ; 65C816 php pla sta NF sta ZF rts - -S6502 jsr SUB1 + +S6502: jsr SUB1 lda AR php pla @@ -350,6 +351,4 @@ S6502 jsr SUB1 sta CF rts - endif - - end TEST + .endif \ No newline at end of file diff --git a/py65/tests/devices/bcd/65C02_decimal_test.lst b/py65/tests/devices/bcd/65C02_decimal_test.lst index 352ee3b..4538433 100644 --- a/py65/tests/devices/bcd/65C02_decimal_test.lst +++ b/py65/tests/devices/bcd/65C02_decimal_test.lst @@ -1,367 +1,359 @@ -AS65 Assembler for R6502 [1.42]. Copyright 1994-2007, Frank A. Kingswood Page 1 ------------------------------------------------------ 65C02_decimal_test.a65 ----------------------------------------------------- +ca65 V2.17 - Git N/A +Main file : 65C02_decimal_test.c65 +Current file: 65C02_decimal_test.c65 -355 lines read, no errors in pass 1. - ; Verify decimal mode behavior - ; Written by Bruce Clark. This code is public domain. - ; see http://www.6502.org/tutorials/decimal_mode.html - ; - ; Returns: - ; ERROR = 0 if the test passed - ; ERROR = 1 if the test failed - ; modify the code at the DONE label for desired program end - ; - ; This routine requires 17 bytes of RAM -- 1 byte each for: - ; AR, CF, DA, DNVZC, ERROR, HA, HNVZC, N1, N1H, N1L, N2, N2L, NF, VF, and ZF - ; and 2 bytes for N2H - ; - ; Variables: - ; N1 and N2 are the two numbers to be added or subtracted - ; N1H, N1L, N2H, and N2L are the upper 4 bits and lower 4 bits of N1 and N2 - ; DA and DNVZC are the actual accumulator and flag results in decimal mode - ; HA and HNVZC are the accumulator and flag results when N1 and N2 are - ; added or subtracted using binary arithmetic - ; AR, NF, VF, ZF, and CF are the predicted decimal mode accumulator and - ; flag results, calculated using binary arithmetic - ; - ; This program takes approximately 1 minute at 1 MHz (a few seconds more on - ; a 65C02 than a 6502 or 65816) - ; - - ; Configuration: -0001 = cputype = 1 ; 0 = 6502, 1 = 65C02, 2 = 65C816 -0000 = vld_bcd = 0 ; 0 = allow invalid bcd, 1 = valid bcd only -0001 = chk_a = 1 ; check accumulator -0001 = chk_n = 1 ; check sign (negative) flag -0001 = chk_v = 1 ; check overflow flag -0001 = chk_z = 1 ; check zero flag -0001 = chk_c = 1 ; check carry flag - - end_of_test macro - db $db ;execute 65C02 stop instruction - endm - - bss -0000 = org 0 - ; operands - register Y = carry in -0000 = N1 ds 1 -0001 = N2 ds 1 - ; binary result -0002 = HA ds 1 -0003 = HNVZC ds 1 - ;04 - ; decimal result -0004 = DA ds 1 -0005 = DNVZC ds 1 - ; predicted results -0006 = AR ds 1 -0007 = NF ds 1 - ;08 -0008 = VF ds 1 -0009 = ZF ds 1 -000a = CF ds 1 -000b = ERROR ds 1 - ;0C - ; workspace -000c = N1L ds 1 -000d = N1H ds 1 -000e = N2L ds 1 -000f = N2H ds 2 - - code -0200 = org $200 -0200 : a001 TEST ldy #1 ; initialize Y (used to loop through carry flag values) -0202 : 840b sty ERROR ; store 1 in ERROR until the test passes -0204 : a900 lda #0 ; initialize N1 and N2 -0206 : 8500 sta N1 -0208 : 8501 sta N2 -020a : a501 LOOP1 lda N2 ; N2L = N2 & $0F -020c : 290f and #$0F ; [1] see text - if vld_bcd = 1 - cmp #$0a - bcs NEXT2 - endif -020e : 850e sta N2L -0210 : a501 lda N2 ; N2H = N2 & $F0 -0212 : 29f0 and #$F0 ; [2] see text - if vld_bcd = 1 - cmp #$a0 - bcs NEXT2 - endif -0214 : 850f sta N2H -0216 : 090f ora #$0F ; N2H+1 = (N2 & $F0) + $0F -0218 : 8510 sta N2H+1 -021a : a500 LOOP2 lda N1 ; N1L = N1 & $0F -021c : 290f and #$0F ; [3] see text - if vld_bcd = 1 - cmp #$0a - bcs NEXT1 - endif -021e : 850c sta N1L -0220 : a500 lda N1 ; N1H = N1 & $F0 -0222 : 29f0 and #$F0 ; [4] see text - if vld_bcd = 1 - cmp #$a0 - bcs NEXT1 - endif -0224 : 850d sta N1H -0226 : 204c02 jsr ADD -0229 : 20ef02 jsr A6502 -022c : 20ca02 jsr COMPARE -022f : d0fe bne * -0231 : 209002 jsr SUB -0234 : 20f802 jsr S6502 -0237 : 20ca02 jsr COMPARE -023a : d0fe bne * -023c : e600 NEXT1 inc N1 ; [5] see text -023e : d0da bne LOOP2 ; loop through all 256 values of N1 -0240 : e601 NEXT2 inc N2 ; [6] see text -0242 : d0c6 bne LOOP1 ; loop through all 256 values of N2 -0244 : 88 dey -0245 : 10c3 bpl LOOP1 ; loop through both values of the carry flag -0247 : a900 lda #0 ; test passed, so store 0 in ERROR -0249 : 850b sta ERROR -024b : DONE - end_of_test -024b : db > db $db ;execute 65C02 stop instruction - - - ; Calculate the actual decimal mode accumulator and flags, the accumulator - ; and flag results when N1 is added to N2 using binary arithmetic, the - ; predicted accumulator result, the predicted carry flag, and the predicted - ; V flag - ; -024c : f8 ADD sed ; decimal mode -024d : c001 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 -024f : a500 lda N1 -0251 : 6501 adc N2 -0253 : 8504 sta DA ; actual accumulator result in decimal mode -0255 : 08 php -0256 : 68 pla -0257 : 8505 sta DNVZC ; actual flags result in decimal mode -0259 : d8 cld ; binary mode -025a : c001 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 -025c : a500 lda N1 -025e : 6501 adc N2 -0260 : 8502 sta HA ; accumulator result of N1+N2 using binary arithmetic - -0262 : 08 php -0263 : 68 pla -0264 : 8503 sta HNVZC ; flags result of N1+N2 using binary arithmetic -0266 : c001 cpy #1 -0268 : a50c lda N1L -026a : 650e adc N2L -026c : c90a cmp #$0A -026e : a200 ldx #0 -0270 : 9006 bcc A1 -0272 : e8 inx -0273 : 6905 adc #5 ; add 6 (carry is set) -0275 : 290f and #$0F -0277 : 38 sec -0278 : 050d A1 ora N1H - ; - ; if N1L + N2L < $0A, then add N2 & $F0 - ; if N1L + N2L >= $0A, then add (N2 & $F0) + $0F + 1 (carry is set) - ; -027a : 750f adc N2H,x -027c : 08 php -027d : b004 bcs A2 -027f : c9a0 cmp #$A0 -0281 : 9003 bcc A3 -0283 : 695f A2 adc #$5F ; add $60 (carry is set) -0285 : 38 sec -0286 : 8506 A3 sta AR ; predicted accumulator result -0288 : 08 php -0289 : 68 pla -028a : 850a sta CF ; predicted carry result -028c : 68 pla - ; - ; note that all 8 bits of the P register are stored in VF - ; -028d : 8508 sta VF ; predicted V flags -028f : 60 rts - - ; Calculate the actual decimal mode accumulator and flags, and the - ; accumulator and flag results when N2 is subtracted from N1 using binary - ; arithmetic - ; -0290 : f8 SUB sed ; decimal mode -0291 : c001 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 -0293 : a500 lda N1 -0295 : e501 sbc N2 -0297 : 8504 sta DA ; actual accumulator result in decimal mode -0299 : 08 php -029a : 68 pla -029b : 8505 sta DNVZC ; actual flags result in decimal mode -029d : d8 cld ; binary mode -029e : c001 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 -02a0 : a500 lda N1 -02a2 : e501 sbc N2 -02a4 : 8502 sta HA ; accumulator result of N1-N2 using binary arithmetic - -02a6 : 08 php -02a7 : 68 pla -02a8 : 8503 sta HNVZC ; flags result of N1-N2 using binary arithmetic -02aa : 60 rts - - if cputype != 1 - ; Calculate the predicted SBC accumulator result for the 6502 and 65816 - ; - SUB1 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 - lda N1L - sbc N2L - ldx #0 - bcs S11 - inx - sbc #5 ; subtract 6 (carry is clear) - and #$0F - clc - S11 ora N1H - ; - ; if N1L - N2L >= 0, then subtract N2 & $F0 - ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) - ; - sbc N2H,x - bcs S12 - sbc #$5F ; subtract $60 (carry is clear) - S12 sta AR - rts - endif - - if cputype = 1 - ; Calculate the predicted SBC accumulator result for the 6502 and 65C02 - ; -02ab : c001 SUB2 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 -02ad : a50c lda N1L -02af : e50e sbc N2L -02b1 : a200 ldx #0 -02b3 : b004 bcs S21 -02b5 : e8 inx -02b6 : 290f and #$0F -02b8 : 18 clc -02b9 : 050d S21 ora N1H - ; - ; if N1L - N2L >= 0, then subtract N2 & $F0 - ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) - ; -02bb : f50f sbc N2H,x -02bd : b002 bcs S22 -02bf : e95f sbc #$5F ; subtract $60 (carry is clear) -02c1 : e000 S22 cpx #0 -02c3 : f002 beq S23 -02c5 : e906 sbc #6 -02c7 : 8506 S23 sta AR ; predicted accumulator result -02c9 : 60 rts - endif - - ; Compare accumulator actual results to predicted results - ; - ; Return: - ; Z flag = 1 (BEQ branch) if same - ; Z flag = 0 (BNE branch) if different - ; -02ca : COMPARE - if chk_a = 1 -02ca : a504 lda DA -02cc : c506 cmp AR -02ce : d01e bne C1 - endif - if chk_n = 1 -02d0 : a505 lda DNVZC ; [7] see text -02d2 : 4507 eor NF -02d4 : 2980 and #$80 ; mask off N flag -02d6 : d016 bne C1 - endif - if chk_v = 1 -02d8 : a505 lda DNVZC ; [8] see text -02da : 4508 eor VF -02dc : 2940 and #$40 ; mask off V flag -02de : d00e bne C1 ; [9] see text - endif - if chk_z = 1 -02e0 : a505 lda DNVZC -02e2 : 4509 eor ZF ; mask off Z flag -02e4 : 2902 and #2 -02e6 : d006 bne C1 ; [10] see text - endif - if chk_c = 1 -02e8 : a505 lda DNVZC -02ea : 450a eor CF -02ec : 2901 and #1 ; mask off C flag - endif -02ee : 60 C1 rts - - ; These routines store the predicted values for ADC and SBC for the 6502, - ; 65C02, and 65816 in AR, CF, NF, VF, and ZF - - if cputype = 0 - - A6502 lda VF ; 6502 - ; - ; since all 8 bits of the P register were stored in VF, bit 7 of VF contains - ; the N flag for NF - ; - sta NF - lda HNVZC - sta ZF - rts - - S6502 jsr SUB1 - lda HNVZC - sta NF - sta VF - sta ZF - sta CF - rts - - endif - if cputype = 1 - -02ef : a506 A6502 lda AR ; 65C02 -02f1 : 08 php -02f2 : 68 pla -02f3 : 8507 sta NF -02f5 : 8509 sta ZF -02f7 : 60 rts - -02f8 : 20ab02 S6502 jsr SUB2 -02fb : a506 lda AR -02fd : 08 php -02fe : 68 pla -02ff : 8507 sta NF -0301 : 8509 sta ZF -0303 : a503 lda HNVZC -0305 : 8508 sta VF -0307 : 850a sta CF -0309 : 60 rts - - endif - if cputype = 2 - - A6502 lda AR ; 65C816 - php - pla - sta NF - sta ZF - rts - - S6502 jsr SUB1 - lda AR - php - pla - sta NF - sta ZF - lda HNVZC - sta VF - sta CF - rts - - endif - -02f8 = end TEST - -No errors in pass 2. -Wrote binary from address $0200 through $0309. -Total size 266 bytes. -Program start address is at $0200 (512). - \ No newline at end of file +000000r 1 ; Verify decimal mode behavior +000000r 1 ; Written by Bruce Clark. This code is public domain. +000000r 1 ; see http://www.6502.org/tutorials/decimal_mode.html +000000r 1 ; +000000r 1 ; Returns: +000000r 1 ; ERROR = 0 if the test passed +000000r 1 ; ERROR = 1 if the test failed +000000r 1 ; modify the code at the DONE label for desired program end +000000r 1 ; +000000r 1 ; This routine requires 17 bytes of RAM -- 1 byte each for: +000000r 1 ; AR, CF, DA, DNVZC, ERROR, HA, HNVZC, N1, N1H, N1L, N2, N2L, NF, VF, and ZF +000000r 1 ; and 2 bytes for N2H +000000r 1 ; +000000r 1 ; Variables: +000000r 1 ; N1 and N2 are the two numbers to be added or subtracted +000000r 1 ; N1H, N1L, N2H, and N2L are the upper 4 bits and lower 4 bits of N1 and N2 +000000r 1 ; DA and DNVZC are the actual accumulator and flag results in decimal mode +000000r 1 ; HA and HNVZC are the accumulator and flag results when N1 and N2 are +000000r 1 ; added or subtracted using binary arithmetic +000000r 1 ; AR, NF, VF, ZF, and CF are the predicted decimal mode accumulator and +000000r 1 ; flag results, calculated using binary arithmetic +000000r 1 ; +000000r 1 ; This program takes approximately 1 minute at 1 MHz (a few seconds more on +000000r 1 ; a 65C02 than a 6502 or 65816) +000000r 1 ; +000000r 1 +000000r 1 ; Configuration: +000000r 1 cputype = 1 ; 0 = 6502, 1 = 65C02, 2 = 65C816 +000000r 1 vld_bcd = 0 ; 0 = allow invalid bcd, 1 = valid bcd only +000000r 1 chk_a = 1 ; check accumulator +000000r 1 chk_n = 1 ; check sign (negative) flag +000000r 1 chk_v = 1 ; check overflow flag +000000r 1 chk_z = 1 ; check zero flag +000000r 1 chk_c = 1 ; check carry flag +000000r 1 +000000r 1 .macro end_of_test +000000r 1 BRK +000000r 1 ; .byte $db ;execute 65C02 stop instruction +000000r 1 .endmacro +000000r 1 +000000r 1 .ZEROPAGE +000000r 1 .org 0 +000000 1 ; operands - register Y = carry in +000000 1 00 N1: .res 1,0 +000001 1 00 N2: .res 1,0 +000002 1 ; binary result +000002 1 00 HA: .res 1,0 +000003 1 00 HNVZC: .res 1,0 +000004 1 ;04 +000004 1 ; decimal result +000004 1 00 DA: .res 1,0 +000005 1 00 DNVZC: .res 1,0 +000006 1 ; predicted results +000006 1 00 AR: .res 1,0 +000007 1 00 NF: .res 1,0 +000008 1 ;08 +000008 1 00 VF: .res 1,0 +000009 1 00 ZF: .res 1,0 +00000A 1 00 CF: .res 1,0 +00000B 1 00 ERROR: .res 1,0 +00000C 1 ;0C +00000C 1 ; workspace +00000C 1 00 N1L: .res 1,0 +00000D 1 00 N1H: .res 1,0 +00000E 1 00 N2L: .res 1,0 +00000F 1 00 00 N2H: .res 2,0 +000011 1 +000011 1 .CODE +000011 1 .org $200 +000200 1 A0 01 TEST: ldy #1 ; initialize Y (used to loop through carry flag values) +000202 1 84 0B sty ERROR ; store 1 in ERROR until the test passes +000204 1 A9 00 lda #0 ; initialize N1 and N2 +000206 1 85 00 sta N1 +000208 1 85 01 sta N2 +00020A 1 A5 01 LOOP1: lda N2 ; N2L = N2 & $0F +00020C 1 29 0F and #$0F ; [1] see text +00020E 1 .if vld_bcd = 1 +00020E 1 cmp #$0a +00020E 1 bcs NEXT2 +00020E 1 .endif +00020E 1 85 0E sta N2L +000210 1 A5 01 lda N2 ; N2H = N2 & $F0 +000212 1 29 F0 and #$F0 ; [2] see text +000214 1 .if vld_bcd = 1 +000214 1 cmp #$a0 +000214 1 bcs NEXT2 +000214 1 .endif +000214 1 85 0F sta N2H +000216 1 09 0F ora #$0F ; N2H+1 = (N2 & $F0) + $0F +000218 1 85 10 sta N2H+1 +00021A 1 A5 00 LOOP2: lda N1 ; N1L = N1 & $0F +00021C 1 29 0F and #$0F ; [3] see text +00021E 1 .if vld_bcd = 1 +00021E 1 cmp #$0a +00021E 1 bcs NEXT1 +00021E 1 .endif +00021E 1 85 0C sta N1L +000220 1 A5 00 lda N1 ; N1H = N1 & $F0 +000222 1 29 F0 and #$F0 ; [4] see text +000224 1 .if vld_bcd = 1 +000224 1 cmp #$a0 +000224 1 bcs NEXT1 +000224 1 .endif +000224 1 85 0D sta N1H +000226 1 20 4C 02 jsr ADD +000229 1 20 EF 02 jsr A6502 +00022C 1 20 CA 02 jsr COMPARE +00022F 1 D0 1A bne DONE +000231 1 20 90 02 jsr SUB +000234 1 20 F8 02 jsr S6502 +000237 1 20 CA 02 jsr COMPARE +00023A 1 D0 0F bne DONE +00023C 1 E6 00 NEXT1: inc N1 ; [5] see text +00023E 1 D0 DA bne LOOP2 ; loop through all 256 values of N1 +000240 1 E6 01 NEXT2: inc N2 ; [6] see text +000242 1 D0 C6 bne LOOP1 ; loop through all 256 values of N2 +000244 1 88 dey +000245 1 10 C3 bpl LOOP1 ; loop through both values of the carry flag +000247 1 A9 00 lda #0 ; test passed, so store 0 in ERROR +000249 1 85 0B sta ERROR +00024B 1 DONE: +00024B 1 00 end_of_test +00024C 1 +00024C 1 ; Calculate the actual decimal mode accumulator and flags, the accumulator +00024C 1 ; and flag results when N1 is added to N2 using binary arithmetic, the +00024C 1 ; predicted accumulator result, the predicted carry flag, and the predicted +00024C 1 ; V flag +00024C 1 ; +00024C 1 F8 ADD: sed ; decimal mode +00024D 1 C0 01 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +00024F 1 A5 00 lda N1 +000251 1 65 01 adc N2 +000253 1 85 04 sta DA ; actual accumulator result in decimal mode +000255 1 08 php +000256 1 68 pla +000257 1 85 05 sta DNVZC ; actual flags result in decimal mode +000259 1 D8 cld ; binary mode +00025A 1 C0 01 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +00025C 1 A5 00 lda N1 +00025E 1 65 01 adc N2 +000260 1 85 02 sta HA ; accumulator result of N1+N2 using binary arithmetic +000262 1 +000262 1 08 php +000263 1 68 pla +000264 1 85 03 sta HNVZC ; flags result of N1+N2 using binary arithmetic +000266 1 C0 01 cpy #1 +000268 1 A5 0C lda N1L +00026A 1 65 0E adc N2L +00026C 1 C9 0A cmp #$0A +00026E 1 A2 00 ldx #0 +000270 1 90 06 bcc A1 +000272 1 E8 inx +000273 1 69 05 adc #5 ; add 6 (carry is set) +000275 1 29 0F and #$0F +000277 1 38 sec +000278 1 05 0D A1: ora N1H +00027A 1 ; +00027A 1 ; if N1L + N2L < $0A, then add N2 & $F0 +00027A 1 ; if N1L + N2L >= $0A, then add (N2 & $F0) + $0F + 1 (carry is set) +00027A 1 ; +00027A 1 75 0F adc N2H,x +00027C 1 08 php +00027D 1 B0 04 bcs A2 +00027F 1 C9 A0 cmp #$A0 +000281 1 90 03 bcc A3 +000283 1 69 5F A2: adc #$5F ; add $60 (carry is set) +000285 1 38 sec +000286 1 85 06 A3: sta AR ; predicted accumulator result +000288 1 08 php +000289 1 68 pla +00028A 1 85 0A sta CF ; predicted carry result +00028C 1 68 pla +00028D 1 ; +00028D 1 ; note that all 8 bits of the P register are stored in VF +00028D 1 ; +00028D 1 85 08 sta VF ; predicted V flags +00028F 1 60 rts +000290 1 +000290 1 ; Calculate the actual decimal mode accumulator and flags, and the +000290 1 ; accumulator and flag results when N2 is subtracted from N1 using binary +000290 1 ; arithmetic +000290 1 ; +000290 1 F8 SUB: sed ; decimal mode +000291 1 C0 01 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +000293 1 A5 00 lda N1 +000295 1 E5 01 sbc N2 +000297 1 85 04 sta DA ; actual accumulator result in decimal mode +000299 1 08 php +00029A 1 68 pla +00029B 1 85 05 sta DNVZC ; actual flags result in decimal mode +00029D 1 D8 cld ; binary mode +00029E 1 C0 01 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +0002A0 1 A5 00 lda N1 +0002A2 1 E5 01 sbc N2 +0002A4 1 85 02 sta HA ; accumulator result of N1-N2 using binary arithmetic +0002A6 1 +0002A6 1 08 php +0002A7 1 68 pla +0002A8 1 85 03 sta HNVZC ; flags result of N1-N2 using binary arithmetic +0002AA 1 60 rts +0002AB 1 +0002AB 1 .if cputype <> 1 +0002AB 1 ; Calculate the predicted SBC accumulator result for the 6502 and 65816 +0002AB 1 ; +0002AB 1 SUB1: cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +0002AB 1 lda N1L +0002AB 1 sbc N2L +0002AB 1 ldx #0 +0002AB 1 bcs S11 +0002AB 1 inx +0002AB 1 sbc #5 ; subtract 6 (carry is clear) +0002AB 1 and #$0F +0002AB 1 clc +0002AB 1 S11: ora N1H +0002AB 1 ; +0002AB 1 ; if N1L - N2L >= 0, then subtract N2 & $F0 +0002AB 1 ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) +0002AB 1 ; +0002AB 1 sbc N2H,x +0002AB 1 bcs S12 +0002AB 1 sbc #$5F ; subtract $60 (carry is clear) +0002AB 1 S12: sta AR +0002AB 1 rts +0002AB 1 .endif +0002AB 1 +0002AB 1 .if cputype = 1 +0002AB 1 ; Calculate the predicted SBC accumulator result for the 6502 and 65C02 +0002AB 1 ; +0002AB 1 C0 01 SUB2: cpy #1 ; set carry if Y = 1, clear carry if Y = 0 +0002AD 1 A5 0C lda N1L +0002AF 1 E5 0E sbc N2L +0002B1 1 A2 00 ldx #0 +0002B3 1 B0 04 bcs S21 +0002B5 1 E8 inx +0002B6 1 29 0F and #$0F +0002B8 1 18 clc +0002B9 1 05 0D S21: ora N1H +0002BB 1 ; +0002BB 1 ; if N1L - N2L >= 0, then subtract N2 & $F0 +0002BB 1 ; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) +0002BB 1 ; +0002BB 1 F5 0F sbc N2H,x +0002BD 1 B0 02 bcs S22 +0002BF 1 E9 5F sbc #$5F ; subtract $60 (carry is clear) +0002C1 1 E0 00 S22: cpx #0 +0002C3 1 F0 02 beq S23 +0002C5 1 E9 06 sbc #6 +0002C7 1 85 06 S23: sta AR ; predicted accumulator result +0002C9 1 60 rts +0002CA 1 .endif +0002CA 1 +0002CA 1 ; Compare accumulator actual results to predicted results +0002CA 1 ; +0002CA 1 ; Return: +0002CA 1 ; Z flag = 1 (BEQ branch) if same +0002CA 1 ; Z flag = 0 (BNE branch) if different +0002CA 1 ; +0002CA 1 COMPARE: +0002CA 1 .if chk_a = 1 +0002CA 1 A5 04 lda DA +0002CC 1 C5 06 cmp AR +0002CE 1 D0 1E bne C1 +0002D0 1 .endif +0002D0 1 .if chk_n = 1 +0002D0 1 A5 05 lda DNVZC ; [7] see text +0002D2 1 45 07 eor NF +0002D4 1 29 80 and #$80 ; mask off N flag +0002D6 1 D0 16 bne C1 +0002D8 1 .endif +0002D8 1 .if chk_v = 1 +0002D8 1 A5 05 lda DNVZC ; [8] see text +0002DA 1 45 08 eor VF +0002DC 1 29 40 and #$40 ; mask off V flag +0002DE 1 D0 0E bne C1 ; [9] see text +0002E0 1 .endif +0002E0 1 .if chk_z = 1 +0002E0 1 A5 05 lda DNVZC +0002E2 1 45 09 eor ZF ; mask off Z flag +0002E4 1 29 02 and #2 +0002E6 1 D0 06 bne C1 ; [10] see text +0002E8 1 .endif +0002E8 1 .if chk_c = 1 +0002E8 1 A5 05 lda DNVZC +0002EA 1 45 0A eor CF +0002EC 1 29 01 and #1 ; mask off C flag +0002EE 1 .endif +0002EE 1 60 C1: rts +0002EF 1 +0002EF 1 ; These routines store the predicted values for ADC and SBC for the 6502, +0002EF 1 ; 65C02, and 65816 in AR, CF, NF, VF, and ZF +0002EF 1 +0002EF 1 .if cputype = 0 +0002EF 1 +0002EF 1 A6502: lda VF ; 6502 +0002EF 1 ; +0002EF 1 ; since all 8 bits of the P register were stored in VF, bit 7 of VF contains +0002EF 1 ; the N flag for NF +0002EF 1 ; +0002EF 1 sta NF +0002EF 1 lda HNVZC +0002EF 1 sta ZF +0002EF 1 rts +0002EF 1 +0002EF 1 S6502: jsr SUB1 +0002EF 1 lda HNVZC +0002EF 1 sta NF +0002EF 1 sta VF +0002EF 1 sta ZF +0002EF 1 sta CF +0002EF 1 rts +0002EF 1 +0002EF 1 .endif +0002EF 1 .if cputype = 1 +0002EF 1 +0002EF 1 A5 06 A6502: lda AR ; 65C02 +0002F1 1 08 php +0002F2 1 68 pla +0002F3 1 85 07 sta NF +0002F5 1 85 09 sta ZF +0002F7 1 60 rts +0002F8 1 +0002F8 1 20 AB 02 S6502: jsr SUB2 +0002FB 1 A5 06 lda AR +0002FD 1 08 php +0002FE 1 68 pla +0002FF 1 85 07 sta NF +000301 1 85 09 sta ZF +000303 1 A5 03 lda HNVZC +000305 1 85 08 sta VF +000307 1 85 0A sta CF +000309 1 60 rts +00030A 1 +00030A 1 .endif +00030A 1 .if cputype = 2 +00030A 1 +00030A 1 A6502: lda AR ; 65C816 +00030A 1 php +00030A 1 pla +00030A 1 sta NF +00030A 1 sta ZF +00030A 1 rts +00030A 1 +00030A 1 S6502: jsr SUB1 +00030A 1 lda AR +00030A 1 php +00030A 1 pla +00030A 1 sta NF +00030A 1 sta ZF +00030A 1 lda HNVZC +00030A 1 sta VF +00030A 1 sta CF +00030A 1 rts +00030A 1 +00030A 1 .endif +00030A 1