include "nesdefs.asm" ;;;;; VARIABLES seg.u RAM org $0 ScrollPos byte ; used during NMI ;;;;; NES CARTRIDGE HEADER NES_HEADER 0,2,1,0 ; mapper 0, 2 PRGs, 1 CHR, horiz. mirror ;;;;; START OF CODE Start: NES_INIT ; set up stack pointer, turn off PPU jsr WaitSync ; wait for VSYNC jsr ClearRAM ; clear RAM jsr WaitSync ; wait for VSYNC (and PPU warmup) jsr SetPalette ; set palette colors jsr FillVRAM ; set PPU video RAM lda #0 sta PPU_ADDR sta PPU_ADDR ; PPU addr = $0000 sta PPU_SCROLL sta PPU_SCROLL ; scroll = $0000 lda #CTRL_NMI sta PPU_CTRL ; enable NMI lda #MASK_BG sta PPU_MASK ; enable rendering .endless jmp .endless ; endless loop ; fill video RAM FillVRAM: subroutine txa ldy #$20 sty PPU_ADDR ; $20?? -> PPU address sta PPU_ADDR ; $2000 -> PPU address ldy #$10 ; set $10 pages ($1000 bytes) .loop: stx PPU_DATA ; X -> PPU data port inx ; X = X + 1 bne .loop ; repeat until 256 bytes dey ; Y = Y - 1 bne .loop ; repeat until Y is 0 rts ; return to caller ; set palette colors SetPalette: subroutine ldy #$00 ; Y = $00 (also palette index) lda #$3f ; A = $3F sta PPU_ADDR ; $3F?? -> PPU address sty PPU_ADDR ; $3F00 -> PPU address .loop: lda Palette,y ; lookup byte in ROM sta PPU_DATA ; store byte to PPU data iny ; Y = Y + 1 cpy #32 ; is Y equal to 32? bne .loop ; not yet, loop rts ; return to caller ;;;;; COMMON SUBROUTINES include "nesppu.asm" ;;;;; INTERRUPT HANDLERS NMIHandler: ; save registers pha ; save A ; update scroll position (must be done after VRAM updates) inc ScrollPos lda ScrollPos sta PPU_SCROLL ; horiz byte lda #0 sta PPU_SCROLL ; vert byte ; reload registers pla ; reload A rti ;;;;; CONSTANT DATA align $100 Palette: hex 1f ;background hex 09092c00 ;bg0 hex 09091900 ;bg1 hex 09091500 ;bg2 hex 09092500 ;bg3 ;;;;; CPU VECTORS NES_VECTORS ;;;;; TILE SETS org $10000 incbin "jroatch.chr"