ANESE/roms/tests/ppu/ppu_read_buffer/source/crash_proof.s
2017-10-21 17:33:02 -07:00

143 lines
2.8 KiB
ArmAsm
Executable file
Vendored

.pushseg
.segment "LIB"
crash_proof_begin:
setb nmi+3, $A2 ; LDX #imm
pla
sta nmi+8
pla
sta nmi+9
tsx
stx nmi+4
setb nmi+5, $9A ; TXS
setb nmi+6, $38 ; SEC
setb nmi+7, $4C ; JMP abs
lda nmi+9
pha
lda nmi+8
pha
inc nmi+8
bne @no_pagewrap
inc nmi+9
@no_pagewrap:
lda #10 ; Tolerate 10 NMIs (frames) before deeming we've crashed
sta nmi_count
setb nmi+0, $4C ; JMP abs
setb nmi+1, <@rescue
setb nmi+2, >@rescue
setb PPUCTRL, $A8 ; Enable NMI
clc
; This routine may return once or twice, like setjmp.
; Carry clear = normal exit. Carry set = crash-recovery exit.
rts
@rescue:
dec nmi_count
bmi @crashed
rti
@crashed:
nmi_crash_recovery:
jsr crash_proof_end
text_white
print_ext_str_flush " CRASH" ;DO_DTE
inc spr0hit_fails_current
jsr fail_current_test
jmp nmi+3
crash_proof_end:
setb PPUCTRL, $28 ; Disable NMI
setb nmi+0, $40 ; RTI
rts
.segment "LIB"
zp_res irq_temp_a
zp_res irq_temp_x
zp_res irq_temp_y
zp_res irq_temp_s
zp_res irq_temp_p
zp_res irq_temp_pc
irq_temp_reg = irq_temp_a
irq: ; We do not expect IRQs.
; Check what is going on.
sta irq_temp_a ; A
stx irq_temp_x ; X
sty irq_temp_y ; Y
pla
sta irq_temp_p ; P
pla
sta irq_temp_pc+0 ; pc lo
pla
sta irq_temp_pc+1 ; pc hi
tsx
stx irq_temp_s ; S
lda irq_temp_p
and #$10
bne @got_spurious_brk
; Wasn't BRK. Was IRQ.
text_white
;jsr console_show
;set_vrom_page 0
print_ext_str " IRQ?",newline,"Did not expect an IRQ" ;DO_DTE
jmp @exit_show_registers
@got_spurious_brk:
; Was crash-proof active?
lda nmi+7
cmp #$4C+100
bne @nope
ldx irq_temp_reg+3
jmp nmi_crash_recovery
@nope:
; Decrement the return PC by 2 to get the location of BRK instruction
dec irq_temp_pc+0
bne :+
dec irq_temp_pc+1
: dec irq_temp_pc+0
bne :+
dec irq_temp_pc+1
: ;
;
text_white
;jsr console_show
;set_vrom_page 0
; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|
print_ext_str " BRK?",newline,"BRK executed where should not" ;DO_DTE
@exit_show_registers:
@delta = $80
.pushseg
.segment "RODATA"
@script:
.byte newline ;DTE_CHARMAP
.byte "PC=" ;DTE_CHARMAP
.byte @delta+1+irq_temp_pc+1-irq_temp_reg
.byte @delta+1+irq_temp_pc+0-irq_temp_reg
.byte ",AXYSP=" ;DTE_CHARMAP
.byte @delta+1+irq_temp_a-irq_temp_reg
.byte "/" ;DTE_CHARMAP
.byte @delta+1+irq_temp_x-irq_temp_reg
.byte "/" ;DTE_CHARMAP
.byte @delta+1+irq_temp_y-irq_temp_reg
.byte "/" ;DTE_CHARMAP
.byte @delta+1+irq_temp_s-irq_temp_reg
.byte "/" ;DTE_CHARMAP
.byte @delta+1+irq_temp_p-irq_temp_reg
.byte newline ;DTE_CHARMAP
.byte "Test failed.",newline ;DTE_CHARMAP
.byte @delta
.popseg
ldy #$FF
ldx #'!' ;DTE_CHARMAP
@l: jsr print_char_x
: iny
ldx @script,y
cpx #@delta
beq @done
bcc @l
lda irq_temp_reg-@delta-1,x
jsr print_hex
bcs :-
@done: jsr print_newline
jsr fail_current_test
jmp main_exit
.popseg