Step cycles in VBlank
[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 X by 3
41 set pen color to ((<not item X of evaluation line = -1> * 16000000 + <not item (X + 1) of evaluation line = -1> * 16000000 + <not item (X + 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 Y to -1
47 pen down
48 repeat 224
49 change Y by 1
50 evaluate sprites scanline: (Y)
51 set x to -128
52 set X to 1
53 repeat until X > 255
54 step CPU
55 repeat cycles
56 emulate 3 PPU cycles
57 end
58 set cycles to 0
59 end
60 set PPU vblank? to 1
61 if PPU generate NMI = 1 then
62 interrupt: vector "0xFFFA"
63 repeat until cycles > 2380
64 step CPU
65 end
66 set cycles to 0
67 end
68 change y by -1
69 end
70 pen up
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 set temp to 1
158 repeat 256
159 mapper read (pagebase + temp)
160 replace item temp of OAM with M
161 change temp by 1
162 end
163
164 define read PPU memory
165 if PPU high address < 32 then
166 set M to item (1 + PPU high address * 256 + PPU low address) of Pattern tables
167 else
168 if PPU high address < 48 then
169 set M to item ((PPU high address * 256) + PPU low address - 8191) of Nametables
170 else
171 if PPU high address < 63 then
172 set M to item ((PPU high address * 256) + PPU low address - 12287) of Nametables
173 else
174 if PPU high address < 64 then
175 set M to item (PPU low address mod 32) + 1 of Palette
176 else
177 ; "TODO: PPU memory mirroring"
178 end
179 end
180 end
181 end
182
183 define write PPU memory (V)
184 if PPU high address < 32 then
185 replace item (1 + PPU high address * 256 + PPU low address) of Pattern tables with V
186 else
187 if PPU high address < 48 then
188 replace item ((PPU high address * 256) + PPU low address - 8191) of Nametables with V
189 else
190 if PPU high address < 63 then
191 replace item ((PPU high address * 256) + PPU low address - 12287) of Nametables with V
192 else
193 if PPU high address < 64 then
194 replace item (PPU low address mod 32) + 1 of Palette with V
195 else
196 ; "TODO: PPU memory mirroring"
197 end
198 end
199 end
200 end
This page took 0.079773 seconds and 5 git commands to generate.