diff --git a/Arcade_MiST/Namco Super Pacman Hardware/Mappy_Hardware.qsf b/Arcade_MiST/Namco Super Pacman Hardware/Mappy_Hardware.qsf index 968d74b8..cd4a8b34 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/Mappy_Hardware.qsf +++ b/Arcade_MiST/Namco Super Pacman Hardware/Mappy_Hardware.qsf @@ -40,7 +40,7 @@ # Project-Wide Assignments # ======================== set_global_assignment -name ORIGINAL_QUARTUS_VERSION 16.0.2 -set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26" +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 set_global_assignment -name PROJECT_CREATION_TIME_DATE "19:48:06 MAY 24,2017" set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files diff --git a/Arcade_MiST/Namco Super Pacman Hardware/README.txt b/Arcade_MiST/Namco Super Pacman Hardware/README.txt index d9ee91e2..d14d82c0 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/README.txt +++ b/Arcade_MiST/Namco Super Pacman Hardware/README.txt @@ -11,10 +11,12 @@ The Tower of Druaga/Mappy/Motos/DigDug II to Mist FPGA by Slingshot -- -- --------------------------------------------------------------------------------- --- +-- -- Arcade: The Tower of Druaga port to MiSTer by MiSTer-X -- 25 September 2019 --- +-- +-- Super Pacman support added by Jose Tejada (jotego), 11th March 2021 +-- --------------------------------------------------------------------------------- -- FPGA Druaga for XILINX Spartan-3 -------------------------------------- @@ -25,8 +27,8 @@ The Tower of Druaga/Mappy/Motos/DigDug II to Mist FPGA by Slingshot --------------------------------------------------- -- Copyright (c) 2016, Greg Miller --------------------------------------------------------------------------------- --- --- +-- +-- -- Keyboard inputs : -- -- F2 : Coin + Start 2 players @@ -45,8 +47,8 @@ The Tower of Druaga/Mappy/Motos/DigDug II to Mist FPGA by Slingshot -- S : Player 2 Trig2 -- -- Joystick support. --- --- +-- +-- -- FIXED: Video timing. -- --------------------------------------------------------------------------------- diff --git a/Arcade_MiST/Namco Super Pacman Hardware/meta/Super Pacman.mra b/Arcade_MiST/Namco Super Pacman Hardware/meta/Super Pacman.mra new file mode 100755 index 00000000..b808ea48 --- /dev/null +++ b/Arcade_MiST/Namco Super Pacman Hardware/meta/Super Pacman.mra @@ -0,0 +1,38 @@ + + Super Pacman + 0220 + superpac + 20210307 + druaga + + 05 + + + + FF + + + + + + + + + + + FF + + + + + + + + + + + + + + + diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/TheTowerofDruaga_mist.sv b/Arcade_MiST/Namco Super Pacman Hardware/rtl/TheTowerofDruaga_mist.sv index fcc56eee..58ab3f37 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/TheTowerofDruaga_mist.sv +++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/TheTowerofDruaga_mist.sv @@ -28,7 +28,7 @@ module TheTowerofDruaga_mist ( ); -`include "rtl\build_id.v" +`include "rtl\build_id.v" `define CORE_NAME "DRUAGA" wire [6:0] core_mod; @@ -115,8 +115,9 @@ always @(*) begin DSW1 = {dcService,dcCabinet,6'd0}; DSW2 = {8'd0}; end - 7'h5: ;// GROBDA - 7'h6: ;// PHOZON + 7'h5: ;// Super Pacman + 7'h6: ;// GROBDA + 7'h7: ;// PHOZON default: ; endcase end @@ -129,7 +130,7 @@ assign SDRAM_CKE = 1; wire clock_48, clock_6, pll_locked; pll pll( .inclk0(CLOCK_27), - .c0(clock_48),//49.147727 + .c0(clock_48),//49.147727 .c1(clock_6), .locked(pll_locked) ); @@ -146,6 +147,8 @@ wire key_strobe; wire key_pressed; wire [7:0] key_code; +// assign core_mod=7'd5; + user_io #(.STRLEN($size(CONF_STR)>>3))user_io( .clk_sys (clock_48 ), .conf_str (CONF_STR ), @@ -289,7 +292,8 @@ fpga_druaga fpga_druaga( .ROMAD(ioctl_addr[16:0]), .ROMDT(ioctl_dout), - .ROMEN(ioctl_wr) + .ROMEN(ioctl_wr), + .MODEL(core_mod[2:0]) ); hvgen hvgen( diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_sprite.v b/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_sprite.v index d913eefa..087da6bc 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_sprite.v +++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_sprite.v @@ -1,35 +1,43 @@ /*********************************** - FPGA Druaga ( Sprite Part ) + FPGA Druaga ( Sprite Part ) + + Copyright (c) 2007 MiSTer-X + + Super Pacman Support + (c) 2021 Jose Tejada, jotego - Copyright (c) 2007 MiSTer-X ************************************/ module DRUAGA_SPRITE ( - input VCLKx8, - input VCLK_EN, + input VCLKx8, + input VCLK_EN, - input [8:0] HPOS, - input [8:0] VPOS, - input oHB, + input [8:0] HPOS, + input [8:0] VPOS, + input oHB, - output [6:0] SPRA_A, - input [23:0] SPRA_D, + output [6:0] SPRA_A, + input [23:0] SPRA_D, - output [4:0] SPCOL, + output [4:0] SPCOL, - input [16:0] ROMAD, - input [7:0] ROMDT, - input ROMEN + input [16:0] ROMAD, + input [7:0] ROMDT, + input ROMEN, + input [2:0] MODEL ); -wire [9:0] CLT1_A; -wire [3:0] CLT1_D; +parameter [2:0] SUPERPAC=3'd5; +reg [9:0] CLT1_A; +wire [3:0] CLT1_D; + +// Colour Look-up Table dpram #(4,10) clut1(.clk_a(VCLKx8), .addr_a(CLT1_A), .q_a(CLT1_D), .clk_b(VCLKx8), .addr_b(ROMAD[9:0]), .we_b(ROMEN & (ROMAD[16:10]=={1'b1,4'h3,2'b00})), .d_b(ROMDT[3:0])); -wire [13:0] SPCH_A; -wire [15:0] SPCH_D; +wire [13:0] SPCH_A; +wire [15:0] SPCH_D; dpram #(8,14) spch0(.clk_a(VCLKx8), .addr_a(SPCH_A), .q_a(SPCH_D[15:8]), .clk_b(VCLKx8), .addr_b(ROMAD[13:0]), .we_b(ROMEN & (ROMAD[16:14]==3'b010)), .d_b(ROMDT)); @@ -37,100 +45,106 @@ dpram #(8,14) spch0(.clk_a(VCLKx8), .addr_a(SPCH_A), .q_a(SPCH_D[15:8]), dpram #(8,14) spch1(.clk_a(VCLKx8), .addr_a(SPCH_A), .q_a(SPCH_D[7:0]), .clk_b(VCLKx8), .addr_b(ROMAD[13:0]), .we_b(ROMEN & (ROMAD[16:14]==3'b011)), .d_b(ROMDT)); -reg lbufr = 1'b0; // 0/1 +reg lbufr = 1'b0; // 0/1 -reg [5:0] loop = 6'h0; // 0~32 -reg [4:0] lpcn = 5'h0; // 0~31 -reg [4:0] xf, yf; // 0~31 -reg [8:0] sx; // 0~511 -reg [4:0] sy; // 0~31 -reg [5:0] pn; // 0x00~0x3F -reg [8:0] vposl; // 0~511 +reg [5:0] loop = 6'h0; // 0~32 +reg [4:0] lpcn = 5'h0; // 0~31 +reg [4:0] xf, yf; // 0~31 +reg [8:0] sx; // 0~511 +reg [4:0] sy; // 0~31 +reg [5:0] pn; // 0x00~0x3F +reg [8:0] vposl; // 0~511 -reg [6:0] nProc = 7'h0; // 0~64 +reg [6:0] nProc = 7'h0; // 0~64 // sprite registers access -reg bLoad = 1'b0; // 0/1 -wire [7:0] spriteram = SPRA_D[7:0]; -wire [7:0] spriteram_2 = SPRA_D[15:8]; -wire [7:0] spriteram_3 = SPRA_D[23:16]; -assign SPRA_A = {nProc[5:0],bLoad}; +reg bLoad = 1'b0; // 0/1 +wire [7:0] spriteram = SPRA_D[7:0]; +wire [7:0] spriteram_2 = SPRA_D[15:8]; +wire [7:0] spriteram_3 = SPRA_D[23:16]; +assign SPRA_A = {nProc[5:0],bLoad}; // laster hit check -wire [8:0] y = spriteram_2 + 8'h10 + vposl; -wire [8:0] m = { 1'b1, ( 8'hF0 ^ { 3'b000, spriteram_3[3], 4'b0000 } )}; -wire bHit = ( ( y & m ) == { 1'b0, m[7:0] } ); +wire [8:0] y = spriteram_2 + 8'h10 + vposl; +wire [8:0] m = { 1'b1, ( 8'hF0 ^ { 3'b000, spriteram_3[3], 4'b0000 } )}; +wire bHit = ( ( y & m ) == { 1'b0, m[7:0] } ); -reg _sizx; -wire sizx = spriteram_3[2]; -wire sizy = spriteram_3[3]; -wire [4:0] mskx = { sizx, 4'b1111 }; -wire [4:0] msky = { sizy, 4'b1111 }; -reg [4:0] _msky = 5'b01111; +reg _sizx; +wire sizx = spriteram_3[2]; +wire sizy = spriteram_3[3]; +wire [4:0] mskx = { sizx, 4'b1111 }; +wire [4:0] msky = { sizy, 4'b1111 }; +reg [4:0] _msky = 5'b01111; -reg bKick = 1'b0; +reg bKick = 1'b0; -reg [7:0] cno; -wire [4:0] ox = { lpcn ^ xf }; +reg [7:0] cno; +wire [4:0] ox = { lpcn ^ xf }; assign SPCH_A = { cno[7:2], (cno[1]|sy[4]), (cno[0]|ox[4]), sy[3], ox[3:2], sy[2:0] }; -wire [15:0] SPCO = SPCH_D; -assign CLT1_A = (ox[1:0]==2'b00) ? { pn, SPCO[15], SPCO[11], SPCO[7], SPCO[3] } : - (ox[1:0]==2'b01) ? { pn, SPCO[14], SPCO[10], SPCO[6], SPCO[2] } : - (ox[1:0]==2'b10) ? { pn, SPCO[13], SPCO[ 9], SPCO[5], SPCO[1] } : - { pn, SPCO[12], SPCO[ 8], SPCO[4], SPCO[0] } ; +wire [15:0] SPCO = SPCH_D; + +always @(*) begin + CLT1_A = (ox[1:0]==2'b00) ? { pn, SPCO[15], SPCO[11], SPCO[7], SPCO[3] } : + (ox[1:0]==2'b01) ? { pn, SPCO[14], SPCO[10], SPCO[6], SPCO[2] } : + (ox[1:0]==2'b10) ? { pn, SPCO[13], SPCO[ 9], SPCO[5], SPCO[1] } : + { pn, SPCO[12], SPCO[ 8], SPCO[4], SPCO[0] } ; + if( MODEL == SUPERPAC ) begin // 2bpp + CLT1_A[9:2]= { 2'd0, CLT1_A[9:4] }; + end +end wire [3:0] SPCL; assign SPCOL = {1'b0,SPCL}; -LINEBUF_DOUBLE linebuf( VCLKx8, ~oHB & VCLK_EN, lbufr, ~VCLKx8 & VCLK_EN, (loop!=0), sx, CLT1_D, HPOS, SPCL ); +LINEBUF_DOUBLE linebuf( VCLKx8, ~oHB & VCLK_EN, lbufr, ~VCLKx8 & VCLK_EN, (loop!=0), sx, CLT1_D, HPOS, SPCL ); always @( posedge VCLKx8 ) begin if (VCLK_EN) begin - if (~oHB) begin // Horizontal display time - bKick <= 1'b1; - if (loop!=0) begin // rend sprite scanline - sx <= sx+1'd1; - lpcn <= lpcn+1'd1; - loop <= loop-1'd1; - end - else begin // rend sprite scanline init. - if (~nProc[6]) begin - if (~bLoad) begin - if (bHit) begin - cno <= spriteram & { 6'b111111, ~sizy, ~sizx }; - xf <= spriteram_3[0] ? mskx : 5'h0; - yf <= spriteram_3[1] ? msky : 5'h0; - sy <= ( 9'h10 + vposl + { 1'b0, spriteram_2 } ); - _msky <= msky; - _sizx <= sizx; - bLoad <= 1'b1; - end - else begin - nProc <= nProc+1; - bLoad <= 1'b0; - end - end - else begin - pn <= spriteram[5:0]; - sx <= { spriteram_3[0], spriteram_2[7:0] } - 9'h38; - sy <= ( sy & _msky ) ^ yf; - loop <= spriteram_3[1] ? 6'h0 : { _sizx, ~_sizx, 4'h0 }; - lpcn <= 6'h0; - nProc <= nProc+1; - bLoad <= 1'b0; - end - end - end - end - else begin // Horizontal blanking time - if (bKick) begin - lbufr <= ~VPOS[0]; - vposl <= VPOS+1; - nProc <= 0; - bKick <= 1'b0; - end - end + if (~oHB) begin // Horizontal display time + bKick <= 1'b1; + if (loop!=0) begin // rend sprite scanline + sx <= sx+1'd1; + lpcn <= lpcn+1'd1; + loop <= loop-1'd1; + end + else begin // rend sprite scanline init. + if (~nProc[6]) begin + if (~bLoad) begin + if (bHit) begin + cno <= spriteram & { 6'b111111, ~sizy, ~sizx }; + xf <= spriteram_3[0] ? mskx : 5'h0; + yf <= spriteram_3[1] ? msky : 5'h0; + sy <= ( 9'h10 + vposl + { 1'b0, spriteram_2 } ); + _msky <= msky; + _sizx <= sizx; + bLoad <= 1'b1; + end + else begin + nProc <= nProc+1; + bLoad <= 1'b0; + end + end + else begin + pn <= spriteram[5:0]; + sx <= { spriteram_3[0], spriteram_2[7:0] } - 9'h38; + sy <= ( sy & _msky ) ^ yf; + loop <= spriteram_3[1] ? 6'h0 : { _sizx, ~_sizx, 4'h0 }; + lpcn <= 6'h0; + nProc <= nProc+1; + bLoad <= 1'b0; + end + end + end + end + else begin // Horizontal blanking time + if (bKick) begin + lbufr <= ~VPOS[0]; + vposl <= VPOS+1; + nProc <= 0; + bKick <= 1'b0; + end + end end end @@ -141,22 +155,22 @@ endmodule //---------------------------------------- module LINEBUF_DOUBLE( CLK, EN, SIDE1, CLK2, WEN, ADRSW, IN, ADRSR, OUT ); -input CLK; -input EN; -input SIDE1; -input CLK2; -input WEN; -input [8:0] ADRSW; -input [3:0] IN; -input [8:0] ADRSR; -output [3:0] OUT; +input CLK; +input EN; +input SIDE1; +input CLK2; +input WEN; +input [8:0] ADRSW; +input [3:0] IN; +input [8:0] ADRSR; +output [3:0] OUT; -wire [3:0] OUT0, OUT1; +wire [3:0] OUT0, OUT1; -wire SIDE0 = ~SIDE1; -wire OPAQUE = ~( IN[0] & IN[1] & IN[2] & IN[3] ); +wire SIDE0 = ~SIDE1; +wire OPAQUE = ~( IN[0] & IN[1] & IN[2] & IN[3] ); -assign OUT = SIDE1 ? OUT1 : OUT0; +assign OUT = SIDE1 ? OUT1 : OUT0; LBUF512 buf0( CLK, SIDE0 ? EN : ( EN & WEN & OPAQUE ), SIDE0 ? ADRSR : ADRSW, SIDE0 ? 4'b1111 : IN, CLK2, EN & SIDE0, ADRSR, OUT0 ); LBUF512 buf1( CLK, SIDE1 ? EN : ( EN & WEN & OPAQUE ), SIDE1 ? ADRSR : ADRSW, SIDE1 ? 4'b1111 : IN, CLK2, EN & SIDE1, ADRSR, OUT1 ); @@ -165,17 +179,24 @@ endmodule module LBUF512 ( - input CLKW, - input WEN, - input [8:0] ADRSW, - input [3:0] IN, - input CLKR, - input REN, - input [8:0] ADRSR, - output [3:0] OUT + input CLKW, + input WEN, + input [8:0] ADRSW, + input [3:0] IN, + input CLKR, + input REN, + input [8:0] ADRSR, + output [3:0] OUT ); -dpram #(4,9) lbuf(.clk_a(CLKW), .we_a(WEN), .addr_a(ADRSW), .d_a(IN), - .clk_b(CLKR), .addr_b(ADRSR), .q_b(OUT)); + dpram #(4,9) lbuf( + .clk_a ( CLKW ), + .we_a ( WEN ), + .addr_a( ADRSW ), + .clk_b ( CLKR ), + .d_a ( IN ), + .addr_b( ADRSR ), + .q_b ( OUT ) + ); endmodule diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_video.v b/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_video.v index a9a52b84..77954e86 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_video.v +++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_video.v @@ -1,50 +1,55 @@ /*********************************** - FPGA Druaga ( Video Part ) + FPGA Druaga ( Video Part ) + + Copyright (c) 2007 MiSTer-X + + Super Pacman Support + (c) 2021 Jose Tejada, jotego - Copyright (c) 2007 MiSTer-X ************************************/ module DRUAGA_VIDEO ( - input VCLKx8, - input VCLK, - input VCLK_EN, + input VCLKx8, + input VCLK, + input VCLK_EN, - input [8:0] PH, - input [8:0] PV, - output PCLK, - output PCLK_EN, - output [7:0] POUT, - output VB, + input [8:0] PH, + input [8:0] PV, + output PCLK, + output PCLK_EN, + output [7:0] POUT, // pixel colour output + output VB, - output [10:0] VRAM_A, - input [15:0] VRAM_D, + output [10:0] VRAM_A, + input [15:0] VRAM_D, - output [6:0] SPRA_A, - input [23:0] SPRA_D, + output [6:0] SPRA_A, + input [23:0] SPRA_D, - input [8:0] SCROLL, + input [8:0] SCROLL, - input [16:0] ROMAD, - input [7:0] ROMDT, - input ROMEN + input [16:0] ROMAD, + input [ 7:0] ROMDT, + input ROMEN, + input [ 2:0] MODEL ); +parameter [2:0] SUPERPAC=3'd5; + wire [8:0] HPOS = PH-8'd16; wire [8:0] VPOS = PV; wire oHB = (PH>=290) & (PH<492); -assign VB = (PV==224); +assign VB = (PV==227); +reg [4:0] PALT_A; +wire [7:0] PALT_D; -reg [4:0] PALT_A; -wire [7:0] PALT_D; +wire [7:0] CLT0_A; +wire [3:0] CLT0_D; -wire [7:0] CLT0_A; -wire [3:0] CLT0_D; - -wire [11:0] BGCH_A; -wire [7:0] BGCH_D; +wire [7:0] BGCH_D; // @@ -58,70 +63,115 @@ always @(posedge VCLKx8) if (PH == 290) BGVSCR <= SCROLL; //---------------------------------------- // BG scanline generator //---------------------------------------- -reg [7:0] BGPN; -reg BGH; +reg [7:0] BGPN; +reg BGH; -wire [5:0] COL = HPOS[8:3]; -wire [5:0] ROW = VPOS[8:3]; -wire [5:0] ROW2 = ROW + 6'h02; +reg [5:0] COL, ROW; -wire [7:0] CHRC = VRAM_D[7:0]; -wire [5:0] BGPL = VRAM_D[13:8]; +wire [7:0] CHRC = VRAM_D[7:0]; +wire [5:0] BGPL = VRAM_D[13:8]; -wire [8:0] HP = HPOS; -wire [8:0] VP = COL[5] ? VPOS : BGVPOS; -wire [11:0] CHRA = { CHRC, ~HP[2], VP[2:0] }; -wire [7:0] CHRO = BGCH_D; +wire [8:0] HP = HPOS; +wire [8:0] VP = COL[5] ? VPOS : BGVPOS; +wire [11:0] CHRA = { CHRC, ~HP[2], VP[2:0] }; +wire [7:0] CHRO = BGCH_D; // Char pixel data +reg [10:0] VRAMADRS; always @ ( posedge VCLKx8 ) begin - if (VCLK_EN) - case ( HP[1:0] ) - 2'b00: begin BGPN <= { BGPL, CHRO[7], CHRO[3] }; BGH <= VRAM_D[14]; end - 2'b01: begin BGPN <= { BGPL, CHRO[6], CHRO[2] }; BGH <= VRAM_D[14]; end - 2'b10: begin BGPN <= { BGPL, CHRO[5], CHRO[1] }; BGH <= VRAM_D[14]; end - 2'b11: begin BGPN <= { BGPL, CHRO[4], CHRO[0] }; BGH <= VRAM_D[14]; end - endcase + if (VCLK_EN) + case ( HP[1:0] ) + 2'b00: begin BGPN <= { BGPL, CHRO[7], CHRO[3] }; BGH <= VRAM_D[14]; end + 2'b01: begin BGPN <= { BGPL, CHRO[6], CHRO[2] }; BGH <= VRAM_D[14]; end + 2'b10: begin BGPN <= { BGPL, CHRO[5], CHRO[1] }; BGH <= VRAM_D[14]; end + 2'b11: begin BGPN <= { BGPL, CHRO[4], CHRO[0] }; BGH <= VRAM_D[14]; end + endcase end -wire [10:0] VRAMADRS = COL[5] ? { 4'b1111, COL[1:0], ROW[4], ROW2[3:0] } : { VP[8:3], HP[7:3] }; -assign CLT0_A = BGPN; -assign BGCH_A = CHRA; -assign VRAM_A = VRAMADRS; +assign CLT0_A = BGPN ^ ( MODEL==SUPERPAC ? 8'h0 : 8'h03 ); +assign VRAM_A = VRAMADRS & ( MODEL==SUPERPAC ? 11'h3FF : 11'h7FF ); -wire BGHI = BGH & (CLT0_D!=4'd15); -wire [4:0] BGCOL = { 1'b1, CLT0_D }; +wire BGHI = BGH & (CLT0_D!=4'd15); +wire [4:0] BGCOL = { 1'b1, (MODEL==SUPERPAC ? ~CLT0_D :CLT0_D) }; +always @(*) begin + COL = HPOS[8:3]; + ROW = VPOS[8:3]; + + if( MODEL==SUPERPAC ) begin + // This +2 adjustment is due to using a linear video timing generator + // rather than the original circuit count. + ROW = ROW + 6'h2; + VRAMADRS = { 1'b0, + COL[5] ? {COL[4:0], ROW[4:0]} : + {ROW[4:0], COL[4:0]} + }; + end else begin + VRAMADRS = COL[5] ? { 4'b1111, COL[1:0], ROW[4], ROW[3:0]+4'h2 } : + { VP[8:3], HP[7:3] }; + end +end //---------------------------------------- // Sprite scanline generator //---------------------------------------- -wire [4:0] SPCOL; +wire [4:0] SPCOL; -DRUAGA_SPRITE spr +DRUAGA_SPRITE #(.SUPERPAC(SUPERPAC)) spr ( - VCLKx8, VCLK_EN, - HPOS, VPOS, oHB, - SPRA_A, SPRA_D, - SPCOL, - ROMAD,ROMDT,ROMEN + VCLKx8, VCLK_EN, + HPOS, VPOS, oHB, + SPRA_A, SPRA_D, + SPCOL, + ROMAD,ROMDT,ROMEN, + MODEL ); //---------------------------------------- // Color mixer & Final output //---------------------------------------- -always @(posedge VCLKx8) if (VCLK_EN) PALT_A <= BGHI ? BGCOL : ((SPCOL[3:0]==4'd15) ? BGCOL : SPCOL ); -assign POUT = oHB ? 8'd0 : PALT_D; -assign PCLK = VCLK; +always @(posedge VCLKx8) if (VCLK_EN) begin + PALT_A <= BGHI ? BGCOL : ((SPCOL[3:0]==4'd15) ? BGCOL : SPCOL ); +end + +assign POUT = oHB ? 8'd0 : PALT_D; +assign PCLK = VCLK; assign PCLK_EN = VCLK_EN; //---------------------------------------- // ROMs //---------------------------------------- -dpram #(8,12) bgchr(.clk_a(VCLKx8), .addr_a(BGCH_A), .q_a(BGCH_D), - .clk_b(VCLKx8), .addr_b(ROMAD[11:0]), .we_b(ROMEN & (ROMAD[16:12]=={1'b1,4'h2})), .d_b(ROMDT)); -dpram #(4,8) clut0(.clk_a(VCLKx8), .addr_a(CLT0_A^8'h03), .q_a(CLT0_D), - .clk_b(VCLKx8), .addr_b(ROMAD[7:0]), .we_b(ROMEN & (ROMAD[16:8]=={1'b1,8'h34})), .d_b(ROMDT[3:0])); -dpram #(8,5) pelet(.clk_a(VCLKx8), .addr_a(PALT_A), .q_a(PALT_D), - .clk_b(VCLKx8), .addr_b(ROMAD[4:0]), .we_b(ROMEN & (ROMAD[16:5]=={1'b1,8'h36,3'b000})), .d_b(ROMDT)); + +// Char Tiles +dpram #(8,12) bgchr(.clk_a ( VCLKx8 ), + .addr_a( CHRA ), + .q_a ( BGCH_D ), + // ROM download + .clk_b ( VCLKx8 ), + .addr_b( ROMAD[11:0] ), + .we_b ( ROMEN & (ROMAD[16:12]=={1'b1,4'h2}) ), + .d_b ( ROMDT ) + ); + +// Char palette LUT +dpram #(4,8) clut0( .clk_a ( VCLKx8 ), + .addr_a( CLT0_A ), + .q_a ( CLT0_D ), + // ROM download + .clk_b ( VCLKx8 ), + .addr_b( ROMAD[7:0] ), + .we_b ( ROMEN & (ROMAD[16:8]=={1'b1,8'h34}) ), + .d_b ( ROMDT[3:0] ) + ); + +// Colour PROM +dpram #(8,5) pelet(.clk_a ( VCLKx8 ), + .addr_a( PALT_A ), + .q_a ( PALT_D ), + // ROM download + .clk_b ( VCLKx8 ), + .addr_b( ROMAD[4:0] ), + .we_b ( ROMEN & (ROMAD[16:5]=={1'b1,8'h36,3'b000}) ), + .d_b ( ROMDT ) + ); endmodule diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/fpga_druaga.v b/Arcade_MiST/Namco Super Pacman Hardware/rtl/fpga_druaga.v index 6de29060..44515e8c 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/fpga_druaga.v +++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/fpga_druaga.v @@ -1,41 +1,47 @@ /*********************************** - FPGA Druaga ( Top module ) + FPGA Druaga ( Top module ) - Copyright (c) 2007 MiSTer-X + Copyright (c) 2007 MiSTer-X - Conversion to clock-enable: - (c) 2019 Slingshot + Conversion to clock-enable: + (c) 2019 Slingshot + + Super Pacman Support + (c) 2021 Jose Tejada, jotego ************************************/ module fpga_druaga ( - input RESET, // RESET - input MCLK, // MasterClock: 49.125MHz - input CLKCPUx2, // CPU clock x 2: MCLK/8 + input RESET, // RESET + input MCLK, // MasterClock: 49.125MHz + input CLKCPUx2, // CPU clock x 2: MCLK/8 - input [8:0] PH, // Screen H - input [8:0] PV, // Screen V - output PCLK, // Pixel Clock - output PCLK_EN, - output [7:0] POUT, // Pixel Color + input [8:0] PH, // Screen H + input [8:0] PV, // Screen V + output PCLK, // Pixel Clock + output PCLK_EN, + output [7:0] POUT, // Pixel Color - output [7:0] SOUT, // Sound Out - output [14:0] rom_addr, - input [7:0] rom_data, - output [12:0] snd_addr, - input [7:0] snd_data, - input [5:0] INP0, // 1P {B2,B1,L,D,R,U} - input [5:0] INP1, // 2P {B2,B1,L,D,R,U} - input [2:0] INP2, // {Coin,Start2P,Start1P} - - input [7:0] DSW0, // DIPSWs (Active Logic) - input [7:0] DSW1, - input [7:0] DSW2, + output [7:0] SOUT, // Sound Out + output [14:0] rom_addr, + input [7:0] rom_data, + output [12:0] snd_addr, + input [7:0] snd_data, + input [5:0] INP0, // 1P {B2,B1,L,D,R,U} + input [5:0] INP1, // 2P {B2,B1,L,D,R,U} + input [2:0] INP2, // {Coin,Start2P,Start1P} - input [16:0] ROMAD, - input [7:0] ROMDT, - input ROMEN + input [7:0] DSW0, // DIPSWs (Active Logic) + input [7:0] DSW1, + input [7:0] DSW2, + + input [16:0] ROMAD, + input [ 7:0] ROMDT, + input ROMEN, + input [ 2:0] MODEL ); +parameter [2:0] SUPERPAC=3'd5; + // Clock Generator reg [4:0] CLKS; @@ -46,43 +52,44 @@ wire VCLK_EN = CLKS[2:0] == 3'b011; always @( posedge MCLK ) CLKS <= CLKS+1'd1; // Main-CPU Interface -wire MCPU_CLK = CLKCPUx2; -wire [15:0] MCPU_ADRS; -wire MCPU_VMA; -wire MCPU_RW; -wire MCPU_WE = ( ~MCPU_RW ); -//wire MCPU_RE = ( MCPU_RW ); -wire [7:0] MCPU_DO; -wire [7:0] MCPU_DI; +wire MCPU_CLK = CLKCPUx2; +wire [15:0] MCPU_ADRS; +wire MCPU_VMA; +wire MCPU_RW; +wire MCPU_WE = ( ~MCPU_RW ); +//wire MCPU_RE = ( MCPU_RW ); +wire [7:0] MCPU_DO; +wire [7:0] MCPU_DI; // Sub-CPU Interface -wire SCPU_CLK = CLKCPUx2; -wire [15:0] SCPU_ADRS; -wire SCPU_VMA; -wire SCPU_RW; -wire SCPU_WE = ( ~SCPU_RW ); -//wire SCPU_RE = ( SCPU_RW ); -wire [7:0] SCPU_DO; -wire [7:0] SCPU_DI; +wire SCPU_CLK = CLKCPUx2; +wire [15:0] SCPU_ADRS; +wire SCPU_VMA; +wire SCPU_RW; +wire SCPU_WE = ( ~SCPU_RW ); +//wire SCPU_RE = ( SCPU_RW ); +wire [7:0] SCPU_DO; +wire [7:0] SCPU_DI; // I/O Interface -wire MCPU_CS_IO, SCPU_WE_WSG; -wire [7:0] IO_O; -wire [10:0] vram_a; -wire [15:0] vram_d; -wire [6:0] spra_a; -wire [23:0] spra_d; -MEMS mems +wire MCPU_CS_IO, SCPU_WE_WSG; +wire [7:0] IO_O; +wire [10:0] vram_a; +wire [15:0] vram_d; +wire [6:0] spra_a; +wire [23:0] spra_d; +MEMS #(.SUPERPAC(SUPERPAC)) mems ( - MCLK, - CLKCPUx2, - rom_addr, rom_data, - snd_addr, snd_data, - MCPU_ADRS, MCPU_VMA, MCPU_WE, MCPU_DO, MCPU_DI, MCPU_CS_IO, IO_O, - SCPU_ADRS, SCPU_VMA, SCPU_WE, SCPU_DO, SCPU_DI, SCPU_WE_WSG, - vram_a,vram_d, - spra_a,spra_d, - ROMAD,ROMDT,ROMEN + MCLK, + CLKCPUx2, + rom_addr, rom_data, + snd_addr, snd_data, + MCPU_ADRS, MCPU_VMA, MCPU_WE, MCPU_DO, MCPU_DI, MCPU_CS_IO, IO_O, + SCPU_ADRS, SCPU_VMA, SCPU_WE, SCPU_DO, SCPU_DI, SCPU_WE_WSG, + vram_a,vram_d, + spra_a,spra_d, + ROMAD,ROMDT,ROMEN, + MODEL ); // Control Registers @@ -92,28 +99,31 @@ wire MCPU_IRQ, MCPU_IRQEN; wire SCPU_IRQ, SCPU_IRQEN; wire SCPU_RESET, IO_RESET; wire PSG_ENABLE; -REGS regs + +REGS #(.SUPERPAC(SUPERPAC)) regs ( - CLKCPUx2, RESET, oVB, - MCPU_ADRS, MCPU_VMA, MCPU_WE, - SCPU_ADRS, SCPU_VMA, SCPU_WE, - SCROLL, - MCPU_IRQ, MCPU_IRQEN, - SCPU_IRQ, SCPU_IRQEN, - SCPU_RESET, IO_RESET, - PSG_ENABLE + CLKCPUx2, RESET, oVB, + MCPU_ADRS, MCPU_VMA, MCPU_WE, + SCPU_ADRS, SCPU_VMA, SCPU_WE, + SCROLL, + MCPU_IRQ, MCPU_IRQEN, + SCPU_IRQ, SCPU_IRQEN, + SCPU_RESET, IO_RESET, + PSG_ENABLE, + MODEL ); // I/O Controler wire IsMOTOS; -IOCTRL ioctrl( - CLKCPUx2, oVB, IO_RESET, MCPU_CS_IO, MCPU_WE, MCPU_ADRS[5:0], - MCPU_DO, - IO_O, - {INP1,INP0},INP2, - {DSW2,DSW1,DSW0}, - IsMOTOS +IOCTRL #(.SUPERPAC(SUPERPAC)) ioctrl( + CLKCPUx2, oVB, IO_RESET, MCPU_CS_IO, MCPU_WE, MCPU_ADRS[5:0], + MCPU_DO, + IO_O, + {INP1,INP0},INP2, + {DSW2,DSW1,DSW0}, + IsMOTOS, + MODEL ); @@ -121,56 +131,60 @@ IOCTRL ioctrl( wire [7:0] oPOUT; DRUAGA_VIDEO video ( - .VCLKx8(VCLK_x8),.VCLK(VCLK_x1), - .VCLK_EN(VCLK_EN), - .PH(PH),.PV(PV), - .PCLK(PCLK),.PCLK_EN(PCLK_EN),.POUT(oPOUT),.VB(oVB), - .VRAM_A(vram_a), .VRAM_D(vram_d), - .SPRA_A(spra_a), .SPRA_D(spra_d), - .SCROLL({1'b0,SCROLL}), - .ROMAD(ROMAD),.ROMDT(ROMDT),.ROMEN(ROMEN) + .VCLKx8(VCLK_x8),.VCLK(VCLK_x1), + .VCLK_EN(VCLK_EN), + .PH(PH),.PV(PV), + .PCLK(PCLK),.PCLK_EN(PCLK_EN),.POUT(oPOUT),.VB(oVB), + .VRAM_A(vram_a), .VRAM_D(vram_d), + .SPRA_A(spra_a), .SPRA_D(spra_d), + .SCROLL({1'b0,SCROLL}), + .ROMAD(ROMAD),.ROMDT(ROMDT),.ROMEN(ROMEN), + .MODEL(MODEL) ); -assign POUT = (IsMOTOS & (PV==0)) ? 8'h0 : oPOUT; + +// This prevents a glitch in the sprites for the first line +// but it hides the top line of the CRT test screen +assign POUT = (IsMOTOS && (PV==0)) ? 8'h0 : oPOUT; // MainCPU cpucore main_cpu ( - .clk(MCPU_CLK), - .rst(RESET), - .rw(MCPU_RW), - .vma(MCPU_VMA), - .address(MCPU_ADRS), - .data_in(MCPU_DI), - .data_out(MCPU_DO), - .halt(1'b0), - .hold(1'b0), - .irq(MCPU_IRQ), - .firq(1'b0), - .nmi(1'b0) + .clk(MCPU_CLK), + .rst(RESET), + .rw(MCPU_RW), + .vma(MCPU_VMA), + .address(MCPU_ADRS), + .data_in(MCPU_DI), + .data_out(MCPU_DO), + .halt(1'b0), + .hold(1'b0), + .irq(MCPU_IRQ), + .firq(1'b0), + .nmi(1'b0) ); // SubCPU cpucore sub_cpu ( - .clk(SCPU_CLK), - .rst(SCPU_RESET), - .rw(SCPU_RW), - .vma(SCPU_VMA), - .address(SCPU_ADRS), - .data_in(SCPU_DI), - .data_out(SCPU_DO), - .halt(1'b0), - .hold(1'b0), - .irq(SCPU_IRQ), - .firq(1'b0), - .nmi(1'b0) + .clk(SCPU_CLK), + .rst(SCPU_RESET), + .rw(SCPU_RW), + .vma(SCPU_VMA), + .address(SCPU_ADRS), + .data_in(SCPU_DI), + .data_out(SCPU_DO), + .halt(1'b0), + .hold(1'b0), + .irq(SCPU_IRQ), + .firq(1'b0), + .nmi(1'b0) ); // SOUND -wire WAVE_CLK; +wire WAVE_CLK; wire [7:0] WAVE_AD; wire [3:0] WAVE_DT; @@ -178,52 +192,55 @@ dpram #(4,8) wsgwv(.clk_a(MCLK), .addr_a(WAVE_AD), .q_a(WAVE_DT), .clk_b(MCLK), .addr_b(ROMAD[7:0]), .we_b(ROMEN & (ROMAD[16:8]=={1'b1,8'h35})), .d_b(ROMDT[3:0])); WSG_8CH wsg( - .MCLK(MCLK), - .ADDR(SCPU_ADRS[5:0]), - .DATA(SCPU_DO), - .WE(SCPU_WE_WSG), - .SND_ENABLE(PSG_ENABLE), - .WAVE_CLK(WAVE_CLK), - .WAVE_AD(WAVE_AD), - .WAVE_DT(WAVE_DT), - .SOUT(SOUT) + .MCLK(MCLK), + .ADDR(SCPU_ADRS[5:0]), + .DATA(SCPU_DO), + .WE(SCPU_WE_WSG), + .SND_ENABLE(PSG_ENABLE), + .WAVE_CLK(WAVE_CLK), + .WAVE_AD(WAVE_AD), + .WAVE_DT(WAVE_DT), + .SOUT(SOUT) ); endmodule module MEMS ( - input MCLK, - input CPUCLKx2, - output [14:0] rom_addr, - input [7:0] rom_data, - output [12:0] snd_addr, - input [7:0] snd_data, - input [15:0] MCPU_ADRS, - input MCPU_VMA, - input MCPU_WE, - input [7:0] MCPU_DO, - output [7:0] MCPU_DI, - output IO_CS, - input [7:0] IO_O, + input MCLK, + input CPUCLKx2, + output [14:0] rom_addr, + input [7:0] rom_data, + output [12:0] snd_addr, + input [7:0] snd_data, + input [15:0] MCPU_ADRS, + input MCPU_VMA, + input MCPU_WE, + input [7:0] MCPU_DO, + output [7:0] MCPU_DI, + output IO_CS, + input [7:0] IO_O, - input [15:0] SCPU_ADRS, - input SCPU_VMA, - input SCPU_WE, - input [7:0] SCPU_DO, - output [7:0] SCPU_DI, - output SCPU_WSG_WE, + input [15:0] SCPU_ADRS, + input SCPU_VMA, + input SCPU_WE, + input [7:0] SCPU_DO, + output [7:0] SCPU_DI, + output SCPU_WSG_WE, - input [10:0] vram_a, - output [15:0] vram_d, - input [6:0] spra_a, - output [23:0] spra_d, + input [10:0] vram_a, + output [15:0] vram_d, + input [6:0] spra_a, + output [23:0] spra_d, - input [16:0] ROMAD, - input [7:0] ROMDT, - input ROMEN + input [16:0] ROMAD, + input [ 7:0] ROMDT, + input ROMEN, + input [2:0] MODEL ); +parameter [2:0] SUPERPAC=3'd5; + wire [7:0] mrom_d, srom_d; //DLROM #(15,8) mcpui( CPUCLKx2, MCPU_ADRS[14:0], mrom_d, ROMCL,ROMAD[14:0],ROMDT,ROMEN & (ROMAD[16:15]==2'b0_0)); assign rom_addr = MCPU_ADRS[14:0]; @@ -234,54 +251,72 @@ assign srom_d = snd_data; //dpram #(8,13) scpui(.clk_a(CPUCLKx2), .addr_a(SCPU_ADRS[12:0]), .q_a(srom_d), // .clk_b(MCLK), .addr_b(ROMAD[12:0]), .we_b(ROMEN & (ROMAD[16:13]==4'b1_000)), .d_b(ROMDT)); -wire mram_cs0 = ( MCPU_ADRS[15:11] == 5'b00000 ) & MCPU_VMA; // $0000-$07FF -wire mram_cs1 = ( MCPU_ADRS[15:11] == 5'b00001 ) & MCPU_VMA; // $0800-$0FFF -wire mram_cs2 = ( MCPU_ADRS[15:11] == 5'b00010 ) & MCPU_VMA; // $1000-$17FF -wire mram_cs3 = ( MCPU_ADRS[15:11] == 5'b00011 ) & MCPU_VMA; // $1800-$1FFF -wire mram_cs4 = ( MCPU_ADRS[15:11] == 5'b00100 ) & MCPU_VMA; // $2000-$27FF -wire mram_cs5 = ( MCPU_ADRS[15:10] == 6'b010000 ) & MCPU_VMA; // $4000-$43FF -assign IO_CS = ( MCPU_ADRS[15:11] == 5'b01001 ) & MCPU_VMA; // $4800-$4FFF -wire mrom_cs = ( MCPU_ADRS[15] ) & MCPU_VMA; // $8000-$FFFF +reg mram_cs0, mram_cs1, + mram_cs2, mram_cs3, + mram_cs4, mram_cs5; -wire mram_w0 = ( mram_cs0 & MCPU_WE ); -wire mram_w1 = ( mram_cs1 & MCPU_WE ); -wire mram_w2 = ( mram_cs2 & MCPU_WE ); -wire mram_w3 = ( mram_cs3 & MCPU_WE ); -wire mram_w4 = ( mram_cs4 & MCPU_WE ); -wire mram_w5 = ( mram_cs5 & MCPU_WE ); +reg [10:0] cram_ad; +wire [10:0] mram_ad = MCPU_ADRS[10:0]; -wire [7:0] mram_o0, mram_o1, mram_o2, mram_o3, mram_o4, mram_o5; +assign IO_CS = ( MCPU_ADRS[15:11] == 5'b01001 ) & MCPU_VMA; // $4800-$4FFF +wire mrom_cs = ( MCPU_ADRS[15] ) & MCPU_VMA; // $8000-$FFFF -assign MCPU_DI = mram_cs0 ? mram_o0 : - mram_cs1 ? mram_o1 : - mram_cs2 ? mram_o2 : - mram_cs3 ? mram_o3 : - mram_cs4 ? mram_o4 : - mram_cs5 ? mram_o5 : - mrom_cs ? mrom_d : - IO_CS ? IO_O : - 8'h0; +always @(*) begin + cram_ad = mram_ad; + if( MODEL == SUPERPAC ) begin + mram_cs0 = ( MCPU_ADRS[15:10] == 6'b000000 ) && MCPU_VMA; // $0000-$03FF + mram_cs1 = ( MCPU_ADRS[15:10] == 6'b000001 ) && MCPU_VMA; // $0400-$07FF + mram_cs2 = ( MCPU_ADRS[15:11] == 5'b00001 ) && MCPU_VMA; // $1000-$17FF + mram_cs3 = ( MCPU_ADRS[15:11] == 5'b00010 ) && MCPU_VMA; // $1800-$1FFF + mram_cs4 = ( MCPU_ADRS[15:11] == 5'b00011 ) && MCPU_VMA; // $2000-$27FF + if( mram_cs0 | mram_cs1 ) cram_ad[10]=0; + end else begin + mram_cs0 = ( MCPU_ADRS[15:11] == 5'b00000 ) && MCPU_VMA; // $0000-$07FF + mram_cs1 = ( MCPU_ADRS[15:11] == 5'b00001 ) && MCPU_VMA; // $0800-$0FFF + mram_cs2 = ( MCPU_ADRS[15:11] == 5'b00010 ) && MCPU_VMA; // $1000-$17FF + mram_cs3 = ( MCPU_ADRS[15:11] == 5'b00011 ) && MCPU_VMA; // $1800-$1FFF + mram_cs4 = ( MCPU_ADRS[15:11] == 5'b00100 ) && MCPU_VMA; // $2000-$27FF + end + mram_cs5 = ( MCPU_ADRS[15:10] == 6'b010000 ) && MCPU_VMA; // $4000-$43FF +end -wire [10:0] mram_ad = MCPU_ADRS[10:0]; +wire mram_w0 = ( mram_cs0 & MCPU_WE ); +wire mram_w1 = ( mram_cs1 & MCPU_WE ); +wire mram_w2 = ( mram_cs2 & MCPU_WE ); +wire mram_w3 = ( mram_cs3 & MCPU_WE ); +wire mram_w4 = ( mram_cs4 & MCPU_WE ); +wire mram_w5 = ( mram_cs5 & MCPU_WE ); -dpram #(8,11) main_ram0( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o0), .we_a(mram_w0), .clk_b(MCLK), .addr_b(vram_a), .q_b(vram_d[ 7:0])); -dpram #(8,11) main_ram1( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o1), .we_a(mram_w1), .clk_b(MCLK), .addr_b(vram_a), .q_b(vram_d[15:8])); +wire [7:0] mram_o0, mram_o1, mram_o2, mram_o3, mram_o4, mram_o5; + +assign MCPU_DI = mram_cs0 ? mram_o0 : + mram_cs1 ? mram_o1 : + mram_cs2 ? mram_o2 : + mram_cs3 ? mram_o3 : + mram_cs4 ? mram_o4 : + mram_cs5 ? mram_o5 : + mrom_cs ? mrom_d : + IO_CS ? IO_O : + 8'h0; + +dpram #(8,11) main_ram0( .clk_a(CPUCLKx2), .addr_a(cram_ad), .d_a(MCPU_DO), .q_a(mram_o0), .we_a(mram_w0), .clk_b(MCLK), .addr_b(vram_a), .q_b(vram_d[ 7:0])); +dpram #(8,11) main_ram1( .clk_a(CPUCLKx2), .addr_a(cram_ad), .d_a(MCPU_DO), .q_a(mram_o1), .we_a(mram_w1), .clk_b(MCLK), .addr_b(vram_a), .q_b(vram_d[15:8])); dpram #(8,11) main_ram2( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o2), .we_a(mram_w2), .clk_b(MCLK), .addr_b({ 4'b1111, spra_a }), .q_b(spra_d[ 7: 0])); dpram #(8,11) main_ram3( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o3), .we_a(mram_w3), .clk_b(MCLK), .addr_b({ 4'b1111, spra_a }), .q_b(spra_d[15: 8])); dpram #(8,11) main_ram4( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o4), .we_a(mram_w4), .clk_b(MCLK), .addr_b({ 4'b1111, spra_a }), .q_b(spra_d[23:16])); - // (SCPU ADRS) -wire SCPU_CS_SREG = ( ( SCPU_ADRS[15:13] == 3'b000 ) & ( SCPU_ADRS[9:6] == 4'b0000 ) ) & SCPU_VMA; -wire srom_cs = ( SCPU_ADRS[15:13] == 3'b111 ) & SCPU_VMA; // $E000-$FFFF -wire sram_cs0 = (~SCPU_CS_SREG) & (~srom_cs) & SCPU_VMA; // $0000-$03FF -wire [7:0] sram_o0; + // (SCPU ADRS) +wire SCPU_CS_SREG = ( ( SCPU_ADRS[15:13] == 3'b000 ) & ( SCPU_ADRS[9:6] == 4'b0000 ) ) & SCPU_VMA; +wire srom_cs = ( SCPU_ADRS[15:13] == 3'b111 ) & SCPU_VMA; // $E000-$FFFF +wire sram_cs0 = (~SCPU_CS_SREG) & (~srom_cs) & SCPU_VMA; // $0000-$03FF +wire [7:0] sram_o0; -assign SCPU_DI = sram_cs0 ? sram_o0 : - srom_cs ? srom_d : - 8'h0; +assign SCPU_DI = sram_cs0 ? sram_o0 : + srom_cs ? srom_d : + 8'h0; -assign SCPU_WSG_WE = SCPU_CS_SREG & SCPU_WE; +assign SCPU_WSG_WE = SCPU_CS_SREG & SCPU_WE; dpram #(8,11) share_ram( .clk_a(CPUCLKx2), .addr_a(mram_ad), .d_a(MCPU_DO), .q_a(mram_o5), .we_a(mram_w5), .clk_b(CPUCLKx2), .addr_b(SCPU_ADRS[9:0]), .d_b(SCPU_DO), .q_b(sram_o0), .we_b(sram_cs0 & SCPU_WE) ); @@ -291,111 +326,120 @@ endmodule module REGS ( - input MCPU_CLK, - input RESET, - input VBLANK, + input MCPU_CLK, + input RESET, + input VBLANK, - input [15:0] MCPU_ADRS, - input MCPU_VMA, - input MCPU_WE, + input [15:0] MCPU_ADRS, + input MCPU_VMA, + input MCPU_WE, - input [15:0] SCPU_ADRS, - input SCPU_VMA, - input SCPU_WE, + input [15:0] SCPU_ADRS, + input SCPU_VMA, + input SCPU_WE, - output reg [7:0] SCROLL, - output MCPU_IRQ, - output reg MCPU_IRQEN, - output SCPU_IRQ, - output reg SCPU_IRQEN, - output SCPU_RESET, - output IO_RESET, - output reg PSG_ENABLE + output reg [7:0] SCROLL, + output MCPU_IRQ, + output reg MCPU_IRQEN, + output SCPU_IRQ, + output reg SCPU_IRQEN, + output SCPU_RESET, + output IO_RESET, + output reg PSG_ENABLE, + input [2:0] MODEL ); +parameter [2:0] SUPERPAC=3'd5; + // BG Scroll Register -wire MCPU_SCRWE = ( ( MCPU_ADRS[15:11] == 5'b00111 ) & MCPU_VMA & MCPU_WE ); +wire MCPU_SCRWE = ( ( MCPU_ADRS[15:11] == 5'b00111 ) & MCPU_VMA & MCPU_WE ); + always @ ( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) SCROLL <= 8'h0; - else if ( MCPU_SCRWE ) SCROLL <= MCPU_ADRS[10:3]; + if ( RESET ) SCROLL <= 8'h0; + else begin + if( MODEL==SUPERPAC ) + SCROLL <= 8'd0; + else if ( MCPU_SCRWE ) + SCROLL <= MCPU_ADRS[10:3]; + end end // MainCPU IRQ Generator -wire MCPU_IRQWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000001 ) & MCPU_VMA & MCPU_WE ); -//wire MCPU_IRQWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000001 ) & SCPU_VMA & SCPU_WE ); +wire MCPU_IRQWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000001 ) & MCPU_VMA & MCPU_WE ); +//wire MCPU_IRQWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000001 ) & SCPU_VMA & SCPU_WE ); assign MCPU_IRQ = MCPU_IRQEN & VBLANK; always @( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) begin - MCPU_IRQEN <= 1'b0; - end - else begin - if ( MCPU_IRQWE ) MCPU_IRQEN <= MCPU_ADRS[0]; -// if ( MCPU_IRQWES ) MCPU_IRQEN <= SCPU_ADRS[0]; - end + if ( RESET ) begin + MCPU_IRQEN <= 1'b0; + end + else begin + if ( MCPU_IRQWE ) MCPU_IRQEN <= MCPU_ADRS[0]; +// if ( MCPU_IRQWES ) MCPU_IRQEN <= SCPU_ADRS[0]; + end end // SubCPU IRQ Generator -wire SCPU_IRQWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000000 ) & MCPU_VMA & MCPU_WE ); -wire SCPU_IRQWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000000 ) & SCPU_VMA & SCPU_WE ); +wire SCPU_IRQWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000000 ) & MCPU_VMA & MCPU_WE ); +wire SCPU_IRQWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000000 ) & SCPU_VMA & SCPU_WE ); assign SCPU_IRQ = SCPU_IRQEN & VBLANK; always @( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) begin - SCPU_IRQEN <= 1'b0; - end - else begin - if ( SCPU_IRQWE ) SCPU_IRQEN <= MCPU_ADRS[0]; - if ( SCPU_IRQWES ) SCPU_IRQEN <= SCPU_ADRS[0]; - end + if ( RESET ) begin + SCPU_IRQEN <= 1'b0; + end + else begin + if ( SCPU_IRQWE ) SCPU_IRQEN <= MCPU_ADRS[0]; + if ( SCPU_IRQWES ) SCPU_IRQEN <= SCPU_ADRS[0]; + end end // SubCPU RESET Control -reg SCPU_RSTf = 1'b0; -wire SCPU_RSTWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000101 ) & MCPU_VMA & MCPU_WE ); -wire SCPU_RSTWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000101 ) & SCPU_VMA & SCPU_WE ); +reg SCPU_RSTf = 1'b0; +wire SCPU_RSTWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000101 ) & MCPU_VMA & MCPU_WE ); +wire SCPU_RSTWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000101 ) & SCPU_VMA & SCPU_WE ); assign SCPU_RESET = ~SCPU_RSTf; always @( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) begin - SCPU_RSTf <= 1'b0; - end - else begin - if ( SCPU_RSTWE ) SCPU_RSTf <= MCPU_ADRS[0]; - if ( SCPU_RSTWES ) SCPU_RSTf <= SCPU_ADRS[0]; - end + if ( RESET ) begin + SCPU_RSTf <= 1'b0; + end + else begin + if ( SCPU_RSTWE ) SCPU_RSTf <= MCPU_ADRS[0]; + if ( SCPU_RSTWES ) SCPU_RSTf <= SCPU_ADRS[0]; + end end // I/O CHIP RESET Control -reg IOCHIP_RSTf = 1'b0; -wire IOCHIP_RSTWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000100 ) & MCPU_VMA & MCPU_WE ); +reg IOCHIP_RSTf = 1'b0; +wire IOCHIP_RSTWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000100 ) & MCPU_VMA & MCPU_WE ); assign IO_RESET = ~IOCHIP_RSTf; always @( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) begin - IOCHIP_RSTf <= 1'b0; - end - else begin - if ( IOCHIP_RSTWE ) IOCHIP_RSTf <= MCPU_ADRS[0]; - end + if ( RESET ) begin + IOCHIP_RSTf <= 1'b0; + end + else begin + if ( IOCHIP_RSTWE ) IOCHIP_RSTf <= MCPU_ADRS[0]; + end end // Sound Enable Control -wire PSG_ENAWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000011 ) & MCPU_VMA & MCPU_WE ); -wire PSG_ENAWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000011 ) & SCPU_VMA & SCPU_WE ); +wire PSG_ENAWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000011 ) & MCPU_VMA & MCPU_WE ); +wire PSG_ENAWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000011 ) & SCPU_VMA & SCPU_WE ); always @( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) begin - PSG_ENABLE <= 1'b0; - end - else begin - if ( PSG_ENAWE ) PSG_ENABLE <= MCPU_ADRS[0]; - if ( PSG_ENAWES ) PSG_ENABLE <= SCPU_ADRS[0]; - end + if ( RESET ) begin + PSG_ENABLE <= 1'b0; + end + else begin + if ( PSG_ENAWE ) PSG_ENABLE <= MCPU_ADRS[0]; + if ( PSG_ENAWES ) PSG_ENABLE <= SCPU_ADRS[0]; + end end endmodule @@ -403,28 +447,28 @@ endmodule module cpucore ( - input clk, - input rst, - output rw, - output vma, - output [15:0] address, - input [7:0] data_in, - output [7:0] data_out, - input halt, - input hold, - input irq, - input firq, - input nmi + input clk, + input rst, + output rw, + output vma, + output [15:0] address, + input [7:0] data_in, + output [7:0] data_out, + input halt, + input hold, + input irq, + input firq, + input nmi ); mc6809 cpu ( .D(data_in), - .DOut(data_out), + .DOut(data_out), .ADDR(address), .RnW(rw), -// .E(vma), +// .E(vma), .nIRQ(~irq), .nFIRQ(~firq), .nNMI(~nmi), @@ -432,9 +476,9 @@ mc6809 cpu .nHALT(~halt), .nRESET(~rst), - .XTAL(1'b0), - .MRDY(1'b1), - .nDMABREQ(1'b1) + .XTAL(1'b0), + .MRDY(1'b1), + .nDMABREQ(1'b1) ); assign vma = 1; diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/hvgen.v b/Arcade_MiST/Namco Super Pacman Hardware/rtl/hvgen.v index e3dc0905..322471a9 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/hvgen.v +++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/hvgen.v @@ -11,6 +11,11 @@ module hvgen output reg VSYN = 1 ); +localparam [8:0] VS_START = 9'd228, + VS_END = VS_START+9'd3, + VB_START = 9'd223, + VB_END = 9'd511; + reg [8:0] hcnt = 0; reg [8:0] vcnt = 0; @@ -26,10 +31,10 @@ always @(posedge MCLK) begin 342: begin HSYN <= 1; hcnt <= 9'd470; end 511: begin hcnt <= 0; case (vcnt) - 223: begin VBLK <= 1; vcnt <= vcnt+1'd1; end - 226: begin VSYN <= 0; vcnt <= vcnt+1'd1; end - 233: begin VSYN <= 1; vcnt <= 9'd483; end - 511: begin VBLK <= 0; vcnt <= 0; end + VB_START: begin VBLK <= 1; vcnt <= vcnt+1'd1; end + VS_START: begin VSYN <= 0; vcnt <= vcnt+1'd1; end + VS_END: begin VSYN <= 1; vcnt <= 9'd483; end + VB_END: begin VBLK <= 0; vcnt <= 0; end default: vcnt <= vcnt+1'd1; endcase end @@ -37,4 +42,4 @@ always @(posedge MCLK) begin endcase end -endmodule \ No newline at end of file +endmodule \ No newline at end of file diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/ioctrl.v b/Arcade_MiST/Namco Super Pacman Hardware/rtl/ioctrl.v index ce3d9600..34bb82c3 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/ioctrl.v +++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/ioctrl.v @@ -1,87 +1,97 @@ /**************************************************** - FPGA Druaga ( Custom I/O chip emulation part ) + FPGA Druaga ( Custom I/O chip emulation part ) + + Copyright (c) 2007 MiSTer-X + + Super Pacman Support + (c) 2021 Jose Tejada, jotego - Copyright (c) 2007 MiSTer-X *****************************************************/ -module IOCTRL( CLK, UPDATE, RESET, ENABLE, WR, ADRS, IN, OUT, STKTRG12, CSTART12, DIPSW, IsMOTOS ); - input CLK; - input UPDATE; - input RESET; - input ENABLE; - input WR; - input [5:0] ADRS; - input [7:0] IN; - output [7:0] OUT; - - input [11:0] STKTRG12; // { STKTRG2[5:0], STKSTG1[5:0] } - input [2:0] CSTART12; // { COIN, START2P, START1P } - input [23:0] DIPSW; // { DSW5[3:0] DSW4[3:0] DSW3[3:0], DSW2[3:0], DSW1[3:0], DSW0[3:0] } +module IOCTRL( CLK, UPDATE, RESET, ENABLE, WR, ADRS, IN, OUT, + STKTRG12, // Joystick controls + CSTART12, // Start buttons + DIPSW, + IsMOTOS, + MODEL ); + input CLK; + input UPDATE; + input RESET; + input ENABLE; + input WR; + input [5:0] ADRS; + input [7:0] IN; + output [7:0] OUT; - output IsMOTOS; + input [11:0] STKTRG12; // { STKTRG2[5:0], STKSTG1[5:0] } + input [2:0] CSTART12; // { COIN, START2P, START1P } + input [23:0] DIPSW; // { DSW5[3:0] DSW4[3:0] DSW3[3:0], DSW2[3:0], DSW1[3:0], DSW0[3:0] } - -reg [3:0] mema[0:15]; -reg [3:0] memb[0:15]; -reg [3:0] memc[0:31]; -reg [3:0] outr; + output IsMOTOS; + input [2:0] MODEL; -reg [7:0] credits; -reg [7:0] credit_add, credit_sub; -reg [9:0] pSTKTRG12; -reg [2:0] pCSTART12; +reg [3:0] mema[0:15]; +reg [3:0] memb[0:15]; +reg [3:0] memc[0:31]; +reg [3:0] outr; -reg bUpdate; -reg bIOMode = 0; +reg [7:0] credits; +reg [7:0] credit_add, credit_sub; -assign OUT = { 4'b1111, outr }; -assign IsMOTOS = bIOMode; +reg [9:0] pSTKTRG12; +reg [2:0] pCSTART12; -wire [11:0] iSTKTRG12 = ( STKTRG12 ^ pSTKTRG12 ) & STKTRG12; -wire [2:0] iCSTART12 = ( CSTART12 ^ pCSTART12 ) & CSTART12; +reg bUpdate; +reg bIOMode; -wire [3:0] CREDIT_ONES, CREDIT_TENS; -BCDCONV creditsBCD( credits, CREDIT_ONES, CREDIT_TENS ); +parameter [2:0] SUPERPAC=3'd5; + +assign OUT = { 4'b1111, outr }; +assign IsMOTOS = bIOMode; + +// Detect falling edges: +wire [11:0] iSTKTRG12 = ( STKTRG12 ^ pSTKTRG12 ) & STKTRG12; +wire [ 2:0] iCSTART12 = ( CSTART12 ^ pCSTART12 ) & CSTART12; + +wire [ 3:0] CREDIT_ONES, CREDIT_TENS; +BCDCONV creditsBCD( credits, CREDIT_ONES, CREDIT_TENS ); always @ ( posedge CLK ) begin + if ( ENABLE ) begin + if ( ADRS[5] ) begin + if ( WR ) memc[ADRS[4:0]] <= IN; + outr <= memc[ADRS[4:0]]; + end else if ( ADRS[4] ) begin + if ( WR ) memb[ADRS[3:0]] <= IN; + outr <= memb[ADRS[3:0]]; + end else begin + if ( WR ) mema[ADRS[3:0]] <= IN; + outr <= mema[ADRS[3:0]]; + end + end + if ( RESET ) begin + pCSTART12 <= 0; + pSTKTRG12 <= 0; + bUpdate <= 0; + bIOMode <= 0; + credits <= 0; + end else begin + if ( UPDATE & (~bUpdate) ) begin + if ( mema[4'h8] == 4'h8 || MODEL==SUPERPAC ) + bIOMode <= 1'b1; // Is running "Motos" ? - if ( ENABLE ) begin - if ( ADRS[5] ) begin - if ( WR ) memc[ADRS[4:0]] <= IN; - outr <= memc[ADRS[4:0]]; - end else if ( ADRS[4] ) begin - if ( WR ) memb[ADRS[3:0]] <= IN; - outr <= memb[ADRS[3:0]]; - end else begin - if ( WR ) mema[ADRS[3:0]] <= IN; - outr <= mema[ADRS[3:0]]; - end - end - - if ( RESET ) begin - pCSTART12 <= 0; - pSTKTRG12 <= 0; - bUpdate <= 0; - bIOMode = 0; - credits = 0; - end - else begin - if ( UPDATE & (~bUpdate) ) begin - if ( mema[4'h8] == 4'h8 ) bIOMode = 1'b1; // Is running "Motos" ? - - if ( bIOMode ) begin - `include "ioctrl_1.v" - end - else begin - `include "ioctrl_0.v" - end - - pCSTART12 <= CSTART12; - pSTKTRG12 <= STKTRG12; - end - bUpdate <= UPDATE; - end + if ( bIOMode ) begin + `include "ioctrl_1.v" + end + else begin + `include "ioctrl_0.v" + end + pCSTART12 <= CSTART12; + pSTKTRG12 <= STKTRG12; + end + bUpdate <= UPDATE; + end end endmodule @@ -95,19 +105,19 @@ output [3:0] out; reg [3:0] out; always @ (in) - case (in) - 4'b0000: out <= 4'b0000; - 4'b0001: out <= 4'b0001; - 4'b0010: out <= 4'b0010; - 4'b0011: out <= 4'b0011; - 4'b0100: out <= 4'b0100; - 4'b0101: out <= 4'b1000; - 4'b0110: out <= 4'b1001; - 4'b0111: out <= 4'b1010; - 4'b1000: out <= 4'b1011; - 4'b1001: out <= 4'b1100; - default: out <= 4'b0000; - endcase + case (in) + 4'b0000: out <= 4'b0000; + 4'b0001: out <= 4'b0001; + 4'b0010: out <= 4'b0010; + 4'b0011: out <= 4'b0011; + 4'b0100: out <= 4'b0100; + 4'b0101: out <= 4'b1000; + 4'b0110: out <= 4'b1001; + 4'b0111: out <= 4'b1010; + 4'b1000: out <= 4'b1011; + 4'b1001: out <= 4'b1100; + default: out <= 4'b0000; + endcase endmodule diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/ioctrl_1.v b/Arcade_MiST/Namco Super Pacman Hardware/rtl/ioctrl_1.v index 9e12d024..1e78daeb 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/ioctrl_1.v +++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/ioctrl_1.v @@ -4,7 +4,7 @@ // Copyright (c) 2007,19 MiSTer-X //------------------------------------------ - case ( mema[4'h8] ) + case ( mema[4'h8] ) 4'h1: begin mema[4'h0] <= { 3'd0, CSTART12[2] }; @@ -17,22 +17,53 @@ mema[4'h7] <= STKTRG12[9:6]; mema[4'h9] <= 0; end - - 4'h8: begin + + // credit management + 4'h4: begin + credit_add = 0; + credit_sub = 0; + + if ( iCSTART12[2] & ( credits < 99 ) ) begin + credit_add = 8'h01; + credits = credits + 1; + end + + if ( mema[4'h9] == 0 ) begin + if ( ( credits >= 2 ) && iCSTART12[1] ) begin + credit_sub = 8'h02; + credits = credits - 2; + end else if ( ( credits >= 1 ) && iCSTART12[0] ) begin + credit_sub = 8'h01; + credits = credits - 1; + end + end + + mema[4'h0] <= credit_add; + mema[4'h1] <= credit_sub | {7'd0,CSTART12[0]}; + mema[4'h2] <= CREDIT_TENS; + mema[4'h3] <= CREDIT_ONES; + mema[4'h4] <= STKTRG12[3:0]; + mema[4'h5] <= { CSTART12[0], iCSTART12[0], STKTRG12[4], iSTKTRG12[4] }; + mema[4'h6] <= STKTRG12[9:6]; + mema[4'h7] <= { CSTART12[1], iCSTART12[1], STKTRG12[10], iSTKTRG12[10] }; + end + + 4'h8: begin // Boot up check, expected values by + // the software (Super Pacman, Motos $69, Phozon $1C) mema[4'h0] <= 4'h6; - mema[4'h1] <= 4'h9; + mema[4'h1] <= 4'h9; end default:; - - endcase + + endcase - case ( memb[4'h8] ) - + case ( memb[4'h8] ) + 4'h8: begin memb[4'h0] <= 4'h6; - memb[4'h1] <= 4'h9; + memb[4'h1] <= 4'h9; end 4'h9: begin @@ -49,5 +80,5 @@ default:; - endcase + endcase