added report to standard output option

This commit is contained in:
Klaus2m5 2013-08-16 13:30:31 +02:00
parent 12434a8e47
commit 2c6a266d5f
5 changed files with 546 additions and 35 deletions

View File

@ -21,7 +21,7 @@
; addressing modes with focus on propper setting of the processor status
; register bits.
;
; version 23-jul-2013
; version 16-aug-2013
; contact info at http://2m5.de or email K@2m5.de
;
; assembled with AS65 from http://www.kingswood-consulting.co.uk/assemblers/
@ -65,35 +65,47 @@
; 02-mar-2013 fixed PLA flags not tested
; 19-jul-2013 allowed ROM vectors to be loaded when load_data_direct = 0
; added test sequence check to detect if tests jump their fence
; 23-jul-2013 added RAM integrity check
; 23-jul-2013 added RAM integrity check option
; 16-aug-2013 added error report to standard output option
; C O N F I G U R A T I O N
;
;ROM_vectors writable (0=no, 1=yes)
;if ROM vectors can not be used interrupts will not be trapped
;as a consequence BRK can not be tested but will be emulated to test RTI
ROM_vectors = 1
;load_data_direct (0=move from code segment, 1=load directly)
;loading directly is preferred but may not be supported by your platform
;0 produces only consecutive object code, 1 is not suitable for a binary image
load_data_direct = 1
;I_flag behavior (0=force enabled, 1=force disabled, 2=prohibit change, 3=allow
;change) 2 requires extra code and is not recommended. SEI & CLI can only be
;tested if you allow changing the interrupt status (I_flag = 3)
I_flag = 3
;configure memory - try to stay away from memory used by the system
;zero_page memory start address, $50 (80) consecutive Bytes required
; add 2 if I_flag = 2
zero_page = $a
;data_segment memory start address, $5B (91) consecutive Bytes required
data_segment = $200
if (data_segment & $ff) != 0
ERROR ERROR ERROR low byte of data_segment MUST be $00 !!
endif
;code_segment memory start address, 13kB of consecutive space required
; add 2.5 kB if I_flag = 2
;parts of the code are self modifying and must reside in RAM
code_segment = $400
;report errors through I/O channel (0=use standard self trap loops, 1=include
;report.i65 as I/O channel, add 3.5 kB)
report = 0
;RAM integrity test option. Checks for undesired RAM writes.
;set lowest non RAM or RAM mirror address page (-1=disable, 0=64k, $40=16k)
;leave disabled if a monitor, OS or background interrupt is allowed to alter RAM
@ -115,6 +127,7 @@ ram_top = -1
; my_error_handler should pop the calling address from the stack and report it.
; putting larger portions of code (more than 3 bytes) inside the trap macro
; may lead to branch range problems for some tests.
if report = 0
trap macro
jmp * ;failed anyway
endm
@ -142,9 +155,62 @@ trap_vs macro
trap_vc macro
bvc * ;failed overflow clear
endm
; please observe that during the test the stack gets invalidated
; therefore a RTS inside the success macro is not possible
success macro
jmp * ;test passed, no errors
endm
endif
if report = 1
trap macro
jsr report_error
endm
trap_eq macro
bne skip\?
trap ;failed equal (zero)
skip\?
endm
trap_ne macro
beq skip\?
trap ;failed not equal (non zero)
skip\?
endm
trap_cs macro
bcc skip\?
trap ;failed carry set
skip\?
endm
trap_cc macro
bcs skip\?
trap ;failed carry clear
skip\?
endm
trap_mi macro
bpl skip\?
trap ;failed minus (bit 7 set)
skip\?
endm
trap_pl macro
bmi skip\?
trap ;failed plus (bit 7 clear)
skip\?
endm
trap_vs macro
bvc skip\?
trap ;failed overflow set
skip\?
endm
trap_vc macro
bvs skip\?
trap ;failed overflow clear
skip\?
endm
; please observe that during the test the stack gets invalidated
; therefore a RTS inside the success macro is not possible
success macro
jsr report_success
endm
endif
carry equ %00000001 ;flag bits in status
@ -465,7 +531,7 @@ next_test macro ;make sure, tests don't jump the fence
cmp #test_num
trap_ne ;test is out of sequence
test_num = test_num + 1
lda #test_num ;*** this tests' number
lda #test_num ;*** next tests' number
sta test_case
;check_ram ;uncomment to find altered RAM after each test
endm
@ -491,7 +557,7 @@ ad1 ds 1 ;operand 1 - accumulator
ad2 ds 1 ;operand 2 - memory / immediate
adrl ds 1 ;expected result bits 0-7
adrh ds 1 ;expected result bit 8 (carry)
adrf ds 1 ;expected flags NV0000ZC (-V in decimal mode)
adrf ds 1 ;expected flags NV0000ZC (only binary mode)
sb2 ds 1 ;operand 2 complemented for subtract
zp_bss
zp1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR
@ -577,6 +643,8 @@ data_bss_end
code
org code_segment
start cld
ldx #$ff
txs
lda #0 ;*** test 0 = initialize
sta test_case
test_num = 0
@ -586,6 +654,11 @@ test_num = 0
sei
endif
;initialize I/O for report channel
if report = 1
jsr report_init
endif
;initialize BSS segment
if load_data_direct != 1
ldx #zp_end-zp_init-1
@ -1036,10 +1109,6 @@ br4 php
bvs nbr12
bcs nbr13
beq nbr14
trap_mi
trap_vs
trap_cs
trap_eq
bpl br11 ;branches should be taken
trap
br11 bvc br12
@ -1061,22 +1130,151 @@ br14 php
cmp_flag 0 ;flags off except break (pushed by sw) + reserved?
trap_ne
;crosscheck flags
set_stat carry
trap_cc
set_stat zero
trap_ne
set_stat overfl
trap_vc
bne brzs1
beq brzs2
brzs1
trap ;branch zero/non zero
brzs2 bcs brzs3
bcc brzs4
brzs3
trap ;branch carry/no carry
brzs4 bmi brzs5
bpl brzs6
brzs5
trap ;branch minus/plus
brzs6 bvs brzs7
bvc brzs8
brzs7
trap ;branch overflow/no overflow
brzs8
set_stat carry
beq brcs1
bne brcs2
brcs1
trap ;branch zero/non zero
brcs2 bcc brcs3
bcs brcs4
brcs3
trap ;branch carry/no carry
brcs4 bmi brcs5
bpl brcs6
brcs5
trap ;branch minus/plus
brcs6 bvs brcs7
bvc brcs8
brcs7
trap ;branch overflow/no overflow
brcs8
set_stat minus
trap_pl
set_stat $ff-carry
trap_cs
beq brmi1
bne brmi2
brmi1
trap ;branch zero/non zero
brmi2 bcs brmi3
bcc brmi4
brmi3
trap ;branch carry/no carry
brmi4 bpl brmi5
bmi brmi6
brmi5
trap ;branch minus/plus
brmi6 bvs brmi7
bvc brmi8
brmi7
trap ;branch overflow/no overflow
brmi8
set_stat overfl
beq brvs1
bne brvs2
brvs1
trap ;branch zero/non zero
brvs2 bcs brvs3
bcc brvs4
brvs3
trap ;branch carry/no carry
brvs4 bmi brvs5
bpl brvs6
brvs5
trap ;branch minus/plus
brvs6 bvc brvs7
bvs brvs8
brvs7
trap ;branch overflow/no overflow
brvs8
set_stat $ff-zero
trap_eq
set_stat $ff-overfl
trap_vs
beq brzc1
bne brzc2
brzc1
trap ;branch zero/non zero
brzc2 bcc brzc3
bcs brzc4
brzc3
trap ;branch carry/no carry
brzc4 bpl brzc5
bmi brzc6
brzc5
trap ;branch minus/plus
brzc6 bvc brzc7
bvs brzc8
brzc7
trap ;branch overflow/no overflow
brzc8
set_stat $ff-carry
bne brcc1
beq brcc2
brcc1
trap ;branch zero/non zero
brcc2 bcs brcc3
bcc brcc4
brcc3
trap ;branch carry/no carry
brcc4 bpl brcc5
bmi brcc6
brcc5
trap ;branch minus/plus
brcc6 bvc brcc7
bvs brcc8
brcc7
trap ;branch overflow/no overflow
brcc8
set_stat $ff-minus
trap_mi
bne brpl1
beq brpl2
brpl1
trap ;branch zero/non zero
brpl2 bcc brpl3
bcs brpl4
brpl3
trap ;branch carry/no carry
brpl4 bmi brpl5
bpl brpl6
brpl5
trap ;branch minus/plus
brpl6 bvc brpl7
bvs brpl8
brpl7
trap ;branch overflow/no overflow
brpl8
set_stat $ff-overfl
bne brvc1
beq brvc2
brvc1
trap ;branch zero/non zero
brvc2 bcc brvc3
bcs brvc4
brvc3
trap ;branch carry/no carry
brvc4 bpl brvc5
bmi brvc6
brvc5
trap ;branch minus/plus
brvc6 bvs brvc7
bvc brvc8
brvc7
trap ;branch overflow/no overflow
brvc8
next_test
; test PHA does not alter flags or accumulator but PLA does
@ -4912,7 +5110,9 @@ tdad7 cld
lda test_case
cmp #test_num
trap_ne ;test is out of sequence
trap_ne ;previous test is out of sequence
lda #$f0 ;mark opcode testing complete
sta test_case
; final RAM integrity test
; verifies that none of the previous tests has altered RAM outside of the
@ -4925,12 +5125,12 @@ tdad7 cld
; allowed during previous tests.
; S U C C E S S ************************************************
; -------------
success ;if you get here everything went well
; -------------
; S U C C E S S ************************************************
; S U C C E S S ************************************************
jmp start ;run again
; core subroutine of the decimal add/subtract test
; *** WARNING - tests documented behavior only! ***
@ -5479,7 +5679,7 @@ irq_trap ;BRK test or unextpected BRK or IRQ
cmp_flag 0 ;break test should have B=1
trap_ne ; - no break flag on stack
pla
cmp #$34 ;should have added interrupt disable
cmp #fai ;should have added interrupt disable
trap_ne
tsx
cpx #$fc ;sp -3? (return addr, flags)
@ -5498,6 +5698,10 @@ irq_trap ;BRK test or unextpected BRK or IRQ
rti
trap ;runover protection
if report = 1
include "report.i65"
endif
;copy of data to initialize BSS segment
if load_data_direct != 1
zp_init

