1; PPU utilities 2 3bss_res ppu_not_present 4 5; Sets PPUADDR to w 6; Preserved: X, Y 7.macro set_ppuaddr w 8 bit PPUSTATUS 9 setb PPUADDR,>w 10 setb PPUADDR,<w 11.endmacro 12 13 14; Delays by no more than n scanlines 15.macro delay_scanlines n 16 .if CLOCK_RATE <> 1789773 17 .error "Currently only supports NTSC" 18 .endif 19 delay ((n)*341)/3 20.endmacro 21 22 23; Waits for VBL then disables PPU rendering. 24; Preserved: A, X, Y 25disable_rendering: 26 pha 27 jsr wait_vbl_optional 28 setb PPUMASK,0 29 pla 30 rts 31 32 33; Fills first nametable with $00 34; Preserved: Y 35clear_nametable: 36 ldx #$20 37 bne clear_nametable_ 38 39clear_nametable2: 40 ldx #$24 41clear_nametable_: 42 lda #0 43 jsr fill_screen_ 44 45 ; Clear pattern table 46 ldx #64 47: sta PPUDATA 48 dex 49 bne :- 50 rts 51 52 53; Fills screen with tile A 54; Preserved: A, Y 55fill_screen: 56 ldx #$20 57 bne fill_screen_ 58 59; Same as fill_screen, but fills other nametable 60fill_screen2: 61 ldx #$24 62fill_screen_: 63 stx PPUADDR 64 ldx #$00 65 stx PPUADDR 66 ldx #240 67: sta PPUDATA 68 sta PPUDATA 69 sta PPUDATA 70 sta PPUDATA 71 dex 72 bne :- 73 rts 74 75 76; Fills palette with $0F 77; Preserved: Y 78clear_palette: 79 set_ppuaddr $3F00 80 ldx #$20 81 lda #$0F 82: sta PPUDATA 83 dex 84 bne :- 85 86 87; Fills OAM with $FF 88; Preserved: Y 89clear_oam: 90 lda #$FF 91 92; Fills OAM with A 93; Preserved: A, Y 94fill_oam: 95 ldx #0 96 stx SPRADDR 97: sta SPRDATA 98 dex 99 bne :- 100 rts 101 102 103; Initializes wait_vbl_optional. Must be called before 104; using it. 105.align 32 106init_wait_vbl: 107 ; Wait for VBL flag to be set, or ~60000 108 ; clocks (2 frames) to pass 109 ldy #24 110 ldx #1 111 bit PPUSTATUS 112: bit PPUSTATUS 113 bmi @set 114 dex 115 bne :- 116 dey 117 bpl :- 118@set: 119 ; Be sure flag didn't stay set (in case 120 ; PPUSTATUS always has high bit set) 121 tya 122 ora PPUSTATUS 123 sta ppu_not_present 124 rts 125 126 127; Same as wait_vbl, but returns immediately if PPU 128; isn't working or doesn't support VBL flag 129; Preserved: A, X, Y 130.align 16 131wait_vbl_optional: 132 bit ppu_not_present 133 bmi :++ 134 ; FALL THROUGH 135 136; Clears VBL flag then waits for it to be set. 137; Preserved: A, X, Y 138wait_vbl: 139 bit PPUSTATUS 140: bit PPUSTATUS 141 bpl :- 142: rts 143 144 145.macro check_ppu_region_ Len 146 ; Delays since VBL began 147 jsr wait_vbl_optional ; 10 average 148 delay Len - 18 - 200 149 lda PPUSTATUS ; 4 150 bmi @ok ; 2 151 delay 200 152 ; Next VBL should roughly begin here if it's the 153 ; one we are detecting 154 delay 200 155 lda PPUSTATUS ; 2 156 bpl @ok 157.endmacro 158 159check_ppu_region: 160 161.ifndef REGION_FREE 162.ifdef PAL_ONLY 163 check_ppu_region_ 29781 164 print_str {newline,"Note: This test is meant for PAL NES only.",newline,newline} 165.endif 166 167.ifdef NTSC_ONLY 168 check_ppu_region_ 33248 169 print_str {newline,"Note: This test is meant for NTSC NES only.",newline,newline} 170.endif 171.endif 172@ok: rts 173 174 175; Loads ASCII font into CHR RAM and fills rest with $FF 176.macro load_chr_ram 177 bit PPUSTATUS 178 setb PPUADDR,0 179 setb PPUADDR,0 180 181 ; Copy ascii_chr to 0 182 setb addr,<ascii_chr 183 ldx #>ascii_chr 184 ldy #0 185@page: 186 stx addr+1 187: lda (addr),y 188 sta PPUDATA 189 iny 190 bne :- 191 inx 192 cpx #>ascii_chr_end 193 bne @page 194 195 ; Fill rest 196 lda #$FF 197: sta PPUDATA 198 iny 199 bne :- 200 inx 201 cpx #$20 202 bne :- 203.endmacro 204