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