View File

@ -20,7 +20,7 @@
; This program is designed to test IRQ and NMI of a 6502 emulator. It requires
; an internal or external feedback register to the IRQ & NMI inputs
;
; version 19-jul-2013
; version 16-aug-2013
; contact info at http://2m5.de or email K@2m5.de
;
; assembled with AS65 from http://www.kingswood-consulting.co.uk/assemblers/
@ -48,6 +48,8 @@
;
; versions:
; 19-jul-2013 1st version distributed for testing
; 16-aug-2013 added error report to standard output option
; C O N F I G U R A T I O N
;
@ -86,6 +88,10 @@ data_segment = $200
;code_segment memory start address
code_segment = $400
;report errors through I/O channel (0=use standard self trap loops, 1=include
;report.i65 as I/O channel)
report = 0
noopt ;do not take shortcuts
;macros for error & success traps to allow user modification
@ -98,6 +104,11 @@ code_segment = $400
; trap ;failed equal (zero)
;skip\?
; endm
;
; my_error_handler should pop the calling address from the stack and report it.
; putting larger portions of code (more than 3 bytes) inside the trap macro
; may lead to branch range problems for some tests.
if report = 0
trap macro
jmp * ;failed anyway
endm
@ -107,9 +118,32 @@ trap_eq macro
trap_ne macro
bne * ;failed not equal (non zero)
endm
; please observe that during the test the stack gets invalidated
; therefore a RTS inside the success macro is not possible
success macro
jmp * ;test passed, no errors
endm
endif
if report = 1
trap macro
jsr report_error
endm
trap_eq macro
bne skip\?
trap ;failed equal (zero)
skip\?
endm
trap_ne macro
beq skip\?
trap ;failed not equal (non zero)
skip\?
endm
; please observe that during the test the stack gets invalidated
; therefore a RTS inside the success macro is not possible
success macro
jsr report_success
endm
endif
carry equ %00000001 ;flag bits in status
@ -156,26 +190,27 @@ set_stat macro ;setting flags in the processor status register
endif
org zero_page
;BRK, IRQ, NMI test interrupt save
zpt
irq_a ds 1 ;a register
irq_x ds 1 ;x register
irq_f ds 1 ;flags
nmi_a ds 1 ;a register
nmi_x ds 1 ;x register
nmi_f ds 1 ;flags
zp_bss
;fixed stack locations
lst_f equ $1fe ;last flags before interrupt
lst_a equ $1ff ;last accumulator before interrupt
org data_segment
data_bss
;concurrent NMI, IRQ & BRK test result
nmi_count ds 1 ;lowest number handled first, $ff = never
irq_count ds 1 ;separation-1 = instructions between interrupts
brk_count ds 1
;expected interrupt mask
I_src ds 1 ;bit: 0=BRK, 1=IRQ, 2=NMI
data_bss_end
data_bss
code
org code_segment
@ -184,6 +219,11 @@ start cld
sta I_src
ldx #$ff
txs
;initialize I/O for report channel
if report = 1
jsr report_init
endif
; load system vectors
if load_data_direct != 1
@ -781,6 +821,7 @@ I_clr macro ibit ;ibit = interrupt bit
; S U C C E S S ************************************************
; check data_segment +0 to +2 for sequence of concurrent interrupts
; e.g. 0x200 = NMI, 0x201 = IRQ, 0x202 = BRK, lower values = earlier
jmp start ;run again
; manual tests for the WAI opcode of the 65c02
@ -788,7 +829,7 @@ wai macro
db $cb ;WAI opcode
endm
; requires single step operation
; requires single step operation, report = 0
; set PC to the 1st instruction of the test
; step to the WAI opcode, then manually tie the IRQ input low
; continue to step until you see the PC advance, then remove IRQ
@ -948,6 +989,11 @@ brk_trap
lda #'K' ;mark (BR)K
plp ;should be reversed by rti
rti
if report = 1
rep_int = 1
include "report.i65"
endif
;system vectors

