; PPU utilities bss_res ppu_not_present ; Sets PPUADDR to w ; Preserved: X, Y .macro set_ppuaddr w bit PPUSTATUS setb PPUADDR,>w setb PPUADDR, 1789773 .error "Currently only supports NTSC" .endif delay ((n)*341)/3 .endmacro ; Waits for VBL then disables PPU rendering. ; Preserved: A, X, Y disable_rendering: pha jsr wait_vbl_optional setb PPUMASK,0 pla rts ; Fills first nametable with $00 ; Preserved: Y clear_nametable: ldx #$20 bne clear_nametable_ clear_nametable2: ldx #$24 clear_nametable_: lda #0 jsr fill_screen_ ; Clear pattern table ldx #64 : sta PPUDATA dex bne :- rts ; Fills screen with tile A ; Preserved: A, Y fill_screen: ldx #$20 bne fill_screen_ ; Same as fill_screen, but fills other nametable fill_screen2: ldx #$24 fill_screen_: stx PPUADDR ldx #$00 stx PPUADDR ldx #240 : sta PPUDATA sta PPUDATA sta PPUDATA sta PPUDATA dex bne :- rts ; Fills palette with $0F ; Preserved: Y clear_palette: set_ppuaddr $3F00 ldx #$20 lda #$0F : sta PPUDATA dex bne :- ; Fills OAM with $FF ; Preserved: Y clear_oam: lda #$FF ; Fills OAM with A ; Preserved: A, Y fill_oam: ldx #0 stx SPRADDR : sta SPRDATA dex bne :- rts ; Initializes wait_vbl_optional. Must be called before ; using it. .align 32 init_wait_vbl: ; Wait for VBL flag to be set, or ~60000 ; clocks (2 frames) to pass ldy #24 ldx #1 bit PPUSTATUS : bit PPUSTATUS bmi @set dex bne :- dey bpl :- @set: ; Be sure flag didn't stay set (in case ; PPUSTATUS always has high bit set) tya ora PPUSTATUS sta ppu_not_present rts ; Same as wait_vbl, but returns immediately if PPU ; isn't working or doesn't support VBL flag ; Preserved: A, X, Y .align 16 wait_vbl_optional: bit ppu_not_present bmi :++ ; FALL THROUGH ; Clears VBL flag then waits for it to be set. ; Preserved: A, X, Y wait_vbl: bit PPUSTATUS : bit PPUSTATUS bpl :- : rts