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
+229 -25
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
+50 -4
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
+87 -5
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
+1 -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
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