View File

@ -22,7 +22,7 @@
; The 6502_functional_test is a prerequisite to this test.
; NMI, IRQ, BRK, STP & WAI are covered in the 6502_interrupt_test.
;
; version 23-jul-2013
; version 16-aug-2013
; contact info at http://2m5.de or email K@2m5.de
;
; assembled with AS65 from http://www.kingswood-consulting.co.uk/assemblers/
@ -60,39 +60,53 @@
; 19-jul-2013 1st version distributed for testing
; 23-jul-2013 fixed BRA out of range due to larger trap macros
; added RAM integrity check
; 16-aug-2013 added error report to standard output option
; C O N F I G U R A T I O N
;
;ROM_vectors writable (0=no, 1=yes)
;if ROM vectors can not be used interrupts will not be trapped
;as a consequence BRK can not be tested but will be emulated to test RTI
ROM_vectors = 1
;load_data_direct (0=move from code segment, 1=load directly)
;loading directly is preferred but may not be supported by your platform
;0 produces only consecutive object code, 1 is not suitable for a binary image
load_data_direct = 1
;I_flag behavior (0=force enabled, 1=force disabled, 2=prohibit change, 3=allow
;change) 2 requires extra code and is not recommended.
I_flag = 3
;configure memory - try to stay away from memory used by the system
;zero_page memory start address, $4e (78) consecutive Bytes required
; add 2 if I_flag = 2
zero_page = $a
;data_segment memory start address, $5D (93) consecutive Bytes required
; + 12 Bytes at data_segment + $f9 (JMP indirect page cross test)
data_segment = $200
if (data_segment & $ff) != 0
ERROR ERROR ERROR low byte of data_segment MUST be $00 !!
endif
;code_segment memory start address, 10kB of consecutive space required
; add 1 kB if I_flag = 2
;parts of the code are self modifying and must reside in RAM
code_segment = $400
;added WDC only opcodes WAI & STP (0=test as NOPs, >0=no test)
wdc_op = 1
;added Rockwell & WDC opcodes BBR, BBS, RMB & SMB
;(0=test as NOPs, 1=full test, >1=no test)
rkwl_wdc_op = 1
;report errors through I/O channel (0=use standard self trap loops, 1=include
;report.i65 as I/O channel, add 3 kB)
report = 0
;RAM integrity test option. Checks for undesired RAM writes.
;set lowest non RAM or RAM mirror address page (-1=disable, 0=64k, $40=16k)
;leave disabled if a monitor, OS or background interrupt is allowed to alter RAM
@ -114,6 +128,7 @@ ram_top = -1
; my_error_handler should pop the calling address from the stack and report it.
; putting larger portions of code (more than 3 bytes) inside the trap macro
; may lead to branch range problems for some tests.
if report = 0
trap macro
jmp * ;failed anyway
endm
@ -141,9 +156,62 @@ trap_vs macro
trap_vc macro
bvc * ;failed overflow clear
endm
; please observe that during the test the stack gets invalidated
; therefore a RTS inside the success macro is not possible
success macro
jmp * ;test passed, no errors
endm
endif
if report = 1
trap macro
jsr report_error
endm
trap_eq macro
bne skip\?
trap ;failed equal (zero)
skip\?
endm
trap_ne macro
beq skip\?
trap ;failed not equal (non zero)
skip\?
endm
trap_cs macro
bcc skip\?
trap ;failed carry set
skip\?
endm
trap_cc macro
bcs skip\?
trap ;failed carry clear
skip\?
endm
trap_mi macro
bpl skip\?
trap ;failed minus (bit 7 set)
skip\?
endm
trap_pl macro
bmi skip\?
trap ;failed plus (bit 7 clear)
skip\?
endm
trap_vs macro
bvc skip\?
trap ;failed overflow set
skip\?
endm
trap_vc macro
bvs skip\?
trap ;failed overflow clear
skip\?
endm
; please observe that during the test the stack gets invalidated
; therefore a RTS inside the success macro is not possible
success macro
jsr report_success
endm
endif
carry equ %00000001 ;flag bits in status
@ -472,7 +540,7 @@ next_test macro ;make sure, tests don't jump the fence
cmp #test_num
trap_ne ;test is out of sequence
test_num = test_num + 1
lda #test_num ;*** this tests' number
lda #test_num ;*** next tests' number
sta test_case
;check_ram ;uncomment to find altered RAM after each test
endm
@ -582,9 +650,12 @@ jxi_tab equ data_segment + $100 - 7 ;JMP (jxi_tab,x) x=6
ji_tab equ data_segment + $100 - 3 ;JMP (ji_tab+2)
jxp_tab equ data_segment + $100 ;JMP (jxp_tab-255) x=255
code
org code_segment
start cld
ldx #$ff
txs
lda #0 ;*** test 0 = initialize
sta test_case
test_num = 0
@ -594,6 +665,11 @@ test_num = 0
sei
endif
;initialize I/O for report channel
if report = 1
jsr report_init
endif
;initialize BSS segment
if load_data_direct != 1
ldx #zp_end-zp_init-1
@ -2129,7 +2205,9 @@ tdad7 cpx #ad2
lda test_case
cmp #test_num
trap_ne ;test is out of sequence
trap_ne ;previous test is out of sequence
lda #$f0 ;mark opcode testing complete
sta test_case
; final RAM integrity test
; verifies that none of the previous tests has altered RAM outside of the
@ -2142,12 +2220,12 @@ tdad7 cpx #ad2
; allowed during previous tests.
; S U C C E S S ************************************************
; -------------
success ;if you get here everything went well
; -------------
; S U C C E S S ************************************************
jmp start ;run again
; core subroutine of the decimal add/subtract test
; *** WARNING - tests documented behavior only! ***
@ -2529,6 +2607,10 @@ irq_trap
else
trap_ne ;check stack for conditions at BRK
endif
if report = 1
include "report.i65"
endif
;copy of data to initialize BSS segment
if load_data_direct != 1

