1
0
mirror of https://github.com/irmen/ksim65.git synced 2024-06-26 02:29:38 +00:00

updating Klaus Dormann's functional tests

This commit is contained in:
Irmen de Jong 2020-02-09 16:51:20 +01:00
parent 7f3dd9c95d
commit de60698349
8 changed files with 797 additions and 803 deletions

View File

@ -8,7 +8,7 @@ import razorvine.ksim65.components.UByte
/** /**
* 6502 cpu simulation (the NMOS version) including the 'illegal' opcodes. * 6502 cpu simulation (the NMOS version) including the 'illegal' opcodes.
* TODO: actually implement the illegal opcodes, see http://www.ffd2.com/fridge/docs/6502-NMOS.extra.opcodes * TODO: actually implement the illegal opcodes, see http://www.ffd2.com/fridge/docs/6502-NMOS.extra.opcodes or https://sourceforge.net/p/moarnes/code/ci/master/tree/src/6502.c
*/ */
open class Cpu6502 : BusComponent() { open class Cpu6502 : BusComponent() {
open val name = "6502" open val name = "6502"
@ -1458,8 +1458,8 @@ open class Cpu6502 : BusComponent() {
TODO("\$${hexB(currentOpcode)} - xaa - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}") TODO("\$${hexB(currentOpcode)} - xaa - ('illegal' instruction) @ \$${hexW(currentOpcodeAddress)}")
} }
// invalid instruction (JAM / KIL) // invalid instruction (JAM / KIL / HLT)
private fun iInvalid() { private fun iInvalid() {
throw InstructionError("invalid instruction encountered: opcode=${hexB(currentOpcode)} instr=${currentInstruction.mnemonic}") throw InstructionError("invalid instruction encountered: opcode=${hexB(currentOpcode)} instr=${currentInstruction.mnemonic} @ ${hexW(currentOpcodeAddress)}")
} }
} }

View File

@ -100,7 +100,7 @@ I_flag = 3
;configure memory - try to stay away from memory used by the system ;configure memory - try to stay away from memory used by the system
;zero_page memory start address, $52 (82) consecutive Bytes required ;zero_page memory start address, $52 (82) consecutive Bytes required
; add 2 if I_flag = 2 ; add 2 if I_flag = 2
zero_page = $a zero_page = $0
;data_segment memory start address, $7B (123) consecutive Bytes required ;data_segment memory start address, $7B (123) consecutive Bytes required
data_segment = $200 data_segment = $200
@ -6106,4 +6106,4 @@ vec_bss equ $fffa
endif endif
end start end start

View File

