e603835f56ce66ac8d3fe5d0f652673a949ea444
[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 item evaluation n of OAM > N 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 change evaluation slot by 4
25 replace item temp of evaluation line with evaluation n
26 replace item temp + 1 of evaluation line with evaluation n
27 replace item temp + 2 of evaluation line with evaluation n
28 replace item temp + 3 of evaluation line with evaluation n
29 replace item temp + 4 of evaluation line with evaluation n
30 replace item temp + 5 of evaluation line with evaluation n
31 replace item temp + 6 of evaluation line with evaluation n
32 replace item temp + 7 of evaluation line with evaluation n
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 emulate frame
40 go to x: -128 y: 128
41 set mY to -1
42 show variable mX
43 show variable mY
44 repeat 224
45 change mY by 1
46 evaluate sprites scanline: (mY)
47 go to x: -128 y: y position - 1
48 pen down
49 set mX to 0
50 repeat until mX > 254
51 step CPU
52 repeat (3*cycles)
53 set pen color to (0)
54 change x by 1
55 change mX by 1
56 end
57 set cycles to 0
58 end
59 pen up
60 end
61 set PPU vblank? to 1
62 if PPU generate NMI = 1 then
63 interrupt: vector "0xFFFA"
64 end
65 repeat until cycles > 2380
66 step CPU
67 end
68 set cycles to 0
69
70 define initialize PPU
71 pen up
72 clear
73 set pen size to 1
74 delete all of OAM
75 repeat 256
76 add "0" to OAM
77 end
78 hide
79
80 define read PPU register (N)
81 if N = 2 then
82 set M to 128 * PPU vblank? + 64 * PPU sprite 0? + 32 * PPU sprite overflow?
83 set PPU address latch to 0
84 set PPU vblank? to 0
85 else
86 if N = 7 then
87 read PPU memory
88 end
89 end
90
91 define get bit mask (N)
92 set temp to N
93 set mask to ""
94 repeat 8
95 set mask to (join (<temp mod 2 = 1> * 1) (mask))
96 set temp to (temp - temp mod 2) * 0.5
97 end
98
99 ; "TODO: use O(logN) lookup instead of O(N)"
100
101 define write PPU register (N) value: (V)
102 if N = 0 then
103 get bit mask (V)
104 set PPU base nametable address to 2 * letter 7 of mask + letter 8 of mask
105 set PPU VRAM increment to letter 6 of mask * 31 + 1
106 set PPU Sprite pattern table to letter 5 of mask * 4096
107 set PPU Background pattern table to letter 4 of mask * 4096
108 set PPU Sprite size to letter 3 of mask
109 set PPU master slave select to letter 2 of mask
110 set PPU generate NMI to letter 1 of mask
111 else
112 if N = 1 then
113 get bit mask (V)
114 set PPU grayscale to letter 8 of mask
115 set PPU show left8 bg to letter 7 of mask
116 set PPU show left8 sprites to letter 6 of mask
117 set PPU show bg to letter 5 of mask
118 set PPU show sprites to letter 4 of mask
119 set PPU emphasize blue to letter 3 of mask
120 set PPU emphasize green to letter 2 of mask
121 set PPU emphasize red to letter 1 of mask
122 else
123 if N = 3 then
124 set PPU OAMADDR to V
125 else
126 if N = 4 then
127 replace item PPU OAMADDR mod 256 + 1 of OAM with V
128 change PPU OAMADDR by 1
129 else
130 if N = 5 then
131 if PPU address latch = 0 then
132 set PPU fine x scroll to V
133 else
134 set PPU fine y scroll to V
135 end
136 else
137 if N = 6 then
138 if PPU address latch = 0 then
139 set PPU high address to V
140 else
141 set PPU low address to V
142 end
143 else
144 if N = 7 then
145 write PPU memory (V)
146 end
147 end
148 end
149 end
150 end
151 end
152 end
153
154 define OAM DMA (pagebase)
155 set temp to 0
156 repeat 256
157 mapper read ( (256*pagebase) + PPU OAMADDR + temp)
158 change temp by 1
159 replace item temp of OAM with M
160 end
161
162 define read PPU memory
163 if PPU high address < 32 then
164 set M to item (1 + PPU high address * 256 + PPU low address) of Pattern tables
165 else
166 if PPU high address < 48 then
167 set M to item ((PPU high address * 256) + PPU low address - 8191) of Nametables
168 else
169 if PPU high address < 63 then
170 set M to item ((PPU high address * 256) + PPU low address - 12287) of Nametables
171 else
172 if PPU high address < 64 then
173 set M to item (PPU low address mod 32) + 1 of Palette
174 else
175 ; "TODO: PPU memory mirroring"
176 end
177 end
178 end
179 end
180
181 define write PPU memory (V)
182 if PPU high address < 32 then
183 replace item (1 + PPU high address * 256 + PPU low address) of Pattern tables with V
184 else
185 if PPU high address < 48 then
186 replace item ((PPU high address * 256) + PPU low address - 8191) of Nametables with V
187 else
188 if PPU high address < 63 then
189 replace item ((PPU high address * 256) + PPU low address - 12287) of Nametables with V
190 else
191 if PPU high address < 64 then
192 replace item (PPU low address mod 32) + 1 of Palette with V
193 else
194 ; "TODO: PPU memory mirroring"
195 end
196 end
197 end
198 end
This page took 0.07555 seconds and 3 git commands to generate.