]> git.zerfleddert.de Git - fpga-games/blob - galaxian/src/mc_top.v
fix object position
[fpga-games] / galaxian / src / mc_top.v
1 //===============================================================================
2 // FPGA GALAXIAN TOP
3 //
4 // Version : 2.50
5 //
6 // Copyright(c) 2004 Katsumi Degawa , All rights reserved
7 //
8 // Important !
9 //
10 // This program is freeware for non-commercial use.
11 // An author does no guarantee about this program.
12 // You can use this under your own risk.
13 //
14 // 2004- 4-30 galaxian modify by K.DEGAWA
15 // 2004- 5- 6 first release.
16 // 2004- 8-23 Improvement with T80-IP.
17 // 2004- 9-18 The description of ALTERA(CYCLONE) and XILINX(SPARTAN2E) was made one.
18 // 2004- 9-22 The problem which missile didn't sometimes come out from was improved.
19 //================================================================================
20
21 `include "src/mc_conf.v"
22
23 module mc_top(
24
25 // FPGA_USE
26 I_CLK_125M,
27
28 `ifdef PSPAD_USE
29 // PS_PAD interface
30 psCLK,
31 psSEL,
32 psTXD,
33 psRXD,
34 `endif
35
36 // INPORT SW IF
37 I_PSW,
38
39 // SOUND OUT
40 O_SOUND_OUT_L,
41 O_SOUND_OUT_R,
42
43 // VGA (VIDEO) IF
44 O_VGA_R,
45 O_VGA_G,
46 O_VGA_B,
47 O_VGA_H_SYNCn,
48 O_VGA_V_SYNCn
49
50 );
51
52 // FPGA_USE
53 input I_CLK_125M;
54
55 // CPU ADDRESS BUS
56 wire [15:0]W_A;
57 // CPU IF
58 wire W_CPU_RDn;
59 wire W_CPU_WRn;
60 wire W_CPU_MREQn;
61 wire W_CPU_RFSHn;
62 wire W_CPU_BUSAKn;
63 wire W_CPU_IORQn;
64 wire W_CPU_M1n;
65 wire W_CPU_CLK;
66 wire W_CPU_HRDWR_RESETn;
67 wire W_CPU_WAITn;
68 wire W_CPU_NMIn;
69
70 `ifdef PSPAD_USE
71 // PS_PAD interface
72 input psRXD;
73 output psTXD,psCLK,psSEL;
74 `endif
75
76 // INPORT SW IF
77 input [8:0]I_PSW;
78
79 // SOUND OUT
80 output O_SOUND_OUT_L;
81 output O_SOUND_OUT_R;
82
83 // VGA (VIDEO) IF
84 output [3:0]O_VGA_R;
85 output [3:0]O_VGA_G;
86 output [3:0]O_VGA_B;
87 output O_VGA_H_SYNCn;
88 output O_VGA_V_SYNCn;
89
90 wire W_RESETn = |(~I_PSW[8:5]);
91 //------ CLOCK GEN ---------------------------
92 wire W_CLK_18M;
93 wire W_CLK_36M;
94 wire W_CLK_12M,WB_CLK_12M;
95 wire W_CLK_6M,WB_CLK_6M;
96 wire W_STARS_CLK;
97
98 mc_dcm clockgen(
99 .CLKIN_IN(I_CLK_125M),
100 .RST_IN(! W_RESETn),
101 .CLKFX_OUT(W_CLK_36M)
102 );
103
104 //------ H&V COUNTER -------------------------
105 wire [8:0]W_H_CNT;
106 wire [7:0]W_V_CNT;
107 wire W_H_BL;
108 wire W_V_BLn;
109 wire W_C_BLn;
110 wire W_H_SYNC;
111 wire W_V_SYNC;
112
113 //------ CPU RAM ----------------------------
114 wire [7:0]W_CPU_RAM_DO;
115
116 //------ ADDRESS DECDER ----------------------
117 wire W_CPU_ROM_CSn;
118 wire W_CPU_RAM_RDn;
119 wire W_CPU_RAM_WRn;
120 wire W_CPU_RAM_CSn;
121 wire W_OBJ_RAM_RDn;
122 wire W_OBJ_RAM_WRn;
123 wire W_OBJ_RAM_RQn;
124 wire W_VID_RAM_RDn;
125 wire W_VID_RAM_WRn;
126 wire W_SW0_OEn;
127 wire W_SW1_OEn;
128 wire W_DIP_OEn;
129 wire W_WDR_OEn;
130 wire W_LAMP_WEn;
131 wire W_SOUND_WEn;
132 wire W_PITCHn;
133 wire W_H_FLIP;
134 wire W_V_FLIP;
135 wire W_BD_G;
136 wire W_STARS_ON;
137
138 wire W_VID_RDn = W_OBJ_RAM_RDn & W_VID_RAM_RDn ;
139 wire W_SW_OEn = W_SW0_OEn & W_SW1_OEn & W_DIP_OEn ;
140 //------- INPORT -----------------------------
141 wire [7:0]W_SW_DO;
142 //------- VIDEO -----------------------------
143 wire [7:0]W_VID_DO;
144 //--------------------------------------------
145
146 mc_clock MC_CLK(
147
148 .I_CLK_36M(W_CLK_36M),
149 .O_CLK_18M(W_CLK_18M),
150 .O_CLK_12M(WB_CLK_12M),
151 .O_CLK_06M(WB_CLK_6M)
152
153 );
154
155 `ifdef DEVICE_CYCLONE
156 assign W_CLK_12M = WB_CLK_12M;
157 assign W_CLK_6M = WB_CLK_6M;
158 `endif
159 `ifdef DEVICE_SPARTAN2E
160 BUFG BUFG_12MHz( .I(WB_CLK_12M),.O(W_CLK_12M) );
161 BUFG BUFG_6MHz ( .I(WB_CLK_6M ),.O(W_CLK_6M ) );
162 `endif
163 //--- DATA I/F -------------------------------------
164 reg [7:0]W_CPU_ROM_DO;
165 wire [7:0]W_CPU_ROM_DOB = W_CPU_ROM_CSn ? 8'h00: W_CPU_ROM_DO ;
166
167 wire [7:0]W_BDO = W_SW_DO | W_VID_DO | W_CPU_RAM_DO | W_CPU_ROM_DOB ;
168 wire [7:0]W_BDI;
169
170 //--- CPU I/F -------------------------------------
171 reg [3:0]rst_count;
172 always@(posedge W_H_CNT[0] or negedge W_RESETn)
173 begin
174 if(! W_RESETn) rst_count <= 0;
175 else begin
176 if( rst_count == 15)
177 rst_count <= rst_count;
178 else
179 rst_count <= rst_count+1;
180 end
181 end
182
183 assign W_CPU_RESETn = W_RESETn;
184 assign W_CPU_CLK = W_H_CNT[0];
185
186 Z80IP CPU(
187
188 .CLK(W_CPU_CLK),
189 .RESET_N(W_CPU_RESETn),
190 .INT_N(1'b1),
191 .NMI_N(W_CPU_NMIn),
192 .ADRS(W_A),
193 .DOUT(W_BDI),
194 .DINP(W_BDO),
195 .M1_N(),
196 .MREQ_N(W_CPU_MREQn),
197 .IORQ_N(),
198 .RD_N(W_CPU_RDn ),
199 .WR_N(W_CPU_WRn ),
200 .WAIT_N(W_CPU_WAITn),
201 .BUSWO(),
202 .RFSH_N(W_CPU_RFSHn),
203 .HALT_N()
204
205 );
206
207 wire W_CPU_RAM_CLK = W_CLK_12M & ~W_CPU_RAM_CSn;
208
209 mc_cpu_ram MC_CPU_RAM(
210
211 .I_CLK(W_CPU_RAM_CLK),
212 .I_ADDR(W_A[9:0]),
213 .I_D(W_BDI),
214 .I_WE(~W_CPU_WRn),
215 .I_OE(~W_CPU_RAM_RDn ),
216 .O_D(W_CPU_RAM_DO)
217
218 );
219
220
221 mc_adec MC_ADEC(
222
223 .I_CLK_12M(W_CLK_12M),
224 .I_CLK_6M(W_CLK_6M),
225 .I_CPU_CLK(W_H_CNT[0]),
226 .I_RSTn(W_RESETn),
227
228 .I_CPU_A(W_A),
229 .I_CPU_D(W_BDI[0]),
230 .I_MREQn(W_CPU_MREQn),
231 .I_RFSHn(W_CPU_RFSHn),
232 .I_RDn(W_CPU_RDn),
233 .I_WRn(W_CPU_WRn),
234 .I_H_BL(W_H_BL),
235 .I_V_BLn(W_V_BLn),
236
237 .O_WAITn(W_CPU_WAITn),
238 .O_NMIn(W_CPU_NMIn),
239 .O_CPU_ROM_CSn(W_CPU_ROM_CSn),
240 .O_CPU_RAM_RDn(W_CPU_RAM_RDn),
241 .O_CPU_RAM_WRn(W_CPU_RAM_WRn),
242 .O_CPU_RAM_CSn(W_CPU_RAM_CSn),
243 .O_OBJ_RAM_RDn(W_OBJ_RAM_RDn),
244 .O_OBJ_RAM_WRn(W_OBJ_RAM_WRn),
245 .O_OBJ_RAM_RQn(W_OBJ_RAM_RQn),
246 .O_VID_RAM_RDn(W_VID_RAM_RDn),
247 .O_VID_RAM_WRn(W_VID_RAM_WRn),
248 .O_SW0_OEn(W_SW0_OEn),
249 .O_SW1_OEn(W_SW1_OEn),
250 .O_DIP_OEn(W_DIP_OEn),
251 .O_WDR_OEn(W_WDR_OEn),
252 .O_LAMP_WEn(W_LAMP_WEn),
253 .O_SOUND_WEn(W_SOUND_WEn),
254 .O_PITCHn(W_PITCHn),
255 .O_H_FLIP(W_H_FLIP),
256 .O_V_FLIP(W_V_FLIP),
257 .O_BD_G(W_BD_G),
258 .O_STARS_ON(W_STARS_ON)
259
260 );
261
262 //-------- SOUND I/F -----------------------------
263 //--- Parts 9L ---------
264 reg [7:0]W_9L_Q;
265 always@(posedge W_CLK_12M or negedge W_RESETn)
266 begin
267 if(W_RESETn == 1'b0)begin
268 W_9L_Q <= 0;
269 end
270 else begin
271 if(W_SOUND_WEn == 1'b0)begin
272 case(W_A[2:0])
273 3'h0 : W_9L_Q[0] <= W_BDI[0];
274 3'h1 : W_9L_Q[1] <= W_BDI[0];
275 3'h2 : W_9L_Q[2] <= W_BDI[0];
276 3'h3 : W_9L_Q[3] <= W_BDI[0];
277 3'h4 : W_9L_Q[4] <= W_BDI[0];
278 3'h5 : W_9L_Q[5] <= W_BDI[0];
279 3'h6 : W_9L_Q[6] <= W_BDI[0];
280 3'h7 : W_9L_Q[7] <= W_BDI[0];
281 endcase
282 end
283 end
284 end
285 wire W_VOL1 = W_9L_Q[6];
286 wire W_VOL2 = W_9L_Q[7];
287 wire W_FIRE = W_9L_Q[5];
288 wire W_HIT = W_9L_Q[3];
289 wire W_FS3 = W_9L_Q[2];
290 wire W_FS2 = W_9L_Q[1];
291 wire W_FS1 = W_9L_Q[0];
292 //---------------------------------------------------
293 //---- CPU DATA WATCH -------------------------------
294 wire ZMWR = W_CPU_MREQn | W_CPU_WRn ;
295
296 reg [1:0]on_game;
297 always @(posedge W_CPU_CLK)
298 begin
299 if(~ZMWR)begin
300 if(W_A == 16'h4007)begin
301 if(W_BDI == 8'h00)
302 on_game[0] <= 1;
303 else
304 on_game[0] <= 0;
305 end
306 if(W_A == 16'h4005)begin
307 if(W_BDI == 8'h03 || W_BDI == 8'h04 )
308 on_game[1] <= 1;
309 else
310 on_game[1] <= 0;
311 end
312 end
313 end
314
315 `ifdef PSPAD_USE
316 reg died;
317 always @(posedge W_CPU_CLK)
318 begin
319 if(~ZMWR)begin
320 if(W_A == 16'h4206)begin
321 if(W_BDI == 8'h00)
322 died <= 0;
323 else
324 died <= 1;
325 end
326 end
327 end
328 //---- PS_PAD Interface -----------------------------
329 wire [8:0]ps_PSW;
330 wire VIB_SW = died & (&on_game[1:0]);
331
332 fpga_arcade_if pspad(
333
334 .CLK_18M432(W_CLK_18M),
335 .I_RSTn(W_RESETn),
336 .psCLK(psCLK),
337 .psSEL(psSEL),
338 .psTXD(psTXD),
339 .psRXD(psRXD),
340 .ps_PSW(ps_PSW),
341 .I_VIB_SW(VIB_SW)
342
343 );
344 `endif
345 //---- SW Interface ---------------------------------
346 `ifdef PSPAD_USE
347 wire L1 = I_PSW[2] & ps_PSW[2];
348 wire R1 = I_PSW[3] & ps_PSW[3];
349 wire U1 = I_PSW[0];
350 wire D1 = I_PSW[1];
351 wire J1 = I_PSW[4] & ps_PSW[8];
352
353 wire S1 = (U1|J1) & ps_PSW[6];
354 wire S2 = (D1|J1) & ps_PSW[7];
355
356 wire C1 = (L1|R1|U1|~D1) & ps_PSW[4];
357 `else
358 wire L1 = ! I_PSW[2];
359 wire R1 = ! I_PSW[3];
360 wire U1 = ! I_PSW[0];
361 wire D1 = ! I_PSW[1];
362 wire J1 = ! I_PSW[4];
363
364 wire S1 = ! I_PSW[5];
365 wire S2 = ! I_PSW[7];
366
367 wire C1 = ! I_PSW[6];
368 `endif
369 wire C2 = ! I_PSW[8];
370
371 wire L2 = L1;
372 wire R2 = R1;
373 wire U2 = U1;
374 wire D2 = D1;
375 wire J2 = J1;
376
377 mc_inport MC_INPORT(
378
379 .I_COIN1(~C1), // ACTIVE HI
380 .I_COIN2(~C2), // ACTIVE HI
381 .I_1P_LE(~L1), // ACTIVE HI
382 .I_1P_RI(~R1), // ACTIVE HI
383 .I_1P_SH(~J1), // ACTIVE HI
384 .I_2P_LE(~L2), // ACTIVE HI
385 .I_2P_RI(~R2), // ACTIVE HI
386 .I_2P_SH(~J2), // ACTIVE HI
387 .I_1P_START(~S1), // ACTIVE HI
388 .I_2P_START(~S2), // ACTIVE HI
389
390 .I_SW0_OEn(W_SW0_OEn),
391 .I_SW1_OEn(W_SW1_OEn),
392 .I_DIP_OEn(W_DIP_OEn),
393
394 .O_D(W_SW_DO)
395
396 );
397
398 //-----------------------------------------------------------------------------
399 //------- ROM -------------------------------------------------------
400 reg [18:0]ROM_A;
401
402 wire [18:0]W_WAV_A0,W_WAV_A1,W_WAV_A2;
403 reg [7:0]W_WAV_D0,W_WAV_D1,W_WAV_D2;
404
405 wire [7:0]ROM_D;
406
407 galaxian_roms ROMS(
408 .I_ROM_CLK(W_CLK_12M),
409 .I_ADDR({3'h0,W_A[15:0]}),
410 .O_DATA(ROM_D)
411 );
412
413 always@(posedge W_CLK_12M)
414 begin
415 W_CPU_ROM_DO <= ROM_D;
416 end
417
418 //-----------------------------------------------------------------------------
419
420 wire W_V_BL2n;
421
422 mc_hv_count MC_HV(
423
424 .I_CLK(WB_CLK_6M),
425 .I_RSTn(W_RESETn),
426
427 .O_H_CNT(W_H_CNT),
428 .O_H_SYNC(W_H_SYNC),
429 .O_H_BL(W_H_BL),
430 .O_V_CNT(W_V_CNT),
431 .O_V_SYNC(W_V_SYNC),
432 .O_V_BL2n(W_V_BL2n),
433 .O_V_BLn(W_V_BLn),
434 .O_C_BLn(W_C_BLn)
435
436 );
437
438 //------ VIDEO -----------------------------
439 wire W_8HF;
440 wire W_1VF;
441 wire W_C_BLnX;
442 wire W_256HnX;
443 wire W_MISSILEn;
444 wire W_SHELLn;
445 wire [1:0]W_VID;
446 wire [2:0]W_COL;
447
448 mc_video MC_VID(
449 .I_CLK_18M(W_CLK_18M),
450 .I_CLK_12M(W_CLK_12M),
451 .I_CLK_6M(W_CLK_6M),
452 .I_H_CNT(W_H_CNT),
453 .I_V_CNT(W_V_CNT),
454 .I_H_FLIP(W_H_FLIP),
455 .I_V_FLIP(W_V_FLIP),
456 .I_V_BLn(W_V_BLn),
457 .I_C_BLn(W_C_BLn),
458
459 .I_A(W_A[9:0]),
460 .I_OBJ_SUB_A(3'b000),
461 .I_BD(W_BDI),
462 .I_OBJ_RAM_RQn(W_OBJ_RAM_RQn),
463 .I_OBJ_RAM_RDn(W_OBJ_RAM_RDn),
464 .I_OBJ_RAM_WRn(W_OBJ_RAM_WRn),
465 .I_VID_RAM_RDn(W_VID_RAM_RDn),
466 .I_VID_RAM_WRn(W_VID_RAM_WRn),
467
468 .O_C_BLnX(W_C_BLnX),
469 .O_8HF(W_8HF),
470 .O_256HnX(W_256HnX),
471 .O_1VF(W_1VF),
472 .O_MISSILEn(W_MISSILEn),
473 .O_SHELLn(W_SHELLn),
474 .O_BD(W_VID_DO),
475 .O_VID(W_VID),
476 .O_COL(W_COL)
477
478 );
479
480 wire W_C_BLX;
481 wire W_STARS_OFFn;
482 wire [2:0]W_VIDEO_R;
483 wire [2:0]W_VIDEO_G;
484 wire [1:0]W_VIDEO_B;
485
486 mc_col_pal MC_COL_PAL(
487
488 .I_CLK_12M(W_CLK_12M),
489 .I_CLK_6M(W_CLK_6M),
490 .I_VID(W_VID),
491 .I_COL(W_COL),
492 .I_C_BLnX(W_C_BLnX),
493
494 .O_C_BLX(W_C_BLX),
495 .O_STARS_OFFn(W_STARS_OFFn),
496 .O_R(W_VIDEO_R),
497 .O_G(W_VIDEO_G),
498 .O_B(W_VIDEO_B)
499
500 );
501
502 wire [2:0]W_STARS_R;
503 wire [2:0]W_STARS_G;
504 wire [1:0]W_STARS_B;
505
506 mc_stars MC_STARS(
507
508 .I_CLK_18M(W_CLK_18M),
509 `ifdef DEVICE_CYCLONE
510 .I_CLK_6M(~WB_CLK_6M),
511 `endif
512 `ifdef DEVICE_SPARTAN2E
513 .I_CLK_6M(WB_CLK_6M),
514 `endif
515 .I_H_FLIP(W_H_FLIP),
516 .I_V_SYNC(W_V_SYNC),
517 .I_8HF(W_8HF),
518 .I_256HnX(W_256HnX),
519 .I_1VF(W_1VF),
520 .I_2V(W_V_CNT[1]),
521 .I_STARS_ON(W_STARS_ON),
522 .I_STARS_OFFn(W_STARS_OFFn),
523
524 .O_R(W_STARS_R),
525 .O_G(W_STARS_G),
526 .O_B(W_STARS_B),
527 .O_NOISE()
528
529 );
530
531 wire [2:0]W_R;
532 wire [2:0]W_G;
533 wire [1:0]W_B;
534
535 mc_vedio_mix MIX(
536
537 .I_VID_R(W_VIDEO_R),
538 .I_VID_G(W_VIDEO_G),
539 .I_VID_B(W_VIDEO_B),
540 .I_STR_R(W_STARS_R),
541 .I_STR_G(W_STARS_G),
542 .I_STR_B(W_STARS_B),
543
544 .I_C_BLnXX(~W_C_BLX),
545 .I_C_BLX(W_C_BLX | ~W_V_BL2n),
546 .I_MISSILEn(W_MISSILEn),
547 .I_SHELLn(W_SHELLn),
548
549 .O_R(W_R),
550 .O_G(W_G),
551 .O_B(W_B)
552
553 );
554
555 wire [2:0]W_VGA_R;
556 wire [2:0]W_VGA_G;
557 wire [1:0]W_VGA_B;
558
559 `ifdef VGA_USE
560 mc_vga_if VGA(
561
562 // input
563 .I_CLK_1(W_CLK_6M),
564 .I_CLK_2(W_CLK_12M),
565 .I_R(W_R),
566 .I_G(W_G),
567 .I_B(W_B),
568 .I_H_SYNC(W_H_SYNC),
569 .I_V_SYNC(W_V_SYNC),
570 // output
571 .O_R(W_VGA_R),
572 .O_G(W_VGA_G),
573 .O_B(W_VGA_B),
574 .O_H_SYNCn(O_VGA_H_SYNCn),
575 .O_V_SYNCn(O_VGA_V_SYNCn)
576
577 );
578
579 `else
580
581 assign W_VGA_R[2:0] = W_R;
582
583 assign W_VGA_G[2:0] = W_G;
584
585 assign W_VGA_B[1:0] = W_B;
586
587 //assign O_VGA_H_SYNCn = W_H_SYNC | W_V_SYNC ; // AKIDUKI LCD USED
588 assign O_VGA_H_SYNCn = ~W_H_SYNC ;
589 assign O_VGA_V_SYNCn = ~W_V_SYNC ;
590
591 `endif
592
593 assign O_VGA_R[3:0] = {W_VGA_R[0], W_VGA_R[1], W_VGA_R[2], 1'b0};
594
595 assign O_VGA_G[3:0] = {W_VGA_G[0], W_VGA_G[1], W_VGA_G[2], 1'b0};
596
597 assign O_VGA_B[3:0] = {W_VGA_B[0], W_VGA_B[1], 2'b0};
598
599 wire [7:0]W_SDAT_A;
600
601 mc_sound_a MC_SOUND_A(
602
603 .I_CLK_12M(W_CLK_12M),
604 .I_CLK_6M(W_CLK_6M),
605 .I_H_CNT1(W_H_CNT[1]),
606 .I_BD(W_BDI),
607 .I_PITCHn(W_PITCHn),
608 .I_VOL1(W_VOL1),
609 .I_VOL2(W_VOL2),
610
611 .O_SDAT(W_SDAT_A),
612 .O_DO()
613
614 );
615
616 wire [7:0]W_SDAT_B;
617
618 mc_sound_b MC_SOUND_B(
619
620 .I_CLK1(W_CLK_18M),
621 .I_CLK2(W_CLK_6M),
622 .I_RSTn(rst_count[3]),
623 .I_SW({&on_game[1:0],W_HIT,W_FIRE}),
624
625 .O_WAV_A0(W_WAV_A0),
626 .O_WAV_A1(W_WAV_A1),
627 .O_WAV_A2(W_WAV_A2),
628 .I_WAV_D0(W_WAV_D0),
629 .I_WAV_D1(W_WAV_D1),
630 .I_WAV_D2(W_WAV_D2),
631
632 .O_SDAT(W_SDAT_B)
633
634 );
635
636 wire W_DAC_A;
637 wire W_DAC_B;
638
639 assign O_SOUND_OUT_L = W_DAC_A;
640 assign O_SOUND_OUT_R = W_DAC_B;
641
642 dac wav_dac_a(
643
644 .Clk(W_CLK_18M),
645 .Reset(~W_RESETn),
646 .DACin(W_SDAT_A),
647 .DACout(W_DAC_A)
648
649 );
650
651 dac wav_dac_b(
652
653 .Clk(W_CLK_18M),
654 .Reset(~W_RESETn),
655 .DACin(W_SDAT_B),
656 .DACout(W_DAC_B)
657
658 );
659
660
661 endmodule
662
Impressum, Datenschutz