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