gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/targets/mos6502/nes/flush_attributes.s
1 .include "global.s"
2
3 .area GBDKOVR (PAG, OVR)
4 .x_save: .ds 1
5 .y_save: .ds 1
6 .attribute_row_dirty: .ds 1
7 .attribute_column_dirty: .ds 1
8
9 .area _HOME
10
11 .macro LOAD_ROW_DIRTY ?lbl, ?lbl2
12 .ifdef NES_WINDOW_LAYER
13 bit *__current_vram_cfg_write
14 bpl lbl
15 lda *_attribute_row_dirty_win,x
16 jmp lbl2
17 .endif
18 lbl:
19 lda *_attribute_row_dirty,x
20 lbl2:
21 .endm
22
23 .macro LOAD_COLUMN_DIRTY ?lbl, ?lbl2
24 .ifdef NES_WINDOW_LAYER
25 bit *__current_vram_cfg_write
26 bpl lbl
27 lda *_attribute_column_dirty_win,x
28 jmp lbl2
29 .endif
30 lbl:
31 lda *_attribute_column_dirty,x
32 lbl2:
33 .endm
34
35 .macro LOAD_ROW_ATTRIBUTE ?lbl, ?lbl2
36 .ifdef NES_WINDOW_LAYER
37 bit *__current_vram_cfg_write
38 bpl lbl
39 lda *_attribute_row_dirty_win,x
40 jmp lbl2
41 .endif
42 lbl:
43 lda *_attribute_row_dirty,x
44 lbl2:
45 .endm
46
47 .macro CLEAR_ATTRIBUTE_DIRTY ?lbl, ?lbl2
48 lda #0
49 .ifdef NES_WINDOW_LAYER
50 bit *__current_vram_cfg_write
51 bpl lbl
52 sta _attribute_row_dirty_win,x
53 sta _attribute_column_dirty_win,x
54 jmp lbl2
55 .endif
56 lbl:
57 sta _attribute_row_dirty,x
58 sta _attribute_column_dirty,x
59 lbl2:
60 .endm
61
62 _flush_shadow_attributes::
63 .ifdef NES_WINDOW_LAYER
64 ; First process window layer
65 lda *__current_vram_cfg_write
66 pha
67 ora #PPUHI_WIN
68 sta *__current_vram_cfg_write
69 jsr _flush_shadow_attributes_impl
70 ; ...then background layer
71 lda *__current_vram_cfg_write
72 and #~PPUHI_WIN
73 sta *__current_vram_cfg_write
74 jsr _flush_shadow_attributes_impl
75 pla
76 sta *__current_vram_cfg_write
77 rts
78 _flush_shadow_attributes_impl::
79 .endif
80 ldx #0
81 .ifndef NES_TILEMAP_S
82 1$:
83 .endif
84 stx *.x_save
85 LOAD_ROW_DIRTY
86 beq 2$
87 sta *.attribute_row_dirty
88 ldy .xy_shift_tab,x
89 jsr _flush_shadow_attributes_rows
90 ldx *.x_save
91 2$:
92 LOAD_COLUMN_DIRTY
93 beq 3$
94 sta *.attribute_column_dirty
95 ldy .xy_shift_tab,x
96 jsr _flush_shadow_attributes_columns
97 3$:
98 ldx *.x_save
99 CLEAR_ATTRIBUTE_DIRTY
100 .ifndef NES_TILEMAP_S
101 inx
102 cpx #NUM_NT
103 bne 1$
104 .endif
105 rts
106
107 ;
108 ; Writes every row of attributes from _shadow_attributes that's been marked
109 ; as dirty in the _attribute_row_dirty byte to PPU memory.
110 ;
111 _flush_shadow_attributes_rows:
112 lda #<PPU_AT0
113 sta *.tmp
114 lda .ppu_hi_tab,x
115 .ifdef NES_WINDOW_LAYER
116 bit *__current_vram_cfg_write
117 bpl 0$
118 ora #PPUHI_WIN
119 0$:
120 .endif
121 sta *.tmp+1
122 _flush_shadow_attributes_row_loop:
123 lsr *.attribute_row_dirty
124 bcc 1$
125 jmp _flush_shadow_attributes_update_row
126 1$:
127 beq _flush_shadow_attributes_end
128 _flush_shadow_attributes_next_row:
129 ; Y += AT_SHADOW_WIDTH
130 tya
131 clc
132 adc #AT_SHADOW_WIDTH
133 tay
134 ; .tmp += ATTRIBUTE_PACKED_WIDTH
135 lda *.tmp
136 adc #ATTRIBUTE_PACKED_WIDTH
137 sta *.tmp
138 jmp _flush_shadow_attributes_row_loop
139 _flush_shadow_attributes_end:
140 rts
141
142 ;
143 ; Flushes all dirty rows of _attribute_shadow by writing them to PPU memory
144 ;
145 _flush_shadow_attributes_update_row:
146 stx *REGTEMP+3
147 ; Update all 8 bytes of row for now, as each row in _attribute_row_dirty only stores 1 bit
148 ; TODO: Could store 8 bytes and update range, at expense of 7 more bytes.
149 lda *.tmp+1
150 tax
151 lda *.tmp
152 jsr .ppu_stripe_begin_horizontal
153 ; Write 8 bytes
154 .ifdef NES_WINDOW_LAYER
155 bit *__current_vram_cfg_write
156 bpl 1$
157 i = 0
158 .rept ATTRIBUTE_PACKED_WIDTH
159 lda _attribute_shadow_win+i,y
160 jsr .ppu_stripe_write_byte
161 i = i + 1
162 .endm
163 jmp 2$
164 1$:
165 .endif
166 i = 0
167 .rept ATTRIBUTE_PACKED_WIDTH
168 lda _attribute_shadow+i,y
169 jsr .ppu_stripe_write_byte
170 i = i + 1
171 .endm
172 2$:
173 jsr .ppu_stripe_end
174 ldx *REGTEMP+3
175 jmp _flush_shadow_attributes_next_row
176
177 ;
178 ; Writes every column of attributes from _shadow_attributes that's been marked
179 ; as dirty in the _attribute_column_dirty byte to PPU memory.
180 ;
181 ;
182 _flush_shadow_attributes_columns:
183 lda #<PPU_AT0
184 sta *.tmp
185 lda .ppu_hi_tab,x
186 .ifdef NES_WINDOW_LAYER
187 bit *__current_vram_cfg_write
188 bpl 0$
189 ora #PPUHI_WIN
190 0$:
191 .endif
192 sta *.tmp+1
193 _flush_shadow_attributes_columns_loop:
194 lsr *.attribute_column_dirty
195 bcc 1$
196 jmp _flush_shadow_attributes_update_column
197 1$:
198 beq _flush_shadow_attributes_columns_end
199 _flush_shadow_attributes_columns_next_column:
200 ; Y += 1
201 iny
202 ; .tmp += 1
203 inc *.tmp
204 jmp _flush_shadow_attributes_columns_loop
205 _flush_shadow_attributes_columns_end:
206 rts
207
208 _write_vert:
209 lda *.tmp+1
210 tax
211 lda *.tmp
212 jsr .ppu_stripe_begin_vertical
213 lda _attribute_shadow,y
214 jsr .ppu_stripe_write_byte
215 lda _attribute_shadow+(AT_SHADOW_WIDTH*4),y
216 jsr .ppu_stripe_write_byte
217 jsr .ppu_stripe_end
218 ; inc src index
219 tya
220 clc
221 adc #AT_SHADOW_WIDTH
222 tay
223 ; inc ppu addr
224 lda *.tmp
225 adc #ATTRIBUTE_PACKED_WIDTH
226 sta *.tmp
227 rts
228
229 ;
230 ; Flushes all dirty rows of _attribute_shadow by writing them to PPU memory
231 ;
232 _flush_shadow_attributes_update_column:
233 stx *REGTEMP+3
234 sty *.y_save
235 lda *.tmp
236 pha
237 ; Update all 8 bytes of column for now, as each column in _attribute_column_dirty only stores 1 bit
238 ; As PPU has no increment-by-8 feature, split writes into 4 separate stripes 2 bytes each
239 ; TODO: Could make a dedicated unrolled transfer routine in nmi handler that writes all 8 bytes as one stripe.
240 .rept 4
241 jsr _write_vert
242 .endm
243 pla
244 sta *.tmp
245 ldy *.y_save
246 ldx *REGTEMP+3
247 jmp _flush_shadow_attributes_columns_next_column
248
249 ; Shift MSB of attribute X / Y (attribute table index) from bits 1 and 0 to 7 and 3
250 .ifdef NES_TILEMAP_F
251 .xy_shift_tab:
252 .db 0b00000000
253 .db 0b00001000
254 .db 0b10000000
255 .db 0b10001000
256 .endif
257 .ifdef NES_TILEMAP_S
258 .xy_shift_tab:
259 .db 0b00000000
260 .db 0b00000000
261 .db 0b00000000
262 .db 0b00000000
263 .endif
264 .ifdef NES_TILEMAP_H
265 .xy_shift_tab:
266 .db 0b00000000
267 .db 0b00001000
268 .endif
269 .ifdef NES_TILEMAP_V
270 .xy_shift_tab:
271 .db 0b00000000
272 .db 0b01000000
273 .endif
274
275 ; Get hi address of attribute table index
276 .ifdef NES_TILEMAP_F
277 .ppu_hi_tab:
278 .db >PPU_AT0
279 .db >PPU_AT1
280 .db >PPU_AT2
281 .db >PPU_AT3
282 .endif
283 .ifdef NES_TILEMAP_S
284 .ppu_hi_tab:
285 .db >PPU_AT0
286 .db >PPU_AT0
287 .db >PPU_AT0
288 .db >PPU_AT0
289 .endif
290 .ifdef NES_TILEMAP_H
291 .ppu_hi_tab:
292 .db >PPU_AT0
293 .db >PPU_AT1
294 .endif
295 .ifdef NES_TILEMAP_V
296 .ppu_hi_tab:
297 .db >PPU_AT0
298 .db >PPU_AT2
299 .endif
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.