pinky/nes-testsuite/roms/cli_latency_tests/source/cli_latency.a
2016-10-23 19:50:32 +02:00

215 lines
4.3 KiB
Text

; Tests the delay in CLI taking effect, and some basic aspects of IRQ
; handling and the APU frame IRQ (needed by the tests).
.include "validation.a"
irq_count = $10
irq_flags = $11
irq_addr = $12
irq_data = $14
test_name:
.db "CLI LATENCY",0
begin_test:
sei
sta result
lda #0
sta irq_count
sta irq_flags
sta irq_addr
sta irq_addr + 1
rts
irq: sta irq_data
pla ; save status flags and return addr from stack
sta irq_flags
pla
sta irq_addr
pla
sta irq_addr + 1
pha ; restore return addr and status flags on stack
lda irq_addr
pha
lda irq_flags
pha
inc irq_count
bpl +
pla
ora #$04 ; set I flag in saved status to disable IRQ
pha
: lda irq_data
rti
; Reports error if none or more than one interrupt occurred,
; or if return address within handler doesn't match YX.
end_test:
sei
nop
cmp irq_count
jsr error_if_ne
cpx irq_addr
jsr error_if_ne
cpy irq_addr + 1
jsr error_if_ne
rts
.code
reset:
sei
lda #0
sta $2000
sta $2001
jsr wait_vbl
jsr wait_vbl
lda #$00
sta $4017
lda #40
jsr delay_msec
; APU frame IRQ should be active by now
lda #2;) RTI should not adjust return address (as RTS does)
sta result
lda #addr.msb
pha
lda #addr.lsb
pha
php
ldx #0
rti
inx
inx
addr: inx
inx
cpx #2
jsr error_if_ne
lda #3;) APU should generate IRQ when $4017 = $00
jsr begin_test
lda #$80 ; have IRQ handler set I flag after first invocation
sta irq_count
cli
ldy #0
: dey
bne -
sei
nop
lda irq_count
cmp #$81
jsr error_if_ne
lda #4;) Exactly one instruction after CLI should execute before IRQ is taken
jsr begin_test
lda #$80 ; have IRQ handler set I flag after first invocation
sta irq_count
cli
nop
irq3:
ldx #irq3.lsb
ldy #irq3.msb
lda #$81
jsr end_test
lda #5;) CLI SEI should allow only one IRQ just after SEI
jsr begin_test
lda #$80 ; have IRQ handler set I flag after first invocation
sta irq_count
cli
sei
irq4:
ldx #irq4.lsb
ldy #irq4.msb
lda #$81
jsr end_test
lda #6;) In IRQ allowed by CLI SEI, I flag should be set in saved status flags
jsr begin_test
cli
sei
nop
nop
lda irq_flags
and #$04
jsr error_if_eq
lda #7;) CLI PLP should allow only one IRQ just after PLP
jsr begin_test
php
cli
plp
irq5:
ldx #irq5.lsb
ldy #irq5.msb
lda #1
jsr end_test
lda #8;) PLP SEI should allow only one IRQ just after SEI
jsr begin_test
lda #0
pha
plp
sei
irq6:
ldx #irq6.lsb
ldy #irq6.msb
lda #1
jsr end_test
lda #9;) PLP PLP should allow only one IRQ just after PLP
jsr begin_test
php
lda #0
pha
plp
plp
irq7:
ldx #irq7.lsb
ldy #irq7.msb
lda #1
jsr end_test
lda #10;) CLI RTI should not allow any IRQs
jsr begin_test
lda #rti1.msb
pha
lda #rti1.lsb
pha
php
cli
rti
rti1: nop
nop
lda irq_count
jsr error_if_ne
lda #11;) Unacknowledged IRQ shouldn't let any mainline code run
jsr begin_test
cli
nop
; IRQ should keep firing here until counter reaches $80
nop
lda irq_count
cmp #$80
jsr error_if_ne
lda #12;) RTI RTI shouldn't let any mainline code run
jsr begin_test
lda #rti3.msb
pha
lda #rti3.lsb
pha
php
lda #rti2.msb
pha
lda #rti2.lsb
pha
lda #0
pha
rti
rti2: rti
rti3: nop
lda irq_count
cmp #$80
jsr error_if_ne
jmp tests_passed