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