df0c2947d0630ff653b9781e0ec57efe62e620fb
[ScratchNES.git] / src / PPU / PPU.tosh
1 define-atomic evaluate sprites scanline: (N)
2 delete all of secondary OAM
3 delete all of evaluation line
4 delete all of secondary bitmaps
5 delete all of secondary Xt
6 delete all of sprite 0
7 repeat 32
8 add "255" to secondary OAM
9 add "-1" to evaluation line
10 add "-1" to evaluation line
11 add "-1" to evaluation line
12 add "-1" to evaluation line
13 add "-1" to evaluation line
14 add "-1" to evaluation line
15 add "-1" to evaluation line
16 add "-1" to evaluation line
17 end
18 set evaluation n to 1
19 set evaluation slot to 1
20 repeat 64
21 if evaluation slot < 32 and not N < item evaluation n of OAM and item evaluation n of OAM + 8 > N then
22 set temp to item (evaluation n + 3) of OAM
23 replace item temp of evaluation line with evaluation slot
24 replace item temp + 1 of evaluation line with evaluation slot
25 replace item temp + 2 of evaluation line with evaluation slot
26 replace item temp + 3 of evaluation line with evaluation slot
27 replace item temp + 4 of evaluation line with evaluation slot
28 replace item temp + 5 of evaluation line with evaluation slot
29 replace item temp + 6 of evaluation line with evaluation slot
30 replace item temp + 7 of evaluation line with evaluation slot
31 get pattern tile: (item (evaluation n + 1) of OAM) scanline: (mY - item evaluation n of OAM) table: (PPU Sprite pattern table)
32 add mask to secondary bitmaps
33 add temp - 3 to secondary Xt
34 add <evaluation n = 1> to sprite 0
35 change evaluation slot by 1
36 end
37 change evaluation n by 4
38 end
39 ; "TODO: evaluate sprites in secondary OAM"
40 ; "TODO: buggy sprite overflow flag"
41
42 define-atomic get pattern tile: (tile) scanline: (scanline) table: (table)
43 set mask to item (16 * tile + scanline + table + 1) of oCHR
44
45 ; "optimizes CHR-ROM"
46
47 define-atomic format chr
48 delete all of oCHR
49 set temp to 1
50 repeat length of CHR-ROM
51 set BG: Plane 0 to item (1 + (join "0x" (item temp of CHR-ROM))) of bitmask
52 set BG: Plane 1 to item (1 + (join "0x" (item (temp + 8) of CHR-ROM))) of bitmask
53 set BG: Plane 0 to (join "1" (BG: Plane 0))
54 set BG: Plane 1 to (join "1" (BG: Plane 1))
55 add BG: Plane 0 + BG: Plane 1 * 2 to oCHR
56 change temp by 1
57 end
58 if length of CHR-ROM = 0 then
59 repeat 8192
60 add "0" to CHR-ROM
61 add "0" to oCHR
62 end
63 end
64
65 when q key pressed
66 emulate frame
67
68 define-atomic VBlank
69 set PPU vblank to 1
70 if PPU generate NMI = 1 then
71 interrupt: vector "0xFFFA"
72 end
73 repeat until cycles > 2380
74 step CPU
75 end
76 set cycles to 0
77
78 define-atomic skip frame
79 ; "TODO: sprite 0 hit etc?"
80 set mY to -1
81 repeat 224
82 change mY by 1
83 repeat until mX > 254
84 step CPU
85 change mX by 3 * cycles
86 set cycles to 0
87 end
88 ; "TODO: HBlank"
89 end
90 VBlank
91
92 define-atomic emulate frame
93 go to x: -128 y: 128
94 set mY to -1
95 set adjacent count to 0
96 set adjacent color to -1
97 set PPU sprite 0 to 0
98 repeat 224
99 change mY by 1
100 evaluate sprites scanline: (mY)
101 go to x: -128 y: y position - 1
102 pen down
103 set mX to 0
104 repeat until mX > 254
105 step CPU
106 step CPU
107 if PPU show bg = 1 or PPU show sprites = 1 then
108 repeat cycles
109 if mX mod 8 = 0 then
110 read PPU memory @ (PPU base nametable address + mX / 8 + 32 * floor of (mY / 8))
111 set BG: Plane 0 to item (16 * M + PPU Background pattern table + mY mod 8 + 1) of oCHR
112 read PPU memory @ (PPU base nametable address + 960 + floor of (mX / 32) + 8 * floor of (mY / 32))
113 set offset to 2 * <mX mod 32 > 15> + 4 * <mY mod 32 > 15>
114 set BG: Palette to 8 * letter (offset + 1) of item (1 + M) of bitmask + 4 * letter (offset + 2) of item (1 + M) of bitmask + 1
115 end
116 if item (mX + 1) of evaluation line < 1 then
117 set color to item (BG: Palette + letter (2 + mX mod 8) of BG: Plane 0) of Palette
118 else
119 change PPU sprite 0 by item item (mX + 1) of evaluation line of sprite 0
120 set tmp to letter (mX - item item (mX + 1) of evaluation line of secondary Xt) of item item (mX + 1) of evaluation line of secondary bitmaps
121 if tmp = 0 then
122 set color to item (BG: Palette + letter (2 + mX mod 8) of BG: Plane 0) of Palette
123 else
124 set color to item (17 + tmp) of Palette
125 end
126 end
127 change mX by 1
128 if adjacent color = color then
129 change adjacent count by 1
130 else
131 set pen color to (adjacent color)
132 change x by adjacent count
133 set adjacent count to 1
134 set adjacent color to color
135 end
136 end
137 else
138 change mX by 3 * cycles
139 end
140 set cycles to 0
141 end
142 if adjacent count > 0 then
143 set pen color to (adjacent color)
144 change x by adjacent count
145 set adjacent count to 0
146 end
147 pen up
148 end
149 VBlank
150
151 define-atomic initialize PPU
152 pen up
153 clear
154 set pen size to 1
155 delete all of OAM
156 repeat 256
157 add "0" to OAM
158 end
159 delete all of Nametables
160 repeat 960
161 add "0x24" to Nametables
162 end
163 repeat 2048 - 960
164 add "0" to Nametables
165 end
166 delete all of Palette
167 repeat 1 + 4 * 4 + 4 * 4
168 add "0" to Palette
169 end
170 hide
171
172 define-atomic read PPU register (N)
173 if N = 2 then
174 set M to 128 * PPU vblank + 64 * <PPU sprite 0 > 0> + 32 * PPU sprite overflow
175 set PPU address latch to 0
176 ; "set PPU vblank to 0"
177 else
178 if N = 7 then
179 read PPU memory
180 end
181 end
182
183 ; "TODO: use O(logN) lookup instead of O(N)"
184
185 define-atomic write PPU register (N) value: (V)
186 if N = 0 then
187 set mask to item (1 + V) of bitmask
188 set PPU base nametable address to 8192 + ((2 * letter 7 of mask + letter 8 of mask) * 1024)
189 set PPU VRAM increment to letter 6 of mask * 31 + 1
190 set PPU Sprite pattern table to letter 5 of mask * 4096
191 set PPU Background pattern table to letter 4 of mask * 4096
192 set PPU Sprite size to letter 3 of mask
193 set PPU master slave select to letter 2 of mask
194 set PPU generate NMI to letter 1 of mask
195 else
196 if N = 1 then
197 set mask to item (1 + V) of bitmask
198 set PPU grayscale to letter 8 of mask
199 set PPU show left8 bg to letter 7 of mask
200 set PPU show left8 sprites to letter 6 of mask
201 set PPU show bg to letter 5 of mask
202 set PPU show sprites to letter 4 of mask
203 set PPU emphasize blue to letter 3 of mask
204 set PPU emphasize green to letter 2 of mask
205 set PPU emphasize red to letter 1 of mask
206 else
207 if N = 3 then
208 set PPU OAMADDR to V
209 else
210 if N = 4 then
211 replace item PPU OAMADDR mod 256 + 1 of OAM with V
212 change PPU OAMADDR by 1
213 else
214 if N = 5 then
215 if PPU address latch = 0 then
216 set PPU fine x scroll to V
217 else
218 set PPU fine y scroll to V
219 end
220 else
221 if N = 6 then
222 if PPU address latch = 0 then
223 ; "TODO: is this correct?"
224 set PPU VRAM address to V * 256
225 set PPU address latch to 1
226 else
227 change PPU VRAM address by V
228 set PPU address latch to 0
229 end
230 else
231 if N = 7 then
232 write PPU memory (V)
233 change PPU VRAM address by 1
234 end
235 end
236 end
237 end
238 end
239 end
240 end
241
242 define-atomic OAM DMA (pagebase)
243 set temp to 0
244 repeat 256
245 mapper read (256 * pagebase + PPU OAMADDR + temp)
246 change temp by 1
247 replace item temp of OAM with M
248 end
249 change cycles by 513
250
251 define-atomic read PPU memory
252 if PPU VRAM address < 32 * 256 then
253 set M to item (1 + PPU VRAM address) of CHR-ROM
254 else
255 if PPU VRAM address < 48 * 256 then
256 set M to item (PPU VRAM address - 8191) of Nametables
257 else
258 if PPU VRAM address < 63 * 256 then
259 set M to item (PPU VRAM address - 12287) of Nametables
260 else
261 if PPU VRAM address < 64 * 256 then
262 set M to item (PPU VRAM address mod 32 + 1) of Palette
263 else
264 ; "TODO: PPU memory mirroring"
265 end
266 end
267 end
268 end
269
270 define-atomic read PPU memory @ [VRAM address]
271 if VRAM address < 32 * 256 then
272 set M to item (1 + VRAM address) of CHR-ROM
273 else
274 if PPU VRAM address < 48 * 256 then
275 set M to item (VRAM address - 8191) of Nametables
276 else
277 if PPU VRAM address < 63 * 256 then
278 set M to item (VRAM address - 12287) of Nametables
279 else
280 if PPU VRAM address < 64 * 256 then
281 set M to item (VRAM address mod 32 + 1) of Palette
282 else
283 ; "TODO: PPU memory mirroring"
284 end
285 end
286 end
287 end
288
289 define-atomic write PPU memory (V)
290 if PPU VRAM address < 32 * 256 then
291 replace item 1 + PPU VRAM address of CHR-ROM with item (V + 1) of hex
292 ; "TODO: debug completely"
293 if PPU VRAM address mod 16 < 8 then
294 set BG: Plane 0 to item (1 + (join "0x" (item (1 + PPU VRAM address) of CHR-ROM))) of bitmask
295 set BG: Plane 1 to item (1 + (join "0x" (item (1 + PPU VRAM address + 8) of CHR-ROM))) of bitmask
296 set BG: Plane 0 to (join "1" (BG: Plane 0))
297 set BG: Plane 1 to (join "1" (BG: Plane 1))
298 replace item 1 + PPU VRAM address of oCHR with BG: Plane 0 + BG: Plane 1 * 2
299 else
300 set BG: Plane 0 to item (1 + (join "0x" (item (1 + PPU VRAM address - 8) of CHR-ROM))) of bitmask
301 set BG: Plane 1 to item (1 + (join "0x" (item (1 + PPU VRAM address) of CHR-ROM))) of bitmask
302 set BG: Plane 0 to (join "1" (BG: Plane 0))
303 set BG: Plane 1 to (join "1" (BG: Plane 1))
304 replace item 1 + PPU VRAM address - 8 of oCHR with BG: Plane 0 + BG: Plane 1 * 2
305 end
306 else
307 if PPU VRAM address < 48 * 256 then
308 replace item PPU VRAM address - 8191 of Nametables with V
309 else
310 if PPU VRAM address < 63 * 256 then
311 replace item PPU VRAM address - 12287 of Nametables with V
312 else
313 if PPU VRAM address < 64 * 256 then
314 replace item PPU VRAM address mod 32 + 1 of Palette with item (V + 1) of RGB
315 else
316 ; "TODO: PPU memory mirroring"
317 ask V and wait
318 end
319 end
320 end
321 end
This page took 0.082914 seconds and 3 git commands to generate.