ca65 V2.18 - N/A Main file : ./6502_65C02_functional_tests/ca65/65C02_extended_opcodes_test.ca65 Current file: ./6502_65C02_functional_tests/ca65/65C02_extended_opcodes_test.ca65 000000r 1 ; 000000r 1 ; 6 5 C 0 2 E X T E N D E D O P C O D E S T E S T 000000r 1 ; 000000r 1 ; Copyright (C) 2013-2017 Klaus Dormann 000000r 1 ; 000000r 1 ; This program is free software: you can redistribute it and/or modify 000000r 1 ; it under the terms of the GNU General Public License as published by 000000r 1 ; the Free Software Foundation, either version 3 of the License, or 000000r 1 ; (at your option) any later version. 000000r 1 ; 000000r 1 ; This program is distributed in the hope that it will be useful, 000000r 1 ; but WITHOUT ANY WARRANTY; without even the implied warranty of 000000r 1 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 000000r 1 ; GNU General Public License for more details. 000000r 1 ; 000000r 1 ; You should have received a copy of the GNU General Public License 000000r 1 ; along with this program. If not, see . 000000r 1 000000r 1 000000r 1 ; This program is designed to test all additional 65C02 opcodes, addressing 000000r 1 ; modes and functionality not available in the NMOS version of the 6502. 000000r 1 ; The 6502_functional_test is a prerequisite to this test. 000000r 1 ; NMI, IRQ, STP & WAI are covered in the 6502_interrupt_test. 000000r 1 ; 000000r 1 ; version 04-dec-2017 000000r 1 ; contact info at http://2m5.de or email K@2m5.de 000000r 1 ; 000000r 1 ; assembled with CA65, linked with LD65 (cc65.github.io): 000000r 1 ; ca65 -l 6502_functional_test.lst 6502_functional_test.ca65 000000r 1 ; ld65 6502_functional_test.o -o 6502_functional_test.bin \ 000000r 1 ; -m 6502_functional_test.map -C example.cfg 000000r 1 ; example linker config (example.cfg): 000000r 1 ; MEMORY { 000000r 1 ; RAM: start = $0000, size=$8000, type = rw, fill = yes, \ 000000r 1 ; fillval = $FF, file = %O; 000000r 1 ; ROM: start = $8000, size=$7FFA, type = ro, fill = yes, \ 000000r 1 ; fillval = $FF, file = %O; 000000r 1 ; ROM_VECTORS: start = $FFFA, size=6, type = ro, fill = yes, \ 000000r 1 ; fillval = $FF, file = %O; 000000r 1 ; } 000000r 1 ; SEGMENTS { 000000r 1 ; ZEROPAGE: load=RAM, type=rw; 000000r 1 ; DATA: load=RAM, type=rw, offset=$0200; 000000r 1 ; CODE: load=RAM, type=rw, offset=$0400; 000000r 1 ; VECTORS: load=ROM_VECTORS, type=ro; 000000r 1 ; } 000000r 1 ; 000000r 1 ; No IO - should be run from a monitor with access to registers. 000000r 1 ; To run load intel hex image with a load command, than alter PC to 400 hex 000000r 1 ; (code_segment) and enter a go command. 000000r 1 ; Loop on program counter determines error or successful completion of test. 000000r 1 ; Check listing for relevant traps (jump/branch *). 000000r 1 ; Please note that in early tests some instructions will have to be used before 000000r 1 ; they are actually tested! 000000r 1 ; 000000r 1 ; RESET, NMI or IRQ should not occur and will be trapped if vectors are enabled. 000000r 1 ; Tests documented behavior of the original 65C02 only! 000000r 1 ; Decimal ops will only be tested with valid BCD operands and the V flag will 000000r 1 ; be ignored as it is absolutely useless in decimal mode. 000000r 1 ; 000000r 1 ; Debugging hints: 000000r 1 ; Most of the code is written sequentially. if you hit a trap, check the 000000r 1 ; immediately preceeding code for the instruction to be tested. Results are 000000r 1 ; tested first, flags are checked second by pushing them onto the stack and 000000r 1 ; pulling them to the accumulator after the result was checked. The "real" 000000r 1 ; flags are no longer valid for the tested instruction at this time! 000000r 1 ; If the tested instruction was indexed, the relevant index (X or Y) must 000000r 1 ; also be checked. Opposed to the flags, X and Y registers are still valid. 000000r 1 ; 000000r 1 ; versions: 000000r 1 ; 19-jul-2013 1st version distributed for testing 000000r 1 ; 23-jul-2013 fixed BRA out of range due to larger trap macros 000000r 1 ; added RAM integrity check 000000r 1 ; 16-aug-2013 added error report to standard output option 000000r 1 ; 23-aug-2015 change revoked 000000r 1 ; 24-aug-2015 all self modifying immediate opcodes now execute in data RAM 000000r 1 ; 28-aug-2015 fixed decimal adc/sbc immediate only testing carry 000000r 1 ; 09-feb-2017 fixed RMB/SMB tested when they shouldn't be tested 000000r 1 ; 04-dec-2017 fixed BRK not tested for actually going through the IRQ vector 000000r 1 ; added option to skip the remainder of a failing test 000000r 1 ; in report.i65 000000r 1 ; added skip override to undefined opcode as NOP test 000000r 1 000000r 1 000000r 1 ; C O N F I G U R A T I O N 000000r 1 000000r 1 ;ROM_vectors writable (0=no, 1=yes) 000000r 1 ;if ROM vectors can not be used interrupts will not be trapped 000000r 1 ;as a consequence BRK can not be tested but will be emulated to test RTI 000000r 1 ROM_vectors = 1 000000r 1 000000r 1 ;load_data_direct (0=move from code segment, 1=load directly) 000000r 1 ;loading directly is preferred but may not be supported by your platform 000000r 1 ;0 produces only consecutive object code, 1 is not suitable for a binary image 000000r 1 load_data_direct = 1 000000r 1 000000r 1 ;I_flag behavior (0=force enabled, 1=force disabled, 2=prohibit change, 3=allow 000000r 1 ;change) 2 requires extra code and is not recommended. 000000r 1 I_flag = 3 000000r 1 000000r 1 ;configure memory - try to stay away from memory used by the system 000000r 1 ;zero_page memory start address, $4e (78) consecutive Bytes required 000000r 1 ; add 2 if I_flag = 2 000000r 1 zero_page = $a 000000r 1 000000r 1 ;data_segment memory start address, $63 (99) consecutive Bytes required 000000r 1 ; + 12 Bytes at data_segment + $f9 (JMP indirect page cross test) 000000r 1 data_segment = $200 000000r 1 .if (data_segment & $ff) <> 0 000000r 1 .error "low byte of data_segment MUST be $00 !!" 000000r 1 .endif 000000r 1 000000r 1 ;code_segment memory start address, 10kB of consecutive space required 000000r 1 ; add 1 kB if I_flag = 2 000000r 1 code_segment = $400 000000r 1 000000r 1 ;added WDC only opcodes WAI & STP (0=test as NOPs, >0=no test) 000000r 1 wdc_op = 1 000000r 1 000000r 1 ;added Rockwell & WDC opcodes BBR, BBS, RMB & SMB 000000r 1 ;(0=test as NOPs, 1=full test, >1=no test) 000000r 1 rkwl_wdc_op = 1 000000r 1 000000r 1 ;skip testing all undefined opcodes override 000000r 1 ;0=test as NOP, >0=skip 000000r 1 skip_nop = 0 000000r 1 000000r 1 ;report errors through I/O channel (0=use standard self trap loops, 1=include 000000r 1 ;report.i65 as I/O channel, add 3 kB) 000000r 1 report = 0 000000r 1 000000r 1 ;RAM integrity test option. Checks for undesired RAM writes. 000000r 1 ;set lowest non RAM or RAM mirror address page (-1=disable, 0=64k, $40=16k) 000000r 1 ;leave disabled if a monitor, OS or background interrupt is allowed to alter RAM 000000r 1 ram_top = -1 000000r 1 000000r 1 ; E N D O F C O N F I G U R A T I O N 000000r 1 000000r 1 ;macros for error & success traps to allow user modification 000000r 1 ;example: 000000r 1 ; .macro trap 000000r 1 ; jsr my_error_handler 000000r 1 ; .endmacro 000000r 1 ; .macro trap_eq 000000r 1 ; bne :+ 000000r 1 ; trap ;failed equal (zero) 000000r 1 ;: 000000r 1 ; .endmacro 000000r 1 ; 000000r 1 ; my_error_handler should pop the calling address from the stack and report it. 000000r 1 ; putting larger portions of code (more than 3 bytes) inside the trap macro 000000r 1 ; may lead to branch range problems for some tests. 000000r 1 .if report = 0 000000r 1 .macro trap 000000r 1 jmp * ;failed anyway 000000r 1 .endmacro 000000r 1 .macro trap_eq 000000r 1 beq * ;failed equal (zero) 000000r 1 .endmacro 000000r 1 .macro trap_ne 000000r 1 bne * ;failed not equal (non zero) 000000r 1 .endmacro 000000r 1 .macro trap_cs 000000r 1 bcs * ;failed carry set 000000r 1 .endmacro 000000r 1 .macro trap_cc 000000r 1 bcc * ;failed carry clear 000000r 1 .endmacro 000000r 1 .macro trap_mi 000000r 1 bmi * ;failed minus (bit 7 set) 000000r 1 .endmacro 000000r 1 .macro trap_pl 000000r 1 bpl * ;failed plus (bit 7 clear) 000000r 1 .endmacro 000000r 1 .macro trap_vs 000000r 1 bvs * ;failed overflow set 000000r 1 .endmacro 000000r 1 .macro trap_vc 000000r 1 bvc * ;failed overflow clear 000000r 1 .endmacro 000000r 1 ; please observe that during the test the stack gets invalidated 000000r 1 ; therefore a RTS inside the success macro is not possible 000000r 1 .macro success 000000r 1 jmp * ;test passed, no errors 000000r 1 .endmacro 000000r 1 .endif 000000r 1 .if report = 1 000000r 1 .macro trap 000000r 1 jsr report_error 000000r 1 .endmacro 000000r 1 .macro trap_eq 000000r 1 bne :+ 000000r 1 trap ;failed equal (zero) 000000r 1 : 000000r 1 .endmacro 000000r 1 .macro trap_ne 000000r 1 beq :+ 000000r 1 trap ;failed not equal (non zero) 000000r 1 : 000000r 1 .endmacro 000000r 1 .macro trap_cs 000000r 1 bcc :+ 000000r 1 trap ;failed carry set 000000r 1 : 000000r 1 .endmacro 000000r 1 .macro trap_cc 000000r 1 bcs :+ 000000r 1 trap ;failed carry clear 000000r 1 : 000000r 1 .endmacro 000000r 1 .macro trap_mi 000000r 1 bpl :+ 000000r 1 trap ;failed minus (bit 7 set) 000000r 1 : 000000r 1 .endmacro 000000r 1 .macro trap_pl 000000r 1 bmi :+ 000000r 1 trap ;failed plus (bit 7 clear) 000000r 1 : 000000r 1 .endmacro 000000r 1 .macro trap_vs 000000r 1 bvc :+ 000000r 1 trap ;failed overflow set 000000r 1 : 000000r 1 .endmacro 000000r 1 .macro trap_vc 000000r 1 bvs :+ 000000r 1 trap ;failed overflow clear 000000r 1 : 000000r 1 .endmacro 000000r 1 ; please observe that during the test the stack gets invalidated 000000r 1 ; therefore a RTS inside the success macro is not possible 000000r 1 .macro success 000000r 1 jsr report_success 000000r 1 .endmacro 000000r 1 .endif 000000r 1 000000r 1 .define equ = 000000r 1 000000r 1 carry equ %00000001 ;flag bits in status 000000r 1 zero equ %00000010 000000r 1 intdis equ %00000100 000000r 1 decmode equ %00001000 000000r 1 break equ %00010000 000000r 1 reserv equ %00100000 000000r 1 overfl equ %01000000 000000r 1 minus equ %10000000 000000r 1 000000r 1 fc equ carry 000000r 1 fz equ zero 000000r 1 fzc equ carry+zero 000000r 1 fv equ overfl 000000r 1 fvz equ overfl+zero 000000r 1 fn equ minus 000000r 1 fnc equ minus+carry 000000r 1 fnz equ minus+zero 000000r 1 fnzc equ minus+zero+carry 000000r 1 fnv equ minus+overfl 000000r 1 000000r 1 fao equ break+reserv ;bits always on after PHP, BRK 000000r 1 fai equ fao+intdis ;+ forced interrupt disable 000000r 1 m8 equ $ff ;8 bit mask 000000r 1 m8i equ $ff&~intdis ;8 bit mask - interrupt disable 000000r 1 000000r 1 ;macros to allow masking of status bits. 000000r 1 ;masking of interrupt enable/disable on load and compare 000000r 1 ;masking of always on bits after PHP or BRK (unused & break) on compare 000000r 1 .if I_flag = 0 000000r 1 .macro load_flag p1 000000r 1 lda #p1&m8i ;force enable interrupts (mask I) 000000r 1 .endmacro 000000r 1 .macro cmp_flag p1 000000r 1 cmp #(p1|fao)&m8i ;I_flag is always enabled + always on bits 000000r 1 .endmacro 000000r 1 .macro eor_flag p1 000000r 1 eor #(p1&m8i|fao) ;mask I, invert expected flags + always on bits 000000r 1 .endmacro 000000r 1 .endif 000000r 1 .if I_flag = 1 000000r 1 .macro load_flag p1 000000r 1 lda #p1|intdis ;force disable interrupts 000000r 1 .endmacro 000000r 1 .macro cmp_flag p1 000000r 1 cmp #(p1|fai)&m8 ;I_flag is always disabled + always on bits 000000r 1 .endmacro 000000r 1 .macro eor_flag p1 000000r 1 eor #(p1|fai) ;invert expected flags + always on bits + I 000000r 1 .endmacro 000000r 1 .endif 000000r 1 .if I_flag = 2 000000r 1 .macro load_flag p1 000000r 1 lda #p1 000000r 1 ora flag_I_on ;restore I-flag 000000r 1 and flag_I_off 000000r 1 .endmacro 000000r 1 .macro cmp_flag p1 000000r 1 eor flag_I_on ;I_flag is never changed 000000r 1 cmp #(p1|fao)&m8i ;expected flags + always on bits, mask I 000000r 1 .endmacro 000000r 1 .macro eor_flag p1 000000r 1 eor flag_I_on ;I_flag is never changed 000000r 1 eor #(p1&m8i|fao) ;mask I, invert expected flags + always on bits 000000r 1 .endmacro 000000r 1 .endif 000000r 1 .if I_flag = 3 000000r 1 .macro load_flag p1 000000r 1 lda #p1 ;allow test to change I-flag (no mask) 000000r 1 .endmacro 000000r 1 .macro cmp_flag p1 000000r 1 cmp #(p1|fao)&m8 ;expected flags + always on bits 000000r 1 .endmacro 000000r 1 .macro eor_flag p1 000000r 1 eor #p1|fao ;invert expected flags + always on bits 000000r 1 .endmacro 000000r 1 .endif 000000r 1 000000r 1 ;macros to set (register|memory|zeropage) & status 000000r 1 .macro set_stat p1 ;setting flags in the processor status register 000000r 1 load_flag p1 000000r 1 pha ;use stack to load status 000000r 1 plp 000000r 1 .endmacro 000000r 1 000000r 1 .macro set_a p1,p2 ;precharging accu & status 000000r 1 load_flag p2 000000r 1 pha ;use stack to load status 000000r 1 lda #p1 ;precharge accu 000000r 1 plp 000000r 1 .endmacro 000000r 1 000000r 1 .macro set_x p1,p2 ;precharging index & status 000000r 1 load_flag p2 000000r 1 pha ;use stack to load status 000000r 1 ldx #p1 ;precharge index x 000000r 1 plp 000000r 1 .endmacro 000000r 1 000000r 1 .macro set_y p1,p2 ;precharging index & status 000000r 1 load_flag p2 000000r 1 pha ;use stack to load status 000000r 1 ldy #p1 ;precharge index y 000000r 1 plp 000000r 1 .endmacro 000000r 1 000000r 1 .macro set_ax p1,p2 ;precharging indexed accu & immediate status 000000r 1 load_flag p2 000000r 1 pha ;use stack to load status 000000r 1 lda p1,x ;precharge accu 000000r 1 plp 000000r 1 .endmacro 000000r 1 000000r 1 .macro set_ay p1,p2 ;precharging indexed accu & immediate status 000000r 1 load_flag p2 000000r 1 pha ;use stack to load status 000000r 1 lda p1,y ;precharge accu 000000r 1 plp 000000r 1 .endmacro 000000r 1 000000r 1 .macro set_z p1,p2 ;precharging indexed zp & immediate status 000000r 1 load_flag p2 000000r 1 pha ;use stack to load status 000000r 1 lda p1,x ;load to zeropage 000000r 1 sta zpt 000000r 1 plp 000000r 1 .endmacro 000000r 1 000000r 1 .macro set_zx p1,p2 ;precharging zp,x & immediate status 000000r 1 load_flag p2 000000r 1 pha ;use stack to load status 000000r 1 lda p1,x ;load to indexed zeropage 000000r 1 sta zpt,x 000000r 1 plp 000000r 1 .endmacro 000000r 1 000000r 1 .macro set_abs p1,p2 ;precharging indexed memory & immediate status 000000r 1 load_flag p2 000000r 1 pha ;use stack to load status 000000r 1 lda p1,x ;load to memory 000000r 1 sta abst 000000r 1 plp 000000r 1 .endmacro 000000r 1 000000r 1 .macro set_absx p1,p2 ;precharging abs,x & immediate status 000000r 1 load_flag p2 000000r 1 pha ;use stack to load status 000000r 1 lda p1,x ;load to indexed memory 000000r 1 sta abst,x 000000r 1 plp 000000r 1 .endmacro 000000r 1 000000r 1 ;macros to test (register|memory|zeropage) & status & (mask) 000000r 1 .macro tst_stat p1 ;testing flags in the processor status register 000000r 1 php ;save status 000000r 1 pla ;use stack to retrieve status 000000r 1 pha 000000r 1 cmp_flag p1 000000r 1 trap_ne 000000r 1 plp ;restore status 000000r 1 .endmacro 000000r 1 000000r 1 .macro tst_a p1,p2 ;testing result in accu & flags 000000r 1 php ;save flags 000000r 1 cmp #p1 ;test result 000000r 1 trap_ne 000000r 1 pla ;load status 000000r 1 pha 000000r 1 cmp_flag p2 000000r 1 trap_ne 000000r 1 plp ;restore status 000000r 1 .endmacro 000000r 1 000000r 1 .macro tst_as p1,p2 ;testing result in accu & flags, save accu 000000r 1 pha 000000r 1 php ;save flags 000000r 1 cmp #p1 ;test result 000000r 1 trap_ne 000000r 1 pla ;load status 000000r 1 pha 000000r 1 cmp_flag p2 000000r 1 trap_ne 000000r 1 plp ;restore status 000000r 1 pla 000000r 1 .endmacro 000000r 1 000000r 1 .macro tst_x p1,p2 ;testing result in x index & flags 000000r 1 php ;save flags 000000r 1 cpx #p1 ;test result 000000r 1 trap_ne 000000r 1 pla ;load status 000000r 1 pha 000000r 1 cmp_flag p2 000000r 1 trap_ne 000000r 1 plp ;restore status 000000r 1 .endmacro 000000r 1 000000r 1 .macro tst_y p1,p2 ;testing result in y index & flags 000000r 1 php ;save flags 000000r 1 cpy #p1 ;test result 000000r 1 trap_ne 000000r 1 pla ;load status 000000r 1 pha 000000r 1 cmp_flag p2 000000r 1 trap_ne 000000r 1 plp ;restore status 000000r 1 .endmacro 000000r 1 000000r 1 .macro tst_ax p1,p2,p3 ;indexed testing result in accu & flags 000000r 1 php ;save flags 000000r 1 cmp p1,x ;test result 000000r 1 trap_ne 000000r 1 pla ;load status 000000r 1 eor_flag p3 000000r 1 cmp p2,x ;test flags 000000r 1 trap_ne ; 000000r 1 .endmacro 000000r 1 000000r 1 .macro tst_ay p1,p2,p3 ;indexed testing result in accu & flags 000000r 1 php ;save flags 000000r 1 cmp p1,y ;test result 000000r 1 trap_ne ; 000000r 1 pla ;load status 000000r 1 eor_flag p3 000000r 1 cmp p2,y ;test flags 000000r 1 trap_ne 000000r 1 .endmacro 000000r 1 000000r 1 .macro tst_z p1,p2,p3 ;indexed testing result in zp & flags 000000r 1 php ;save flags 000000r 1 lda zpt 000000r 1 cmp p1,x ;test result 000000r 1 trap_ne 000000r 1 pla ;load status 000000r 1 eor_flag p3 000000r 1 cmp p2,x ;test flags 000000r 1 trap_ne 000000r 1 .endmacro 000000r 1 000000r 1 .macro tst_zx p1,p2,p3 ;testing result in zp,x & flags 000000r 1 php ;save flags 000000r 1 lda zpt,x 000000r 1 cmp p1,x ;test result 000000r 1 trap_ne 000000r 1 pla ;load status 000000r 1 eor_flag p3 000000r 1 cmp p2,x ;test flags 000000r 1 trap_ne 000000r 1 .endmacro 000000r 1 000000r 1 .macro tst_abs p1,p2,p3 ;indexed testing result in memory & flags 000000r 1 php ;save flags 000000r 1 lda abst 000000r 1 cmp p1,x ;test result 000000r 1 trap_ne 000000r 1 pla ;load status 000000r 1 eor_flag p3 000000r 1 cmp p2,x ;test flags 000000r 1 trap_ne 000000r 1 .endmacro 000000r 1 000000r 1 .macro tst_absx p1,p2,p3 ;testing result in abs,x & flags 000000r 1 php ;save flags 000000r 1 lda abst,x 000000r 1 cmp p1,x ;test result 000000r 1 trap_ne 000000r 1 pla ;load status 000000r 1 eor_flag p3 000000r 1 cmp p2,x ;test flags 000000r 1 trap_ne 000000r 1 .endmacro 000000r 1 000000r 1 ; RAM integrity test 000000r 1 ; verifies that none of the previous tests has altered RAM outside of the 000000r 1 ; designated write areas. 000000r 1 ; uses zpt word as indirect pointer, zpt+2 word as checksum 000000r 1 .if ram_top > -1 000000r 1 .macro check_ram 000000r 1 .local ccs1, ccs2, ccs3, ccs4, ccs5 000000r 1 cld 000000r 1 lda #0 000000r 1 sta zpt ;set low byte of indirect pointer 000000r 1 sta zpt+3 ;checksum high byte 000000r 1 ldx #11 ;reset modifiable RAM 000000r 1 ccs1: sta jxi_tab,x ;JMP indirect page cross area 000000r 1 dex 000000r 1 bpl ccs1 000000r 1 clc 000000r 1 ldx #zp_bss-zero_page ;zeropage - write test area 000000r 1 ccs3: adc zero_page,x 000000r 1 bcc ccs2 000000r 1 inc zpt+3 ;carry to high byte 000000r 1 clc 000000r 1 ccs2: inx 000000r 1 bne ccs3 000000r 1 ldx #>abs1 ;set high byte of indirect pointer 000000r 1 stx zpt+1 000000r 1 ldy # 1 000409 1 ldx #zp_end-zp_init-1 000409 1 ld_zp: lda zp_init,x 000409 1 sta zp_bss,x 000409 1 dex 000409 1 bpl ld_zp 000409 1 ldx #data_end-data_init-1 000409 1 ld_data:lda data_init,x 000409 1 sta data_bss,x 000409 1 dex 000409 1 bpl ld_data 000409 1 .if ROM_vectors = 1 000409 1 ldx #5 000409 1 ld_vect:lda vec_init,x 000409 1 sta vec_bss,x 000409 1 dex 000409 1 bpl ld_vect 000409 1 .endif 000409 1 .endif 000409 1 000409 1 ;retain status of interrupt flag 000409 1 .if I_flag = 2 000409 1 php 000409 1 pla 000409 1 and #4 ;isolate flag 000409 1 sta flag_I_on ;or mask 000409 1 eor #<(~4) ;reverse 000409 1 sta flag_I_off ;and mask 000409 1 .endif 000409 1 000409 1 ;generate checksum for RAM integrity test 000409 1 .if ram_top > -1 000409 1 lda #0 000409 1 sta zpt ;set low byte of indirect pointer 000409 1 sta ram_chksm+1 ;checksum high byte 000409 1 ldx #11 ;reset modifiable RAM 000409 1 gcs1: sta jxi_tab,x ;JMP indirect page cross area 000409 1 dex 000409 1 bpl gcs1 000409 1 clc 000409 1 ldx #zp_bss-zero_page ;zeropage - write test area 000409 1 gcs3: adc zero_page,x 000409 1 bcc gcs2 000409 1 inc ram_chksm+1 ;carry to high byte 000409 1 clc 000409 1 gcs2: inx 000409 1 bne gcs3 000409 1 ldx #>abs1 ;set high byte of indirect pointer 000409 1 stx zpt+1 000409 1 ldy #= 0 000C04 1 set_a $aa-opcode,$ff 000C04 1 .else 000C04 1 set_a $ff+$aa-opcode,$ff 000C04 1 .endif 000C04 1 .byte opcode ;test nop integrity - flags on 000C04 1 nop 000C04 1 nop 000C04 1 .if $aa-opcode >= 0 000C04 1 tst_a $aa-opcode,$ff 000C04 1 .else 000C04 1 tst_a $ff+$aa-opcode,$ff 000C04 1 .endif 000C04 1 cpy #$42 000C04 1 trap_ne ;y changed 000C04 1 cpx #0 000C04 1 trap_ne ;x changed 000C04 1 .endmacro 000C04 1 000C04 1 .if skip_nop = 0 000C04 1 A0 42 A2 02 nop_test $02,2 000C08 1 02 C8 CA CA 000C0C 1 D0 FE A9 00 000C40 1 A0 42 A2 02 nop_test $22,2 000C44 1 22 C8 CA CA 000C48 1 D0 FE A9 00 000C7C 1 A0 42 A2 02 nop_test $42,2 000C80 1 42 C8 CA CA 000C84 1 D0 FE A9 00 000CB8 1 A0 42 A2 02 nop_test $62,2 000CBC 1 62 C8 CA CA 000CC0 1 D0 FE A9 00 000CF4 1 A0 42 A2 02 nop_test $82,2 000CF8 1 82 C8 CA CA 000CFC 1 D0 FE A9 00 000D30 1 A0 42 A2 02 nop_test $c2,2 000D34 1 C2 C8 CA CA 000D38 1 D0 FE A9 00 000D6C 1 A0 42 A2 02 nop_test $e2,2 000D70 1 E2 C8 CA CA 000D74 1 D0 FE A9 00 000DA8 1 A0 42 A2 02 nop_test $44,2 000DAC 1 44 C8 CA CA 000DB0 1 D0 FE A9 00 000DE4 1 A0 42 A2 02 nop_test $54,2 000DE8 1 54 C8 CA CA 000DEC 1 D0 FE A9 00 000E20 1 A0 42 A2 02 nop_test $d4,2 000E24 1 D4 C8 CA CA 000E28 1 D0 FE A9 00 000E5C 1 A0 42 A2 02 nop_test $f4,2 000E60 1 F4 C8 CA CA 000E64 1 D0 FE A9 00 000E98 1 A0 42 A2 01 nop_test $5c,3 000E9C 1 5C C8 C8 CA 000EA0 1 D0 FE A9 00 000ED4 1 A0 42 A2 01 nop_test $dc,3 000ED8 1 DC C8 C8 CA 000EDC 1 D0 FE A9 00 000F10 1 A0 42 A2 01 nop_test $fc,3 000F14 1 FC C8 C8 CA 000F18 1 D0 FE A9 00 000F4C 1 A0 42 A2 03 nop_test $03,1 000F50 1 03 CA CA CA 000F54 1 D0 FE A9 00 000F88 1 A0 42 A2 03 nop_test $13,1 000F8C 1 13 CA CA CA 000F90 1 D0 FE A9 00 000FC4 1 A0 42 A2 03 nop_test $23,1 000FC8 1 23 CA CA CA 000FCC 1 D0 FE A9 00 001000 1 A0 42 A2 03 nop_test $33,1 001004 1 33 CA CA CA 001008 1 D0 FE A9 00 00103C 1 A0 42 A2 03 nop_test $43,1 001040 1 43 CA CA CA 001044 1 D0 FE A9 00 001078 1 A0 42 A2 03 nop_test $53,1 00107C 1 53 CA CA CA 001080 1 D0 FE A9 00 0010B4 1 A0 42 A2 03 nop_test $63,1 0010B8 1 63 CA CA CA 0010BC 1 D0 FE A9 00 0010F0 1 A0 42 A2 03 nop_test $73,1 0010F4 1 73 CA CA CA 0010F8 1 D0 FE A9 00 00112C 1 A0 42 A2 03 nop_test $83,1 001130 1 83 CA CA CA 001134 1 D0 FE A9 00 001168 1 A0 42 A2 03 nop_test $93,1 00116C 1 93 CA CA CA 001170 1 D0 FE A9 00 0011A4 1 A0 42 A2 03 nop_test $a3,1 0011A8 1 A3 CA CA CA 0011AC 1 D0 FE A9 00 0011E0 1 A0 42 A2 03 nop_test $b3,1 0011E4 1 B3 CA CA CA 0011E8 1 D0 FE A9 00 00121C 1 A0 42 A2 03 nop_test $c3,1 001220 1 C3 CA CA CA 001224 1 D0 FE A9 00 001258 1 A0 42 A2 03 nop_test $d3,1 00125C 1 D3 CA CA CA 001260 1 D0 FE A9 00 001294 1 A0 42 A2 03 nop_test $e3,1 001298 1 E3 CA CA CA 00129C 1 D0 FE A9 00 0012D0 1 A0 42 A2 03 nop_test $f3,1 0012D4 1 F3 CA CA CA 0012D8 1 D0 FE A9 00 00130C 1 A0 42 A2 03 nop_test $0b,1 001310 1 0B CA CA CA 001314 1 D0 FE A9 00 001348 1 A0 42 A2 03 nop_test $1b,1 00134C 1 1B CA CA CA 001350 1 D0 FE A9 00 001384 1 A0 42 A2 03 nop_test $2b,1 001388 1 2B CA CA CA 00138C 1 D0 FE A9 00 0013C0 1 A0 42 A2 03 nop_test $3b,1 0013C4 1 3B CA CA CA 0013C8 1 D0 FE A9 00 0013FC 1 A0 42 A2 03 nop_test $4b,1 001400 1 4B CA CA CA 001404 1 D0 FE A9 00 001438 1 A0 42 A2 03 nop_test $5b,1 00143C 1 5B CA CA CA 001440 1 D0 FE A9 00 001474 1 A0 42 A2 03 nop_test $6b,1 001478 1 6B CA CA CA 00147C 1 D0 FE A9 00 0014B0 1 A0 42 A2 03 nop_test $7b,1 0014B4 1 7B CA CA CA 0014B8 1 D0 FE A9 00 0014EC 1 A0 42 A2 03 nop_test $8b,1 0014F0 1 8B CA CA CA 0014F4 1 D0 FE A9 00 001528 1 A0 42 A2 03 nop_test $9b,1 00152C 1 9B CA CA CA 001530 1 D0 FE A9 00 001564 1 A0 42 A2 03 nop_test $ab,1 001568 1 AB CA CA CA 00156C 1 D0 FE A9 00 0015A0 1 A0 42 A2 03 nop_test $bb,1 0015A4 1 BB CA CA CA 0015A8 1 D0 FE A9 00 0015DC 1 A0 42 A2 03 nop_test $eb,1 0015E0 1 EB CA CA CA 0015E4 1 D0 FE A9 00 001618 1 A0 42 A2 03 nop_test $fb,1 00161C 1 FB CA CA CA 001620 1 D0 FE A9 00 001654 1 .if rkwl_wdc_op = 0 ;NOPs not available on Rockwell & WDC 65C02 001654 1 nop_test $07,1 001654 1 nop_test $17,1 001654 1 nop_test $27,1 001654 1 nop_test $37,1 001654 1 nop_test $47,1 001654 1 nop_test $57,1 001654 1 nop_test $67,1 001654 1 nop_test $77,1 001654 1 nop_test $87,1 001654 1 nop_test $97,1 001654 1 nop_test $a7,1 001654 1 nop_test $b7,1 001654 1 nop_test $c7,1 001654 1 nop_test $d7,1 001654 1 nop_test $e7,1 001654 1 nop_test $f7,1 001654 1 nop_test $0f,1 001654 1 nop_test $1f,1 001654 1 nop_test $2f,1 001654 1 nop_test $3f,1 001654 1 nop_test $4f,1 001654 1 nop_test $5f,1 001654 1 nop_test $6f,1 001654 1 nop_test $7f,1 001654 1 nop_test $8f,1 001654 1 nop_test $9f,1 001654 1 nop_test $af,1 001654 1 nop_test $bf,1 001654 1 nop_test $cf,1 001654 1 nop_test $df,1 001654 1 nop_test $ef,1 001654 1 nop_test $ff,1 001654 1 .endif 001654 1 .if wdc_op = 0 ;NOPs not available on WDC 65C02 (WAI, STP) 001654 1 nop_test $cb,1 001654 1 nop_test $db,1 001654 1 .endif 001654 1 AD 02 02 C9 next_test 001658 1 08 D0 FE A9 00165C 1 09 8D 02 02 001660 1 .endif 001660 1 001660 1 ; jump indirect (test page cross bug is fixed) 001660 1 A2 03 ldx #3 ;prepare table 001662 1 BD 8B 26 ji1: lda ji_adr,x 001665 1 9D FD 02 sta ji_tab,x 001668 1 CA dex 001669 1 10 F7 bpl ji1 00166B 1 A9 28 lda #>ji_px ;high address if page cross bug 00166D 1 8D 00 02 sta pg_x 001670 1 A9 00 48 28 set_stat 0 001674 1 A9 49 lda #'I' 001676 1 A2 4E ldx #'N' 001678 1 A0 44 ldy #'D' ;N=0, V=0, Z=0, C=0 00167A 1 6C FD 02 jmp (ji_tab) 00167D 1 EA nop 00167E 1 D0 FE trap_ne ;runover protection 001680 1 001680 1 88 dey 001681 1 88 dey 001682 1 08 ji_ret: php ;either SP or Y count will fail, if we do not hit 001683 1 88 dey 001684 1 88 dey 001685 1 88 dey 001686 1 28 plp 001687 1 F0 FE trap_eq ;returned flags OK? 001689 1 10 FE trap_pl 00168B 1 90 FE trap_cc 00168D 1 50 FE trap_vc 00168F 1 C9 E3 cmp #('I'^$aa) ;returned registers OK? 001691 1 D0 FE trap_ne 001693 1 E0 4F cpx #('N'+1) 001695 1 D0 FE trap_ne 001697 1 C0 3E cpy #('D'-6) 001699 1 D0 FE trap_ne 00169B 1 BA tsx ;SP check 00169C 1 E0 FF cpx #$ff 00169E 1 D0 FE trap_ne 0016A0 1 AD 02 02 C9 next_test 0016A4 1 09 D0 FE A9 0016A8 1 0A 8D 02 02 0016AC 1 0016AC 1 ; jump indexed indirect 0016AC 1 A2 0B ldx #11 ;prepare table 0016AE 1 BD C7 26 jxi1: lda jxi_adr,x 0016B1 1 9D F9 02 sta jxi_tab,x 0016B4 1 CA dex 0016B5 1 10 F7 bpl jxi1 0016B7 1 A9 27 lda #>jxi_px ;high address if page cross bug 0016B9 1 8D 00 02 sta pg_x 0016BC 1 A9 00 48 28 set_stat 0 0016C0 1 A9 58 lda #'X' 0016C2 1 A2 04 ldx #4 0016C4 1 A0 49 ldy #'I' ;N=0, V=0, Z=0, C=0 0016C6 1 7C F9 02 jmp (jxi_tab,x) 0016C9 1 EA nop 0016CA 1 D0 FE trap_ne ;runover protection 0016CC 1 0016CC 1 88 dey 0016CD 1 88 dey 0016CE 1 08 jxi_ret:php ;either SP or Y count will fail, if we do not hit 0016CF 1 88 dey 0016D0 1 88 dey 0016D1 1 88 dey 0016D2 1 28 plp 0016D3 1 F0 FE trap_eq ;returned flags OK? 0016D5 1 10 FE trap_pl 0016D7 1 90 FE trap_cc 0016D9 1 50 FE trap_vc 0016DB 1 C9 F2 cmp #('X'^$aa) ;returned registers OK? 0016DD 1 D0 FE trap_ne 0016DF 1 E0 06 cpx #6 0016E1 1 D0 FE trap_ne 0016E3 1 C0 43 cpy #('I'-6) 0016E5 1 D0 FE trap_ne 0016E7 1 BA tsx ;SP check 0016E8 1 E0 FF cpx #$ff 0016EA 1 D0 FE trap_ne 0016EC 1 0016EC 1 A9 08 lda #jxp_ok 0016F3 1 8D 01 03 sta jxp_tab+1 0016F6 1 A9 05 lda #jxp_px 0016FD 1 8D 01 02 sta pg_x+1 001700 1 A2 FF ldx #$ff 001702 1 7C 01 02 jmp (jxp_tab-$ff,x) 001705 1 001705 1 jxp_px: 001705 1 4C 05 17 trap ;page cross by index to wrong page 001708 1 001708 1 jxp_ok: 001708 1 AD 02 02 C9 next_test 00170C 1 0A D0 FE A9 001710 1 0B 8D 02 02 001714 1 001714 1 .if ROM_vectors = 1 001714 1 ; test BRK clears decimal mode 001714 1 A9 00 load_flag 0 ;with interrupts enabled if allowed! 001716 1 48 pha 001717 1 A9 42 lda #'B' 001719 1 A2 52 ldx #'R' 00171B 1 A0 4B ldy #'K' 00171D 1 28 plp ;N=0, V=0, Z=0, C=0 00171E 1 00 brk 00171F 1 88 dey ;should not be executed 001720 1 brk_ret0: ;address of break return 001720 1 08 php ;either SP or Y count will fail, if we do not hit 001721 1 88 dey 001722 1 88 dey 001723 1 88 dey 001724 1 C9 E8 cmp #'B'^$aa ;returned registers OK? 001726 1 ;the IRQ vector was never executed if A & X stay unmodified 001726 1 D0 FE trap_ne 001728 1 E0 53 cpx #'R'+1 00172A 1 D0 FE trap_ne 00172C 1 C0 45 cpy #'K'-6 00172E 1 D0 FE trap_ne 001730 1 68 pla ;returned flags OK (unchanged)? 001731 1 C9 30 cmp_flag 0 001733 1 D0 FE trap_ne 001735 1 BA tsx ;sp? 001736 1 E0 FF cpx #$ff 001738 1 D0 FE trap_ne 00173A 1 ;pass 2 00173A 1 A9 FF load_flag $ff ;with interrupts disabled if allowed! 00173C 1 48 pha 00173D 1 A9 BD lda #$ff-'B' 00173F 1 A2 AD ldx #$ff-'R' 001741 1 A0 B4 ldy #$ff-'K' 001743 1 28 plp ;N=1, V=1, Z=1, C=1 001744 1 00 brk 001745 1 88 dey ;should not be executed 001746 1 brk_ret1: ;address of break return 001746 1 08 php ;either SP or Y count will fail, if we do not hit 001747 1 88 dey 001748 1 88 dey 001749 1 88 dey 00174A 1 C9 17 cmp #($ff-'B')^$aa ;returned registers OK? 00174C 1 ;the IRQ vector was never executed if A & X stay unmodified 00174C 1 D0 FE trap_ne 00174E 1 E0 AE cpx #$ff-'R'+1 001750 1 D0 FE trap_ne 001752 1 C0 AE cpy #$ff-'K'-6 001754 1 D0 FE trap_ne 001756 1 68 pla ;returned flags OK (unchanged)? 001757 1 C9 FF cmp_flag $ff 001759 1 D0 FE trap_ne 00175B 1 BA tsx ;sp? 00175C 1 E0 FF cpx #$ff 00175E 1 D0 FE trap_ne 001760 1 AD 02 02 C9 next_test 001764 1 0B D0 FE A9 001768 1 0C 8D 02 02 00176C 1 .endif 00176C 1 00176C 1 ; testing accumulator increment/decrement INC A & DEC A 00176C 1 A2 AC ldx #$ac ;protect x & y 00176E 1 A0 DC ldy #$dc 001770 1 A9 FF 48 A9 set_a $fe,$ff 001774 1 FE 28 001776 1 1A inc a ;ff 001777 1 48 08 C9 FF tst_as $ff,$ff-zero 00177B 1 D0 FE 68 48 00177F 1 C9 FD D0 FE 001785 1 1A inc a ;00 001786 1 48 08 C9 00 tst_as 0,$ff-minus 00178A 1 D0 FE 68 48 00178E 1 C9 7F D0 FE 001794 1 1A inc a ;01 001795 1 48 08 C9 01 tst_as 1,$ff-minus-zero 001799 1 D0 FE 68 48 00179D 1 C9 7D D0 FE 0017A3 1 3A dec a ;00 0017A4 1 48 08 C9 00 tst_as 0,$ff-minus 0017A8 1 D0 FE 68 48 0017AC 1 C9 7F D0 FE 0017B2 1 3A dec a ;ff 0017B3 1 48 08 C9 FF tst_as $ff,$ff-zero 0017B7 1 D0 FE 68 48 0017BB 1 C9 FD D0 FE 0017C1 1 3A dec a ;fe 0017C2 1 A9 00 48 A9 set_a $fe,0 0017C6 1 FE 28 0017C8 1 1A inc a ;ff 0017C9 1 48 08 C9 FF tst_as $ff,minus 0017CD 1 D0 FE 68 48 0017D1 1 C9 B0 D0 FE 0017D7 1 1A inc a ;00 0017D8 1 48 08 C9 00 tst_as 0,zero 0017DC 1 D0 FE 68 48 0017E0 1 C9 32 D0 FE 0017E6 1 1A inc a ;01 0017E7 1 48 08 C9 01 tst_as 1,0 0017EB 1 D0 FE 68 48 0017EF 1 C9 30 D0 FE 0017F5 1 3A dec a ;00 0017F6 1 48 08 C9 00 tst_as 0,zero 0017FA 1 D0 FE 68 48 0017FE 1 C9 32 D0 FE 001804 1 3A dec a ;ff 001805 1 48 08 C9 FF tst_as $ff,minus 001809 1 D0 FE 68 48 00180D 1 C9 B0 D0 FE 001813 1 E0 AC cpx #$ac 001815 1 D0 FE trap_ne ;x altered during test 001817 1 C0 DC cpy #$dc 001819 1 D0 FE trap_ne ;y altered during test 00181B 1 BA tsx 00181C 1 E0 FF cpx #$ff 00181E 1 D0 FE trap_ne ;sp push/pop mismatch 001820 1 AD 02 02 C9 next_test 001824 1 0C D0 FE A9 001828 1 0D 8D 02 02 00182C 1 00182C 1 ; testing load / store accumulator LDA / STA (zp) 00182C 1 A2 99 ldx #$99 ;protect x & y 00182E 1 A0 66 ldy #$66 001830 1 A9 00 48 28 set_stat 0 001834 1 B2 24 lda (ind1) 001836 1 08 php ;test stores do not alter flags 001837 1 49 C3 eor #$c3 001839 1 28 plp 00183A 1 92 30 sta (indt) 00183C 1 08 php ;flags after load/store sequence 00183D 1 49 C3 eor #$c3 00183F 1 C9 C3 cmp #$c3 ;test result 001841 1 D0 FE trap_ne 001843 1 68 pla ;load status 001844 1 49 30 eor_flag 0 001846 1 CD 15 02 cmp fLDx ;test flags 001849 1 D0 FE trap_ne 00184B 1 A9 00 48 28 set_stat 0 00184F 1 B2 26 lda (ind1+2) 001851 1 08 php ;test stores do not alter flags 001852 1 49 C3 eor #$c3 001854 1 28 plp 001855 1 92 32 sta (indt+2) 001857 1 08 php ;flags after load/store sequence 001858 1 49 C3 eor #$c3 00185A 1 C9 82 cmp #$82 ;test result 00185C 1 D0 FE trap_ne 00185E 1 68 pla ;load status 00185F 1 49 30 eor_flag 0 001861 1 CD 16 02 cmp fLDx+1 ;test flags 001864 1 D0 FE trap_ne 001866 1 A9 00 48 28 set_stat 0 00186A 1 B2 28 lda (ind1+4) 00186C 1 08 php ;test stores do not alter flags 00186D 1 49 C3 eor #$c3 00186F 1 28 plp 001870 1 92 34 sta (indt+4) 001872 1 08 php ;flags after load/store sequence 001873 1 49 C3 eor #$c3 001875 1 C9 41 cmp #$41 ;test result 001877 1 D0 FE trap_ne 001879 1 68 pla ;load status 00187A 1 49 30 eor_flag 0 00187C 1 CD 17 02 cmp fLDx+2 ;test flags 00187F 1 D0 FE trap_ne 001881 1 A9 00 48 28 set_stat 0 001885 1 B2 2A lda (ind1+6) 001887 1 08 php ;test stores do not alter flags 001888 1 49 C3 eor #$c3 00188A 1 28 plp 00188B 1 92 36 sta (indt+6) 00188D 1 08 php ;flags after load/store sequence 00188E 1 49 C3 eor #$c3 001890 1 C9 00 cmp #0 ;test result 001892 1 D0 FE trap_ne 001894 1 68 pla ;load status 001895 1 49 30 eor_flag 0 001897 1 CD 18 02 cmp fLDx+3 ;test flags 00189A 1 D0 FE trap_ne 00189C 1 E0 99 cpx #$99 00189E 1 D0 FE trap_ne ;x altered during test 0018A0 1 C0 66 cpy #$66 0018A2 1 D0 FE trap_ne ;y altered during test 0018A4 1 0018A4 1 A0 03 ldy #3 ;testing store result 0018A6 1 A2 00 ldx #0 0018A8 1 B9 05 02 tstai1: lda abst,y 0018AB 1 49 C3 eor #$c3 0018AD 1 D9 10 02 cmp abs1,y 0018B0 1 D0 FE trap_ne ;store to indirect data 0018B2 1 8A txa 0018B3 1 99 05 02 sta abst,y ;clear 0018B6 1 88 dey 0018B7 1 10 EF bpl tstai1 0018B9 1 0018B9 1 A2 99 ldx #$99 ;protect x & y 0018BB 1 A0 66 ldy #$66 0018BD 1 A9 FF 48 28 set_stat $ff 0018C1 1 B2 24 lda (ind1) 0018C3 1 08 php ;test stores do not alter flags 0018C4 1 49 C3 eor #$c3 0018C6 1 28 plp 0018C7 1 92 30 sta (indt) 0018C9 1 08 php ;flags after load/store sequence 0018CA 1 49 C3 eor #$c3 0018CC 1 C9 C3 cmp #$c3 ;test result 0018CE 1 D0 FE trap_ne 0018D0 1 68 pla ;load status 0018D1 1 49 7D eor_flag <(~fnz) ;mask bits not altered 0018D3 1 CD 15 02 cmp fLDx ;test flags 0018D6 1 D0 FE trap_ne 0018D8 1 A9 FF 48 28 set_stat $ff 0018DC 1 B2 26 lda (ind1+2) 0018DE 1 08 php ;test stores do not alter flags 0018DF 1 49 C3 eor #$c3 0018E1 1 28 plp 0018E2 1 92 32 sta (indt+2) 0018E4 1 08 php ;flags after load/store sequence 0018E5 1 49 C3 eor #$c3 0018E7 1 C9 82 cmp #$82 ;test result 0018E9 1 D0 FE trap_ne 0018EB 1 68 pla ;load status 0018EC 1 49 7D eor_flag <(~fnz) ;mask bits not altered 0018EE 1 CD 16 02 cmp fLDx+1 ;test flags 0018F1 1 D0 FE trap_ne 0018F3 1 A9 FF 48 28 set_stat $ff 0018F7 1 B2 28 lda (ind1+4) 0018F9 1 08 php ;test stores do not alter flags 0018FA 1 49 C3 eor #$c3 0018FC 1 28 plp 0018FD 1 92 34 sta (indt+4) 0018FF 1 08 php ;flags after load/store sequence 001900 1 49 C3 eor #$c3 001902 1 C9 41 cmp #$41 ;test result 001904 1 D0 FE trap_ne 001906 1 68 pla ;load status 001907 1 49 7D eor_flag <(~fnz) ;mask bits not altered 001909 1 CD 17 02 cmp fLDx+2 ;test flags 00190C 1 D0 FE trap_ne 00190E 1 A9 FF 48 28 set_stat $ff 001912 1 B2 2A lda (ind1+6) 001914 1 08 php ;test stores do not alter flags 001915 1 49 C3 eor #$c3 001917 1 28 plp 001918 1 92 36 sta (indt+6) 00191A 1 08 php ;flags after load/store sequence 00191B 1 49 C3 eor #$c3 00191D 1 C9 00 cmp #0 ;test result 00191F 1 D0 FE trap_ne 001921 1 68 pla ;load status 001922 1 49 7D eor_flag <(~fnz) ;mask bits not altered 001924 1 CD 18 02 cmp fLDx+3 ;test flags 001927 1 D0 FE trap_ne 001929 1 E0 99 cpx #$99 00192B 1 D0 FE trap_ne ;x altered during test 00192D 1 C0 66 cpy #$66 00192F 1 D0 FE trap_ne ;y altered during test 001931 1 001931 1 A0 03 ldy #3 ;testing store result 001933 1 A2 00 ldx #0 001935 1 B9 05 02 tstai2: lda abst,y 001938 1 49 C3 eor #$c3 00193A 1 D9 10 02 cmp abs1,y 00193D 1 D0 FE trap_ne ;store to indirect data 00193F 1 8A txa 001940 1 99 05 02 sta abst,y ;clear 001943 1 88 dey 001944 1 10 EF bpl tstai2 001946 1 BA tsx 001947 1 E0 FF cpx #$ff 001949 1 D0 FE trap_ne ;sp push/pop mismatch 00194B 1 AD 02 02 C9 next_test 00194F 1 0D D0 FE A9 001953 1 0E 8D 02 02 001957 1 001957 1 ; testing STZ - zp / abs / zp,x / abs,x 001957 1 A0 7B ldy #123 ;protect y 001959 1 A2 04 ldx #4 ;precharge test area 00195B 1 A9 07 lda #7 00195D 1 95 0C tstz1: sta zpt,x 00195F 1 0A asl a 001960 1 CA dex 001961 1 10 FA bpl tstz1 001963 1 A2 04 ldx #4 001965 1 A9 FF 48 A9 set_a $55,$ff 001969 1 55 28 00196B 1 64 0C stz zpt 00196D 1 64 0D stz zpt+1 00196F 1 64 0E stz zpt+2 001971 1 64 0F stz zpt+3 001973 1 64 10 stz zpt+4 001975 1 08 C9 55 D0 tst_a $55,$ff 001979 1 FE 68 48 C9 00197D 1 FF D0 FE 28 001981 1 B5 0C tstz2: lda zpt,x ;verify zeros stored 001983 1 D0 FE trap_ne ;non zero after STZ zp 001985 1 CA dex 001986 1 10 F9 bpl tstz2 001988 1 A2 04 ldx #4 ;precharge test area 00198A 1 A9 07 lda #7 00198C 1 95 0C tstz3: sta zpt,x 00198E 1 0A asl a 00198F 1 CA dex 001990 1 10 FA bpl tstz3 001992 1 A2 04 ldx #4 001994 1 A9 00 48 A9 set_a $aa,0 001998 1 AA 28 00199A 1 64 0C stz zpt 00199C 1 64 0D stz zpt+1 00199E 1 64 0E stz zpt+2 0019A0 1 64 0F stz zpt+3 0019A2 1 64 10 stz zpt+4 0019A4 1 08 C9 AA D0 tst_a $aa,0 0019A8 1 FE 68 48 C9 0019AC 1 30 D0 FE 28 0019B0 1 B5 0C tstz4: lda zpt,x ;verify zeros stored 0019B2 1 D0 FE trap_ne ;non zero after STZ zp 0019B4 1 CA dex 0019B5 1 10 F9 bpl tstz4 0019B7 1 0019B7 1 A2 04 ldx #4 ;precharge test area 0019B9 1 A9 07 lda #7 0019BB 1 9D 05 02 tstz5: sta abst,x 0019BE 1 0A asl a 0019BF 1 CA dex 0019C0 1 10 F9 bpl tstz5 0019C2 1 A2 04 ldx #4 0019C4 1 A9 FF 48 A9 set_a $55,$ff 0019C8 1 55 28 0019CA 1 9C 05 02 stz abst 0019CD 1 9C 06 02 stz abst+1 0019D0 1 9C 07 02 stz abst+2 0019D3 1 9C 08 02 stz abst+3 0019D6 1 9C 09 02 stz abst+4 0019D9 1 08 C9 55 D0 tst_a $55,$ff 0019DD 1 FE 68 48 C9 0019E1 1 FF D0 FE 28 0019E5 1 BD 05 02 tstz6: lda abst,x ;verify zeros stored 0019E8 1 D0 FE trap_ne ;non zero after STZ abs 0019EA 1 CA dex 0019EB 1 10 F8 bpl tstz6 0019ED 1 A2 04 ldx #4 ;precharge test area 0019EF 1 A9 07 lda #7 0019F1 1 9D 05 02 tstz7: sta abst,x 0019F4 1 0A asl a 0019F5 1 CA dex 0019F6 1 10 F9 bpl tstz7 0019F8 1 A2 04 ldx #4 0019FA 1 A9 00 48 A9 set_a $aa,0 0019FE 1 AA 28 001A00 1 9C 05 02 stz abst 001A03 1 9C 06 02 stz abst+1 001A06 1 9C 07 02 stz abst+2 001A09 1 9C 08 02 stz abst+3 001A0C 1 9C 09 02 stz abst+4 001A0F 1 08 C9 AA D0 tst_a $aa,0 001A13 1 FE 68 48 C9 001A17 1 30 D0 FE 28 001A1B 1 BD 05 02 tstz8: lda abst,x ;verify zeros stored 001A1E 1 D0 FE trap_ne ;non zero after STZ abs 001A20 1 CA dex 001A21 1 10 F8 bpl tstz8 001A23 1 001A23 1 A2 04 ldx #4 ;precharge test area 001A25 1 A9 07 lda #7 001A27 1 95 0C tstz11: sta zpt,x 001A29 1 0A asl a 001A2A 1 CA dex 001A2B 1 10 FA bpl tstz11 001A2D 1 A2 04 ldx #4 001A2F 1 tstz15: 001A2F 1 A9 FF 48 A9 set_a $55,$ff 001A33 1 55 28 001A35 1 74 0C stz zpt,x 001A37 1 08 C9 55 D0 tst_a $55,$ff 001A3B 1 FE 68 48 C9 001A3F 1 FF D0 FE 28 001A43 1 CA dex 001A44 1 10 E9 bpl tstz15 001A46 1 A2 04 ldx #4 001A48 1 B5 0C tstz12: lda zpt,x ;verify zeros stored 001A4A 1 D0 FE trap_ne ;non zero after STZ zp 001A4C 1 CA dex 001A4D 1 10 F9 bpl tstz12 001A4F 1 A2 04 ldx #4 ;precharge test area 001A51 1 A9 07 lda #7 001A53 1 95 0C tstz13: sta zpt,x 001A55 1 0A asl a 001A56 1 CA dex 001A57 1 10 FA bpl tstz13 001A59 1 A2 04 ldx #4 001A5B 1 tstz16: 001A5B 1 A9 00 48 A9 set_a $aa,0 001A5F 1 AA 28 001A61 1 74 0C stz zpt,x 001A63 1 08 C9 AA D0 tst_a $aa,0 001A67 1 FE 68 48 C9 001A6B 1 30 D0 FE 28 001A6F 1 CA dex 001A70 1 10 E9 bpl tstz16 001A72 1 A2 04 ldx #4 001A74 1 B5 0C tstz14: lda zpt,x ;verify zeros stored 001A76 1 D0 FE trap_ne ;non zero after STZ zp 001A78 1 CA dex 001A79 1 10 F9 bpl tstz14 001A7B 1 001A7B 1 A2 04 ldx #4 ;precharge test area 001A7D 1 A9 07 lda #7 001A7F 1 9D 05 02 tstz21: sta abst,x 001A82 1 0A asl a 001A83 1 CA dex 001A84 1 10 F9 bpl tstz21 001A86 1 A2 04 ldx #4 001A88 1 tstz25: 001A88 1 A9 FF 48 A9 set_a $55,$ff 001A8C 1 55 28 001A8E 1 9E 05 02 stz abst,x 001A91 1 08 C9 55 D0 tst_a $55,$ff 001A95 1 FE 68 48 C9 001A99 1 FF D0 FE 28 001A9D 1 CA dex 001A9E 1 10 E8 bpl tstz25 001AA0 1 A2 04 ldx #4 001AA2 1 BD 05 02 tstz22: lda abst,x ;verify zeros stored 001AA5 1 D0 FE trap_ne ;non zero after STZ zp 001AA7 1 CA dex 001AA8 1 10 F8 bpl tstz22 001AAA 1 A2 04 ldx #4 ;precharge test area 001AAC 1 A9 07 lda #7 001AAE 1 9D 05 02 tstz23: sta abst,x 001AB1 1 0A asl a 001AB2 1 CA dex 001AB3 1 10 F9 bpl tstz23 001AB5 1 A2 04 ldx #4 001AB7 1 tstz26: 001AB7 1 A9 00 48 A9 set_a $aa,0 001ABB 1 AA 28 001ABD 1 9E 05 02 stz abst,x 001AC0 1 08 C9 AA D0 tst_a $aa,0 001AC4 1 FE 68 48 C9 001AC8 1 30 D0 FE 28 001ACC 1 CA dex 001ACD 1 10 E8 bpl tstz26 001ACF 1 A2 04 ldx #4 001AD1 1 BD 05 02 tstz24: lda abst,x ;verify zeros stored 001AD4 1 D0 FE trap_ne ;non zero after STZ zp 001AD6 1 CA dex 001AD7 1 10 F8 bpl tstz24 001AD9 1 001AD9 1 C0 7B cpy #123 001ADB 1 D0 FE trap_ne ;y altered during test 001ADD 1 BA tsx 001ADE 1 E0 FF cpx #$ff 001AE0 1 D0 FE trap_ne ;sp push/pop mismatch 001AE2 1 AD 02 02 C9 next_test 001AE6 1 0E D0 FE A9 001AEA 1 0F 8D 02 02 001AEE 1 001AEE 1 ; testing BIT - zp,x / abs,x / # 001AEE 1 A0 42 ldy #$42 001AF0 1 A2 03 ldx #3 001AF2 1 A9 00 48 A9 set_a $ff,0 001AF6 1 FF 28 001AF8 1 34 13 bit zp1,x ;00 - should set Z / clear NV 001AFA 1 08 C9 FF D0 tst_a $ff,fz 001AFE 1 FE 68 48 C9 001B02 1 32 D0 FE 28 001B06 1 CA dex 001B07 1 A9 00 48 A9 set_a 1,0 001B0B 1 01 28 001B0D 1 34 13 bit zp1,x ;41 - should set V (M6) / clear NZ 001B0F 1 08 C9 01 D0 tst_a 1,fv 001B13 1 FE 68 48 C9 001B17 1 70 D0 FE 28 001B1B 1 CA dex 001B1C 1 A9 00 48 A9 set_a 1,0 001B20 1 01 28 001B22 1 34 13 bit zp1,x ;82 - should set N (M7) & Z / clear V 001B24 1 08 C9 01 D0 tst_a 1,fnz 001B28 1 FE 68 48 C9 001B2C 1 B2 D0 FE 28 001B30 1 CA dex 001B31 1 A9 00 48 A9 set_a 1,0 001B35 1 01 28 001B37 1 34 13 bit zp1,x ;c3 - should set N (M7) & V (M6) / clear Z 001B39 1 08 C9 01 D0 tst_a 1,fnv 001B3D 1 FE 68 48 C9 001B41 1 F0 D0 FE 28 001B45 1 001B45 1 A9 FF 48 A9 set_a 1,$ff 001B49 1 01 28 001B4B 1 34 13 bit zp1,x ;c3 - should set N (M7) & V (M6) / clear Z 001B4D 1 08 C9 01 D0 tst_a 1,~fz 001B51 1 FE 68 48 C9 001B55 1 FD D0 FE 28 001B59 1 E8 inx 001B5A 1 A9 FF 48 A9 set_a 1,$ff 001B5E 1 01 28 001B60 1 34 13 bit zp1,x ;82 - should set N (M7) & Z / clear V 001B62 1 08 C9 01 D0 tst_a 1,~fv 001B66 1 FE 68 48 C9 001B6A 1 BF D0 FE 28 001B6E 1 E8 inx 001B6F 1 A9 FF 48 A9 set_a 1,$ff 001B73 1 01 28 001B75 1 34 13 bit zp1,x ;41 - should set V (M6) / clear NZ 001B77 1 08 C9 01 D0 tst_a 1,~fnz 001B7B 1 FE 68 48 C9 001B7F 1 7D D0 FE 28 001B83 1 E8 inx 001B84 1 A9 FF 48 A9 set_a $ff,$ff 001B88 1 FF 28 001B8A 1 34 13 bit zp1,x ;00 - should set Z / clear NV 001B8C 1 08 C9 FF D0 tst_a $ff,~fnv 001B90 1 FE 68 48 C9 001B94 1 3F D0 FE 28 001B98 1 001B98 1 A9 00 48 A9 set_a $ff,0 001B9C 1 FF 28 001B9E 1 3C 10 02 bit abs1,x ;00 - should set Z / clear NV 001BA1 1 08 C9 FF D0 tst_a $ff,fz 001BA5 1 FE 68 48 C9 001BA9 1 32 D0 FE 28 001BAD 1 CA dex 001BAE 1 A9 00 48 A9 set_a 1,0 001BB2 1 01 28 001BB4 1 3C 10 02 bit abs1,x ;41 - should set V (M6) / clear NZ 001BB7 1 08 C9 01 D0 tst_a 1,fv 001BBB 1 FE 68 48 C9 001BBF 1 70 D0 FE 28 001BC3 1 CA dex 001BC4 1 A9 00 48 A9 set_a 1,0 001BC8 1 01 28 001BCA 1 3C 10 02 bit abs1,x ;82 - should set N (M7) & Z / clear V 001BCD 1 08 C9 01 D0 tst_a 1,fnz 001BD1 1 FE 68 48 C9 001BD5 1 B2 D0 FE 28 001BD9 1 CA dex 001BDA 1 A9 00 48 A9 set_a 1,0 001BDE 1 01 28 001BE0 1 3C 10 02 bit abs1,x ;c3 - should set N (M7) & V (M6) / clear Z 001BE3 1 08 C9 01 D0 tst_a 1,fnv 001BE7 1 FE 68 48 C9 001BEB 1 F0 D0 FE 28 001BEF 1 001BEF 1 A9 FF 48 A9 set_a 1,$ff 001BF3 1 01 28 001BF5 1 3C 10 02 bit abs1,x ;c3 - should set N (M7) & V (M6) / clear Z 001BF8 1 08 C9 01 D0 tst_a 1,~fz 001BFC 1 FE 68 48 C9 001C00 1 FD D0 FE 28 001C04 1 E8 inx 001C05 1 A9 FF 48 A9 set_a 1,$ff 001C09 1 01 28 001C0B 1 3C 10 02 bit abs1,x ;82 - should set N (M7) & Z / clear V 001C0E 1 08 C9 01 D0 tst_a 1,~fv 001C12 1 FE 68 48 C9 001C16 1 BF D0 FE 28 001C1A 1 E8 inx 001C1B 1 A9 FF 48 A9 set_a 1,$ff 001C1F 1 01 28 001C21 1 3C 10 02 bit abs1,x ;41 - should set V (M6) / clear NZ 001C24 1 08 C9 01 D0 tst_a 1,~fnz 001C28 1 FE 68 48 C9 001C2C 1 7D D0 FE 28 001C30 1 E8 inx 001C31 1 A9 FF 48 A9 set_a $ff,$ff 001C35 1 FF 28 001C37 1 3C 10 02 bit abs1,x ;00 - should set Z / clear NV 001C3A 1 08 C9 FF D0 tst_a $ff,~fnv 001C3E 1 FE 68 48 C9 001C42 1 3F D0 FE 28 001C46 1 001C46 1 A9 00 48 A9 set_a $ff,0 001C4A 1 FF 28 001C4C 1 89 00 bit #$00 ;00 - should set Z 001C4E 1 08 C9 FF D0 tst_a $ff,fz 001C52 1 FE 68 48 C9 001C56 1 32 D0 FE 28 001C5A 1 CA dex 001C5B 1 A9 00 48 A9 set_a 1,0 001C5F 1 01 28 001C61 1 89 41 bit #$41 ;41 - should clear Z 001C63 1 08 C9 01 D0 tst_a 1,0 001C67 1 FE 68 48 C9 001C6B 1 30 D0 FE 28 001C6F 1 ; *** DEBUG INFO *** 001C6F 1 ; if it fails the previous test and your BIT # has set the V flag 001C6F 1 ; see http://forum.6502.org/viewtopic.php?f=2&t=2241&p=27243#p27239 001C6F 1 ; why it shouldn't alter N or V flags on a BIT # 001C6F 1 CA dex 001C70 1 A9 00 48 A9 set_a 1,0 001C74 1 01 28 001C76 1 89 82 bit #$82 ;82 - should set Z 001C78 1 08 C9 01 D0 tst_a 1,fz 001C7C 1 FE 68 48 C9 001C80 1 32 D0 FE 28 001C84 1 CA dex 001C85 1 A9 00 48 A9 set_a 1,0 001C89 1 01 28 001C8B 1 89 C3 bit #$c3 ;c3 - should clear Z 001C8D 1 08 C9 01 D0 tst_a 1,0 001C91 1 FE 68 48 C9 001C95 1 30 D0 FE 28 001C99 1 001C99 1 A9 FF 48 A9 set_a 1,$ff 001C9D 1 01 28 001C9F 1 89 C3 bit #$c3 ;c3 - clear Z 001CA1 1 08 C9 01 D0 tst_a 1,~fz 001CA5 1 FE 68 48 C9 001CA9 1 FD D0 FE 28 001CAD 1 E8 inx 001CAE 1 A9 FF 48 A9 set_a 1,$ff 001CB2 1 01 28 001CB4 1 89 82 bit #$82 ;82 - should set Z 001CB6 1 08 C9 01 D0 tst_a 1,$ff 001CBA 1 FE 68 48 C9 001CBE 1 FF D0 FE 28 001CC2 1 E8 inx 001CC3 1 A9 FF 48 A9 set_a 1,$ff 001CC7 1 01 28 001CC9 1 89 41 bit #$41 ;41 - should clear Z 001CCB 1 08 C9 01 D0 tst_a 1,~fz 001CCF 1 FE 68 48 C9 001CD3 1 FD D0 FE 28 001CD7 1 E8 inx 001CD8 1 A9 FF 48 A9 set_a $ff,$ff 001CDC 1 FF 28 001CDE 1 89 00 bit #$00 ;00 - should set Z 001CE0 1 08 C9 FF D0 tst_a $ff,$ff 001CE4 1 FE 68 48 C9 001CE8 1 FF D0 FE 28 001CEC 1 001CEC 1 E0 03 cpx #3 001CEE 1 D0 FE trap_ne ;x altered during test 001CF0 1 C0 42 cpy #$42 001CF2 1 D0 FE trap_ne ;y altered during test 001CF4 1 BA tsx 001CF5 1 E0 FF cpx #$ff 001CF7 1 D0 FE trap_ne ;sp push/pop mismatch 001CF9 1 AD 02 02 C9 next_test 001CFD 1 0F D0 FE A9 001D01 1 10 8D 02 02 001D05 1 001D05 1 ; testing TRB, TSB - zp / abs 001D05 1 001D05 1 .macro trbt memory, flags 001D05 1 sty memory 001D05 1 load_flag flags 001D05 1 pha 001D05 1 lda zpt+1 001D05 1 plp 001D05 1 trb memory 001D05 1 php 001D05 1 cmp zpt+1 001D05 1 trap_ne ;accu was changed 001D05 1 pla 001D05 1 pha 001D05 1 ora #fz ;mask Z 001D05 1 cmp_flag flags|fz 001D05 1 trap_ne ;flags changed except Z 001D05 1 pla 001D05 1 and #fz 001D05 1 cmp zpt+2 001D05 1 trap_ne ;Z flag invalid 001D05 1 lda zpt+3 001D05 1 cmp zpt 001D05 1 trap_ne ;altered bits in memory wrong 001D05 1 .endmacro 001D05 1 001D05 1 .macro tsbt memory, flags 001D05 1 sty memory 001D05 1 load_flag flags 001D05 1 pha 001D05 1 lda zpt+1 001D05 1 plp 001D05 1 tsb memory 001D05 1 php 001D05 1 cmp zpt+1 001D05 1 trap_ne ;accu was changed 001D05 1 pla 001D05 1 pha 001D05 1 ora #fz ;mask Z 001D05 1 cmp_flag flags|fz 001D05 1 trap_ne ;flags changed except Z 001D05 1 pla 001D05 1 and #fz 001D05 1 cmp zpt+2 001D05 1 trap_ne ;Z flag invalid 001D05 1 lda zpt+4 001D05 1 cmp zpt 001D05 1 trap_ne ;altered bits in memory wrong 001D05 1 .endmacro 001D05 1 001D05 1 A2 C0 ldx #$c0 001D07 1 A0 00 ldy #0 ;op1 - memory save 001D09 1 ; zpt ;op1 - memory modifiable 001D09 1 64 0D stz zpt+1 ;op2 - accu 001D0B 1 ; zpt+2 ;and flags 001D0B 1 ; zpt+3 ;memory after reset 001D0B 1 ; zpt+4 ;memory after set 001D0B 1 001D0B 1 98 tbt1: tya 001D0C 1 25 0D and zpt+1 ;set Z by anding the 2 operands 001D0E 1 08 php 001D0F 1 68 pla 001D10 1 29 02 and #fz ;mask Z 001D12 1 85 0E sta zpt+2 001D14 1 98 tya ;reset op1 bits by op2 001D15 1 49 FF eor #$ff 001D17 1 05 0D ora zpt+1 001D19 1 49 FF eor #$ff 001D1B 1 85 0F sta zpt+3 001D1D 1 98 tya ;set op1 bits by op2 001D1E 1 05 0D ora zpt+1 001D20 1 85 10 sta zpt+4 001D22 1 001D22 1 84 0C A9 FF trbt zpt,$ff 001D26 1 48 A5 0D 28 001D2A 1 14 0C 08 C5 001D46 1 8C 05 02 A9 trbt abst,$ff 001D4A 1 FF 48 A5 0D 001D4E 1 28 1C 05 02 001D6C 1 84 0C A9 00 trbt zpt,0 001D70 1 48 A5 0D 28 001D74 1 14 0C 08 C5 001D90 1 8C 05 02 A9 trbt abst,0 001D94 1 00 48 A5 0D 001D98 1 28 1C 05 02 001DB6 1 84 0C A9 FF tsbt zpt,$ff 001DBA 1 48 A5 0D 28 001DBE 1 04 0C 08 C5 001DDA 1 8C 05 02 A9 tsbt abst,$ff 001DDE 1 FF 48 A5 0D 001DE2 1 28 0C 05 02 001E00 1 84 0C A9 00 tsbt zpt,0 001E04 1 48 A5 0D 28 001E08 1 04 0C 08 C5 001E24 1 8C 05 02 A9 tsbt abst,0 001E28 1 00 48 A5 0D 001E2C 1 28 0C 05 02 001E4A 1 001E4A 1 C8 iny ;iterate op1 001E4B 1 D0 04 bne tbt3 001E4D 1 E6 0D inc zpt+1 ;iterate op2 001E4F 1 F0 03 beq tbt2 001E51 1 4C 0B 1D tbt3: jmp tbt1 001E54 1 tbt2: 001E54 1 E0 C0 cpx #$c0 001E56 1 D0 FE trap_ne ;x altered during test 001E58 1 BA tsx 001E59 1 E0 FF cpx #$ff 001E5B 1 D0 FE trap_ne ;sp push/pop mismatch 001E5D 1 AD 02 02 C9 next_test 001E61 1 10 D0 FE A9 001E65 1 11 8D 02 02 001E69 1 001E69 1 .if rkwl_wdc_op = 1 001E69 1 ; testing RMB, SMB - zp 001E69 1 001E69 1 .macro rmb n,addr 001E69 1 .if n = 0 001E69 1 rmb0 addr 001E69 1 .elseif n = 1 001E69 1 rmb1 addr 001E69 1 .elseif n = 2 001E69 1 rmb2 addr 001E69 1 .elseif n = 3 001E69 1 rmb3 addr 001E69 1 .elseif n = 4 001E69 1 rmb4 addr 001E69 1 .elseif n = 5 001E69 1 rmb5 addr 001E69 1 .elseif n = 6 001E69 1 rmb6 addr 001E69 1 .elseif n = 7 001E69 1 rmb7 addr 001E69 1 .else 001E69 1 .error "syntax error in rmb" 001E69 1 .endif 001E69 1 .endmacro 001E69 1 001E69 1 .macro smb n,addr 001E69 1 .if n = 0 001E69 1 smb0 addr 001E69 1 .elseif n = 1 001E69 1 smb1 addr 001E69 1 .elseif n = 2 001E69 1 smb2 addr 001E69 1 .elseif n = 3 001E69 1 smb3 addr 001E69 1 .elseif n = 4 001E69 1 smb4 addr 001E69 1 .elseif n = 5 001E69 1 smb5 addr 001E69 1 .elseif n = 6 001E69 1 smb6 addr 001E69 1 .elseif n = 7 001E69 1 smb7 addr 001E69 1 .else 001E69 1 .error "syntax error in smb" 001E69 1 .endif 001E69 1 .endmacro 001E69 1 001E69 1 .macro rmbt bitnum 001E69 1 lda #$ff 001E69 1 sta zpt 001E69 1 set_a $a5,0 001E69 1 rmb bitnum,zpt 001E69 1 tst_a $a5,0 001E69 1 lda zpt 001E69 1 cmp #$ff-(1<brk_ret0 002753 1 D0 FE trap_ne 002755 1 AD FE 01 lda $1fe 002758 1 C9 20 cmp #brk_ret1 002791 1 D0 FE trap_ne 002793 1 AD FE 01 lda $1fe 002796 1 C9 46 cmp # 1 0027AC 1 zp_init: 0027AC 1 zp1_: .byte $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR 0027AC 1 zp7f_: .byte $7f ;test pattern for compare 0027AC 1 ;logical zeropage operands 0027AC 1 zpOR_: .byte 0,$1f,$71,$80 ;test pattern for OR 0027AC 1 zpAN_: .byte $0f,$ff,$7f,$80 ;test pattern for AND 0027AC 1 zpEO_: .byte $ff,$0f,$8f,$8f ;test pattern for EOR 0027AC 1 ;indirect addressing pointers 0027AC 1 ind1_: .word abs1 ;indirect pointer to pattern in absolute memory 0027AC 1 .word abs1+1 0027AC 1 .word abs1+2 0027AC 1 .word abs1+3 0027AC 1 .word abs7f 0027AC 1 inw1_: .word abs1-$f8 ;indirect pointer for wrap-test pattern 0027AC 1 indt_: .word abst ;indirect pointer to store area in absolute memory 0027AC 1 .word abst+1 0027AC 1 .word abst+2 0027AC 1 .word abst+3 0027AC 1 inwt_: .word abst-$f8 ;indirect pointer for wrap-test store 0027AC 1 indAN_: .word absAN ;indirect pointer to AND pattern in absolute memory 0027AC 1 .word absAN+1 0027AC 1 .word absAN+2 0027AC 1 .word absAN+3 0027AC 1 indEO_: .word absEO ;indirect pointer to EOR pattern in absolute memory 0027AC 1 .word absEO+1 0027AC 1 .word absEO+2 0027AC 1 .word absEO+3 0027AC 1 indOR_: .word absOR ;indirect pointer to OR pattern in absolute memory 0027AC 1 .word absOR+1 0027AC 1 .word absOR+2 0027AC 1 .word absOR+3 0027AC 1 ;add/subtract indirect pointers 0027AC 1 adi2_: .word ada2 ;indirect pointer to operand 2 in absolute memory 0027AC 1 sbi2_: .word sba2 ;indirect pointer to complemented operand 2 (SBC) 0027AC 1 adiy2_: .word ada2-$ff ;with offset for indirect indexed 0027AC 1 sbiy2_: .word sba2-$ff 0027AC 1 zp_end: 0027AC 1 .if (zp_end - zp_init) <> (zp_bss_end - zp_bss) 0027AC 1 ;force assembler error if size is different 0027AC 1 .error "mismatch between bss and zeropage data" 0027AC 1 .endif 0027AC 1 data_init: 0027AC 1 ex_adc_:adc #0 ;execute immediate opcodes 0027AC 1 rts 0027AC 1 ex_sbc_:sbc #0 ;execute immediate opcodes 0027AC 1 rts 0027AC 1 abs1_: .byte $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR 0027AC 1 abs7f_: .byte $7f ;test pattern for compare 0027AC 1 ;loads 0027AC 1 fLDx_: .byte fn,fn,0,fz ;expected flags for load 0027AC 1 ;shifts 0027AC 1 rASL_: ;expected result ASL & ROL -carry 0027AC 1 rROL_: .byte $86,$04,$82,0 ; " 0027AC 1 rROLc_: .byte $87,$05,$83,1 ;expected result ROL +carry 0027AC 1 rLSR_: ;expected result LSR & ROR -carry 0027AC 1 rROR_: .byte $61,$41,$20,0 ; " 0027AC 1 rRORc_: .byte $e1,$c1,$a0,$80 ;expected result ROR +carry 0027AC 1 fASL_: ;expected flags for shifts 0027AC 1 fROL_: .byte fnc,fc,fn,fz ;no carry in 0027AC 1 fROLc_: .byte fnc,fc,fn,0 ;carry in 0027AC 1 fLSR_: 0027AC 1 fROR_: .byte fc,0,fc,fz ;no carry in 0027AC 1 fRORc_: .byte fnc,fn,fnc,fn ;carry in 0027AC 1 ;increments (decrements) 0027AC 1 rINC_: .byte $7f,$80,$ff,0,1 ;expected result for INC/DEC 0027AC 1 fINC_: .byte 0,fn,fn,fz,0 ;expected flags for INC/DEC 0027AC 1 ;logical memory operand 0027AC 1 absOR_: .byte 0,$1f,$71,$80 ;test pattern for OR 0027AC 1 absAN_: .byte $0f,$ff,$7f,$80 ;test pattern for AND 0027AC 1 absEO_: .byte $ff,$0f,$8f,$8f ;test pattern for EOR 0027AC 1 ;logical accu operand 0027AC 1 absORa_:.byte 0,$f1,$1f,0 ;test pattern for OR 0027AC 1 absANa_:.byte $f0,$ff,$ff,$ff ;test pattern for AND 0027AC 1 absEOa_:.byte $ff,$f0,$f0,$0f ;test pattern for EOR 0027AC 1 ;logical results 0027AC 1 absrlo_:.byte 0,$ff,$7f,$80 0027AC 1 absflo_:.byte fz,fn,0,fn 0027AC 1 data_end: 0027AC 1 .if (data_end - data_init) <> (data_bss_end - data_bss) 0027AC 1 ;force assembler error if size is different 0027AC 1 .error "mismatch between bss and data" 0027AC 1 .endif 0027AC 1 0027AC 1 vec_init: 0027AC 1 .word nmi_trap 0027AC 1 .word res_trap 0027AC 1 .word irq_trap 0027AC 1 vec_bss equ $fffa 0027AC 1 .endif ;end of RAM init data 0027AC 1 0027AC 1 ; code at end of image due to the need to add blank space as required 0027AC 1 .if ($ff & (ji_ret - * - 2)) < ($ff & (jxi_ret - * - 2)) 0027AC 1 ; JMP (abs) when $xxff and $xx00 are from same page 0027AC 1 .res <(ji_ret - * - 2) 0027AC 1 nop 0027AC 1 nop 0027AC 1 ji_px: nop ;low address byte matched with ji_ret 0027AC 1 nop 0027AC 1 trap ;jmp indirect page cross bug 0027AC 1 0027AC 1 ; JMP (abs,x) when $xxff and $xx00 are from same page 0027AC 1 .res <(jxi_ret - * - 2) 0027AC 1 nop 0027AC 1 nop 0027AC 1 jxi_px: nop ;low address byte matched with jxi_ret 0027AC 1 nop 0027AC 1 trap ;jmp indexed indirect page cross bug 0027AC 1 .else 0027AC 1 ; JMP (abs,x) when $xxff and $xx00 are from same page 0027AC 1 xx xx xx xx .res <(jxi_ret - * - 2) 0027B0 1 xx xx xx xx 0027B4 1 xx xx xx xx 0027CC 1 EA nop 0027CD 1 EA nop 0027CE 1 EA jxi_px: nop ;low address byte matched with jxi_ret 0027CF 1 EA nop 0027D0 1 4C D0 27 trap ;jmp indexed indirect page cross bug 0027D3 1 0027D3 1 ; JMP (abs) when $xxff and $xx00 are from same page 0027D3 1 xx xx xx xx .res <(ji_ret - * - 2) 0027D7 1 xx xx xx xx 0027DB 1 xx xx xx xx 002880 1 EA nop 002881 1 EA nop 002882 1 EA ji_px: nop ;low address byte matched with ji_ret 002883 1 EA nop 002884 1 4C 84 28 trap ;jmp indirect page cross bug 002887 1 .endif 002887 1 002887 1 .if (load_data_direct = 1) & (ROM_vectors = 1) 002887 1 .segment "VECTORS" 002887 1 16 27 .word nmi_trap 002889 1 1C 27 .word res_trap 00288B 1 24 27 .word irq_trap 00288D 1 .endif 00288D 1