1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-02-03 07:10:20 +00:00

Merge pull request #114 from jotego/superpac

Super Pac-Man
This commit is contained in:
Marcel
2021-03-11 16:26:42 +01:00
committed by GitHub
10 changed files with 759 additions and 554 deletions

View File

@@ -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

View File

@@ -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.
--
---------------------------------------------------------------------------------

View File

@@ -0,0 +1,38 @@
<misterromdescription>
<name>Super Pacman</name>
<mameversion>0220</mameversion>
<setname>superpac</setname>
<mratimestamp>20210307</mratimestamp>
<rbf>druaga</rbf>
<rom index="1">
<part>05</part>
</rom>
<rom index="0" zip="superpac.zip" md5="None">
<!-- main CPU -->
<part repeat="0x4000"> FF </part>
<part name="sp1-2.1c"/>
<part name="sp1-1.1b"/>
<!-- GFX2 -->
<part name="spv-2.3f"/>
<part name="spv-2.3f"/>
<part name="spv-2.3f"/>
<part name="spv-2.3f"/>
<!-- sound CPU -->
<part repeat="0x1000"> FF </part>
<part name="spc-3.1k"/>
<!-- GFX1 -->
<part name="sp1-6.3c"/>
<part name="superpac.3l"/>
<part name="superpac.3l"/>
<part name="superpac.3l"/>
<part name="superpac.3l"/>
<part name="superpac.4e"/>
<part name="superpac.3m"/>
<part name="superpac.4c"/>
</rom>
</misterromdescription>

View File

@@ -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(

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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
endmodule

View File

@@ -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

View File

@@ -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