Clearly the correct operation of zero-page and the stack page is the most critical. Without them, a significant proportion of 6502 opcodes become useless. But I think we can now assume that the VIA and ROM are working correctly.
So here's an attempt to verify pages 0-3 (the first kilobyte) without relying on correct RAM functionality, and using the VIA for status output:
Code:
coldstart:
LDX #$FF
STX via1ddrb
STZ via1rb ; output $00 -> filling zeroes
INX
fillzero:
STZ $00,X
STZ $100,X
STZ $200,X
STZ $300,X
INX
BNE fillzero
INC via1rb ; output $01 -> checking zeroes
checkzero:
LDA $00,X
BNE error0
LDA $100,X
BNE error1
LDA $200,X
BNE error2
LDA $300,X
BNE error3
INX
BNE checkzero
INC via1rb ; output $02 -> filling ones
DEC A
fillones:
STA $00,X
STA $100,X
STA $200,X
STA $300,X
INX
BNE fillones
INC via1rb ; output $03 -> checking ones
checkones:
CMP $00,X
BNE error0
CMP $100,X
BNE error1
CMP $200,X
BNE error2
CMP $300,X
BNE error3
INX
BNE checkones
INC via1rb ; output $04 -> filling self-address
BRA filladdr
; Error routines in the middle so they can be reached from both ends
error0:
LDY #$00
TXS
BRA errorloop
error1:
LDY #$10
TXS
BRA errorloop
error2:
LDY #$20
TXS
BRA errorloop
error3:
LDY #$30
TXS
errorloop: ; rapidly cycle through indication of test stage, error page (moved to high nybble), error index within page
INX
BNE errorloop
INC A
BNE errorloop
TSX
TXA
LDX via1rb
STY via1rb
TAY
TXS
LDA #0
BRA errorloop
filladdr:
TXA
STA $00,X
STA $100,X
STA $200,X
STA $300,X
INX
BNE filladdr
INC via1rb ; output $05 -> checking self-address
checkaddr:
TXA
CMP $00,X
BNE error0
CMP $100,X
BNE error1
CMP $200,X
BNE error2
CMP $300,X
BNE error3
INX
BNE checkaddr
INC via1rb ; output $06 -> filling self-page
fillpage:
STZ $00,X
LDA #1
STA $100,X
LDA #2
STA $200,X
LDA #3
STA $300,X
INX
BNE fillpage
INC via1rb ; output $07 -> checking self-page
checkpage:
LDA $00,X
BNE error0
INC A
CMP $100,X
BNE error1
INC A
CMP $200,X
BNE error2
INC A
CMP $300,X
BNE error3
INX
BNE checkpage
INC via1rb ; output $08 -> test complete
done:
WAI
BRA done
I've edited it to ensure that none of the branches should be out of range, and to make the output sequence slow enough to read.