@ -19,7 +19,7 @@
; This program is designed to test IRQ and NMI of a 6502 emulator. It requires ; 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 ; an internal or external feedback register to the IRQ & NMI inputs
; ;
; version 15-aug-2014 ; version 15-aug-2014
; contact info at http://2m5.de or email K@2m5.de ; contact info at http://2m5.de or email K@2m5.de
; ;
@ -83,10 +83,10 @@ D_clear = 0 ;0 = not cleared (NMOS), 1 = cleared (CMOS)
;configure memory - try to stay away from memory used by the system ;configure memory - try to stay away from memory used by the system
;zero_page memory start address, 6 consecutive Bytes required ;zero_page memory start address, 6 consecutive Bytes required
zero_page = $a zero_page = $0
;data_segment memory start address, 4 consecutive Bytes required ;data_segment memory start address, 4 consecutive Bytes required
data_segment = $200 data_segment = $200
;code_segment memory start address ;code_segment memory start address
code_segment = $400 code_segment = $400
@ -205,7 +205,7 @@ zp_bss
;fixed stack locations ;fixed stack locations
lst_f equ $1fe ;last flags before interrupt lst_f equ $1fe ;last flags before interrupt
lst_a equ $1ff ;last accumulator before interrupt lst_a equ $1ff ;last accumulator before interrupt
org data_segment org data_segment
;concurrent NMI, IRQ & BRK test result ;concurrent NMI, IRQ & BRK test result
nmi_count ds 1 ;lowest number handled first, $ff = never nmi_count ds 1 ;lowest number handled first, $ff = never
@ -222,7 +222,7 @@ start cld
sta I_src sta I_src
ldx #$ff ldx #$ff
txs txs
;initialize I/O for report channel ;initialize I/O for report channel
if report = 1 if report = 1
jsr report_init jsr report_init
@ -263,7 +263,7 @@ I_clr macro ibit ;ibit = interrupt bit
and #I_filter and #I_filter
ora #(1<<IRQ_bit) ora #(1<<IRQ_bit)
sta I_ddr sta I_ddr
endif endif
else ;open collector, 0 -> I_DDR or I_port to force interrupt else ;open collector, 0 -> I_DDR or I_port to force interrupt
if I_ddr != 0 ;with DDR if I_ddr != 0 ;with DDR
I_set macro ibit ;ibit = interrupt bit I_set macro ibit ;ibit = interrupt bit
@ -278,7 +278,7 @@ I_set macro ibit ;ibit = interrupt bit
I_clr macro ibit ;ibit = interrupt bit I_clr macro ibit ;ibit = interrupt bit
lda I_ddr ;turn off interrupt by bit lda I_ddr ;turn off interrupt by bit
and #I_filter-(1<<ibit) and #I_filter-(1<<ibit)
sta I_ddr sta I_ddr
endm endm
I_clr IRQ_bit ;turn off IRQ I_clr IRQ_bit ;turn off IRQ
lda I_port ;precharge IRQ lda I_port ;precharge IRQ
@ -329,7 +329,7 @@ I_clr macro ibit ;ibit = interrupt bit
and #I_filter and #I_filter
ora #(1<<IRQ_bit|1<<NMI_bit) ora #(1<<IRQ_bit|1<<NMI_bit)
sta I_ddr sta I_ddr
endif endif
else ;open collector, 0 -> I_DDR or I_port to force interrupt else ;open collector, 0 -> I_DDR or I_port to force interrupt
if I_ddr != 0 ;with DDR if I_ddr != 0 ;with DDR
I_set macro ibit ;ibit = interrupt bit I_set macro ibit ;ibit = interrupt bit
@ -348,7 +348,7 @@ I_set macro ibit ;ibit = interrupt bit
I_clr macro ibit ;ibit = interrupt bit I_clr macro ibit ;ibit = interrupt bit
lda I_ddr ;turn off interrupt by bit lda I_ddr ;turn off interrupt by bit
and #I_filter-(1<<ibit) and #I_filter-(1<<ibit)
sta I_ddr sta I_ddr
endm endm
I_clr IRQ_bit ;turn off IRQ & NMI I_clr IRQ_bit ;turn off IRQ & NMI
I_clr NMI_bit I_clr NMI_bit
@ -379,7 +379,7 @@ I_clr macro ibit ;ibit = interrupt bit
endif endif
endif endif
endif endif
; IRQ integrity test ; IRQ integrity test
; test for clear flags seen in IRQ vector ; test for clear flags seen in IRQ vector
lda #2 ;set expected interrupt source IRQ lda #2 ;set expected interrupt source IRQ
@ -633,7 +633,7 @@ I_clr macro ibit ;ibit = interrupt bit
ldx #0 ldx #0
lda #0 lda #0
sta I_src sta I_src
push_stat intdis push_stat intdis
I_set IRQ_bit ;IRQ pending I_set IRQ_bit ;IRQ pending
inx inx
inx inx
@ -657,7 +657,7 @@ I_clr macro ibit ;ibit = interrupt bit
sta nmi_count sta nmi_count
sta irq_count sta irq_count
sta brk_count sta brk_count
push_stat 0 push_stat 0
I_set IRQ_bit ;trigger IRQ I_set IRQ_bit ;trigger IRQ
else else
; NMI integrity test ; NMI integrity test
@ -782,7 +782,7 @@ I_clr macro ibit ;ibit = interrupt bit
ldx #0 ldx #0
lda #4 ;set expected interrupt NMI only lda #4 ;set expected interrupt NMI only
sta I_src sta I_src
push_stat intdis push_stat intdis
I_set 8 ;both interrupts pending I_set 8 ;both interrupts pending
inx inx
inx inx
@ -825,21 +825,21 @@ I_clr macro ibit ;ibit = interrupt bit
;may fail due to a bug on a real NMOS 6502 - NMI could mask BRK ;may fail due to a bug on a real NMOS 6502 - NMI could mask BRK
trap_ne ;lost an interrupt trap_ne ;lost an interrupt
; S U C C E S S ************************************************ ; S U C C E S S ************************************************
; ------------- ; -------------
success ;if you get here everything went well success ;if you get here everything went well
; ------------- ; -------------
; S U C C E S S ************************************************ ; S U C C E S S ************************************************
; check data_segment +0 to +2 for sequence of concurrent interrupts ; check data_segment +0 to +2 for sequence of concurrent interrupts
; e.g. 0x200 = NMI, 0x201 = IRQ, 0x202 = BRK, lower values = earlier ; e.g. 0x200 = NMI, 0x201 = IRQ, 0x202 = BRK, lower values = earlier
jmp start ;run again jmp start ;run again
; manual tests for the WAI opcode of the 65c02 ; manual tests for the WAI opcode of the 65c02
wai macro wai macro
db $cb ;WAI opcode db $cb ;WAI opcode
endm endm
; requires single step operation, report = 0 ; requires single step operation, report = 0
; set PC to the 1st instruction of the test ; set PC to the 1st instruction of the test
; step to the WAI opcode, then manually tie the IRQ input low ; step to the WAI opcode, then manually tie the IRQ input low
@ -860,7 +860,7 @@ wai macro
trap_ne ;skipped opcodes! trap_ne ;skipped opcodes!
success success
; WAI with interrupts enabled ; WAI with interrupts enabled
ldx #$ff ldx #$ff
txs txs
@ -878,13 +878,13 @@ wai macro
trap_ne ;skipped opcodes! trap_ne ;skipped opcodes!
success success
; manual test for the STP opcode of the 65c02 ; manual test for the STP opcode of the 65c02
stp macro stp macro
db $db ;STP opcode db $db ;STP opcode
endm endm
; set PC to the 1st instruction of the test, then run ; set PC to the 1st instruction of the test, then run
nop nop
nop nop
@ -916,7 +916,7 @@ nmi_trap
pha pha
sta nmi_f sta nmi_f
lda I_src ;NMI expected? lda I_src ;NMI expected?
and #4 and #4
trap_eq ;unexpexted NMI - check stack for conditions trap_eq ;unexpexted NMI - check stack for conditions
pla ;test I-flag was set pla ;test I-flag was set
pha pha
@ -925,7 +925,7 @@ nmi_trap
pla ;return with other flags reversed pla ;return with other flags reversed
eor #m8-fai-decmode eor #m8-fai-decmode
pha pha
tsx tsx
lda $102,x ;test break on stack lda $102,x ;test break on stack
and #break and #break
trap_ne ;unexpected B-flag! - this may fail on a real 6502 trap_ne ;unexpected B-flag! - this may fail on a real 6502
@ -933,7 +933,7 @@ nmi_trap
lda I_src ;mark expected NMI has occured lda I_src ;mark expected NMI has occured
and #$ff-4 and #$ff-4
sta I_src sta I_src
I_clr NMI_bit I_clr NMI_bit
ldx nmi_x ldx nmi_x
inx inx
stx nmi_count stx nmi_count
@ -944,7 +944,7 @@ nmi_trap
res_trap res_trap
trap ;unexpected RESET trap ;unexpected RESET
dey dey
dey dey
irq_trap ;BRK & IRQ test irq_trap ;BRK & IRQ test
@ -958,7 +958,7 @@ irq_trap ;BRK & IRQ test
pha pha
sta irq_f sta irq_f
lda I_src ;IRQ expected? lda I_src ;IRQ expected?
and #3 and #3
trap_eq ;unexpexted IRQ/BRK - check stack for conditions trap_eq ;unexpexted IRQ/BRK - check stack for conditions
pla ;test I-flag was set pla ;test I-flag was set
pha pha
@ -966,26 +966,26 @@ irq_trap ;BRK & IRQ test
trap_eq ;I-flag not set trap_eq ;I-flag not set
pla ;return with other flags reversed pla ;return with other flags reversed
eor #m8-fai-decmode eor #m8-fai-decmode
pha pha
tsx tsx
lda $102,x ;test break on stack lda $102,x ;test break on stack
and #break and #break
bne brk_trap bne brk_trap
lda I_src ;IRQ expected? lda I_src ;IRQ expected?
and #2 and #2
trap_eq ;unexpexted IRQ - check stack for conditions trap_eq ;unexpexted IRQ - check stack for conditions
lda I_src ;mark expected IRQ has occured lda I_src ;mark expected IRQ has occured
and #$ff-2 and #$ff-2
sta I_src sta I_src
I_clr IRQ_bit I_clr IRQ_bit
ldx irq_x ldx irq_x
inx inx
stx irq_count stx irq_count
lda #'Q' ;mark (IR)Q lda #'Q' ;mark (IR)Q
plp ;should be reversed by rti plp ;should be reversed by rti
rti rti
brk_trap brk_trap
lda I_src ;break expected? lda I_src ;break expected?
and #1 and #1
@ -995,18 +995,18 @@ brk_trap
sta I_src sta I_src
ldx irq_x ldx irq_x
inx inx
stx brk_count stx brk_count
lda irq_a lda irq_a
lda #'K' ;mark (BR)K lda #'K' ;mark (BR)K
plp ;should be reversed by rti plp ;should be reversed by rti
rti rti
if report = 1 if report = 1
rep_int = 1 rep_int = 1
include "report.i65" include "report.i65"
endif endif
;system vectors ;system vectors
if (load_data_direct = 1) if (load_data_direct = 1)
org $fffa org $fffa
@ -1020,7 +1020,6 @@ vec_bss equ $fffa
dw res_trap dw res_trap
dw irq_trap dw irq_trap
endif endif
end start end start

