//=============================================================================== // FPGA GALAXIAN VIDEO // // Version : 2.50 // // Copyright(c) 2004 Katsumi Degawa , All rights reserved // // Important ! // // This program is freeware for non-commercial use. // An author does no guarantee about this program. // You can use this under your own risk. // // 2004- 4-30 galaxian modify by K.DEGAWA // 2004- 5- 6 first release. // 2004- 8-23 Improvement with T80-IP. // 2004- 9-22 The problem which missile didn't sometimes come out from was improved. //================================================================================ //----------------------------------------------------------------------------------------- // 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], // 1 H 2 H 4H 8H 16 H 32H 64 H 128 H 256 H //----------------------------------------------------------------------------------------- // V_CNT[0], V_CNT[1], V_CNT[2], V_CNT[3], V_CNT[4], V_CNT[5], V_CNT[6], V_CNT[7] // 1 V 2 V 4 V 8 V 16 V 32 V 64 V 128 V //----------------------------------------------------------------------------------------- module mc_video( I_CLK_18M, I_CLK_12M, I_CLK_6M, I_H_CNT, I_V_CNT, I_H_FLIP, I_V_FLIP, I_V_BLn, I_C_BLn, I_A, I_OBJ_SUB_A, I_BD, I_OBJ_RAM_RQn, I_OBJ_RAM_RDn, I_OBJ_RAM_WRn, I_VID_RAM_RDn, I_VID_RAM_WRn, O_C_BLnX, O_8HF, O_256HnX, O_1VF, O_MISSILEn, O_SHELLn, O_BD, O_VID, O_COL ); input I_CLK_18M; input I_CLK_12M; input I_CLK_6M; input [8:0]I_H_CNT; input [7:0]I_V_CNT; input I_H_FLIP; input I_V_FLIP; input I_V_BLn; input I_C_BLn; input [9:0]I_A; input [7:0]I_BD; input [2:0]I_OBJ_SUB_A; input I_OBJ_RAM_RQn; input I_OBJ_RAM_RDn; input I_OBJ_RAM_WRn; input I_VID_RAM_RDn; input I_VID_RAM_WRn; output O_C_BLnX; output O_8HF; output O_256HnX; output O_1VF; output O_MISSILEn; output O_SHELLn; output [7:0]O_BD; output [1:0]O_VID; output [2:0]O_COL; wire WB_LDn; wire WB_CNTRLDn; wire WB_CNTRCLRn; wire WB_COLLn; wire WB_VPLn; wire WB_OBJDATALn; wire WB_MLDn; wire WB_SLDn; wire W_3D; reg W_LDn; reg W_CNTRLDn; reg W_CNTRCLRn; reg W_COLLn; reg W_VPLn; reg W_OBJDATALn; reg W_MLDn; reg W_SLDn; always@(negedge I_CLK_12M) begin W_LDn <= WB_LDn; W_CNTRLDn <= WB_CNTRLDn; W_CNTRCLRn <= WB_CNTRCLRn; W_COLLn <= WB_COLLn; W_VPLn <= WB_VPLn; W_OBJDATALn <= WB_OBJDATALn; W_MLDn <= WB_MLDn; W_SLDn <= WB_SLDn; end mc_ld_pls LD_PLS( .I_CLK_6M(I_CLK_6M), .I_H_CNT(I_H_CNT), .I_3D_DI(W_3D), .O_LDn(WB_LDn), .O_CNTRLDn(WB_CNTRLDn), .O_CNTRCLRn(WB_CNTRCLRn), .O_COLLn(WB_COLLn), .O_VPLn(WB_VPLn), .O_OBJDATALn(WB_OBJDATALn), .O_MLDn(WB_MLDn), .O_SLDn(WB_SLDn) ); wire W_H_FLIP1 = ~I_H_CNT[8]&I_H_FLIP; wire [7:3]W_HF_CNT = I_H_CNT[7:3]^{5{W_H_FLIP1}}; wire [7:0]W_VF_CNT = I_V_CNT[7:0]^{8{I_V_FLIP}}; assign O_8HF = W_HF_CNT[3]; assign O_1VF = W_VF_CNT[0]; reg [7:0]W_OBJ_D; wire [3:0]W_6J_DA = {I_H_FLIP , W_HF_CNT[7],W_HF_CNT[3],I_H_CNT[2]}; 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]}; wire [3:0]W_6J_Q = I_H_CNT[8] ? W_6J_DB:W_6J_DA; wire W_H_FLIP2 = W_6J_Q[3]; // Prats 4F,5F 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]}; wire [7:0]W_OBJ_RAM_A = I_OBJ_RAM_RQn ? W_OBJ_RAM_AB: I_A[7:0] ; wire [7:0]W_OBJ_RAM_DOA,W_OBJ_RAM_DOB; reg [7:0]W_H_POSI; always@(posedge I_CLK_12M) W_H_POSI <= W_OBJ_RAM_DOB; mc_obj_ram OBJ_RAM( .I_CLKA(I_CLK_12M), .I_ADDRA(I_A[7:0]), .I_WEA(~I_OBJ_RAM_WRn), .I_CEA(~I_OBJ_RAM_RQn), .I_DA(I_BD), .O_DA(W_OBJ_RAM_DOA), .I_CLKB(I_CLK_12M), .I_ADDRB(W_OBJ_RAM_AB), .I_WEB(1'b0), .I_CEB(1'b1), .I_DB(8'h00), .O_DB(W_OBJ_RAM_DOB) ); wire [7:0]W_OBJ_RAM_D = I_OBJ_RAM_RDn ? 8'h00: W_OBJ_RAM_DOA; // Prats 4L always@(posedge W_OBJDATALn) W_OBJ_D <= W_H_POSI; // Prats 4,5N wire [8:0]W_45N_Q = W_VF_CNT[7:0] + W_H_POSI ; assign W_3D = ~(&W_45N_Q[7:0]); reg [7:0]W_2M_Q; always@(posedge W_VPLn or negedge I_V_BLn) begin if(I_V_BLn==1'b0) W_2M_Q <= 0; else W_2M_Q <= W_45N_Q[7:0]; end wire W_2N = I_H_CNT[8]&W_OBJ_D[7]; wire [3:0]W_1M = W_2M_Q[3:0]^{W_2N,W_2N,W_2N,W_2N}; wire W_VID_RAM_CSn = I_VID_RAM_RDn & I_VID_RAM_WRn; wire [7:0]W_VID_RAM_DI = I_VID_RAM_WRn ? 8'h00 : I_BD ; wire [7:0]W_VID_RAM_DOA; wire [11:0]W_VID_RAM_AA = {~(&W_2M_Q[7:4]),W_VID_RAM_CSn, 10'h00 /*I_A[9:0]*/}; wire [11:0]W_VID_RAM_AB = { 1'b0, 1'b0,W_2M_Q[7:4],W_1M[3],W_HF_CNT[7:3]}; wire [11:0]W_VID_RAM_A = I_C_BLn ? W_VID_RAM_AB:W_VID_RAM_AA; wire [7:0]W_VID_RAM_D = I_VID_RAM_RDn ? 8'h00 :W_VID_RAM_DOA; wire [7:0]W_VID_RAM_DOB; mc_vid_ram VID_RAM( .I_CLKA(I_CLK_12M), .I_ADDRA(I_A[9:0]), .I_DA(W_VID_RAM_DI), .I_WEA(~I_VID_RAM_WRn), .I_CEA(~W_VID_RAM_CSn), .O_DA(W_VID_RAM_DOA), .I_CLKB(I_CLK_12M), .I_ADDRB(W_VID_RAM_A[9:0]), .I_DB(8'h00), .I_WEB(1'b0), .I_CEB(1'b1), .O_DB(W_VID_RAM_DOB) ); //-- VIDEO DATA OUTPUT -------------- assign O_BD = W_OBJ_RAM_D | W_VID_RAM_D; wire W_SRLD = ~(W_LDn | W_VID_RAM_A[11]); wire [7:0]W_OBJ_ROM_AB = {W_OBJ_D[5:0],W_1M[3],W_OBJ_D[6]^I_H_CNT[3]}; wire [7:0]W_OBJ_ROM_A = I_H_CNT[8] ? W_OBJ_ROM_AB: W_VID_RAM_DOB; wire [10:0]W_O_OBJ_ROM_A = {W_OBJ_ROM_A,W_1M[2:0]}; wire [7:0]W_1K_D; wire [7:0]W_1H_D; //1K VID-Rom GALAXIAN_1K K_ROM( .CLK(I_CLK_12M), .ADDR(W_O_OBJ_ROM_A), .DATA(W_1K_D), .ENA(1'b1) ); //1H VID-Rom GALAXIAN_1H H_ROM( .CLK(I_CLK_12M), .ADDR(W_O_OBJ_ROM_A), .DATA(W_1H_D), .ENA(1'b1) ); //--------------------------------------------------------------------------------- wire W_2L_Qa,W_2K_Qd; wire W_2J_Qa,W_2H_Qd; wire W_H_FLIP2X; wire [3:0]W_3L_A = {W_2J_Qa,W_2L_Qa, 1'b1,W_SRLD}; wire [3:0]W_3L_B = {W_2H_Qd,W_2K_Qd,W_SRLD, 1'b1}; wire [3:0]W_3L_Y = W_H_FLIP2X ? W_3L_B: W_3L_A; // [3]=RAW1,[2]=RAW0 wire W_RAW0 = W_3L_Y[2]; wire W_RAW1 = W_3L_Y[3]; wire W_SRCLK = I_CLK_6M; //------ PARTS 2KL ---------------------------------------------- wire [1:0]C_2KL = W_3L_Y[1:0]; wire [7:0]I_2KL = W_1K_D; reg [7:0]reg_2KL; assign W_2L_Qa = reg_2KL[7]; assign W_2K_Qd = reg_2KL[0]; always@(posedge W_SRCLK) begin case(C_2KL) 2'b00: reg_2KL <= reg_2KL; 2'b10: reg_2KL <= {reg_2KL[6:0],1'b0}; 2'b01: reg_2KL <= {1'b0,reg_2KL[7:1]}; 2'b11: reg_2KL <= I_2KL; endcase end //------ PARTS 2HJ ---------------------------------------------- wire [1:0]C_2HJ = W_3L_Y[1:0]; wire [7:0]I_2HJ = W_1H_D; reg [7:0]reg_2HJ; assign W_2J_Qa = reg_2HJ[7]; assign W_2H_Qd = reg_2HJ[0]; always@(posedge W_SRCLK) begin case(C_2HJ) 2'b00: reg_2HJ <= reg_2HJ; 2'b10: reg_2HJ <= {reg_2HJ[6:0],1'b0}; 2'b01: reg_2HJ <= {1'b0,reg_2HJ[7:1]}; 2'b11: reg_2HJ <= I_2HJ; endcase end //----- SHT2 ----------------------------------------------------- // Prats 6K reg [2:0]W_6K_Q; always@(posedge W_COLLn) W_6K_Q <= W_H_POSI[2:0]; // Prats 6P reg [6:0]W_6P_Q; always@(posedge I_CLK_6M) begin 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]}; else W_6P_Q <= W_6P_Q; end assign W_H_FLIP2X = W_6P_Q[6]; wire W_H_FLIP1X = W_6P_Q[5]; wire W_C_BLnX = W_6P_Q[4]; wire W_256HnX = W_6P_Q[3]; wire [2:0]W_CD = W_6P_Q[2:0]; assign O_256HnX = W_256HnX; assign O_C_BLnX = W_C_BLnX; wire W_45T_CLR = W_CNTRCLRn | W_256HnX ; reg [7:0]W_45T_Q; always@(posedge I_CLK_6M) begin if(W_45T_CLR==1'b0) W_45T_Q <= 0; else if(W_CNTRLDn==1'b0) W_45T_Q <= W_H_POSI; else W_45T_Q <= W_45T_Q + 1; end wire [7:0]W_LRAM_A = W_45T_Q^{8{W_H_FLIP1X}}; wire [4:0]W_LRAM_DI; wire [4:0]W_LRAM_DO; reg [1:0]W_RV; reg [2:0]W_RC; always@(negedge I_CLK_6M) begin W_RV <= W_LRAM_DO[1:0]; W_RC <= W_LRAM_DO[4:2]; end wire W_LRAM_AND = ~(~((W_LRAM_A[4]|W_LRAM_A[5])|(W_LRAM_A[6]|W_LRAM_A[7]))|W_256HnX ); wire W_RAW_OR = W_RAW0 | W_RAW1 ; wire [1:0]W_VID; wire [2:0]W_COL; assign W_VID[0] = ~(~(W_RAW0&W_RV[1])&W_RV[0]); assign W_VID[1] = ~(~(W_RAW1&W_RV[0])&W_RV[1]); assign W_COL[0] = ~(~(W_RAW_OR&W_CD[0]&W_RC[1]&W_RC[2])&W_RC[0]); assign W_COL[1] = ~(~(W_RAW_OR&W_CD[1]&W_RC[2]&W_RC[0])&W_RC[1]); assign W_COL[2] = ~(~(W_RAW_OR&W_CD[2]&W_RC[0]&W_RC[1])&W_RC[2]); assign O_VID = W_VID; assign O_COL = W_COL; assign W_LRAM_DI[0] = W_LRAM_AND&W_VID[0]; assign W_LRAM_DI[1] = W_LRAM_AND&W_VID[1]; assign W_LRAM_DI[2] = W_LRAM_AND&W_COL[0]; assign W_LRAM_DI[3] = W_LRAM_AND&W_COL[1]; assign W_LRAM_DI[4] = W_LRAM_AND&W_COL[2]; mc_lram LRAM( .I_CLK(I_CLK_18M), .I_ADDR(W_LRAM_A), .I_WE(I_CLK_6M), .I_D(W_LRAM_DI), .O_Dn(W_LRAM_DO) ); mc_missile MISSILE( .I_CLK_18M(I_CLK_18M), .I_CLK_6M(I_CLK_6M), .I_C_BLn_X(W_C_BLnX), .I_MLDn(W_MLDn), .I_SLDn(W_SLDn), .I_HPOS(W_H_POSI), .O_MISSILEn(O_MISSILEn), .O_SHELLn(O_SHELLn) ); endmodule