View File

@ -21,7 +21,7 @@ project. You can find it here: http://2m5.de/6502_Emu/index.htm
A discussion about the tests can be found here:
http://forum.6502.org/viewtopic.php?f=2&t=2241
Good luck debugging your emulator, simulator, vhdl core, discrete
Good luck debugging your emulator, simulator, fpga core, discrete
logic implementation or whatever you have!

179
report.i65 Normal file
View File

@ -0,0 +1,179 @@
;**** report 6502 funtional test errors to standard I/O ****
;
;this include file is part of the 6502 functional tests
;it is used when you configure report = 1 in the tests
;
;to adopt the standard output vectors of your test environment
;you must modify the rchar and rget subroutines in this include
;
;I/O hardware may have to be initialized in report_init
;print message macro - \1 = message location
rprt macro
ldx #0
lda \1
loop\?
jsr rchar
inx
lda \1,x
bne loop\?
endm
;initialize I/O as required (example: configure & enable ACIA)
report_init
;nothing to initialize
rprt rmsg_start
rts
;show stack (with saved registers), zeropage and absolute memory workspace
;after an error was trapped in the test program
report_error
;save registers
php
pha
txa
pha
tya
pha
cld
;show stack with index to registers at error
rprt rmsg_stack
tsx
inx
lda #1 ;address high
jsr rhex
txa ;address low
jsr rhex
rstack jsr rspace
lda $100,x ;stack data
jsr rhex
inx
bne rstack
jsr rcrlf ;new line
;show zero page workspace
lda #0
jsr rhex
lda #zpt
tax
jsr rhex
rzp jsr rspace
lda 0,x
jsr rhex
inx
cpx #zp_bss
bne rzp
jsr rcrlf
;show absolute workspace
lda #hi(data_segment)
jsr rhex
lda #lo(data_segment)
jsr rhex
ldx #0
rabs jsr rspace
lda data_segment,x
jsr rhex
inx
cpx #(data_bss-data_segment)
bne rabs
;ask to continue
rprt rmsg_cont
rerr1 jsr rget
cmp #'C'
bne rerr1
;restore registers
pla
tay
pla
tax
pla
plp
rts
;show test has ended, ask to repeat
report_success
if rep_int = 1
rprt rmsg_priority
lda data_segment ;show interrupt sequence
jsr rhex
jsr rspace
lda data_segment+1
jsr rhex
jsr rspace
lda data_segment+2
jsr rhex
endif
rprt rmsg_success
rsuc1 jsr rget
cmp #'R'
bne rsuc1
rts
;input subroutine
;get a character from standard input
;adjust according to the needs in your test environment
rget ;get character in A
;rget1
; lda $bff1 ;wait RDRF
; and #8
; beq rget1
;not a real ACIA - so RDRF is not checked
lda $bff0 ;read acia rx reg
;the load can be replaced by a call to a kernal routine
; jsr $ffcf ;example: CHRIN for a C64
cmp #'a' ;lower case
bcc rget1
and #$5f ;convert to upper case
rget1 rts
;output subroutines
rcrlf lda #10
jsr rchar
lda #13
bne rchar
rspace lda #' '
bne rchar
rhex pha ;report hex byte in A
lsr a ;high nibble first
lsr a
lsr a
lsr a
jsr rnib
pla ;now low nibble
and #$f
rnib clc ;report nibble in A
adc #'0' ;make printable 0-9
cmp #'9'+1
bcc rchar
adc #6 ;make printable A-F
;send a character to standard output
;adjust according to the needs in your test environment
;register X needs to be preserved!
rchar ;report character in A
; pha ;wait TDRF
;rchar1 lda $bff1
; and #$10
; beq rchar1
; pla
;not a real ACIA - so TDRF is not checked
sta $bff0 ;write acia tx reg
;the store can be replaced by a call to a kernal routine
; jsr $ffd2 ;example: CHROUT for a C64
rts
rmsg_start
db 10,13,"Started testing",10,13,0
rmsg_stack
db 10,13,"regs Y X A PS PCLPCH",10,13,0
rmsg_cont
db 10,13,"press C to continue",10,13,0
rmsg_success
db 10,13,"All tests completed, press R to repeat",10,13,0
if rep_int = 1
rmsg_priority
db 10,13,"interrupt sequence (NMI IRQ BRK) ",0
endif