; 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