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