View File

@ -23,7 +23,7 @@ AS65 Assembler for R6502 [1.42]. Copyright 1994-2007, Frank A. Kingswood
; This program is designed to test IRQ and NMI of a 6502 emulator. It requires ; 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 ; an internal or external feedback register to the IRQ & NMI inputs
; ;
; version 15-aug-2014 ; version 15-aug-2014
; contact info at http://2m5.de or email K@2m5.de ; contact info at http://2m5.de or email K@2m5.de
; ;
@ -87,10 +87,10 @@ bffc = I_port = $bffc ;feedback port address
;configure memory - try to stay away from memory used by the system ;configure memory - try to stay away from memory used by the system
;zero_page memory start address, 6 consecutive Bytes required ;zero_page memory start address, 6 consecutive Bytes required
000a = zero_page = $a 0000 = zero_page = $0
;data_segment memory start address, 4 consecutive Bytes required ;data_segment memory start address, 4 consecutive Bytes required
0200 = data_segment = $200 0200 = data_segment = $200
;code_segment memory start address ;code_segment memory start address
0400 = code_segment = $400 0400 = code_segment = $400
@ -195,21 +195,21 @@ bffc = I_port = $bffc ;feedback port address
else else
bss ;uninitialized segment, copy of data at end of code! bss ;uninitialized segment, copy of data at end of code!
endif endif
000a = org zero_page 0000 = org zero_page
;BRK, IRQ, NMI test interrupt save ;BRK, IRQ, NMI test interrupt save
000a : zpt 0000 : zpt
000a : 00 irq_a ds 1 ;a register 0000 : 00 irq_a ds 1 ;a register
000b : 00 irq_x ds 1 ;x register 0001 : 00 irq_x ds 1 ;x register
000c : 00 irq_f ds 1 ;flags 0002 : 00 irq_f ds 1 ;flags
000d : 00 nmi_a ds 1 ;a register 0003 : 00 nmi_a ds 1 ;a register
000e : 00 nmi_x ds 1 ;x register 0004 : 00 nmi_x ds 1 ;x register
000f : 00 nmi_f ds 1 ;flags 0005 : 00 nmi_f ds 1 ;flags
0010 : zp_bss 0006 : zp_bss
;fixed stack locations ;fixed stack locations
01fe = lst_f equ $1fe ;last flags before interrupt 01fe = lst_f equ $1fe ;last flags before interrupt
01ff = lst_a equ $1ff ;last accumulator before interrupt 01ff = lst_a equ $1ff ;last accumulator before interrupt
0200 = org data_segment 0200 = org data_segment
;concurrent NMI, IRQ & BRK test result ;concurrent NMI, IRQ & BRK test result
0200 : 00 nmi_count ds 1 ;lowest number handled first, $ff = never 0200 : 00 nmi_count ds 1 ;lowest number handled first, $ff = never
@ -226,7 +226,7 @@ bffc = I_port = $bffc ;feedback port address
0403 : 8d0302 sta I_src 0403 : 8d0302 sta I_src
0406 : a2ff ldx #$ff 0406 : a2ff ldx #$ff
0408 : 9a txs 0408 : 9a txs
;initialize I/O for report channel ;initialize I/O for report channel
if report = 1 if report = 1
jsr report_init jsr report_init
@ -267,7 +267,7 @@ bffc = I_port = $bffc ;feedback port address
and #I_filter and #I_filter
ora #(1<<IRQ_bit) ora #(1<<IRQ_bit)
sta I_ddr sta I_ddr
endif endif
else ;open collector, 0 -> I_DDR or I_port to force interrupt else ;open collector, 0 -> I_DDR or I_port to force interrupt
if I_ddr != 0 ;with DDR if I_ddr != 0 ;with DDR
I_set macro ibit ;ibit = interrupt bit I_set macro ibit ;ibit = interrupt bit
@ -282,7 +282,7 @@ bffc = I_port = $bffc ;feedback port address
I_clr macro ibit ;ibit = interrupt bit I_clr macro ibit ;ibit = interrupt bit
lda I_ddr ;turn off interrupt by bit lda I_ddr ;turn off interrupt by bit
and #I_filter-(1<<ibit) and #I_filter-(1<<ibit)
sta I_ddr sta I_ddr
endm endm
I_clr IRQ_bit ;turn off IRQ I_clr IRQ_bit ;turn off IRQ
lda I_port ;precharge IRQ lda I_port ;precharge IRQ
@ -333,7 +333,7 @@ bffc = I_port = $bffc ;feedback port address
and #I_filter and #I_filter
ora #(1<<IRQ_bit|1<<NMI_bit) ora #(1<<IRQ_bit|1<<NMI_bit)
sta I_ddr sta I_ddr
endif endif
else ;open collector, 0 -> I_DDR or I_port to force interrupt else ;open collector, 0 -> I_DDR or I_port to force interrupt
if I_ddr != 0 ;with DDR if I_ddr != 0 ;with DDR
I_set macro ibit ;ibit = interrupt bit I_set macro ibit ;ibit = interrupt bit
@ -352,7 +352,7 @@ bffc = I_port = $bffc ;feedback port address
I_clr macro ibit ;ibit = interrupt bit I_clr macro ibit ;ibit = interrupt bit
lda I_ddr ;turn off interrupt by bit lda I_ddr ;turn off interrupt by bit
and #I_filter-(1<<ibit) and #I_filter-(1<<ibit)
sta I_ddr sta I_ddr
endm endm
I_clr IRQ_bit ;turn off IRQ & NMI I_clr IRQ_bit ;turn off IRQ & NMI
I_clr NMI_bit I_clr NMI_bit
@ -391,7 +391,7 @@ bffc = I_port = $bffc ;feedback port address
endif endif
endif endif
endif endif
; IRQ integrity test ; IRQ integrity test
; test for clear flags seen in IRQ vector ; test for clear flags seen in IRQ vector
0419 : a902 lda #2 ;set expected interrupt source IRQ 0419 : a902 lda #2 ;set expected interrupt source IRQ
@ -425,7 +425,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned SP trap_ne ;returned SP
0439 : d0fe > bne * ;failed not equal (non zero) 0439 : d0fe > bne * ;failed not equal (non zero)
043b : a50c lda irq_f ;flags seen in IRQ vector 043b : a502 lda irq_f ;flags seen in IRQ vector
if D_clear = 1 if D_clear = 1
and #decmode and #decmode
trap_ne ;D-flag not cleared trap_ne ;D-flag not cleared
@ -492,7 +492,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned flags trap_ne ;returned flags
047c : d0fe > bne * ;failed not equal (non zero) 047c : d0fe > bne * ;failed not equal (non zero)
047e : a50a lda irq_a ;accu seen in IRQ vector 047e : a500 lda irq_a ;accu seen in IRQ vector
0480 : cdff01 cmp lst_a 0480 : cdff01 cmp lst_a
trap_ne ;IRQ A received trap_ne ;IRQ A received
0483 : d0fe > bne * ;failed not equal (non zero) 0483 : d0fe > bne * ;failed not equal (non zero)
@ -549,7 +549,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned flags trap_ne ;returned flags
04bd : d0fe > bne * ;failed not equal (non zero) 04bd : d0fe > bne * ;failed not equal (non zero)
04bf : a50a lda irq_a ;accu seen in IRQ vector 04bf : a500 lda irq_a ;accu seen in IRQ vector
04c1 : cdff01 cmp lst_a 04c1 : cdff01 cmp lst_a
trap_ne ;IRQ A received trap_ne ;IRQ A received
04c4 : d0fe > bne * ;failed not equal (non zero) 04c4 : d0fe > bne * ;failed not equal (non zero)
@ -588,7 +588,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned SP trap_ne ;returned SP
04e9 : d0fe > bne * ;failed not equal (non zero) 04e9 : d0fe > bne * ;failed not equal (non zero)
04eb : a50c lda irq_f ;flags seen in IRQ vector 04eb : a502 lda irq_f ;flags seen in IRQ vector
if D_clear = 1 if D_clear = 1
and #decmode and #decmode
trap_ne ;D-flag not cleared trap_ne ;D-flag not cleared
@ -631,7 +631,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned SP trap_ne ;returned SP
050f : d0fe > bne * ;failed not equal (non zero) 050f : d0fe > bne * ;failed not equal (non zero)
0511 : a50c lda irq_f ;flags seen in IRQ vector 0511 : a502 lda irq_f ;flags seen in IRQ vector
if D_clear = 1 if D_clear = 1
and #decmode and #decmode
trap_ne ;D-flag not cleared trap_ne ;D-flag not cleared
@ -690,7 +690,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned flags trap_ne ;returned flags
054a : d0fe > bne * ;failed not equal (non zero) 054a : d0fe > bne * ;failed not equal (non zero)
054c : a50a lda irq_a ;accu seen in IRQ vector 054c : a500 lda irq_a ;accu seen in IRQ vector
054e : cdff01 cmp lst_a 054e : cdff01 cmp lst_a
trap_ne ;IRQ A received trap_ne ;IRQ A received
0551 : d0fe > bne * ;failed not equal (non zero) 0551 : d0fe > bne * ;failed not equal (non zero)
@ -739,7 +739,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned flags trap_ne ;returned flags
0583 : d0fe > bne * ;failed not equal (non zero) 0583 : d0fe > bne * ;failed not equal (non zero)
0585 : a50a lda irq_a ;accu seen in IRQ vector 0585 : a500 lda irq_a ;accu seen in IRQ vector
0587 : cdff01 cmp lst_a 0587 : cdff01 cmp lst_a
trap_ne ;IRQ A received trap_ne ;IRQ A received
058a : d0fe > bne * ;failed not equal (non zero) 058a : d0fe > bne * ;failed not equal (non zero)
@ -770,7 +770,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned SP trap_ne ;returned SP
05a7 : d0fe > bne * ;failed not equal (non zero) 05a7 : d0fe > bne * ;failed not equal (non zero)
05a9 : a50c lda irq_f ;flags seen in IRQ vector 05a9 : a502 lda irq_f ;flags seen in IRQ vector
if D_clear = 1 if D_clear = 1
and #decmode and #decmode
trap_ne ;D-flag not cleared trap_ne ;D-flag not cleared
@ -793,7 +793,7 @@ bffc = I_port = $bffc ;feedback port address
ldx #0 ldx #0
lda #0 lda #0
sta I_src sta I_src
push_stat intdis push_stat intdis
I_set IRQ_bit ;IRQ pending I_set IRQ_bit ;IRQ pending
inx inx
inx inx
@ -817,7 +817,7 @@ bffc = I_port = $bffc ;feedback port address
sta nmi_count sta nmi_count
sta irq_count sta irq_count
sta brk_count sta brk_count
push_stat 0 push_stat 0
I_set IRQ_bit ;trigger IRQ I_set IRQ_bit ;trigger IRQ
else else
; NMI integrity test ; NMI integrity test
@ -853,7 +853,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned SP trap_ne ;returned SP
05d5 : d0fe > bne * ;failed not equal (non zero) 05d5 : d0fe > bne * ;failed not equal (non zero)
05d7 : a50f lda nmi_f ;flags seen in NMI vector 05d7 : a505 lda nmi_f ;flags seen in NMI vector
if D_clear = 1 if D_clear = 1
and #decmode and #decmode
trap_ne ;D-flag not cleared trap_ne ;D-flag not cleared
@ -920,7 +920,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned flags trap_ne ;returned flags
0618 : d0fe > bne * ;failed not equal (non zero) 0618 : d0fe > bne * ;failed not equal (non zero)
061a : a50d lda nmi_a ;accu seen in NMI vector 061a : a503 lda nmi_a ;accu seen in NMI vector
061c : cdff01 cmp lst_a 061c : cdff01 cmp lst_a
trap_ne ;NMI A received trap_ne ;NMI A received
061f : d0fe > bne * ;failed not equal (non zero) 061f : d0fe > bne * ;failed not equal (non zero)
@ -977,7 +977,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned flags trap_ne ;returned flags
0659 : d0fe > bne * ;failed not equal (non zero) 0659 : d0fe > bne * ;failed not equal (non zero)
065b : a50d lda nmi_a ;accu seen in NMI vector 065b : a503 lda nmi_a ;accu seen in NMI vector
065d : cdff01 cmp lst_a 065d : cdff01 cmp lst_a
trap_ne ;NMI A received trap_ne ;NMI A received
0660 : d0fe > bne * ;failed not equal (non zero) 0660 : d0fe > bne * ;failed not equal (non zero)
@ -1016,7 +1016,7 @@ bffc = I_port = $bffc ;feedback port address
trap_ne ;returned SP trap_ne ;returned SP
0685 : d0fe > bne * ;failed not equal (non zero) 0685 : d0fe > bne * ;failed not equal (non zero)
0687 : a50f lda nmi_f ;flags seen in NMI vector 0687 : a505 lda nmi_f ;flags seen in NMI vector
if D_clear = 1 if D_clear = 1
and #decmode and #decmode
trap_ne ;D-flag not cleared trap_ne ;D-flag not cleared
@ -1038,8 +1038,8 @@ bffc = I_port = $bffc ;feedback port address
0693 : a200 ldx #0 0693 : a200 ldx #0
0695 : a904 lda #4 ;set expected interrupt NMI only 0695 : a904 lda #4 ;set expected interrupt NMI only
0697 : 8d0302 sta I_src 0697 : 8d0302 sta I_src
push_stat intdis push_stat intdis
069a : a904 > lda #intdis 069a : a904 > lda #intdis
069c : 48 > pha ;use stack to load status 069c : 48 > pha ;use stack to load status
I_set 8 ;both interrupts pending I_set 8 ;both interrupts pending
@ -1117,23 +1117,23 @@ bffc = I_port = $bffc ;feedback port address
06f3 : d0fe > bne * ;failed not equal (non zero) 06f3 : d0fe > bne * ;failed not equal (non zero)
; S U C C E S S ************************************************ ; S U C C E S S ************************************************
; ------------- ; -------------
success ;if you get here everything went well success ;if you get here everything went well
06f5 : 4cf506 > jmp * ;test passed, no errors 06f5 : 4cf506 > jmp * ;test passed, no errors
; ------------- ; -------------
; S U C C E S S ************************************************ ; S U C C E S S ************************************************
; check data_segment +0 to +2 for sequence of concurrent interrupts ; check data_segment +0 to +2 for sequence of concurrent interrupts
; e.g. 0x200 = NMI, 0x201 = IRQ, 0x202 = BRK, lower values = earlier ; e.g. 0x200 = NMI, 0x201 = IRQ, 0x202 = BRK, lower values = earlier
06f8 : 4c0004 jmp start ;run again 06f8 : 4c0004 jmp start ;run again
; manual tests for the WAI opcode of the 65c02 ; manual tests for the WAI opcode of the 65c02
wai macro wai macro
db $cb ;WAI opcode db $cb ;WAI opcode
endm endm
; requires single step operation, report = 0 ; requires single step operation, report = 0
; set PC to the 1st instruction of the test ; set PC to the 1st instruction of the test
; step to the WAI opcode, then manually tie the IRQ input low ; step to the WAI opcode, then manually tie the IRQ input low
@ -1164,7 +1164,7 @@ bffc = I_port = $bffc ;feedback port address
success success
070f : 4c0f07 > jmp * ;test passed, no errors 070f : 4c0f07 > jmp * ;test passed, no errors
; WAI with interrupts enabled ; WAI with interrupts enabled
0712 : a2ff ldx #$ff 0712 : a2ff ldx #$ff
0714 : 9a txs 0714 : 9a txs
@ -1194,13 +1194,13 @@ bffc = I_port = $bffc ;feedback port address
success success
072c : 4c2c07 > jmp * ;test passed, no errors 072c : 4c2c07 > jmp * ;test passed, no errors
; manual test for the STP opcode of the 65c02 ; manual test for the STP opcode of the 65c02
stp macro stp macro
db $db ;STP opcode db $db ;STP opcode
endm endm
; set PC to the 1st instruction of the test, then run ; set PC to the 1st instruction of the test, then run
072f : ea nop 072f : ea nop
0730 : ea nop 0730 : ea nop
@ -1230,13 +1230,13 @@ bffc = I_port = $bffc ;feedback port address
073a : 88 dey 073a : 88 dey
073b : 88 dey 073b : 88 dey
073c : 88 dey 073c : 88 dey
073d : 850d sta nmi_a ;save regsters during NMI 073d : 8503 sta nmi_a ;save regsters during NMI
073f : 860e stx nmi_x 073f : 8604 stx nmi_x
0741 : 68 pla 0741 : 68 pla
0742 : 48 pha 0742 : 48 pha
0743 : 850f sta nmi_f 0743 : 8505 sta nmi_f
0745 : ad0302 lda I_src ;NMI expected? 0745 : ad0302 lda I_src ;NMI expected?
0748 : 2904 and #4 0748 : 2904 and #4
trap_eq ;unexpexted NMI - check stack for conditions trap_eq ;unexpexted NMI - check stack for conditions
074a : f0fe > beq * ;failed equal (zero) 074a : f0fe > beq * ;failed equal (zero)
@ -1249,7 +1249,7 @@ bffc = I_port = $bffc ;feedback port address
0752 : 68 pla ;return with other flags reversed 0752 : 68 pla ;return with other flags reversed
0753 : 49c3 eor #m8-fai-decmode 0753 : 49c3 eor #m8-fai-decmode
0755 : 48 pha 0755 : 48 pha
0756 : ba tsx 0756 : ba tsx
0757 : bd0201 lda $102,x ;test break on stack 0757 : bd0201 lda $102,x ;test break on stack
075a : 2910 and #break 075a : 2910 and #break
trap_ne ;unexpected B-flag! - this may fail on a real 6502 trap_ne ;unexpected B-flag! - this may fail on a real 6502
@ -1259,12 +1259,12 @@ bffc = I_port = $bffc ;feedback port address
075e : ad0302 lda I_src ;mark expected NMI has occured 075e : ad0302 lda I_src ;mark expected NMI has occured
0761 : 29fb and #$ff-4 0761 : 29fb and #$ff-4
0763 : 8d0302 sta I_src 0763 : 8d0302 sta I_src
I_clr NMI_bit I_clr NMI_bit
0766 : adfcbf > lda I_port ;turn off interrupt by bit 0766 : adfcbf > lda I_port ;turn off interrupt by bit
0769 : 297d > and #I_filter-(1<<NMI_bit ) 0769 : 297d > and #I_filter-(1<<NMI_bit)
076b : 8dfcbf > sta I_port 076b : 8dfcbf > sta I_port
076e : a60e ldx nmi_x 076e : a604 ldx nmi_x
0770 : e8 inx 0770 : e8 inx
0771 : 8e0002 stx nmi_count 0771 : 8e0002 stx nmi_count
0774 : a949 lda #'I' ;mark (NM)I 0774 : a949 lda #'I' ;mark (NM)I
@ -1276,7 +1276,7 @@ bffc = I_port = $bffc ;feedback port address
trap ;unexpected RESET trap ;unexpected RESET
0778 : 4c7807 > jmp * ;failed anyway 0778 : 4c7807 > jmp * ;failed anyway
077b : 88 dey 077b : 88 dey
077c : 88 dey 077c : 88 dey
077d : irq_trap ;BRK & IRQ test 077d : irq_trap ;BRK & IRQ test
@ -1284,13 +1284,13 @@ bffc = I_port = $bffc ;feedback port address
077e : 88 dey 077e : 88 dey
077f : 88 dey 077f : 88 dey
0780 : 88 dey 0780 : 88 dey
0781 : 850a sta irq_a ;save registers during IRQ/BRK 0781 : 8500 sta irq_a ;save registers during IRQ/BRK
0783 : 860b stx irq_x 0783 : 8601 stx irq_x
0785 : 68 pla 0785 : 68 pla
0786 : 48 pha 0786 : 48 pha
0787 : 850c sta irq_f 0787 : 8502 sta irq_f
0789 : ad0302 lda I_src ;IRQ expected? 0789 : ad0302 lda I_src ;IRQ expected?
078c : 2903 and #3 078c : 2903 and #3
trap_eq ;unexpexted IRQ/BRK - check stack for conditions trap_eq ;unexpexted IRQ/BRK - check stack for conditions
078e : f0fe > beq * ;failed equal (zero) 078e : f0fe > beq * ;failed equal (zero)
@ -1302,32 +1302,32 @@ bffc = I_port = $bffc ;feedback port address
0796 : 68 pla ;return with other flags reversed 0796 : 68 pla ;return with other flags reversed
0797 : 49c3 eor #m8-fai-decmode 0797 : 49c3 eor #m8-fai-decmode
0799 : 48 pha 0799 : 48 pha
079a : ba tsx 079a : ba tsx
079b : bd0201 lda $102,x ;test break on stack 079b : bd0201 lda $102,x ;test break on stack
079e : 2910 and #break 079e : 2910 and #break
07a0 : d021 bne brk_trap 07a0 : d021 bne brk_trap
07a2 : ad0302 lda I_src ;IRQ expected? 07a2 : ad0302 lda I_src ;IRQ expected?
07a5 : 2902 and #2 07a5 : 2902 and #2
trap_eq ;unexpexted IRQ - check stack for conditions trap_eq ;unexpexted IRQ - check stack for conditions
07a7 : f0fe > beq * ;failed equal (zero) 07a7 : f0fe > beq * ;failed equal (zero)
07a9 : ad0302 lda I_src ;mark expected IRQ has occured 07a9 : ad0302 lda I_src ;mark expected IRQ has occured
07ac : 29fd and #$ff-2 07ac : 29fd and #$ff-2
07ae : 8d0302 sta I_src 07ae : 8d0302 sta I_src
I_clr IRQ_bit I_clr IRQ_bit
07b1 : adfcbf > lda I_port ;turn off interrupt by bit 07b1 : adfcbf > lda I_port ;turn off interrupt by bit
07b4 : 297e > and #I_filter-(1<<IRQ_bit ) 07b4 : 297e > and #I_filter-(1<<IRQ_bit)
07b6 : 8dfcbf > sta I_port 07b6 : 8dfcbf > sta I_port
07b9 : a60b ldx irq_x 07b9 : a601 ldx irq_x
07bb : e8 inx 07bb : e8 inx
07bc : 8e0102 stx irq_count 07bc : 8e0102 stx irq_count
07bf : a951 lda #'Q' ;mark (IR)Q 07bf : a951 lda #'Q' ;mark (IR)Q
07c1 : 28 plp ;should be reversed by rti 07c1 : 28 plp ;should be reversed by rti
07c2 : 40 rti 07c2 : 40 rti
07c3 : brk_trap 07c3 : brk_trap
07c3 : ad0302 lda I_src ;break expected? 07c3 : ad0302 lda I_src ;break expected?
07c6 : 2901 and #1 07c6 : 2901 and #1
@ -1337,20 +1337,20 @@ bffc = I_port = $bffc ;feedback port address
07ca : ad0302 lda I_src ;mark expected BRK has occured 07ca : ad0302 lda I_src ;mark expected BRK has occured
07cd : 29fe and #$ff-1 07cd : 29fe and #$ff-1
07cf : 8d0302 sta I_src 07cf : 8d0302 sta I_src
07d2 : a60b ldx irq_x 07d2 : a601 ldx irq_x
07d4 : e8 inx 07d4 : e8 inx
07d5 : 8e0202 stx brk_count 07d5 : 8e0202 stx brk_count
07d8 : a50a lda irq_a 07d8 : a500 lda irq_a
07da : a94b lda #'K' ;mark (BR)K 07da : a94b lda #'K' ;mark (BR)K
07dc : 28 plp ;should be reversed by rti 07dc : 28 plp ;should be reversed by rti
07dd : 40 rti 07dd : 40 rti
if report = 1 if report = 1
rep_int = 1 rep_int = 1
include "report.i65" include "report.i65"
endif endif
;system vectors ;system vectors
if (load_data_direct = 1) if (load_data_direct = 1)
fffa = org $fffa fffa = org $fffa
@ -1364,12 +1364,12 @@ fffe : 7d07 dw irq_trap
dw res_trap dw res_trap
dw irq_trap dw irq_trap
endif endif
fffa = end start fffa = end start
No errors in pass 2. No errors in pass 2.
Wrote binary from address $000a through $ffff. Wrote binary from address $0000 through $ffff.
Total size 65526 bytes. Total size 65536 bytes.
Program start address is at $0400 (1024). Program start address is at $0400 (1024).

