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