48f5d52a7007bf6114b6e1f8edd431b3d01149e5
[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 repeat 32
5 add "255" to secondary OAM
6 add "-1" to evaluation line
7 add "-1" to evaluation line
8 add "-1" to evaluation line
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 end
15 set evaluation n to 1
16 set evaluation slot to 1
17 repeat 64
18 if <evaluation slot < 32> and <not N < item evaluation n of OAM> and <item evaluation n of OAM + 8 > N> then
19 replace item evaluation slot of secondary OAM with item evaluation n of OAM
20 replace item evaluation slot + 1 of secondary OAM with item (evaluation n + 1) of OAM
21 replace item evaluation slot + 2 of secondary OAM with item (evaluation n + 2) of OAM
22 set temp to item (evaluation n + 3) of OAM
23 replace item evaluation slot + 3 of secondary OAM with temp
24 replace item temp of evaluation line with evaluation slot
25 replace item temp + 1 of evaluation line with evaluation slot
26 replace item temp + 2 of evaluation line with evaluation slot
27 replace item temp + 3 of evaluation line with evaluation slot
28 replace item temp + 4 of evaluation line with evaluation slot
29 replace item temp + 5 of evaluation line with evaluation slot
30 replace item temp + 6 of evaluation line with evaluation slot
31 replace item temp + 7 of evaluation line with evaluation slot
32 change evaluation slot by 4
33 end
34 change evaluation n by 4
35 end
36 ; "TODO: evaluate sprites in secondary OAM"
37 ; "TODO: buggy sprite overflow flag"
38
39 define-atomic get pattern tile: (tile) scanline: (scanline) table: (table)
40 get bit mask (join "0x" ((item (16 * tile + scanline + table+1) of CHR-ROM)))
41 set lower mask to mask
42 get bit mask (join "0x" ((item (16 * tile + scanline + table+9) of CHR-ROM)))
43
44 define-atomic compute background pixel
45 ; "Fetch it from CHR and decode, not unlike sprites"
46 ; "Only a bit different indexing"
47 get pattern tile: BG: Nametable scanline: (mY mod 8) table: PPU Background pattern table
48 set offset to mX mod 8
49 set tmp to (2*letter offset + 1 of lower mask) + letter offset+1 of mask
50 if tmp > 1 then
51 if tmp = 2 then
52 set tmp to "0xFF0000"
53 else
54 set tmp to "0x00FF00"
55 end
56 else
57 if tmp = 1 then
58 set tmp to "0x0000FF"
59 else
60 set tmp to "0x000000"
61 end
62 end
63
64 define-atomic compute pixel
65 ; "Perform BACKGROUND tasks"
66 if mX mod 8 = 0 then
67 set PPU VRAM address to 8192 + (mX/8) + (32*(floor of (mY / 8)))
68 read PPU memory
69 set BG: Nametable to M
70 end
71 if item mX of evaluation line = -1 then
72 compute background pixel
73 else
74 ; "A sprite! That I can do! Fetch it from CHR and decode"
75 get pattern tile: item ((item mX of evaluation line))+1 of secondary OAM scanline: (mY - (item (item mX of evaluation line) of secondary OAM)) table: PPU Sprite pattern table
76 set offset to mX - item (item mX of evaluation line + 3) of secondary OAM
77 set tmp to (2 * letter offset+1 of lower mask) + letter offset+1 of mask
78 if tmp > 1 then
79 if tmp = 2 then
80 set tmp to "0xFF0000"
81 else
82 set tmp to "0xFFFFFF"
83 end
84 else
85 if tmp = 0 then
86 set tmp to "0x000000"
87 else
88 set tmp to "0x0000FF"
89 end
90 end
91 end
92
93 define-atomic emulate frame
94 go to x: -128 y: 128
95 set mY to -1
96 show list Nametables
97 repeat 224
98 change mY by 1
99 evaluate sprites scanline: (mY)
100 go to x: -128 y: y position - 1
101 pen down
102 set mX to 0
103 repeat until mX > 254
104 step CPU
105 if PPU show bg = 1 or PPU show sprites = 1 then
106 repeat cycles
107 compute pixel
108 set pen color to (tmp*1)
109 change mX by 1
110 change x by 1
111 compute pixel
112 set pen color to (tmp*1)
113 change x by 1
114 change mX by 1
115 compute pixel
116 set pen color to (tmp*1)
117 change x by 1
118 change mX by 1
119 end
120 else
121 change mX by 3 * cycles
122 end
123 set cycles to 0
124 end
125 pen up
126 end
127 set PPU vblank? to 1
128 if PPU generate NMI = 1 then
129 interrupt: vector "0xFFFA"
130 end
131 repeat until cycles > 2380
132 step CPU
133 end
134 set cycles to 0
135
136 define-atomic initialize PPU
137 pen up
138 clear
139 set pen size to 1
140 delete all of OAM
141 repeat 256
142 add "0" to OAM
143 end
144 delete all of Nametables
145 repeat 2048
146 add "0" to Nametables
147 end
148 hide
149
150 define-atomic read PPU register (N)
151 if N = 2 then
152 set M to 128 * PPU vblank? + 64 * PPU sprite 0? + 32 * PPU sprite overflow?
153 set PPU address latch to 0
154 set PPU vblank? to 0
155 else
156 if N = 7 then
157 read PPU memory
158 end
159 end
160
161 define-atomic get bit mask (N)
162 set temp to N
163 set mask to ""
164 repeat 8
165 set mask to (join (<temp mod 2 = 1> * 1) (mask))
166 set temp to (temp - temp mod 2) * 0.5
167 end
168
169 ; "TODO: use O(logN) lookup instead of O(N)"
170
171 define-atomic write PPU register (N) value: (V)
172 if N = 0 then
173 get bit mask (V)
174 set PPU base nametable address to 2 * letter 7 of mask + letter 8 of mask
175 set PPU VRAM increment to letter 6 of mask * 31 + 1
176 set PPU Sprite pattern table to letter 5 of mask * 4096
177 set PPU Background pattern table to letter 4 of mask * 4096
178 set PPU Sprite size to letter 3 of mask
179 set PPU master slave select to letter 2 of mask
180 set PPU generate NMI to letter 1 of mask
181 else
182 if N = 1 then
183 get bit mask (V)
184 set PPU grayscale to letter 8 of mask
185 set PPU show left8 bg to letter 7 of mask
186 set PPU show left8 sprites to letter 6 of mask
187 set PPU show bg to letter 5 of mask
188 set PPU show sprites to letter 4 of mask
189 set PPU emphasize blue to letter 3 of mask
190 set PPU emphasize green to letter 2 of mask
191 set PPU emphasize red to letter 1 of mask
192 else
193 if N = 3 then
194 set PPU OAMADDR to V
195 else
196 if N = 4 then
197 replace item PPU OAMADDR mod 256 + 1 of OAM with V
198 change PPU OAMADDR by 1
199 else
200 if N = 5 then
201 if PPU address latch = 0 then
202 set PPU fine x scroll to V
203 else
204 set PPU fine y scroll to V
205 end
206 else
207 if N = 6 then
208 if PPU address latch = 0 then
209 ; "TODO: is this correct?"
210 set PPU VRAM address to (V*256)
211 set PPU address latch to 1
212 else
213 change PPU VRAM address by V
214 set PPU address latch to 0
215 end
216 else
217 if N = 7 then
218 write PPU memory (V)
219 change PPU VRAM address by 1
220 end
221 end
222 end
223 end
224 end
225 end
226 end
227
228 define-atomic OAM DMA (pagebase)
229 set temp to 0
230 repeat 256
231 mapper read (256 * pagebase + PPU OAMADDR + temp)
232 change temp by 1
233 replace item temp of OAM with M
234 end
235
236 define-atomic read PPU memory
237 if PPU VRAM address < 32*256 then
238 set M to item (1 + PPU VRAM address) of Pattern tables
239 else
240 if PPU VRAM address < 48*256 then
241 set M to item (PPU VRAM address - 8191) of Nametables
242 else
243 if PPU VRAM address < 63*256 then
244 set M to item (PPU VRAM address - 12287) of Nametables
245 else
246 if PPU VRAM address < 64*256 then
247 set M to item (PPU VRAM address mod 32 + 1) of Palette
248 else
249 ; "TODO: PPU memory mirroring"
250 end
251 end
252 end
253 end
254
255 define-atomic write PPU memory (V)
256 if PPU VRAM address < 32*256 then
257 replace item 1 + PPU VRAM address of Pattern tables with V
258 else
259 if PPU VRAM address < 48*256 then
260 replace item PPU VRAM address - 8191 of Nametables with V
261 else
262 if PPU VRAM address < 63*256 then
263 replace item PPU VRAM address - 12287 of Nametables with V
264 else
265 if PPU VRAM address < 64*256 then
266 replace item PPU VRAM address mod 32 + 1 of Palette with V
267 else
268 ; "TODO: PPU memory mirroring"
269 end
270 end
271 end
272 end
This page took 0.084382 seconds and 3 git commands to generate.