Init code: Difference between revisions
From NESdev Wiki
Jump to navigationJump to search
m (internal link) |
m (1 revision: Rest of pages not related to reference) |
Revision as of 04:22, 13 June 2009
When the NES is powered on or reset, the program should do the following within a fixed bank:
- Set IRQ ignore bit (not strictly necessary as the 6502 sets this flag on all interrupts, including RESET, but it allows program code to simulate a reset by
JMP ($FFFC)
) - Disable decimal mode (not strictly necessary as the 2A03 has no decimal mode, but it maintains compatibility with generic 6502 debuggers)
- Initialize stack pointer
- If using a mapper that generates IRQs, disable APU timer IRQs
- Disable DMC IRQs [1]
- Disable PPU NMIs and rendering
- Initialize the mapper (if any)
The init code after this point may be placed in a separate bank using a bankswitch followed by a JMP
:
- Set all RAM that your program uses to a known state. This often involves clearing internal RAM (@ $0000-$07FF) (and PRG RAM if needed (@ $6000-$7FFF)), except that which is intended to survive a reset (such as high scores).
- Wait at least 30,000 cycles (see Power-up state of PPU) before reading or writing registers $2003 through $2007. This is commonly done by waiting for the PPU to signal the start of vertical blank twice through $2002.
Some mappers have no fixed bank because they switch all 32 KB of PRG at a time. These include AxROM, BxROM, GxROM, and some configurations of Nintendo MMC1. You'll have to put the interrupt vectors and the code up to the end of the JMP
in a separate section that is duplicated in each bank.
Sample implementation:
reset: sei ; ignore IRQs cld ; disable decimal mode ldx #$40 stx $4017 ; disable APU frame IRQ ldx #$ff txs ; Set up stack inx ; now X = 0 stx $2000 ; disable NMI stx $2001 ; disable rendering stx $4010 ; disable DMC IRQs ; Optional (omitted): ; Set up mapper and jmp to further init code here. ; Clear the vblank flag, so we know that we are waiting for the ; start of a vertical blank and not powering on with the ; vblank flag spuriously set bit $2002 ; First of two waits for vertical blank to make sure that the ; PPU has stabilized @vblankwait1: bit $2002 bpl @vblankwait1 ; We now have about 30,000 cycles to burn before the PPU stabilizes. ; Use it to clear RAM. X is still 0... txa @clrmem: sta $000,x sta $100,x sta $200,x sta $300,x sta $400,x sta $500,x sta $600,x sta $700,x ; Remove this if you're storing reset-persistent data inx bne @clrmem @vblankwait2: bit $2002 bpl @vblankwait2