]> git.zerfleddert.de Git - fpga-games/blob - galaxian/src/mc_video.v
aafdcd3103b589173affb40fbb0f0f823cfa892c
[fpga-games] / galaxian / src / mc_video.v
1 //===============================================================================
2 // FPGA GALAXIAN VIDEO
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-22 The problem which missile didn't sometimes come out from was improved.
18 //================================================================================
19 //-----------------------------------------------------------------------------------------
20 // H_CNT[0],H_CNT[1],H_CNT[2],H_CNT[3],H_CNT[4],H_CNT[5],H_CNT[6],H_CNT[7],H_CNT[8],
21 // 1 H 2 H 4H 8H 16 H 32H 64 H 128 H 256 H
22 //-----------------------------------------------------------------------------------------
23 // V_CNT[0], V_CNT[1], V_CNT[2], V_CNT[3], V_CNT[4], V_CNT[5], V_CNT[6], V_CNT[7]
24 // 1 V 2 V 4 V 8 V 16 V 32 V 64 V 128 V
25 //-----------------------------------------------------------------------------------------
26
27 module mc_video(
28
29 I_CLK_18M,
30 I_CLK_12M,
31 I_CLK_6M,
32 I_H_CNT,
33 I_V_CNT,
34 I_H_FLIP,
35 I_V_FLIP,
36 I_V_BLn,
37 I_C_BLn,
38
39 I_A,
40 I_OBJ_SUB_A,
41 I_BD,
42 I_OBJ_RAM_RQn,
43 I_OBJ_RAM_RDn,
44 I_OBJ_RAM_WRn,
45 I_VID_RAM_RDn,
46 I_VID_RAM_WRn,
47
48 O_OBJ_ROM_A,
49 I_OBJ_ROM_A_D,
50 I_OBJ_ROM_B_D,
51
52 O_C_BLnX,
53 O_8HF,
54 O_256HnX,
55 O_1VF,
56 O_MISSILEn,
57 O_SHELLn,
58 O_BD,
59 O_VID,
60 O_COL
61
62 );
63
64 input I_CLK_18M;
65 input I_CLK_12M;
66 input I_CLK_6M;
67 input [8:0]I_H_CNT;
68 input [7:0]I_V_CNT;
69 input I_H_FLIP;
70 input I_V_FLIP;
71 input I_V_BLn;
72 input I_C_BLn;
73
74 input [9:0]I_A;
75 input [7:0]I_BD;
76 input [2:0]I_OBJ_SUB_A;
77 input I_OBJ_RAM_RQn;
78 input I_OBJ_RAM_RDn;
79 input I_OBJ_RAM_WRn;
80 input I_VID_RAM_RDn;
81 input I_VID_RAM_WRn;
82
83 output [10:0]O_OBJ_ROM_A;
84 input [7:0]I_OBJ_ROM_A_D;
85 input [7:0]I_OBJ_ROM_B_D;
86
87 output O_C_BLnX;
88 output O_8HF;
89 output O_256HnX;
90 output O_1VF;
91 output O_MISSILEn;
92 output O_SHELLn;
93
94 output [7:0]O_BD;
95 output [1:0]O_VID;
96 output [2:0]O_COL;
97
98 wire WB_LDn;
99 wire WB_CNTRLDn;
100 wire WB_CNTRCLRn;
101 wire WB_COLLn;
102 wire WB_VPLn;
103 wire WB_OBJDATALn;
104 wire WB_MLDn;
105 wire WB_SLDn;
106 wire W_3D;
107 reg W_LDn;
108 reg W_CNTRLDn;
109 reg W_CNTRCLRn;
110 reg W_COLLn;
111 reg W_VPLn;
112 reg W_OBJDATALn;
113 reg W_MLDn;
114 reg W_SLDn;
115
116 always@(negedge I_CLK_12M)
117 begin
118 W_LDn <= WB_LDn;
119 W_CNTRLDn <= WB_CNTRLDn;
120 W_CNTRCLRn <= WB_CNTRCLRn;
121 W_COLLn <= WB_COLLn;
122 W_VPLn <= WB_VPLn;
123 W_OBJDATALn <= WB_OBJDATALn;
124 W_MLDn <= WB_MLDn;
125 W_SLDn <= WB_SLDn;
126 end
127
128 mc_ld_pls LD_PLS(
129
130 .I_CLK_6M(~I_CLK_6M),
131 .I_H_CNT(I_H_CNT),
132 .I_3D_DI(W_3D),
133
134 .O_LDn(WB_LDn),
135 .O_CNTRLDn(WB_CNTRLDn),
136 .O_CNTRCLRn(WB_CNTRCLRn),
137 .O_COLLn(WB_COLLn),
138 .O_VPLn(WB_VPLn),
139 .O_OBJDATALn(WB_OBJDATALn),
140 .O_MLDn(WB_MLDn),
141 .O_SLDn(WB_SLDn)
142
143 );
144
145 wire W_H_FLIP1 = ~I_H_CNT[8]&I_H_FLIP;
146
147 wire [7:3]W_HF_CNT = I_H_CNT[7:3]^{5{W_H_FLIP1}};
148 wire [7:0]W_VF_CNT = I_V_CNT[7:0]^{8{I_V_FLIP}};
149
150 assign O_8HF = W_HF_CNT[3];
151 assign O_1VF = I_V_CNT[0]^1'b1; //XXX: breaks when flipped
152
153 reg [7:0]W_OBJ_D;
154 wire [3:0]W_6J_DA = {I_H_FLIP , W_HF_CNT[7],W_HF_CNT[3],I_H_CNT[2]};
155 wire [3:0]W_6J_DB = {W_OBJ_D[6],W_HF_CNT[3]&I_H_CNT[1], I_H_CNT[2],I_H_CNT[1]};
156 wire [3:0]W_6J_Q = I_H_CNT[8] ? W_6J_DB:W_6J_DA;
157
158 wire W_H_FLIP2 = W_6J_Q[3];
159 // Prats 4F,5F
160 wire [7:0]W_OBJ_RAM_AB = {1'b0,I_H_CNT[8],W_6J_Q[2],W_HF_CNT[6:4],W_6J_Q[1:0]};
161 wire [7:0]W_OBJ_RAM_A = I_OBJ_RAM_RQn ? W_OBJ_RAM_AB: I_A[7:0] ;
162
163 wire [7:0]W_OBJ_RAM_DOA,W_OBJ_RAM_DOB;
164
165 reg [7:0]W_H_POSI;
166 always@(posedge I_CLK_12M) W_H_POSI <= W_OBJ_RAM_DOB;
167
168 mc_obj_ram OBJ_RAM(
169
170 .I_CLKA(I_CLK_12M),
171 .I_ADDRA(I_A[7:0]),
172 .I_WEA(~I_OBJ_RAM_WRn),
173 .I_CEA(~I_OBJ_RAM_RQn),
174 .I_DA(I_BD),
175 .O_DA(W_OBJ_RAM_DOA),
176
177 .I_CLKB(I_CLK_12M),
178 .I_ADDRB(W_OBJ_RAM_AB),
179 .I_WEB(1'b0),
180 .I_CEB(1'b1),
181 .I_DB(8'h00),
182 .O_DB(W_OBJ_RAM_DOB)
183
184 );
185
186 wire [7:0]W_OBJ_RAM_D = I_OBJ_RAM_RDn ? 8'h00: W_OBJ_RAM_DOA;
187 // Prats 4L
188 always@(posedge W_OBJDATALn) W_OBJ_D <= W_H_POSI;
189 // Prats 4,5N
190
191 wire [8:0]W_45N_Q = W_VF_CNT[7:0] + W_H_POSI ;
192 assign W_3D = ~(&W_45N_Q[7:0]);
193
194 reg [7:0]W_2M_Q;
195 always@(posedge W_VPLn or negedge I_V_BLn)
196 begin
197 if(I_V_BLn==1'b0)
198 W_2M_Q <= 0;
199 else
200 W_2M_Q <= W_45N_Q[7:0];
201 end
202
203 wire W_2N = I_H_CNT[8]&W_OBJ_D[7];
204 wire [3:0]W_1M = W_2M_Q[3:0]^{W_2N,W_2N,W_2N,W_2N};
205
206 wire W_VID_RAM_CSn = I_VID_RAM_RDn & I_VID_RAM_WRn;
207
208 wire [7:0]W_VID_RAM_DI = I_VID_RAM_WRn ? 8'h00 : I_BD ;
209 wire [7:0]W_VID_RAM_DOA;
210
211 wire [11:0]W_VID_RAM_AA = {~(&W_2M_Q[7:4]),W_VID_RAM_CSn, 10'h00 /*I_A[9:0]*/};
212 wire [11:0]W_VID_RAM_AB = { 1'b0, 1'b0,W_2M_Q[7:4],W_1M[3],W_HF_CNT[7:3]};
213
214 wire [11:0]W_VID_RAM_A = I_C_BLn ? W_VID_RAM_AB:W_VID_RAM_AA;
215
216 wire [7:0]W_VID_RAM_D = I_VID_RAM_RDn ? 8'h00 :W_VID_RAM_DOA;
217
218 wire [7:0]W_VID_RAM_DOB;
219
220 mc_vid_ram VID_RAM(
221
222 .I_CLKA(I_CLK_12M),
223 .I_ADDRA(I_A[9:0]),
224 .I_DA(W_VID_RAM_DI),
225 .I_WEA(~I_VID_RAM_WRn),
226 .I_CEA(~W_VID_RAM_CSn),
227 .O_DA(W_VID_RAM_DOA),
228
229 .I_CLKB(I_CLK_12M),
230 .I_ADDRB(W_VID_RAM_A[9:0]),
231 .I_DB(8'h00),
232 .I_WEB(1'b0),
233 .I_CEB(1'b1),
234 .O_DB(W_VID_RAM_DOB)
235
236 );
237 //-- VIDEO DATA OUTPUT --------------
238 assign O_BD = W_OBJ_RAM_D | W_VID_RAM_D;
239
240 wire W_SRLD = ~(W_LDn | W_VID_RAM_A[11]);
241
242 wire [7:0]W_OBJ_ROM_AB = {W_OBJ_D[5:0],W_1M[3],W_OBJ_D[6]^I_H_CNT[3]};
243
244 wire [7:0]W_OBJ_ROM_A = I_H_CNT[8] ? W_OBJ_ROM_AB: W_VID_RAM_DOB;
245
246 assign O_OBJ_ROM_A = {W_OBJ_ROM_A,W_1M[2:0]};
247
248 wire [7:0]W_1K_D = I_OBJ_ROM_A_D;
249 wire [7:0]W_1H_D = I_OBJ_ROM_B_D;
250
251 //---------------------------------------------------------------------------------
252 wire W_2L_Qa,W_2K_Qd;
253 wire W_2J_Qa,W_2H_Qd;
254 wire W_H_FLIP2X;
255
256 wire [3:0]W_3L_A = {W_2J_Qa,W_2L_Qa, 1'b1,W_SRLD};
257 wire [3:0]W_3L_B = {W_2H_Qd,W_2K_Qd,W_SRLD, 1'b1};
258 wire [3:0]W_3L_Y = W_H_FLIP2X ? W_3L_B: W_3L_A; // [3]=RAW1,[2]=RAW0
259
260 wire W_RAW0 = W_3L_Y[2];
261 wire W_RAW1 = W_3L_Y[3];
262
263 wire W_SRCLK = I_CLK_6M;
264 //------ PARTS 2KL ----------------------------------------------
265 wire [1:0]C_2KL = W_3L_Y[1:0];
266 wire [7:0]I_2KL = W_1K_D;
267 reg [7:0]reg_2KL;
268
269 assign W_2L_Qa = reg_2KL[7];
270 assign W_2K_Qd = reg_2KL[0];
271 always@(posedge W_SRCLK)
272 begin
273 case(C_2KL)
274 2'b00: reg_2KL <= reg_2KL;
275 2'b10: reg_2KL <= {reg_2KL[6:0],1'b0};
276 2'b01: reg_2KL <= {1'b0,reg_2KL[7:1]};
277 2'b11: reg_2KL <= I_2KL;
278 endcase
279 end
280 //------ PARTS 2HJ ----------------------------------------------
281 wire [1:0]C_2HJ = W_3L_Y[1:0];
282 wire [7:0]I_2HJ = W_1H_D;
283 reg [7:0]reg_2HJ;
284
285 assign W_2J_Qa = reg_2HJ[7];
286 assign W_2H_Qd = reg_2HJ[0];
287 always@(posedge W_SRCLK)
288 begin
289 case(C_2HJ)
290 2'b00: reg_2HJ <= reg_2HJ;
291 2'b10: reg_2HJ <= {reg_2HJ[6:0],1'b0};
292 2'b01: reg_2HJ <= {1'b0,reg_2HJ[7:1]};
293 2'b11: reg_2HJ <= I_2HJ;
294 endcase
295 end
296
297 //----- SHT2 -----------------------------------------------------
298 // Prats 6K
299 reg [2:0]W_6K_Q;
300 always@(posedge W_COLLn) W_6K_Q <= W_H_POSI[2:0];
301
302 // Prats 6P
303 reg [6:0]W_6P_Q;
304 always@(posedge I_CLK_6M)
305 begin
306 if(W_LDn==1'b0) W_6P_Q <= {W_H_FLIP2,W_H_FLIP1,I_C_BLn,~I_H_CNT[8],W_6K_Q[2:0]};
307 else W_6P_Q <= W_6P_Q;
308 end
309
310 assign W_H_FLIP2X = W_6P_Q[6];
311 wire W_H_FLIP1X = W_6P_Q[5];
312 wire W_C_BLnX = W_6P_Q[4];
313 wire W_256HnX = W_6P_Q[3];
314 wire [2:0]W_CD = W_6P_Q[2:0];
315
316 assign O_256HnX = W_256HnX;
317 assign O_C_BLnX = W_C_BLnX;
318
319 wire W_45T_CLR = W_CNTRCLRn | W_256HnX ;
320 reg [7:0]W_45T_Q;
321
322 always@(posedge I_CLK_6M)
323 begin
324 if(W_45T_CLR==1'b0)
325 W_45T_Q <= 0;
326 else if(W_CNTRLDn==1'b0)
327 W_45T_Q <= W_H_POSI;
328 else
329 W_45T_Q <= W_45T_Q + 1;
330 end
331
332 wire [7:0]W_LRAM_A = W_45T_Q^{8{W_H_FLIP1X}};
333 wire W_LRAM_WE = ~I_CLK_6M;
334
335 wire [4:0]W_LRAM_DI;
336 wire [4:0]W_LRAM_DO;
337
338 reg [1:0]W_RV;
339 reg [2:0]W_RC;
340 wire W_1U_CLK = ~I_CLK_6M;
341
342 always@(posedge W_1U_CLK)
343 begin
344 W_RV <= W_LRAM_DO[1:0];
345 W_RC <= W_LRAM_DO[4:2];
346 end
347
348 wire W_LRAM_AND = ~(~((W_LRAM_A[4]|W_LRAM_A[5])|(W_LRAM_A[6]|W_LRAM_A[7]))|W_256HnX );
349 wire W_RAW_OR = W_RAW0 | W_RAW1 ;
350
351 wire [1:0]W_VID;
352 wire [2:0]W_COL;
353
354 assign W_VID[0] = ~(~(W_RAW0&W_RV[1])&W_RV[0]);
355 assign W_VID[1] = ~(~(W_RAW1&W_RV[0])&W_RV[1]);
356 assign W_COL[0] = ~(~(W_RAW_OR&W_CD[0]&W_RC[1]&W_RC[2])&W_RC[0]);
357 assign W_COL[1] = ~(~(W_RAW_OR&W_CD[1]&W_RC[2]&W_RC[0])&W_RC[1]);
358 assign W_COL[2] = ~(~(W_RAW_OR&W_CD[2]&W_RC[0]&W_RC[1])&W_RC[2]);
359
360 assign O_VID = W_VID;
361 assign O_COL = W_COL;
362
363 assign W_LRAM_DI[0] = W_LRAM_AND&W_VID[0];
364 assign W_LRAM_DI[1] = W_LRAM_AND&W_VID[1];
365 assign W_LRAM_DI[2] = W_LRAM_AND&W_COL[0];
366 assign W_LRAM_DI[3] = W_LRAM_AND&W_COL[1];
367 assign W_LRAM_DI[4] = W_LRAM_AND&W_COL[2];
368
369 mc_lram LRAM(
370
371 .I_CLK(I_CLK_18M),
372 .I_ADDR(W_LRAM_A),
373 .I_WE(W_LRAM_WE),
374 .I_D(W_LRAM_DI),
375 .O_Dn(W_LRAM_DO)
376
377 );
378
379 mc_missile MISSILE(
380
381 .I_CLK_18M(I_CLK_18M),
382 .I_CLK_6M(I_CLK_6M),
383 .I_C_BLn_X(W_C_BLnX),
384 .I_MLDn(W_MLDn),
385 .I_SLDn(W_SLDn),
386 .I_HPOS(W_H_POSI),
387
388 .O_MISSILEn(O_MISSILEn),
389 .O_SHELLn(O_SHELLn)
390
391 );
392
393 endmodule
394
395
Impressum, Datenschutz