2 use ieee.std_logic_1164.all;
\r
6 pi_rst_n : in std_logic;
\r
7 pi_base_clk : in std_logic;
\r
8 pi_cpu_en : in std_logic_vector (7 downto 0);
\r
9 pi_rdy : in std_logic;
\r
10 pi_irq_n : in std_logic;
\r
11 pi_nmi_n : in std_logic;
\r
12 po_oe_n : out std_logic;
\r
13 po_we_n : out std_logic;
\r
14 po_addr : out std_logic_vector ( 15 downto 0);
\r
15 pio_d_io : inout std_logic_vector ( 7 downto 0);
\r
18 po_dbg_cnt : out std_logic_vector (63 downto 0);
\r
19 po_exc_cnt : out std_logic_vector (63 downto 0)
\r
23 architecture rtl of mos6502 is
\r
25 signal reg_oe_n : std_logic;
\r
26 signal reg_we_n : std_logic;
\r
27 signal reg_addr : std_logic_vector ( 15 downto 0);
\r
28 signal reg_d_in : std_logic_vector ( 7 downto 0);
\r
29 signal reg_d_out : std_logic_vector ( 7 downto 0);
\r
31 signal dummy_ad : std_logic_vector (12 downto 0) := "0000000000000";
\r
32 signal dummy_cnt : integer := 0;
\r
36 po_oe_n <= reg_oe_n;
\r
37 po_we_n <= reg_we_n;
\r
38 po_addr <= reg_addr;
\r
39 pio_d_io <= reg_d_out;
\r
40 reg_d_in <= pio_d_io;
\r
43 set_ppu_p : process (pi_base_clk, pi_rst_n)
\r
44 use ieee.std_logic_arith.conv_std_logic_vector;
\r
46 variable init_step_cnt, plt_step_cnt,
\r
47 nt_step_cnt, spr_step_cnt, dma_step_cnt, scl_step_cnt,
\r
48 enable_ppu_step_cnt, nmi_step_cnt : integer;
\r
49 variable init_done : std_logic;
\r
50 variable global_step_cnt : integer;
\r
51 constant cpu_io_multi : integer := 3; --io happens every 4 cpu cycle.
\r
52 variable i, j : integer;
\r
53 variable ch : integer := 16#41# ;
\r
54 variable nmi_oam_x : integer range 0 to 255;
\r
55 variable nmi_scl_y : integer range 0 to 255;
\r
57 variable ref_cnt : integer range 0 to 120;
\r
59 procedure io_out (ad: in integer; dt : in integer) is
\r
63 reg_addr <= conv_std_logic_vector(ad, 16);
\r
64 reg_d_out <= conv_std_logic_vector(dt, 8);
\r
68 use ieee.std_logic_unsigned.all;
\r
70 --fake ram read/write to emulate dummy i/o.
\r
71 -- reg_addr <= "000" & dummy_ad;
\r
72 -- dummy_ad <= dummy_ad + 1;
\r
73 -- if (dummy_cnt = 0) then
\r
74 -- reg_d_out <= (others => 'Z');
\r
79 -- reg_d_out <= dummy_ad(7 downto 0);
\r
84 reg_d_out <= (others => 'Z');
\r
89 procedure io_read (ad: in integer) is
\r
93 reg_addr <= conv_std_logic_vector(ad, 16);
\r
94 reg_d_out <= (others => 'Z');
\r
98 if (pi_rst_n = '0') then
\r
102 reg_addr <= (others => 'Z');
\r
103 reg_d_out <= (others => 'Z');
\r
106 global_step_cnt := 0;
\r
107 init_step_cnt := 0;
\r
113 enable_ppu_step_cnt := 0;
\r
119 elsif (rising_edge(pi_base_clk)) then
\r
120 if (pi_cpu_en(0) = '1') then
\r
121 if (pi_rdy = '1') then
\r
122 if (init_done = '0') then
\r
123 if (global_step_cnt = 0) then
\r
124 --step0.0 = init ppu.
\r
125 if (init_step_cnt = 0 * cpu_io_multi) then
\r
126 --PPUCTRL=01 for test...
\r
127 io_out(16#2000#, 16#01#);
\r
128 elsif (init_step_cnt = 1 * cpu_io_multi) then
\r
130 io_out(16#2001#, 16#02#);
\r
131 elsif (init_step_cnt = 2 * cpu_io_multi) then
\r
133 io_out(16#2000#, 16#00#);
\r
134 elsif (init_step_cnt = 3 * cpu_io_multi) then
\r
136 io_out(16#2001#, 16#00#);
\r
137 elsif (init_step_cnt = 4 * cpu_io_multi) then
\r
139 io_out(16#2006#, 16#02#);
\r
140 elsif (init_step_cnt = 5 * cpu_io_multi) then
\r
141 io_out(16#2006#, 16#40#);
\r
142 elsif (init_step_cnt = 6 * cpu_io_multi) then
\r
144 io_out(16#2005#, 16#21#);
\r
145 elsif (init_step_cnt = 7 * cpu_io_multi) then
\r
146 io_out(16#2005#, 16#5#);
\r
148 elsif (init_step_cnt = 8 * cpu_io_multi) then
\r
150 io_out(16#2006#, 16#1e#);
\r
151 elsif (init_step_cnt = 9 * cpu_io_multi) then
\r
153 io_out(16#2006#, 16#c0#);
\r
154 elsif (init_step_cnt = 10 * cpu_io_multi) then
\r
156 io_out(16#2007#, 10);
\r
157 elsif (init_step_cnt = 11 * cpu_io_multi) then
\r
159 elsif (init_step_cnt = 12 * cpu_io_multi) then
\r
164 if (init_step_cnt > 13 * cpu_io_multi) then
\r
165 global_step_cnt := global_step_cnt + 1;
\r
168 init_step_cnt := init_step_cnt + 1;
\r
169 elsif (global_step_cnt = 1) then
\r
170 --step0.1 = palette set.
\r
173 -- .byte $0f, $00, $10, $20
\r
174 -- .byte $0f, $04, $14, $24
\r
175 -- .byte $0f, $08, $18, $28
\r
176 -- .byte $0f, $0c, $1c, $2c
\r
178 -- .byte $0f, $00, $10, $20
\r
179 -- .byte $0f, $06, $16, $26
\r
180 -- .byte $0f, $08, $18, $28
\r
181 -- .byte $0f, $0a, $1a, $2a
\r
184 if (plt_step_cnt = 0 * cpu_io_multi) then
\r
185 --set vram addr 3f00
\r
186 io_out(16#2006#, 16#3f#);
\r
187 elsif (plt_step_cnt = 1 * cpu_io_multi) then
\r
188 io_out(16#2006#, 16#00#);
\r
190 elsif (plt_step_cnt = 2 * cpu_io_multi) then
\r
191 --set palette bg data
\r
192 io_out(16#2007#, 16#11#);
\r
193 elsif (plt_step_cnt = 3 * cpu_io_multi) then
\r
194 io_out(16#2007#, 16#01#);
\r
195 elsif (plt_step_cnt = 4 * cpu_io_multi) then
\r
196 io_out(16#2007#, 16#03#);
\r
197 elsif (plt_step_cnt = 5 * cpu_io_multi) then
\r
198 io_out(16#2007#, 16#13#);
\r
200 elsif (plt_step_cnt = 6 * cpu_io_multi) then
\r
201 io_out(16#2007#, 16#0f#);
\r
202 elsif (plt_step_cnt = 7 * cpu_io_multi) then
\r
203 io_out(16#2007#, 16#04#);
\r
204 elsif (plt_step_cnt = 8 * cpu_io_multi) then
\r
205 io_out(16#2007#, 16#14#);
\r
206 elsif (plt_step_cnt = 9 * cpu_io_multi) then
\r
207 io_out(16#2007#, 16#24#);
\r
209 elsif (plt_step_cnt = 10 * cpu_io_multi) then
\r
210 io_out(16#2007#, 16#0f#);
\r
211 elsif (plt_step_cnt = 11 * cpu_io_multi) then
\r
212 io_out(16#2007#, 16#08#);
\r
213 elsif (plt_step_cnt = 12 * cpu_io_multi) then
\r
214 io_out(16#2007#, 16#18#);
\r
215 elsif (plt_step_cnt = 13 * cpu_io_multi) then
\r
216 io_out(16#2007#, 16#28#);
\r
218 elsif (plt_step_cnt = 14 * cpu_io_multi) then
\r
219 io_out(16#2007#, 16#05#);
\r
220 elsif (plt_step_cnt = 15 * cpu_io_multi) then
\r
221 io_out(16#2007#, 16#0c#);
\r
222 elsif (plt_step_cnt = 16 * cpu_io_multi) then
\r
223 io_out(16#2007#, 16#1c#);
\r
224 elsif (plt_step_cnt = 17 * cpu_io_multi) then
\r
225 io_out(16#2007#, 16#2c#);
\r
227 elsif (plt_step_cnt = 18 * cpu_io_multi) then
\r
228 --below is sprite pallete
\r
229 io_out(16#2007#, 16#00#);
\r
230 elsif (plt_step_cnt = 19 * cpu_io_multi) then
\r
231 io_out(16#2007#, 16#24#);
\r
232 elsif (plt_step_cnt = 20 * cpu_io_multi) then
\r
233 io_out(16#2007#, 16#1b#);
\r
234 elsif (plt_step_cnt = 21 * cpu_io_multi) then
\r
235 io_out(16#2007#, 16#11#);
\r
237 elsif (plt_step_cnt = 22 * cpu_io_multi) then
\r
238 io_out(16#2007#, 16#00#);
\r
239 elsif (plt_step_cnt = 23 * cpu_io_multi) then
\r
240 io_out(16#2007#, 16#32#);
\r
241 elsif (plt_step_cnt = 24 * cpu_io_multi) then
\r
242 io_out(16#2007#, 16#16#);
\r
243 elsif (plt_step_cnt = 25 * cpu_io_multi) then
\r
244 io_out(16#2007#, 16#20#);
\r
246 elsif (plt_step_cnt = 26 * cpu_io_multi) then
\r
247 io_out(16#2007#, 16#00#);
\r
248 elsif (plt_step_cnt = 27 * cpu_io_multi) then
\r
249 io_out(16#2007#, 16#26#);
\r
250 elsif (plt_step_cnt = 28 * cpu_io_multi) then
\r
251 io_out(16#2007#, 16#01#);
\r
252 elsif (plt_step_cnt = 29 * cpu_io_multi) then
\r
253 io_out(16#2007#, 16#31#);
\r
257 if (plt_step_cnt > 30 * cpu_io_multi) then
\r
258 global_step_cnt := global_step_cnt + 1;
\r
261 plt_step_cnt := plt_step_cnt + 1;
\r
263 elsif (global_step_cnt = 2) then
\r
264 --step1 = name table set.
\r
265 if (nt_step_cnt = 0 * cpu_io_multi) then
\r
266 --set vram addr 2005 (2nd row, 6th col)
\r
267 io_out(16#2006#, 16#20#);
\r
268 elsif (nt_step_cnt = 1 * cpu_io_multi) then
\r
269 io_out(16#2006#, 16#26#);
\r
270 elsif (nt_step_cnt = 2 * cpu_io_multi) then
\r
271 --set name tbl data
\r
272 --0x44, 45, 45 = DEM
\r
273 io_out(16#2007#, 16#44#);
\r
274 elsif (nt_step_cnt = 3 * cpu_io_multi) then
\r
275 io_out(16#2007#, 16#45#);
\r
276 elsif (nt_step_cnt = 4 * cpu_io_multi) then
\r
277 io_out(16#2007#, 16#4d#);
\r
280 elsif (nt_step_cnt = 5 * cpu_io_multi) then
\r
281 io_out(16#2006#, 16#20#);
\r
282 elsif (nt_step_cnt = 6 * cpu_io_multi) then
\r
283 io_out(16#2006#, 16#2a#);
\r
284 elsif (nt_step_cnt = 7 * cpu_io_multi) then
\r
285 io_out(16#2007#, 16#44#);
\r
287 elsif (nt_step_cnt = 8 * cpu_io_multi) then
\r
288 io_out(16#2006#, 16#24#);
\r
289 elsif (nt_step_cnt = 9 * cpu_io_multi) then
\r
290 io_out(16#2006#, 16#43#);
\r
291 elsif (nt_step_cnt = 10 * cpu_io_multi) then
\r
292 io_out(16#2007#, 16#6d#);
\r
293 elsif (nt_step_cnt = 11 * cpu_io_multi) then
\r
294 io_out(16#2007#, 16#6f#);
\r
295 elsif (nt_step_cnt = 12 * cpu_io_multi) then
\r
296 io_out(16#2007#, 16#74#);
\r
297 elsif (nt_step_cnt = 13 * cpu_io_multi) then
\r
298 io_out(16#2007#, 16#6f#);
\r
300 elsif (nt_step_cnt = 14 * cpu_io_multi) then
\r
301 io_out(16#2006#, 16#2e#);
\r
302 elsif (nt_step_cnt = 15 * cpu_io_multi) then
\r
303 io_out(16#2006#, 16#93#);
\r
304 elsif (nt_step_cnt = 16 * cpu_io_multi) then
\r
305 io_out(16#2007#, 16#59#);
\r
307 elsif (nt_step_cnt = 17 * cpu_io_multi) then
\r
308 io_out(16#2007#, 16#00#);
\r
312 if (nt_step_cnt > 4 * cpu_io_multi) then
\r
313 global_step_cnt := global_step_cnt + 1;
\r
317 nt_step_cnt := nt_step_cnt + 1;
\r
319 elsif (global_step_cnt = 3) then
\r
320 --step2 = sprite set.
\r
321 if (spr_step_cnt = 0) then
\r
322 --set sprite addr=00 (first sprite)
\r
323 io_out(16#2003#, 16#00#);
\r
325 elsif (spr_step_cnt = 1 * cpu_io_multi) then
\r
326 --set sprite data: y=02
\r
327 io_out(16#2004#, 16#05#);
\r
328 elsif (spr_step_cnt = 2 * cpu_io_multi) then
\r
329 --tile=0x4d (ascii 'O')
\r
330 io_out(16#2004#, 16#4f#);
\r
331 elsif (spr_step_cnt = 3 * cpu_io_multi) then
\r
332 --set sprite attr=01 (palette 01)
\r
333 io_out(16#2004#, 16#01#);
\r
334 elsif (spr_step_cnt = 4 * cpu_io_multi) then
\r
335 --set sprite data: x=60
\r
336 io_out(16#2004#, 16#3c#);
\r
338 elsif (spr_step_cnt = 5 * cpu_io_multi) then
\r
339 --set sprite data: y=50
\r
340 io_out(16#2004#, 1);
\r
341 elsif (spr_step_cnt = 6 * cpu_io_multi) then
\r
342 --tile=0x4f (ascii 'M')
\r
343 io_out(16#2004#, 16#4d#);
\r
344 elsif (spr_step_cnt = 7 * cpu_io_multi) then
\r
345 --set sprite attr=02
\r
346 io_out(16#2004#, 16#02#);
\r
347 elsif (spr_step_cnt = 8 * cpu_io_multi) then
\r
348 --set sprite data: x=100
\r
349 io_out(16#2004#, 16#64#);
\r
351 -- elsif (spr_step_cnt = 9 * cpu_io_multi) then
\r
352 -- --set sprite data: y=60
\r
353 -- io_out(16#2004#, 60);
\r
354 -- elsif (spr_step_cnt = 10 * cpu_io_multi) then
\r
355 -- --tile=0x4d (ascii 'P')
\r
356 -- io_out(16#2004#, 16#50#);
\r
357 -- elsif (spr_step_cnt = 11 * cpu_io_multi) then
\r
358 -- --set sprite attr=01
\r
359 -- io_out(16#2004#, 16#01#);
\r
360 -- elsif (spr_step_cnt = 12 * cpu_io_multi) then
\r
361 -- --set sprite data: x=33
\r
362 -- io_out(16#2004#, 16#21#);
\r
364 -- elsif (spr_step_cnt = 13 * cpu_io_multi) then
\r
365 -- --set sprite data: y=61
\r
366 -- io_out(16#2004#, 16#3d#);
\r
367 -- elsif (spr_step_cnt = 14 * cpu_io_multi) then
\r
368 -- --tile=0x4d (ascii 'Q')
\r
369 -- io_out(16#2004#, 16#51#);
\r
370 -- elsif (spr_step_cnt = 15 * cpu_io_multi) then
\r
371 -- --set sprite attr=02
\r
372 -- io_out(16#2004#, 16#02#);
\r
373 -- elsif (spr_step_cnt = 16 * cpu_io_multi) then
\r
374 -- --set sprite data: x=45
\r
375 -- io_out(16#2004#, 45);
\r
379 if (spr_step_cnt > 8 * cpu_io_multi) then
\r
380 global_step_cnt := global_step_cnt + 2;
\r
383 spr_step_cnt := spr_step_cnt + 1;
\r
385 elsif (global_step_cnt = 4) then
\r
387 -- for i in 0 to 64 loop
\r
389 -- if (ch = 16#5b#) then
\r
392 -- ch := 16#41# + i;
\r
395 -- --if (i < 64) then
\r
396 -- if (i < 10) then
\r
397 -- --set dma value on the ram.
\r
398 -- if (dma_step_cnt = (0 + j) * cpu_io_multi) then
\r
399 -- io_out(16#0200# + j, i);
\r
400 -- elsif (dma_step_cnt = (1 + j) * cpu_io_multi) then
\r
401 -- io_out(16#0201# + j, ch);
\r
402 -- elsif (dma_step_cnt = (2 + j) * cpu_io_multi) then
\r
403 -- io_out(16#0202# + j, 16#01#);
\r
404 -- elsif (dma_step_cnt = (3 + j) * cpu_io_multi) then
\r
405 -- io_out(16#0203# + j, j);
\r
406 -- elsif (dma_step_cnt = (0 + j) * cpu_io_multi + 1) or
\r
407 -- (dma_step_cnt = (1 + j) * cpu_io_multi + 1) or
\r
408 -- (dma_step_cnt = (2 + j) * cpu_io_multi + 1) or
\r
409 -- (dma_step_cnt = (3 + j) * cpu_io_multi + 1) then
\r
410 -- io_read(16#00#);
\r
413 -- if (dma_step_cnt = (0 + j) * cpu_io_multi) then
\r
415 -- io_out(16#4014#, 16#02#);
\r
416 -- elsif (dma_step_cnt = (0 + j) * cpu_io_multi + 1) then
\r
417 -- io_read(16#00#);
\r
418 -- elsif (dma_step_cnt = (0 + j) * cpu_io_multi + 2) then
\r
420 global_step_cnt := global_step_cnt + 1;
\r
425 -- dma_step_cnt := dma_step_cnt + 1;
\r
427 elsif (global_step_cnt = 5) then
\r
428 --step4 = scroll test and ppu reg read test.
\r
429 if (scl_step_cnt = 123) then
\r
431 io_out(16#2005#, 5);
\r
432 elsif (scl_step_cnt = 1 * cpu_io_multi) then
\r
434 io_out(16#2005#, 9);
\r
436 elsif (scl_step_cnt = 2 * cpu_io_multi) then
\r
440 elsif (scl_step_cnt = 3 * cpu_io_multi) then
\r
442 io_out(16#2006#, 16#20#);
\r
444 elsif (scl_step_cnt = 4 * cpu_io_multi) then
\r
445 io_out(16#2006#, 16#03#);
\r
447 elsif (scl_step_cnt = 5 * cpu_io_multi) then
\r
450 elsif (scl_step_cnt = 6 * cpu_io_multi) then
\r
452 io_out(16#2006#, 16#04#);
\r
454 elsif (scl_step_cnt = 7 * cpu_io_multi) then
\r
455 io_out(16#2006#, 16#d1#);
\r
457 elsif (scl_step_cnt = 8 * cpu_io_multi) then
\r
460 elsif (scl_step_cnt = 9 * cpu_io_multi) then
\r
462 io_out(16#2006#, 16#23#);
\r
464 elsif (scl_step_cnt = 10 * cpu_io_multi) then
\r
465 io_out(16#2006#, 16#c0#);
\r
467 elsif (scl_step_cnt = 11 * cpu_io_multi) then
\r
469 io_out(16#2007#, 16#5a#);
\r
471 elsif (scl_step_cnt = 12 * cpu_io_multi) then
\r
472 io_out(16#2006#, 16#23#);
\r
474 elsif (scl_step_cnt = 13 * cpu_io_multi) then
\r
475 io_out(16#2006#, 16#c0#);
\r
477 elsif (scl_step_cnt = 14 * cpu_io_multi) then
\r
480 elsif (scl_step_cnt = 15 * cpu_io_multi) then
\r
481 --read palette tbl.
\r
482 io_out(16#2006#, 16#3f#);
\r
484 elsif (scl_step_cnt = 16 * cpu_io_multi) then
\r
485 io_out(16#2006#, 16#11#);
\r
487 elsif (scl_step_cnt = 17 * cpu_io_multi) then
\r
492 if (scl_step_cnt > 17 * cpu_io_multi) then
\r
493 global_step_cnt := global_step_cnt + 1;
\r
496 scl_step_cnt := scl_step_cnt + 1;
\r
498 elsif (global_step_cnt = 6) then
\r
499 --final step = enable ppu.
\r
500 if (enable_ppu_step_cnt = 0 * cpu_io_multi) then
\r
502 --PPUMASK=1e (show bg and sprite)
\r
503 --PPUMASK=0e (show bg only)
\r
504 io_out(16#2001#, 16#1e#);
\r
505 elsif (enable_ppu_step_cnt = 1 * cpu_io_multi) then
\r
508 io_out(16#2000#, 16#80#);
\r
511 if (enable_ppu_step_cnt > 1 * cpu_io_multi) then
\r
512 --skip nmi test at this momemnt..
\r
513 global_step_cnt := global_step_cnt + 1;
\r
516 enable_ppu_step_cnt := enable_ppu_step_cnt + 1;
\r
518 elsif (global_step_cnt = 7) then
\r
520 if (pi_nmi_n = '0') then
\r
522 if (nmi_step_cnt = 0 * cpu_io_multi) then
\r
523 --set sprite addr=00 (first sprite)
\r
524 io_out(16#2003#, 16#03#);
\r
525 elsif (nmi_step_cnt = 1 * cpu_io_multi) then
\r
526 --set sprite data: x=100
\r
527 io_out(16#2004#, nmi_oam_x);
\r
528 elsif (nmi_step_cnt = 2 * cpu_io_multi) then
\r
530 io_out(16#2005#, nmi_scl_y);
\r
531 elsif (nmi_step_cnt = 3 * cpu_io_multi) then
\r
533 io_out(16#2005#, nmi_scl_y);
\r
534 elsif (nmi_step_cnt = 4 * cpu_io_multi) then
\r
535 --set sprite addr=00 (first sprite)
\r
536 io_out(16#2003#, 16#04#);
\r
537 elsif (nmi_step_cnt = 5 * cpu_io_multi) then
\r
538 --set sprite data: x=100
\r
539 io_out(16#2004#, nmi_oam_x);
\r
541 if (ref_cnt = 0) then
\r
542 nmi_oam_x := nmi_oam_x + 1;
\r
544 if (nmi_step_cnt mod 10 = 0) then
\r
545 nmi_scl_y := nmi_scl_y + 1;
\r
548 if (nmi_step_cnt > 5 * cpu_io_multi) then
\r
549 ref_cnt := ref_cnt + 1;
\r
550 global_step_cnt := global_step_cnt + 1;
\r
553 nmi_step_cnt := nmi_step_cnt + 1;
\r
555 elsif (global_step_cnt = 8) then
\r
556 ----back to nmi tests.....
\r
557 if (pi_nmi_n = '1') then
\r
559 global_step_cnt := global_step_cnt - 1;
\r
567 end if;--if (init_done = '0') then
\r
570 end if;--if (rdy = '1') then
\r
571 end if;--if (pi_cpu_en(0) = '1') then
\r
572 end if; --if (rst_n = '0') then
\r
581 -----------dummy prg rom
\r
583 use ieee.std_logic_1164.all;
\r
586 pi_base_clk : in std_logic;
\r
587 pi_ce_n : in std_logic;
\r
588 pi_oe_n : in std_logic;
\r
589 pi_addr : in std_logic_vector (14 downto 0);
\r
590 po_data : out std_logic_vector (7 downto 0)
\r
593 architecture rtl of prg_rom is
\r
595 p_read : process (pi_base_clk)
\r
597 if (rising_edge(pi_base_clk)) then
\r
598 if (pi_ce_n = '0') then
\r
600 po_data <= "00110011";
\r
602 po_data <= (others => 'Z');
\r