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