View File

@ -27,28 +27,22 @@ class Test6502Klaus2m5Functional {
bus.add(ram) bus.add(ram)
cpu.reset() cpu.reset()
cpu.regPC = 0x0400 cpu.regPC = 0x0400
cpu.addBreakpoint(0x3469) { _, _ ->
// reaching this address means successful test result
if(cpu.currentOpcode==0x4c)
throw SuccessfulTestResult()
Cpu6502.BreakpointResultAction(null, null)
}
try { try {
while (cpu.totalCycles < 100000000) { do {
cpu.clock() val previousPC = cpu.regPC
} cpu.step()
} catch (sx: SuccessfulTestResult) { } while(cpu.regPC!=previousPC)
println("test successful ${cpu.totalCycles}")
return
} catch(nx: NotImplementedError) { } catch(nx: NotImplementedError) {
println("encountered a not yet implemented feature: ${nx.message}") println("encountered a not yet implemented feature: ${nx.message}")
} }
println(cpu.snapshot()) // the test is successful if address 0x3469 is reached ("success" label in source code)
val d = cpu.disassemble(ram, max(0, cpu.regPC-20), min(65535, cpu.regPC+20)) if(cpu.regPC!=0x3469) {
println(d.first.joinToString ("\n")) println(cpu.snapshot())
fail("test failed") val d = cpu.disassemble(ram, max(0, cpu.regPC-20), min(65535, cpu.regPC+20))
println(d.first.joinToString("\n"))
fail("test failed")
}
} }
@Test @Test
@ -80,8 +74,8 @@ class Test6502Klaus2m5Functional {
} }
@Test @Test
//@Ignore("todo: fix the interrupt tests") // TODO the test code is not correct
fun testInterrupts6502() { fun testInterrupts6502() {
// TODO fix this test code
val cpu = Cpu6502() val cpu = Cpu6502()
val bus = Bus() val bus = Bus()
val ram = Ram(0, 0xffff) val ram = Ram(0, 0xffff)