1. The code in your VBLANK label does not return from the interrupt, yet you're setting NMI in the 6502 vectors section to that label/address. This is bad. You need an rti as your last instruction, otherwise your jmp Infinite is technically running inside of NMI.
2. Again in your VBLANK routine: you're clearing bit 7 too soon. There's a known race condition on the NES where if you do this too soon you end up skipping NMI entirely. See last bullet point item here https://wiki.nesdev.com/w/index.php/PPU ... #PPUSTATUS as well as this: https://wiki.nesdev.com/w/index.php/NMI#Race_condition
If you don't want to deal with that, just add two nop instructions prior to the bit $2002 (and loop against the bit $2002 line, not the two nops) which will waste 4 cycles.
3. The code in your VECTORS section for IRQ/BRK vector uses .word 0, which literally means .word $0000, which means your IRQ/BRK vector is pointing to $0000 (i.e. the first and second bytes of zero page). Stop/pause for a moment and think what you want: you essentially, right now, want it to point to some code that essentially does, nothing, right? Pretty simple:
Code: Select all
IRQ: rti .segment "VECTORS" .word VBLANK .word RESET .word IRQ