ca65 V2.18 - N/A Main file : ./6502_65C02_functional_tests/ca65/6502_functional_test.ca65 Current file: ./6502_65C02_functional_tests/ca65/6502_functional_test.ca65 000000r 1 ; 000000r 1 ; 6 5 0 2 F U N C T I O N A L T E S T 000000r 1 ; 000000r 1 ; Copyright (C) 2012-2020 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 opcodes of a 6502 emulator using all 000000r 1 ; addressing modes with focus on propper setting of the processor status 000000r 1 ; register bits. 000000r 1 ; 000000r 1 ; version 05-jan-2020 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 NMOS 6502 only! No unofficial 000000r 1 ; opcodes. Additional opcodes of newer versions of the CPU (65C02, 65816) will 000000r 1 ; not be tested. Decimal ops will only be tested with valid BCD operands and 000000r 1 ; N V Z flags will be ignored. 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 ; 28-jul-2012 1st version distributed for testing 000000r 1 ; 29-jul-2012 fixed references to location 0, now #0 000000r 1 ; added license - GPLv3 000000r 1 ; 30-jul-2012 added configuration options 000000r 1 ; 01-aug-2012 added trap macro to allow user to change error handling 000000r 1 ; 01-dec-2012 fixed trap in branch field must be a branch 000000r 1 ; 02-mar-2013 fixed PLA flags not tested 000000r 1 ; 19-jul-2013 allowed ROM vectors to be loaded when load_data_direct = 0 000000r 1 ; added test sequence check to detect if tests jump their fence 000000r 1 ; 23-jul-2013 added RAM integrity check option 000000r 1 ; 16-aug-2013 added error report to standard output option 000000r 1 ; 13-dec-2014 added binary/decimal opcode table switch test 000000r 1 ; 14-dec-2014 improved relative address test 000000r 1 ; 23-aug-2015 added option to disable self modifying tests 000000r 1 ; 24-aug-2015 all self modifying immediate opcodes now execute in data RAM 000000r 1 ; added small branch offset pretest 000000r 1 ; 21-oct-2015 added option to disable decimal mode ADC & SBC tests 000000r 1 ; 04-dec-2017 fixed BRK only tested with interrupts enabled 000000r 1 ; added option to skip the remainder of a failing test 000000r 1 ; in report.i65 000000r 1 ; 05-jan-2020 fixed shifts not testing zero result and flag when last 1-bit 000000r 1 ; is shifted out 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. SEI & CLI can only be 000000r 1 ;tested if you allow changing the interrupt status (I_flag = 3) 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, $52 (82) 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, $7B (123) consecutive Bytes required 000000r 1 ; check that this matches the linker configuration file 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, 13.1kB of consecutive space required 000000r 1 ; add 2.5 kB if I_flag = 2 000000r 1 ; check that this matches the linker configuration file 000000r 1 code_segment = $400 000000r 1 000000r 1 ;self modifying code may be disabled to allow running in ROM 000000r 1 ;0=part of the code is self modifying and must reside in RAM 000000r 1 ;1=tests disabled: branch range 000000r 1 disable_selfmod = 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.5 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 ;disable test decimal mode ADC & SBC, 0=enable, 1=disable, 000000r 1 ;2=disable including decimal flag in processor status 000000r 1 disable_decimal = 0 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 faod equ fao+decmode ;+ ignore decimal 000000r 1 faid equ fai+decmode ;+ ignore decimal 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 test of decimal bit 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 disable_decimal < 2 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 .else 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 ora #decmode ;ignore decimal mode bit 000000r 1 cmp #(p1|faod)&m8i ;I_flag is always enabled + always on bits 000000r 1 .endmacro 000000r 1 .macro eor_flag p1 000000r 1 ora #decmode ;ignore decimal mode bit 000000r 1 eor #(p1&m8i|faod) ;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 ora #decmode ;ignore decimal mode bit 000000r 1 cmp #(p1|faid)&m8 ;I_flag is always disabled + always on bits 000000r 1 .endmacro 000000r 1 .macro eor_flag p1 000000r 1 ora #decmode ;ignore decimal mode bit 000000r 1 eor #(p1|faid) ;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 ora #decmode ;ignore decimal mode bit 000000r 1 cmp #(p1|faod)&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 ora #decmode ;ignore decimal mode bit 000000r 1 eor #(p1&m8i|faod) ;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 ora #decmode ;ignore decimal mode bit 000000r 1 cmp #(p1|faod)&m8 ;expected flags + always on bits 000000r 1 .endmacro 000000r 1 .macro eor_flag p1 000000r 1 ora #decmode ;ignore decimal mode bit 000000r 1 eor #p1|faod ;invert expected flags + always on bits 000000r 1 .endmacro 000000r 1 .endif 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_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 check_ram macro 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 .if disable_selfmod = 0 000000r 1 sta range_adr ;reset self modifying code 000000r 1 .endif 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 #hi(abs1) ;set high byte of indirect pointer 000000r 1 stx zpt+1 000000r 1 ldy #lo(abs1) ;data after write & execute test area 000000r 1 ccs5: adc (zpt),y 000000r 1 bcc ccs4 000000r 1 inc zpt+3 ;carry to high byte 000000r 1 clc 000000r 1 ccs4: iny 000000r 1 bne ccs5 000000r 1 inx ;advance RAM high address 000000r 1 stx zpt+1 000000r 1 cpx #ram_top 000000r 1 bne ccs5 000000r 1 sta zpt+2 ;checksum low is 000000r 1 cmp ram_chksm ;checksum low expected 000000r 1 trap_ne ;checksum mismatch 000000r 1 lda zpt+3 ;checksum high is 000000r 1 cmp ram_chksm+1 ;checksum high expected 000000r 1 trap_ne ;checksum mismatch 000000r 1 .endmacro 000000r 1 .else 000000r 1 .macro check_ram 000000r 1 ;RAM check disabled - RAM size not set 000000r 1 .endmacro 000000r 1 .endif 000000r 1 000000r 1 .macro next_test ;make sure, tests don't jump the fence 000000r 1 lda test_case ;previous test 000000r 1 cmp #test_num 000000r 1 trap_ne ;test is out of sequence 000000r 1 test_num .set test_num + 1 000000r 1 lda #test_num ;*** next tests' number 000000r 1 sta test_case 000000r 1 ;check_ram ;uncomment to find altered RAM after each test 000000r 1 .endmacro 000000r 1 000000r 1 .ZEROPAGE 000000r 1 00 00 00 00 .res zero_page, 0 000004r 1 00 00 00 00 000008r 1 00 00 00000Ar 1 .org zero_page 00000A 1 00000A 1 ;break test interrupt save 00000A 1 00 irq_a: .res 1,0 ;a register 00000B 1 00 irq_x: .res 1,0 ;x register 00000C 1 .if I_flag = 2 00000C 1 ;masking for I bit in status 00000C 1 flag_I_on: .res 1,0 ;or mask to load flags 00000C 1 flag_I_off: .res 1,0 ;and mask to load flags 00000C 1 .endif 00000C 1 zpt: ;6 bytes store/modify test area 00000C 1 ;add/subtract operand generation and result/flag prediction 00000C 1 00 adfc: .res 1,0 ;carry flag before op 00000D 1 00 ad1: .res 1,0 ;operand 1 - accumulator 00000E 1 00 ad2: .res 1,0 ;operand 2 - memory / immediate 00000F 1 00 adrl: .res 1,0 ;expected result bits 0-7 000010 1 00 adrh: .res 1,0 ;expected result bit 8 (carry) 000011 1 00 adrf: .res 1,0 ;expected flags NV0000ZC (only binary mode) 000012 1 00 sb2: .res 1,0 ;operand 2 complemented for subtract 000013 1 zp_bss: 000013 1 80 01 zps: .byte $80,1 ;additional shift pattern to test zero result & flag 000015 1 C3 82 41 00 zp1: .byte $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR 000019 1 7F zp7f: .byte $7f ;test pattern for compare 00001A 1 ;logical zeropage operands 00001A 1 00 1F 71 80 zpOR: .byte 0,$1f,$71,$80 ;test pattern for OR 00001E 1 0F FF 7F 80 zpAN: .byte $0f,$ff,$7f,$80 ;test pattern for AND 000022 1 FF 0F 8F 8F zpEO: .byte $ff,$0f,$8f,$8f ;test pattern for EOR 000026 1 ;indirect addressing pointers 000026 1 18 02 ind1: .word abs1 ;indirect pointer to pattern in absolute memory 000028 1 19 02 .word abs1+1 00002A 1 1A 02 .word abs1+2 00002C 1 1B 02 .word abs1+3 00002E 1 1C 02 .word abs7f 000030 1 20 01 inw1: .word abs1-$f8 ;indirect pointer for wrap-test pattern 000032 1 03 02 indt: .word abst ;indirect pointer to store area in absolute memory 000034 1 04 02 .word abst+1 000036 1 05 02 .word abst+2 000038 1 06 02 .word abst+3 00003A 1 0B 01 inwt: .word abst-$f8 ;indirect pointer for wrap-test store 00003C 1 5F 02 indAN: .word absAN ;indirect pointer to AND pattern in absolute memory 00003E 1 60 02 .word absAN+1 000040 1 61 02 .word absAN+2 000042 1 62 02 .word absAN+3 000044 1 63 02 indEO: .word absEO ;indirect pointer to EOR pattern in absolute memory 000046 1 64 02 .word absEO+1 000048 1 65 02 .word absEO+2 00004A 1 66 02 .word absEO+3 00004C 1 5B 02 indOR: .word absOR ;indirect pointer to OR pattern in absolute memory 00004E 1 5C 02 .word absOR+1 000050 1 5D 02 .word absOR+2 000052 1 5E 02 .word absOR+3 000054 1 ;add/subtract indirect pointers 000054 1 03 02 adi2: .word ada2 ;indirect pointer to operand 2 in absolute memory 000056 1 04 02 sbi2: .word sba2 ;indirect pointer to complemented operand 2 (SBC) 000058 1 04 01 adiy2: .word ada2-$ff ;with offset for indirect indexed 00005A 1 05 01 sbiy2: .word sba2-$ff 00005C 1 zp_bss_end: 00005C 1 00005C 1 .DATA 00005C 1 .org data_segment 000200 1 000200 1 00 test_case: .res 1,0 ;current test number 000201 1 00 00 ram_chksm: .res 2,0 ;checksum for RAM integrity test 000203 1 ;add/subtract operand copy - abs tests write area 000203 1 abst: ;6 bytes store/modify test area 000203 1 00 ada2: .res 1,0 ;operand 2 000204 1 00 sba2: .res 1,0 ;operand 2 complemented for subtract 000205 1 00 00 00 00 .res 4,0 ;fill remaining bytes 000209 1 data_bss: 000209 1 .if load_data_direct = 1 000209 1 29 00 ex_andi:and #0 ;execute immediate opcodes 00020B 1 60 rts 00020C 1 49 00 ex_eori:eor #0 ;execute immediate opcodes 00020E 1 60 rts 00020F 1 09 00 ex_orai:ora #0 ;execute immediate opcodes 000211 1 60 rts 000212 1 69 00 ex_adci:adc #0 ;execute immediate opcodes 000214 1 60 rts 000215 1 E9 00 ex_sbci:sbc #0 ;execute immediate opcodes 000217 1 60 rts 000218 1 .else 000218 1 ex_andi:.res 3 000218 1 ex_eori:.res 3 000218 1 ex_orai:.res 3 000218 1 ex_adci:.res 3 000218 1 ex_sbci:.res 3 000218 1 .endif 000218 1 ;zps .byte $80,1 ;additional shift patterns test zero result & flag 000218 1 C3 82 41 00 abs1: .byte $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR 00021C 1 7F abs7f: .byte $7f ;test pattern for compare 00021D 1 ;loads 00021D 1 80 80 00 02 fLDx: .byte fn,fn,0,fz ;expected flags for load 000221 1 ;shifts 000221 1 rASL: ;expected result ASL & ROL -carry 000221 1 00 02 86 04 rROL: .byte 0,2,$86,$04,$82,0 000225 1 82 00 000227 1 01 03 87 05 rROLc: .byte 1,3,$87,$05,$83,1 ;expected result ROL +carry 00022B 1 83 01 00022D 1 rLSR: ;expected result LSR & ROR -carry 00022D 1 40 00 61 41 rROR: .byte $40,0,$61,$41,$20,0 000231 1 20 00 000233 1 C0 80 E1 C1 rRORc: .byte $c0,$80,$e1,$c1,$a0,$80 ;expected result ROR +carry 000237 1 A0 80 000239 1 fASL: ;expected flags for shifts 000239 1 03 00 81 01 fROL: .byte fzc,0,fnc,fc,fn,fz ;no carry in 00023D 1 80 02 00023F 1 01 00 81 01 fROLc: .byte fc,0,fnc,fc,fn,0 ;carry in 000243 1 80 00 000245 1 fLSR: 000245 1 00 03 01 00 fROR: .byte 0,fzc,fc,0,fc,fz ;no carry in 000249 1 01 02 00024B 1 80 81 81 80 fRORc: .byte fn,fnc,fnc,fn,fnc,fn ;carry in 00024F 1 81 80 000251 1 ;increments (decrements) 000251 1 7F 80 FF 00 rINC: .byte $7f,$80,$ff,0,1 ;expected result for INC/DEC 000255 1 01 000256 1 00 80 80 02 fINC: .byte 0,fn,fn,fz,0 ;expected flags for INC/DEC 00025A 1 00 00025B 1 ;logical memory operand 00025B 1 00 1F 71 80 absOR: .byte 0,$1f,$71,$80 ;test pattern for OR 00025F 1 0F FF 7F 80 absAN: .byte $0f,$ff,$7f,$80 ;test pattern for AND 000263 1 FF 0F 8F 8F absEO: .byte $ff,$0f,$8f,$8f ;test pattern for EOR 000267 1 ;logical accu operand 000267 1 00 F1 1F 00 absORa: .byte 0,$f1,$1f,0 ;test pattern for OR 00026B 1 F0 FF FF FF absANa: .byte $f0,$ff,$ff,$ff ;test pattern for AND 00026F 1 FF F0 F0 0F absEOa: .byte $ff,$f0,$f0,$0f ;test pattern for EOR 000273 1 ;logical results 000273 1 00 FF 7F 80 absrlo: .byte 0,$ff,$7f,$80 000277 1 02 80 00 80 absflo: .byte fz,fn,0,fn 00027B 1 data_bss_end: 00027B 1 00027B 1 00027B 1 .CODE 00027B 1 .org code_segment 000400 1 .P02 ; disable 65SC02, 65C02 and 65816 instructions 000400 1 D8 start: cld 000401 1 A2 FF ldx #$ff 000403 1 9A txs 000404 1 A9 00 lda #0 ;*** test 0 = initialize 000406 1 8D 00 02 sta test_case 000409 1 test_num .set 0 000409 1 000409 1 ;stop interrupts before initializing BSS 000409 1 .if I_flag = 1 000409 1 sei 000409 1 .endif 000409 1 000409 1 ;initialize I/O for report channel 000409 1 .if report = 1 000409 1 jsr report_init 000409 1 .endif 000409 1 000409 1 ;pretest small branch offset 000409 1 A2 05 ldx #5 00040B 1 4C 33 04 jmp psb_test 00040E 1 psb_bwok: 00040E 1 A0 05 ldy #5 000410 1 D0 08 bne psb_forw 000412 1 4C 12 04 trap ;branch should be taken 000415 1 88 dey ;forward landing zone 000416 1 88 dey 000417 1 88 dey 000418 1 88 dey 000419 1 88 dey 00041A 1 psb_forw: 00041A 1 88 dey 00041B 1 88 dey 00041C 1 88 dey 00041D 1 88 dey 00041E 1 88 dey 00041F 1 F0 17 beq psb_fwok 000421 1 4C 21 04 trap ;forward offset 000424 1 000424 1 CA dex ;backward landing zone 000425 1 CA dex 000426 1 CA dex 000427 1 CA dex 000428 1 CA dex 000429 1 psb_back: 000429 1 CA dex 00042A 1 CA dex 00042B 1 CA dex 00042C 1 CA dex 00042D 1 CA dex 00042E 1 F0 DE beq psb_bwok 000430 1 4C 30 04 trap ;backward offset 000433 1 psb_test: 000433 1 D0 F4 bne psb_back 000435 1 4C 35 04 trap ;branch should be taken 000438 1 psb_fwok: 000438 1 000438 1 ;initialize BSS segment 000438 1 .if load_data_direct <> 1 000438 1 ldx #zp_end-zp_init-1 000438 1 ld_zp: lda zp_init,x 000438 1 sta zp_bss,x 000438 1 dex 000438 1 bpl ld_zp 000438 1 ldx #data_end-data_init-1 000438 1 ld_data:lda data_init,x 000438 1 sta data_bss,x 000438 1 dex 000438 1 bpl ld_data 000438 1 .if ROM_vectors = 1 000438 1 ldx #5 000438 1 ld_vect:lda vec_init,x 000438 1 sta vec_bss,x 000438 1 dex 000438 1 bpl ld_vect 000438 1 .endif 000438 1 .endif 000438 1 000438 1 ;retain status of interrupt flag 000438 1 .if I_flag = 2 000438 1 php 000438 1 pla 000438 1 and #4 ;isolate flag 000438 1 sta flag_I_on ;or mask 000438 1 eor #lo(~4) ;reverse 000438 1 sta flag_I_off ;and mask 000438 1 .endif 000438 1 000438 1 ;generate checksum for RAM integrity test 000438 1 .if ram_top > -1 000438 1 lda #0 000438 1 sta zpt ;set low byte of indirect pointer 000438 1 sta ram_chksm+1 ;checksum high byte 000438 1 .if disable_selfmod = 0 000438 1 sta range_adr ;reset self modifying code 000438 1 .endif 000438 1 clc 000438 1 ldx #zp_bss-zero_page ;zeropage - write test area 000438 1 gcs3: adc zero_page,x 000438 1 bcc gcs2 000438 1 inc ram_chksm+1 ;carry to high byte 000438 1 clc 000438 1 gcs2: inx 000438 1 bne gcs3 000438 1 ldx #hi(abs1) ;set high byte of indirect pointer 000438 1 stx zpt+1 000438 1 ldy #lo(abs1) ;data after write & execute test area 000438 1 gcs5: adc (zpt),y 000438 1 bcc gcs4 000438 1 inc ram_chksm+1 ;carry to high byte 000438 1 clc 000438 1 gcs4: iny 000438 1 bne gcs5 000438 1 inx ;advance RAM high address 000438 1 stx zpt+1 000438 1 cpx #ram_top 000438 1 bne gcs5 000438 1 sta ram_chksm ;checksum complete 000438 1 .endif 000438 1 AD 00 02 C9 next_test 00043C 1 00 D0 FE A9 000440 1 01 8D 00 02 000444 1 000444 1 .if disable_selfmod = 0 000444 1 ;testing relative addressing with BEQ 000444 1 A0 FE ldy #$fe ;testing maximum range, not -1/-2 (invalid/self adr) 000446 1 range_loop: 000446 1 88 dey ;next relative address 000447 1 98 tya 000448 1 AA tax ;precharge count to end of loop 000449 1 10 08 bpl range_fw ;calculate relative address 00044B 1 18 clc ;avoid branch self or to relative address of branch 00044C 1 69 02 adc #2 00044E 1 EA nop ;offset landing zone - tolerate +/-5 offset to branch 00044F 1 EA nop 000450 1 EA nop 000451 1 EA nop 000452 1 EA nop 000453 1 range_fw: 000453 1 EA nop 000454 1 EA nop 000455 1 EA nop 000456 1 EA nop 000457 1 EA nop 000458 1 49 7F eor #$7f ;complement except sign 00045A 1 8D E6 04 sta range_adr ;load into test target 00045D 1 A9 00 lda #0 ;should set zero flag in status register 00045F 1 4C E5 04 jmp range_op 000462 1 000462 1 CA dex ; offset landing zone - backward branch too far 000463 1 CA dex 000464 1 CA dex 000465 1 CA dex 000466 1 CA dex 000467 1 ;relative address target field with branch under test in the middle 000467 1 CA dex ;-128 - max backward 000468 1 CA dex 000469 1 CA dex 00046A 1 CA dex 00046B 1 CA dex 00046C 1 CA dex 00046D 1 CA dex 00046E 1 CA dex 00046F 1 CA dex ;-120 000470 1 CA dex 000471 1 CA dex 000472 1 CA dex 000473 1 CA dex 000474 1 CA dex 000475 1 CA dex 000476 1 CA dex 000477 1 CA dex 000478 1 CA dex 000479 1 CA dex ;-110 00047A 1 CA dex 00047B 1 CA dex 00047C 1 CA dex 00047D 1 CA dex 00047E 1 CA dex 00047F 1 CA dex 000480 1 CA dex 000481 1 CA dex 000482 1 CA dex 000483 1 CA dex ;-100 000484 1 CA dex 000485 1 CA dex 000486 1 CA dex 000487 1 CA dex 000488 1 CA dex 000489 1 CA dex 00048A 1 CA dex 00048B 1 CA dex 00048C 1 CA dex 00048D 1 CA dex ;-90 00048E 1 CA dex 00048F 1 CA dex 000490 1 CA dex 000491 1 CA dex 000492 1 CA dex 000493 1 CA dex 000494 1 CA dex 000495 1 CA dex 000496 1 CA dex 000497 1 CA dex ;-80 000498 1 CA dex 000499 1 CA dex 00049A 1 CA dex 00049B 1 CA dex 00049C 1 CA dex 00049D 1 CA dex 00049E 1 CA dex 00049F 1 CA dex 0004A0 1 CA dex 0004A1 1 CA dex ;-70 0004A2 1 CA dex 0004A3 1 CA dex 0004A4 1 CA dex 0004A5 1 CA dex 0004A6 1 CA dex 0004A7 1 CA dex 0004A8 1 CA dex 0004A9 1 CA dex 0004AA 1 CA dex 0004AB 1 CA dex ;-60 0004AC 1 CA dex 0004AD 1 CA dex 0004AE 1 CA dex 0004AF 1 CA dex 0004B0 1 CA dex 0004B1 1 CA dex 0004B2 1 CA dex 0004B3 1 CA dex 0004B4 1 CA dex 0004B5 1 CA dex ;-50 0004B6 1 CA dex 0004B7 1 CA dex 0004B8 1 CA dex 0004B9 1 CA dex 0004BA 1 CA dex 0004BB 1 CA dex 0004BC 1 CA dex 0004BD 1 CA dex 0004BE 1 CA dex 0004BF 1 CA dex ;-40 0004C0 1 CA dex 0004C1 1 CA dex 0004C2 1 CA dex 0004C3 1 CA dex 0004C4 1 CA dex 0004C5 1 CA dex 0004C6 1 CA dex 0004C7 1 CA dex 0004C8 1 CA dex 0004C9 1 CA dex ;-30 0004CA 1 CA dex 0004CB 1 CA dex 0004CC 1 CA dex 0004CD 1 CA dex 0004CE 1 CA dex 0004CF 1 CA dex 0004D0 1 CA dex 0004D1 1 CA dex 0004D2 1 CA dex 0004D3 1 CA dex ;-20 0004D4 1 CA dex 0004D5 1 CA dex 0004D6 1 CA dex 0004D7 1 CA dex 0004D8 1 CA dex 0004D9 1 CA dex 0004DA 1 CA dex 0004DB 1 CA dex 0004DC 1 CA dex 0004DD 1 CA dex ;-10 0004DE 1 CA dex 0004DF 1 CA dex 0004E0 1 CA dex 0004E1 1 CA dex 0004E2 1 CA dex 0004E3 1 CA dex 0004E4 1 CA dex ;-3 0004E5 1 range_op: ;test target with zero flag=0, z=1 if previous dex 0004E5 1 range_adr = *+1 ;modifiable relative address 0004E5 1 F0 3E beq *+64 ;+64 if called without modification 0004E7 1 CA dex ;+0 0004E8 1 CA dex 0004E9 1 CA dex 0004EA 1 CA dex 0004EB 1 CA dex 0004EC 1 CA dex 0004ED 1 CA dex 0004EE 1 CA dex 0004EF 1 CA dex 0004F0 1 CA dex 0004F1 1 CA dex ;+10 0004F2 1 CA dex 0004F3 1 CA dex 0004F4 1 CA dex 0004F5 1 CA dex 0004F6 1 CA dex 0004F7 1 CA dex 0004F8 1 CA dex 0004F9 1 CA dex 0004FA 1 CA dex 0004FB 1 CA dex ;+20 0004FC 1 CA dex 0004FD 1 CA dex 0004FE 1 CA dex 0004FF 1 CA dex 000500 1 CA dex 000501 1 CA dex 000502 1 CA dex 000503 1 CA dex 000504 1 CA dex 000505 1 CA dex ;+30 000506 1 CA dex 000507 1 CA dex 000508 1 CA dex 000509 1 CA dex 00050A 1 CA dex 00050B 1 CA dex 00050C 1 CA dex 00050D 1 CA dex 00050E 1 CA dex 00050F 1 CA dex ;+40 000510 1 CA dex 000511 1 CA dex 000512 1 CA dex 000513 1 CA dex 000514 1 CA dex 000515 1 CA dex 000516 1 CA dex 000517 1 CA dex 000518 1 CA dex 000519 1 CA dex ;+50 00051A 1 CA dex 00051B 1 CA dex 00051C 1 CA dex 00051D 1 CA dex 00051E 1 CA dex 00051F 1 CA dex 000520 1 CA dex 000521 1 CA dex 000522 1 CA dex 000523 1 CA dex ;+60 000524 1 CA dex 000525 1 CA dex 000526 1 CA dex 000527 1 CA dex 000528 1 CA dex 000529 1 CA dex 00052A 1 CA dex 00052B 1 CA dex 00052C 1 CA dex 00052D 1 CA dex ;+70 00052E 1 CA dex 00052F 1 CA dex 000530 1 CA dex 000531 1 CA dex 000532 1 CA dex 000533 1 CA dex 000534 1 CA dex 000535 1 CA dex 000536 1 CA dex 000537 1 CA dex ;+80 000538 1 CA dex 000539 1 CA dex 00053A 1 CA dex 00053B 1 CA dex 00053C 1 CA dex 00053D 1 CA dex 00053E 1 CA dex 00053F 1 CA dex 000540 1 CA dex 000541 1 CA dex ;+90 000542 1 CA dex 000543 1 CA dex 000544 1 CA dex 000545 1 CA dex 000546 1 CA dex 000547 1 CA dex 000548 1 CA dex 000549 1 CA dex 00054A 1 CA dex 00054B 1 CA dex ;+100 00054C 1 CA dex 00054D 1 CA dex 00054E 1 CA dex 00054F 1 CA dex 000550 1 CA dex 000551 1 CA dex 000552 1 CA dex 000553 1 CA dex 000554 1 CA dex 000555 1 CA dex ;+110 000556 1 CA dex 000557 1 CA dex 000558 1 CA dex 000559 1 CA dex 00055A 1 CA dex 00055B 1 CA dex 00055C 1 CA dex 00055D 1 CA dex 00055E 1 CA dex 00055F 1 CA dex ;+120 000560 1 CA dex 000561 1 CA dex 000562 1 CA dex 000563 1 CA dex 000564 1 CA dex 000565 1 CA dex 000566 1 EA nop ;offset landing zone - forward branch too far 000567 1 EA nop 000568 1 EA nop 000569 1 EA nop 00056A 1 EA nop 00056B 1 F0 08 beq range_ok ;+127 - max forward 00056D 1 4C 6D 05 trap ; bad range 000570 1 EA nop ;offset landing zone - tolerate +/-5 offset to branch 000571 1 EA nop 000572 1 EA nop 000573 1 EA nop 000574 1 EA nop 000575 1 range_ok: 000575 1 EA nop 000576 1 EA nop 000577 1 EA nop 000578 1 EA nop 000579 1 EA nop 00057A 1 C0 00 cpy #0 00057C 1 F0 03 beq range_end 00057E 1 4C 46 04 jmp range_loop 000581 1 range_end: ;range test successful 000581 1 .endif 000581 1 AD 00 02 C9 next_test 000585 1 01 D0 FE A9 000589 1 02 8D 00 02 00058D 1 00058D 1 ;partial test BNE & CMP, CPX, CPY immediate 00058D 1 C0 01 cpy #1 ;testing BNE true 00058F 1 D0 03 bne test_bne 000591 1 4C 91 05 trap 000594 1 test_bne: 000594 1 A9 00 lda #0 000596 1 C9 00 cmp #0 ;test compare immediate 000598 1 D0 FE trap_ne 00059A 1 90 FE trap_cc 00059C 1 30 FE trap_mi 00059E 1 C9 01 cmp #1 0005A0 1 F0 FE trap_eq 0005A2 1 B0 FE trap_cs 0005A4 1 10 FE trap_pl 0005A6 1 AA tax 0005A7 1 E0 00 cpx #0 ;test compare x immediate 0005A9 1 D0 FE trap_ne 0005AB 1 90 FE trap_cc 0005AD 1 30 FE trap_mi 0005AF 1 E0 01 cpx #1 0005B1 1 F0 FE trap_eq 0005B3 1 B0 FE trap_cs 0005B5 1 10 FE trap_pl 0005B7 1 A8 tay 0005B8 1 C0 00 cpy #0 ;test compare y immediate 0005BA 1 D0 FE trap_ne 0005BC 1 90 FE trap_cc 0005BE 1 30 FE trap_mi 0005C0 1 C0 01 cpy #1 0005C2 1 F0 FE trap_eq 0005C4 1 B0 FE trap_cs 0005C6 1 10 FE trap_pl 0005C8 1 AD 00 02 C9 next_test 0005CC 1 02 D0 FE A9 0005D0 1 03 8D 00 02 0005D4 1 ;testing stack operations PHA PHP PLA PLP 0005D4 1 0005D4 1 A2 FF ldx #$ff ;initialize stack 0005D6 1 9A txs 0005D7 1 A9 55 lda #$55 0005D9 1 48 pha 0005DA 1 A9 AA lda #$aa 0005DC 1 48 pha 0005DD 1 CD FE 01 cmp $1fe ;on stack ? 0005E0 1 D0 FE trap_ne 0005E2 1 BA tsx 0005E3 1 8A txa ;overwrite accu 0005E4 1 C9 FD cmp #$fd ;sp decremented? 0005E6 1 D0 FE trap_ne 0005E8 1 68 pla 0005E9 1 C9 AA cmp #$aa ;successful retreived from stack? 0005EB 1 D0 FE trap_ne 0005ED 1 68 pla 0005EE 1 C9 55 cmp #$55 0005F0 1 D0 FE trap_ne 0005F2 1 CD FF 01 cmp $1ff ;remains on stack? 0005F5 1 D0 FE trap_ne 0005F7 1 BA tsx 0005F8 1 E0 FF cpx #$ff ;sp incremented? 0005FA 1 D0 FE trap_ne 0005FC 1 AD 00 02 C9 next_test 000600 1 03 D0 FE A9 000604 1 04 8D 00 02 000608 1 000608 1 ;testing branch decisions BPL BMI BVC BVS BCC BCS BNE BEQ 000608 1 A9 FF 48 28 set_stat $ff ;all on 00060C 1 10 1A bpl nbr1 ;branches should not be taken 00060E 1 50 1B bvc nbr2 000610 1 90 1C bcc nbr3 000612 1 D0 1D bne nbr4 000614 1 30 03 bmi br1 ;branches should be taken 000616 1 4C 16 06 trap 000619 1 70 03 br1: bvs br2 00061B 1 4C 1B 06 trap 00061E 1 B0 03 br2: bcs br3 000620 1 4C 20 06 trap 000623 1 F0 0F br3: beq br4 000625 1 4C 25 06 trap 000628 1 nbr1: 000628 1 4C 28 06 trap ;previous bpl taken 00062B 1 nbr2: 00062B 1 4C 2B 06 trap ;previous bvc taken 00062E 1 nbr3: 00062E 1 4C 2E 06 trap ;previous bcc taken 000631 1 nbr4: 000631 1 4C 31 06 trap ;previous bne taken 000634 1 08 br4: php 000635 1 BA tsx 000636 1 E0 FE cpx #$fe ;sp after php? 000638 1 D0 FE trap_ne 00063A 1 68 pla 00063B 1 C9 FF cmp_flag $ff ;returned all flags on? 00063D 1 D0 FE trap_ne 00063F 1 BA tsx 000640 1 E0 FF cpx #$ff ;sp after php? 000642 1 D0 FE trap_ne 000644 1 A9 00 48 28 set_stat 0 ;all off 000648 1 30 1A bmi nbr11 ;branches should not be taken 00064A 1 70 1B bvs nbr12 00064C 1 B0 1C bcs nbr13 00064E 1 F0 1D beq nbr14 000650 1 10 03 bpl br11 ;branches should be taken 000652 1 4C 52 06 trap 000655 1 50 03 br11: bvc br12 000657 1 4C 57 06 trap 00065A 1 90 03 br12: bcc br13 00065C 1 4C 5C 06 trap 00065F 1 D0 0F br13: bne br14 000661 1 4C 61 06 trap 000664 1 nbr11: 000664 1 4C 64 06 trap ;previous bmi taken 000667 1 nbr12: 000667 1 4C 67 06 trap ;previous bvs taken 00066A 1 nbr13: 00066A 1 4C 6A 06 trap ;previous bcs taken 00066D 1 nbr14: 00066D 1 4C 6D 06 trap ;previous beq taken 000670 1 08 br14: php 000671 1 68 pla 000672 1 C9 30 cmp_flag 0 ;flags off except break (pushed by sw) + reserved? 000674 1 D0 FE trap_ne 000676 1 ;crosscheck flags 000676 1 A9 02 48 28 set_stat zero 00067A 1 D0 02 bne brzs1 00067C 1 F0 03 beq brzs2 00067E 1 brzs1: 00067E 1 4C 7E 06 trap ;branch zero/non zero 000681 1 B0 02 brzs2: bcs brzs3 000683 1 90 03 bcc brzs4 000685 1 brzs3: 000685 1 4C 85 06 trap ;branch carry/no carry 000688 1 30 02 brzs4: bmi brzs5 00068A 1 10 03 bpl brzs6 00068C 1 brzs5: 00068C 1 4C 8C 06 trap ;branch minus/plus 00068F 1 70 02 brzs6: bvs brzs7 000691 1 50 03 bvc brzs8 000693 1 brzs7: 000693 1 4C 93 06 trap ;branch overflow/no overflow 000696 1 brzs8: 000696 1 A9 01 48 28 set_stat carry 00069A 1 F0 02 beq brcs1 00069C 1 D0 03 bne brcs2 00069E 1 brcs1: 00069E 1 4C 9E 06 trap ;branch zero/non zero 0006A1 1 90 02 brcs2: bcc brcs3 0006A3 1 B0 03 bcs brcs4 0006A5 1 brcs3: 0006A5 1 4C A5 06 trap ;branch carry/no carry 0006A8 1 30 02 brcs4: bmi brcs5 0006AA 1 10 03 bpl brcs6 0006AC 1 brcs5: 0006AC 1 4C AC 06 trap ;branch minus/plus 0006AF 1 70 02 brcs6: bvs brcs7 0006B1 1 50 03 bvc brcs8 0006B3 1 brcs7: 0006B3 1 4C B3 06 trap ;branch overflow/no overflow 0006B6 1 0006B6 1 brcs8: 0006B6 1 A9 80 48 28 set_stat minus 0006BA 1 F0 02 beq brmi1 0006BC 1 D0 03 bne brmi2 0006BE 1 brmi1: 0006BE 1 4C BE 06 trap ;branch zero/non zero 0006C1 1 B0 02 brmi2: bcs brmi3 0006C3 1 90 03 bcc brmi4 0006C5 1 brmi3: 0006C5 1 4C C5 06 trap ;branch carry/no carry 0006C8 1 10 02 brmi4: bpl brmi5 0006CA 1 30 03 bmi brmi6 0006CC 1 brmi5: 0006CC 1 4C CC 06 trap ;branch minus/plus 0006CF 1 70 02 brmi6: bvs brmi7 0006D1 1 50 03 bvc brmi8 0006D3 1 brmi7: 0006D3 1 4C D3 06 trap ;branch overflow/no overflow 0006D6 1 brmi8: 0006D6 1 A9 40 48 28 set_stat overfl 0006DA 1 F0 02 beq brvs1 0006DC 1 D0 03 bne brvs2 0006DE 1 brvs1: 0006DE 1 4C DE 06 trap ;branch zero/non zero 0006E1 1 B0 02 brvs2: bcs brvs3 0006E3 1 90 03 bcc brvs4 0006E5 1 brvs3: 0006E5 1 4C E5 06 trap ;branch carry/no carry 0006E8 1 30 02 brvs4: bmi brvs5 0006EA 1 10 03 bpl brvs6 0006EC 1 brvs5: 0006EC 1 4C EC 06 trap ;branch minus/plus 0006EF 1 50 02 brvs6: bvc brvs7 0006F1 1 70 03 bvs brvs8 0006F3 1 brvs7: 0006F3 1 4C F3 06 trap ;branch overflow/no overflow 0006F6 1 brvs8: 0006F6 1 A9 FD 48 28 set_stat $ff-zero 0006FA 1 F0 02 beq brzc1 0006FC 1 D0 03 bne brzc2 0006FE 1 brzc1: 0006FE 1 4C FE 06 trap ;branch zero/non zero 000701 1 90 02 brzc2: bcc brzc3 000703 1 B0 03 bcs brzc4 000705 1 brzc3: 000705 1 4C 05 07 trap ;branch carry/no carry 000708 1 10 02 brzc4: bpl brzc5 00070A 1 30 03 bmi brzc6 00070C 1 brzc5: 00070C 1 4C 0C 07 trap ;branch minus/plus 00070F 1 50 02 brzc6: bvc brzc7 000711 1 70 03 bvs brzc8 000713 1 brzc7: 000713 1 4C 13 07 trap ;branch overflow/no overflow 000716 1 brzc8: 000716 1 A9 FE 48 28 set_stat $ff-carry 00071A 1 D0 02 bne brcc1 00071C 1 F0 03 beq brcc2 00071E 1 brcc1: 00071E 1 4C 1E 07 trap ;branch zero/non zero 000721 1 B0 02 brcc2: bcs brcc3 000723 1 90 03 bcc brcc4 000725 1 brcc3: 000725 1 4C 25 07 trap ;branch carry/no carry 000728 1 10 02 brcc4: bpl brcc5 00072A 1 30 03 bmi brcc6 00072C 1 brcc5: 00072C 1 4C 2C 07 trap ;branch minus/plus 00072F 1 50 02 brcc6: bvc brcc7 000731 1 70 03 bvs brcc8 000733 1 brcc7: 000733 1 4C 33 07 trap ;branch overflow/no overflow 000736 1 brcc8: 000736 1 A9 7F 48 28 set_stat $ff-minus 00073A 1 D0 02 bne brpl1 00073C 1 F0 03 beq brpl2 00073E 1 brpl1: 00073E 1 4C 3E 07 trap ;branch zero/non zero 000741 1 90 02 brpl2: bcc brpl3 000743 1 B0 03 bcs brpl4 000745 1 brpl3: 000745 1 4C 45 07 trap ;branch carry/no carry 000748 1 30 02 brpl4: bmi brpl5 00074A 1 10 03 bpl brpl6 00074C 1 brpl5: 00074C 1 4C 4C 07 trap ;branch minus/plus 00074F 1 50 02 brpl6: bvc brpl7 000751 1 70 03 bvs brpl8 000753 1 brpl7: 000753 1 4C 53 07 trap ;branch overflow/no overflow 000756 1 brpl8: 000756 1 A9 BF 48 28 set_stat $ff-overfl 00075A 1 D0 02 bne brvc1 00075C 1 F0 03 beq brvc2 00075E 1 brvc1: 00075E 1 4C 5E 07 trap ;branch zero/non zero 000761 1 90 02 brvc2: bcc brvc3 000763 1 B0 03 bcs brvc4 000765 1 brvc3: 000765 1 4C 65 07 trap ;branch carry/no carry 000768 1 10 02 brvc4: bpl brvc5 00076A 1 30 03 bmi brvc6 00076C 1 brvc5: 00076C 1 4C 6C 07 trap ;branch minus/plus 00076F 1 70 02 brvc6: bvs brvc7 000771 1 50 03 bvc brvc8 000773 1 brvc7: 000773 1 4C 73 07 trap ;branch overflow/no overflow 000776 1 brvc8: 000776 1 AD 00 02 C9 next_test 00077A 1 04 D0 FE A9 00077E 1 05 8D 00 02 000782 1 000782 1 ; test PHA does not alter flags or accumulator but PLA does 000782 1 A2 55 ldx #$55 ;x & y protected 000784 1 A0 AA ldy #$aa 000786 1 A9 FF 48 A9 set_a 1,$ff ;push 00078A 1 01 28 00078C 1 48 pha 00078D 1 08 C9 01 D0 tst_a 1,$ff 000791 1 FE 68 48 C9 000795 1 FF D0 FE 28 000799 1 A9 00 48 A9 set_a 0,0 00079D 1 00 28 00079F 1 48 pha 0007A0 1 08 C9 00 D0 tst_a 0,0 0007A4 1 FE 68 48 C9 0007A8 1 30 D0 FE 28 0007AC 1 A9 FF 48 A9 set_a $ff,$ff 0007B0 1 FF 28 0007B2 1 48 pha 0007B3 1 08 C9 FF D0 tst_a $ff,$ff 0007B7 1 FE 68 48 C9 0007BB 1 FF D0 FE 28 0007BF 1 A9 00 48 A9 set_a 1,0 0007C3 1 01 28 0007C5 1 48 pha 0007C6 1 08 C9 01 D0 tst_a 1,0 0007CA 1 FE 68 48 C9 0007CE 1 30 D0 FE 28 0007D2 1 A9 FF 48 A9 set_a 0,$ff 0007D6 1 00 28 0007D8 1 48 pha 0007D9 1 08 C9 00 D0 tst_a 0,$ff 0007DD 1 FE 68 48 C9 0007E1 1 FF D0 FE 28 0007E5 1 A9 00 48 A9 set_a $ff,0 0007E9 1 FF 28 0007EB 1 48 pha 0007EC 1 08 C9 FF D0 tst_a $ff,0 0007F0 1 FE 68 48 C9 0007F4 1 30 D0 FE 28 0007F8 1 A9 FF 48 A9 set_a 0,$ff ;pull 0007FC 1 00 28 0007FE 1 68 pla 0007FF 1 08 C9 FF D0 tst_a $ff,$ff-zero 000803 1 FE 68 48 C9 000807 1 FD D0 FE 28 00080B 1 A9 00 48 A9 set_a $ff,0 00080F 1 FF 28 000811 1 68 pla 000812 1 08 C9 00 D0 tst_a 0,zero 000816 1 FE 68 48 C9 00081A 1 32 D0 FE 28 00081E 1 A9 FF 48 A9 set_a $fe,$ff 000822 1 FE 28 000824 1 68 pla 000825 1 08 C9 01 D0 tst_a 1,$ff-zero-minus 000829 1 FE 68 48 C9 00082D 1 7D D0 FE 28 000831 1 A9 00 48 A9 set_a 0,0 000835 1 00 28 000837 1 68 pla 000838 1 08 C9 FF D0 tst_a $ff,minus 00083C 1 FE 68 48 C9 000840 1 B0 D0 FE 28 000844 1 A9 FF 48 A9 set_a $ff,$ff 000848 1 FF 28 00084A 1 68 pla 00084B 1 08 C9 00 D0 tst_a 0,$ff-minus 00084F 1 FE 68 48 C9 000853 1 7F D0 FE 28 000857 1 A9 00 48 A9 set_a $fe,0 00085B 1 FE 28 00085D 1 68 pla 00085E 1 08 C9 01 D0 tst_a 1,0 000862 1 FE 68 48 C9 000866 1 30 D0 FE 28 00086A 1 E0 55 cpx #$55 ;x & y unchanged? 00086C 1 D0 FE trap_ne 00086E 1 C0 AA cpy #$aa 000870 1 D0 FE trap_ne 000872 1 AD 00 02 C9 next_test 000876 1 05 D0 FE A9 00087A 1 06 8D 00 02 00087E 1 00087E 1 ; partial pretest EOR # 00087E 1 A9 00 48 A9 set_a $3c,0 000882 1 3C 28 000884 1 49 C3 eor #$c3 000886 1 08 C9 FF D0 tst_a $ff,fn 00088A 1 FE 68 48 C9 00088E 1 B0 D0 FE 28 000892 1 A9 00 48 A9 set_a $c3,0 000896 1 C3 28 000898 1 49 C3 eor #$c3 00089A 1 08 C9 00 D0 tst_a 0,fz 00089E 1 FE 68 48 C9 0008A2 1 32 D0 FE 28 0008A6 1 AD 00 02 C9 next_test 0008AA 1 06 D0 FE A9 0008AE 1 07 8D 00 02 0008B2 1 0008B2 1 ; PC modifying instructions except branches (NOP, JMP, JSR, RTS, BRK, RTI) 0008B2 1 ; testing NOP 0008B2 1 A2 24 ldx #$24 0008B4 1 A0 42 ldy #$42 0008B6 1 A9 00 48 A9 set_a $18,0 0008BA 1 18 28 0008BC 1 EA nop 0008BD 1 08 C9 18 D0 tst_a $18,0 0008C1 1 FE 68 48 C9 0008C5 1 30 D0 FE 28 0008C9 1 E0 24 cpx #$24 0008CB 1 D0 FE trap_ne 0008CD 1 C0 42 cpy #$42 0008CF 1 D0 FE trap_ne 0008D1 1 A2 DB ldx #$db 0008D3 1 A0 BD ldy #$bd 0008D5 1 A9 FF 48 A9 set_a $e7,$ff 0008D9 1 E7 28 0008DB 1 EA nop 0008DC 1 08 C9 E7 D0 tst_a $e7,$ff 0008E0 1 FE 68 48 C9 0008E4 1 FF D0 FE 28 0008E8 1 E0 DB cpx #$db 0008EA 1 D0 FE trap_ne 0008EC 1 C0 BD cpy #$bd 0008EE 1 D0 FE trap_ne 0008F0 1 AD 00 02 C9 next_test 0008F4 1 07 D0 FE A9 0008F8 1 08 8D 00 02 0008FC 1 0008FC 1 ; jump absolute 0008FC 1 A9 00 48 28 set_stat $0 000900 1 A9 46 lda #'F' 000902 1 A2 41 ldx #'A' 000904 1 A0 52 ldy #'R' ;N=0, V=0, Z=0, C=0 000906 1 4C EF 36 jmp test_far 000909 1 EA nop 00090A 1 EA nop 00090B 1 D0 FE trap_ne ;runover protection 00090D 1 E8 inx 00090E 1 E8 inx 00090F 1 far_ret: 00090F 1 F0 FE trap_eq ;returned flags OK? 000911 1 10 FE trap_pl 000913 1 90 FE trap_cc 000915 1 50 FE trap_vc 000917 1 C9 EC cmp #('F'^$aa) ;returned registers OK? 000919 1 D0 FE trap_ne 00091B 1 E0 42 cpx #('A'+1) 00091D 1 D0 FE trap_ne 00091F 1 C0 4F cpy #('R'-3) 000921 1 D0 FE trap_ne 000923 1 CA dex 000924 1 C8 iny 000925 1 C8 iny 000926 1 C8 iny 000927 1 49 AA eor #$aa ;N=0, V=1, Z=0, C=1 000929 1 4C 32 09 jmp test_near 00092C 1 EA nop 00092D 1 EA nop 00092E 1 D0 FE trap_ne ;runover protection 000930 1 E8 inx 000931 1 E8 inx 000932 1 test_near: 000932 1 F0 FE trap_eq ;passed flags OK? 000934 1 30 FE trap_mi 000936 1 90 FE trap_cc 000938 1 50 FE trap_vc 00093A 1 C9 46 cmp #'F' ;passed registers OK? 00093C 1 D0 FE trap_ne 00093E 1 E0 41 cpx #'A' 000940 1 D0 FE trap_ne 000942 1 C0 52 cpy #'R' 000944 1 D0 FE trap_ne 000946 1 AD 00 02 C9 next_test 00094A 1 08 D0 FE A9 00094E 1 09 8D 00 02 000952 1 000952 1 ; jump indirect 000952 1 A9 00 48 28 set_stat 0 000956 1 A9 49 lda #'I' 000958 1 A2 4E ldx #'N' 00095A 1 A0 44 ldy #'D' ;N=0, V=0, Z=0, C=0 00095C 1 6C 1E 37 jmp (ptr_tst_ind) 00095F 1 EA nop 000960 1 D0 FE trap_ne ;runover protection 000962 1 88 dey 000963 1 88 dey 000964 1 ind_ret: 000964 1 08 php ;either SP or Y count will fail, if we do not hit 000965 1 88 dey 000966 1 88 dey 000967 1 88 dey 000968 1 28 plp 000969 1 F0 FE trap_eq ;returned flags OK? 00096B 1 10 FE trap_pl 00096D 1 90 FE trap_cc 00096F 1 50 FE trap_vc 000971 1 C9 E3 cmp #('I'^$aa) ;returned registers OK? 000973 1 D0 FE trap_ne 000975 1 E0 4F cpx #('N'+1) 000977 1 D0 FE trap_ne 000979 1 C0 3E cpy #('D'-6) 00097B 1 D0 FE trap_ne 00097D 1 BA tsx ;SP check 00097E 1 E0 FF cpx #$ff 000980 1 D0 FE trap_ne 000982 1 AD 00 02 C9 next_test 000986 1 09 D0 FE A9 00098A 1 0A 8D 00 02 00098E 1 00098E 1 ; jump subroutine & return from subroutine 00098E 1 A9 00 48 28 set_stat 0 000992 1 A9 4A lda #'J' 000994 1 A2 53 ldx #'S' 000996 1 A0 52 ldy #'R' ;N=0, V=0, Z=0, C=0 000998 1 20 5D 37 jsr test_jsr 00099B 1 jsr_ret = *-1 ;last address of jsr = return address 00099B 1 08 php ;either SP or Y count will fail, if we do not hit 00099C 1 88 dey 00099D 1 88 dey 00099E 1 88 dey 00099F 1 28 plp 0009A0 1 F0 FE trap_eq ;returned flags OK? 0009A2 1 10 FE trap_pl 0009A4 1 90 FE trap_cc 0009A6 1 50 FE trap_vc 0009A8 1 C9 E0 cmp #('J'^$aa) ;returned registers OK? 0009AA 1 D0 FE trap_ne 0009AC 1 E0 54 cpx #('S'+1) 0009AE 1 D0 FE trap_ne 0009B0 1 C0 4C cpy #('R'-6) 0009B2 1 D0 FE trap_ne 0009B4 1 BA tsx ;sp? 0009B5 1 E0 FF cpx #$ff 0009B7 1 D0 FE trap_ne 0009B9 1 AD 00 02 C9 next_test 0009BD 1 0A D0 FE A9 0009C1 1 0B 8D 00 02 0009C5 1 0009C5 1 ; break & return from interrupt 0009C5 1 .if ROM_vectors = 1 0009C5 1 A9 00 load_flag 0 ;with interrupts enabled if allowed! 0009C7 1 48 pha 0009C8 1 A9 42 lda #'B' 0009CA 1 A2 52 ldx #'R' 0009CC 1 A0 4B ldy #'K' 0009CE 1 28 plp ;N=0, V=0, Z=0, C=0 0009CF 1 00 brk 0009D0 1 .else 0009D0 1 lda #>brk_ret0 ;emulated break 0009D0 1 pha 0009D0 1 lda #brk_ret1 ;emulated break 0009F6 1 pha 0009F6 1 lda #bin_rti_ret ;emulated interrupt for rti 00343D 1 48 pha 00343E 1 A9 55 lda #dec_rti_ret ;emulated interrupt for rti 003445 1 48 pha 003446 1 A9 4C lda #jsr_ret 003783 1 D0 FE trap_ne 003785 1 AD FE 01 lda $1fe 003788 1 C9 9A cmp #brk_ret0 0037DA 1 D0 FE trap_ne 0037DC 1 AD FE 01 lda $1fe 0037DF 1 C9 D1 cmp #brk_ret1 00381A 1 D0 FE trap_ne 00381C 1 AD FE 01 lda $1fe 00381F 1 C9 F7 cmp # 1 003835 1 zp_init: 003835 1 zps_: .byte $80,1 ;additional shift pattern to test zero result & flag 003835 1 zp1_: .byte $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR 003835 1 zp7f_: .byte $7f ;test pattern for compare 003835 1 ;logical zeropage operands 003835 1 zpOR_: .byte 0,$1f,$71,$80 ;test pattern for OR 003835 1 zpAN_: .byte $0f,$ff,$7f,$80 ;test pattern for AND 003835 1 zpEO_: .byte $ff,$0f,$8f,$8f ;test pattern for EOR 003835 1 ;indirect addressing pointers 003835 1 ind1_: .word abs1 ;indirect pointer to pattern in absolute memory 003835 1 .word abs1+1 003835 1 .word abs1+2 003835 1 .word abs1+3 003835 1 .word abs7f 003835 1 inw1_: .word abs1-$f8 ;indirect pointer for wrap-test pattern 003835 1 indt_: .word abst ;indirect pointer to store area in absolute memory 003835 1 .word abst+1 003835 1 .word abst+2 003835 1 .word abst+3 003835 1 inwt_: .word abst-$f8 ;indirect pointer for wrap-test store 003835 1 indAN_: .word absAN ;indirect pointer to AND pattern in absolute memory 003835 1 .word absAN+1 003835 1 .word absAN+2 003835 1 .word absAN+3 003835 1 indEO_: .word absEO ;indirect pointer to EOR pattern in absolute memory 003835 1 .word absEO+1 003835 1 .word absEO+2 003835 1 .word absEO+3 003835 1 indOR_: .word absOR ;indirect pointer to OR pattern in absolute memory 003835 1 .word absOR+1 003835 1 .word absOR+2 003835 1 .word absOR+3 003835 1 ;add/subtract indirect pointers 003835 1 adi2_: .word ada2 ;indirect pointer to operand 2 in absolute memory 003835 1 sbi2_: .word sba2 ;indirect pointer to complemented operand 2 (SBC) 003835 1 adiy2_: .word ada2-$ff ;with offset for indirect indexed 003835 1 sbiy2_: .word sba2-$ff 003835 1 zp_end: 003835 1 .if (zp_end - zp_init) <> (zp_bss_end - zp_bss) 003835 1 ;force assembler error if size is different 003835 1 .error "mismatch between bss and zeropage data" 003835 1 .endif 003835 1 data_init: 003835 1 ex_and_:and #0 ;execute immediate opcodes 003835 1 rts 003835 1 ex_eor_:eor #0 ;execute immediate opcodes 003835 1 rts 003835 1 ex_ora_:ora #0 ;execute immediate opcodes 003835 1 rts 003835 1 ex_adc_:adc #0 ;execute immediate opcodes 003835 1 rts 003835 1 ex_sbc_:sbc #0 ;execute immediate opcodes 003835 1 rts 003835 1 ;zps: .byte $80,1 ;additional shift patterns test zero result & flag 003835 1 abs1_: .byte $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR 003835 1 abs7f_: .byte $7f ;test pattern for compare 003835 1 ;loads 003835 1 fLDx_: .byte fn,fn,0,fz ;expected flags for load 003835 1 ;shifts 003835 1 rASL_: ;expected result ASL & ROL -carry 003835 1 rROL_: .byte 0,2,$86,$04,$82,0 003835 1 rROLc_: .byte 1,3,$87,$05,$83,1 ;expected result ROL +carry 003835 1 rLSR_: ;expected result LSR & ROR -carry 003835 1 rROR_: .byte $40,0,$61,$41,$20,0 003835 1 rRORc_: .byte $c0,$80,$e1,$c1,$a0,$80 ;expected result ROR +carry 003835 1 fASL_: ;expected flags for shifts 003835 1 fROL_: .byte fzc,0,fnc,fc,fn,fz ;no carry in 003835 1 fROLc_: .byte fc,0,fnc,fc,fn,0 ;carry in 003835 1 fLSR_: 003835 1 fROR_: .byte 0,fzc,fc,0,fc,fz ;no carry in 003835 1 fRORc_: .byte fn,fnc,fnc,fn,fnc,fn ;carry in 003835 1 ;increments (decrements) 003835 1 rINC_: .byte $7f,$80,$ff,0,1 ;expected result for INC/DEC 003835 1 fINC_: .byte 0,fn,fn,fz,0 ;expected flags for INC/DEC 003835 1 ;logical memory operand 003835 1 absOR_: .byte 0,$1f,$71,$80 ;test pattern for OR 003835 1 absAN_: .byte $0f,$ff,$7f,$80 ;test pattern for AND 003835 1 absEO_: .byte $ff,$0f,$8f,$8f ;test pattern for EOR 003835 1 ;logical accu operand 003835 1 absORa_:.byte 0,$f1,$1f,0 ;test pattern for OR 003835 1 absANa_:.byte $f0,$ff,$ff,$ff ;test pattern for AND 003835 1 absEOa_:.byte $ff,$f0,$f0,$0f ;test pattern for EOR 003835 1 ;logical results 003835 1 absrlo_:.byte 0,$ff,$7f,$80 003835 1 absflo_:.byte fz,fn,0,fn 003835 1 data_end 003835 1 .if (data_end - data_init) <> (data_bss_end - data_bss) 003835 1 ;force assembler error if size is different 003835 1 .error "mismatch between bss and data" 003835 1 .endif 003835 1 003835 1 vec_init 003835 1 .word nmi_trap 003835 1 .word res_trap 003835 1 .word irq_trap 003835 1 vec_bss equ $fffa 003835 1 .endif ;end of RAM init data 003835 1 003835 1 .if (load_data_direct = 1) & (ROM_vectors = 1) 003835 1 .segment "VECTORS" 003835 1 .org $fffa ;vectors 00FFFA 1 9D 37 .word nmi_trap 00FFFC 1 A3 37 .word res_trap 00FFFE 1 AB 37 .word irq_trap 010000 1 .endif 010000 1