1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-19 17:27:59 +00:00

IremM62: add 2nd tilemap backround, Battle Road is fully working now

This commit is contained in:
Gyorgy Szombathelyi 2020-03-12 18:53:04 +01:00
parent 6203669ee0
commit 4645083652
9 changed files with 165 additions and 31 deletions

View File

@ -5,7 +5,7 @@
<manufacturer>Irem</manufacturer>
<rbf>iremm62</rbf>
<rom index="1"><part>6</part></rom>
<rom index="0" zip="battroad.zip" md5="e4dd9d396dd574a11189c2183cf4cead" type="merged|nonmerged">
<rom index="0" zip="battroad.zip" md5="4d5de2720b53b64fb63beed407cbeb19" type="merged|nonmerged">
<!-- CPU1, 128k -->
<part name="br-a-4e.b"/>
<part name="br-a-4d.b"/>
@ -106,16 +106,16 @@
<!-- GFX3, 64k -->
<group width="32">
<part name="br-c-1b"/>
<part name="br-c-1c"/>
<part name="br-c-1b"/>
<part name="br-c-1c"/>
<part name="br-c-1b"/>
</group>
<group width="32">
<part name="br-c-1b"/>
<part name="br-c-1c"/>
<part name="br-c-1b"/>
<part name="br-c-1c"/>
<part name="br-c-1b"/>
</group>
<!-- spr_color_proms, 3*256b -->
@ -129,7 +129,8 @@
<part name="br-c-3k"/>
<!-- fg_color_proms, 3*256b br-c-1j -->
<part repeat="0x300">FF</part>
<part name="br-c-1j"/>
<part repeat="0x2e0">FF</part>
<!-- spr_height_prom -->
<part name="br-b-5p"/>

View File

@ -122,7 +122,8 @@ begin
video_o.hsync <= hsync;
video_o.vsync <= vsync;
hblank <= hblank2 when hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 or hwsel = HW_KIDNIKI or hwsel = HW_HORIZON or hwsel = HW_YOUJYUDN else hblank1;
hblank <= hblank2 when hwsel = HW_BATTROAD or hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 or hwsel = HW_KIDNIKI or hwsel = HW_HORIZON or hwsel = HW_YOUJYUDN
else hblank1;
video_o.hblank <= hblank;
video_o.vblank <= vblank;
video_ctl_o.stb <= '1';

View File

@ -50,7 +50,9 @@ entity PACE is
gfx1_addr : out std_logic_vector(17 downto 2);
gfx1_do : in std_logic_vector(31 downto 0);
gfx2_addr : out std_logic_vector(17 downto 2);
gfx2_do : in std_logic_vector(31 downto 0)
gfx2_do : in std_logic_vector(31 downto 0);
gfx3_addr : out std_logic_vector(17 downto 2);
gfx3_do : in std_logic_vector(31 downto 0)
);
end entity PACE;
@ -151,7 +153,9 @@ begin
gfx1_addr => gfx1_addr,
gfx1_do => gfx1_do,
gfx2_addr => gfx2_addr,
gfx2_do => gfx2_do
gfx2_do => gfx2_do,
gfx3_addr => gfx3_addr,
gfx3_do => gfx3_do
);
graphics_inst : entity work.Graphics

View File

@ -66,7 +66,9 @@ entity platform is
gfx1_addr : out std_logic_vector(17 downto 2);
gfx1_do : in std_logic_vector(31 downto 0);
gfx2_addr : out std_logic_vector(17 downto 2);
gfx2_do : in std_logic_vector(31 downto 0)
gfx2_do : in std_logic_vector(31 downto 0);
gfx3_addr : out std_logic_vector(17 downto 2);
gfx3_do : in std_logic_vector(31 downto 0)
);
end platform;
@ -113,10 +115,12 @@ architecture SYN of platform is
signal sprite_cs : std_logic;
-- text RAM
signal textram_a : std_logic_vector(11 downto 0);
signal textram_cs : std_logic;
signal textram_wr : std_logic;
signal textram_d_o : std_logic_vector(7 downto 0);
signal textram_q : std_logic_vector(15 downto 0);
-- misc signals
signal in_cs : std_logic;
signal in_d_o : std_logic_vector(7 downto 0);
@ -561,6 +565,10 @@ begin
tilemap_o(1).tile_d(23 downto 0) <= gfx1_do(7 downto 0) & gfx1_do(15 downto 8) & gfx1_do(23 downto 16);
gfx3_addr <= '0' & tilemap_i(2).tile_a(14 downto 0);
tilemap_o(2).tile_d(23 downto 0) <= gfx3_do(7 downto 0) & gfx3_do(15 downto 8) & gfx3_do(23 downto 16);
-- internal background ROMs
-- GEN_CHAR_ROMS : for i in M62_CHAR_ROM'range generate
-- char_rom_inst : entity work.sprom
@ -625,11 +633,13 @@ begin
signal vram_a : std_logic_vector(11 downto 0);
alias cram_a : std_logic_vector(11 downto 0) is vram_a;
begin
textram_a <= '0' & cpu_a(10 downto 0) when hwsel = HW_BATTROAD else cpu_a(11 downto 0);
vram_a <= '0' & cpu_a(10 downto 0) when hwsel = HW_KUNGFUM else
cpu_a(12 downto 1) when hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 else
'0' & cpu_a(11 downto 1);
vram_inst : entity work.dpram
generic map
(
@ -681,22 +691,28 @@ begin
(
init_file => "",
widthad_a => 11,
widthad_b => 11
width_a => 16,
widthad_b => 12,
width_b => 8
)
port map
(
clock_b => clk_sys,
address_b => cpu_a(10 downto 0),
address_b => textram_a,
wren_b => textram_wr,
data_b => cpu_d_o,
q_b => textram_d_o,
clock_a => clk_video,
address_a => (others => '0'),
address_a => tilemap_i(2).map_a(10 downto 0),
wren_a => '0',
data_a => (others => 'X'),
q_a => open
q_a => textram_q
);
tilemap_o(2).attr_d(7 downto 0) <= textram_q(15 downto 8);
tilemap_o(2).map_d(7 downto 0) <= textram_q(7 downto 0);
end block BLK_VRAM;
wram_inst : entity work.spram
@ -804,7 +820,11 @@ begin
-- tilemap 2 palette address
-- Use this for Spelunk2's second blue ROM, too
tilemap2_pal_a <= spelunk2_palbank(0) & tilemap_i(1).pal_a(6 downto 0) when hwsel = HW_SPELUNK2 else
(others => '0');
tilemap_i(2).pal_a(7 downto 0);
tilemap_o(2).rgb.r(9 downto 2) <= pal2_r_q(7 downto 6) & pal2_r_q(7 downto 6) & pal2_r_q(7 downto 6) & pal2_r_q(7 downto 6);
tilemap_o(2).rgb.g(9 downto 2) <= pal2_r_q(5 downto 3) & pal2_r_q(5 downto 3) & pal2_r_q(5 downto 4);
tilemap_o(2).rgb.b(9 downto 2) <= pal2_r_q(2 downto 0) & pal2_r_q(2 downto 0) & pal2_r_q(2 downto 1);
-- tilemap 2 palettes
pal2_r : entity work.dpram

View File

@ -47,7 +47,7 @@ package platform_pkg is
constant M62_VIDEO_V_SIZE : integer := 256;
constant PACE_VIDEO_NUM_BITMAPS : natural := 0;
constant PACE_VIDEO_NUM_TILEMAPS : natural := 1;
constant PACE_VIDEO_NUM_TILEMAPS : natural := 2;
constant PACE_VIDEO_NUM_SPRITES : natural := 64;
-- constant PACE_VIDEO_H_SIZE : integer := M62_VIDEO_H_SIZE;
constant PACE_VIDEO_V_SIZE : integer := M62_VIDEO_V_SIZE;

View File

@ -62,6 +62,8 @@ module sdram (
input [19:2] chr1_addr,
output reg [31:0] chr1_q,
input [19:2] chr2_addr,
output reg [31:0] chr2_q,
input [19:2] sp_addr,
output reg [31:0] sp_q
);
@ -165,7 +167,7 @@ assign SDRAM_nWE = sd_cmd[0];
reg [24:1] addr_latch[2];
reg [24:1] addr_latch_next[2];
reg [17:1] addr_last[2];
reg [19:2] addr_last2[2];
reg [19:2] addr_last2[4];
reg [15:0] din_latch[2];
reg [1:0] oe_latch;
reg [1:0] we_latch;
@ -174,15 +176,16 @@ reg [1:0] ds[2];
reg port1_state;
reg port2_state;
localparam PORT_NONE = 2'd0;
localparam PORT_CPU1 = 2'd1;
localparam PORT_CPU2 = 2'd2;
localparam PORT_SP = 2'd1;
localparam PORT_CHR1 = 2'd2;
localparam PORT_REQ = 2'd3;
localparam PORT_NONE = 3'd0;
localparam PORT_CPU1 = 3'd1;
localparam PORT_CPU2 = 3'd2;
localparam PORT_SP = 3'd1;
localparam PORT_CHR1 = 3'd2;
localparam PORT_CHR2 = 3'd3;
localparam PORT_REQ = 3'd4;
reg [1:0] next_port[2];
reg [1:0] port[2];
reg [2:0] next_port[2];
reg [2:0] port[2];
reg refresh;
reg [10:0] refresh_cnt;
@ -219,6 +222,9 @@ always @(*) begin
end else if (chr1_addr != addr_last2[PORT_CHR1]) begin
next_port[1] = PORT_CHR1;
addr_latch_next[1] = { 1'b1, 4'd0, chr1_addr, 1'b0 };
end else if (chr2_addr != addr_last2[PORT_CHR2]) begin
next_port[1] = PORT_CHR2;
addr_latch_next[1] = { 1'b1, 4'd0, chr2_addr, 1'b0 };
end else begin
next_port[1] = PORT_NONE;
addr_latch_next[1] = addr_latch[1];
@ -346,6 +352,7 @@ always @(posedge clk) begin
PORT_REQ : port2_q[15:0] <= sd_din;
PORT_SP : sp_q[15:0] <= sd_din;
PORT_CHR1: chr1_q[15:0] <= sd_din;
PORT_CHR2: chr2_q[15:0] <= sd_din;
default: ;
endcase;
end
@ -357,6 +364,7 @@ always @(posedge clk) begin
PORT_REQ : begin port2_q[31:16] <= sd_din; port2_ack <= port2_req; end
PORT_SP : begin sp_q[31:16] <= sd_din; end
PORT_CHR1 : begin chr1_q[31:16] <= sd_din; end
PORT_CHR2 : begin chr2_q[31:16] <= sd_din; end
default: ;
endcase;
end

View File

@ -53,7 +53,9 @@ entity target_top is port(
gfx1_addr : out std_logic_vector(17 downto 2);
gfx1_do : in std_logic_vector(31 downto 0);
gfx2_addr : out std_logic_vector(17 downto 2);
gfx2_do : in std_logic_vector(31 downto 0)
gfx2_do : in std_logic_vector(31 downto 0);
gfx3_addr : out std_logic_vector(17 downto 2);
gfx3_do : in std_logic_vector(31 downto 0)
);
end target_top;
@ -164,7 +166,9 @@ pace_inst : entity work.pace
gfx1_addr => gfx1_addr,
gfx1_do => gfx1_do,
gfx2_addr => gfx2_addr,
gfx2_do => gfx2_do
gfx2_do => gfx2_do,
gfx3_addr => gfx3_addr,
gfx3_do => gfx3_do
);
inputs_i.jamma_n.coin(1) <= not usr_coin1;

View File

@ -181,9 +181,9 @@ begin
-- pal_rgb(0)(7 downto 5) /= "000" or
-- pal_rgb(1)(7 downto 5) /= "000" or
-- pal_rgb(2)(7 downto 5) /= "000" then
if graphics_i.bit8(0)(3) = '1' then
-- if graphics_i.bit8(0)(3) = '1' then
ctl_o.set <= '1';
end if;
-- end if;
-- end if;
end if; -- clk_ena
@ -192,3 +192,99 @@ begin
end process;
end architecture TILEMAP_1;
-- Irem M62 second tilemap background
architecture TILEMAP_2 of tilemapCtl is
alias clk : std_logic is video_ctl.clk;
alias clk_ena : std_logic is video_ctl.clk_ena;
alias stb : std_logic is video_ctl.stb;
alias hblank : std_logic is video_ctl.hblank;
alias vblank : std_logic is video_ctl.vblank;
signal x : std_logic_vector(video_ctl.x'range);
signal y : std_logic_vector(video_ctl.y'range);
alias rot_en : std_logic is graphics_i.bit8(0)(0);
alias hscroll : std_logic_vector(15 downto 0) is graphics_i.bit16(0);
alias vscroll : std_logic_vector(15 downto 0) is graphics_i.bit16(1);
begin
ctl_o.rgb <= ctl_i.rgb;
--ctl_o.rgb.r <= x"aa"&"10";
-- not used
ctl_o.map_a(ctl_o.map_a'left downto 10) <= (others => '0');
ctl_o.attr_a(ctl_o.attr_a'left downto 10) <= (others => '0');
ctl_o.tile_a(ctl_o.tile_a'left downto 15) <= (others => '0');
-- tilemap scroll
x <= std_logic_vector(unsigned(video_ctl.x) - 256 + 64) when hires = '1' else
std_logic_vector(unsigned(video_ctl.x) - 256);
y <= std_logic_vector(unsigned(video_ctl.y) - 256 + 128) when hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 else
std_logic_vector(unsigned(video_ctl.y) - 256);
-- generate pixel
process (clk, clk_ena)
variable tile_d_r : std_logic_vector(23 downto 0);
variable attr_d_r : std_logic_vector(7 downto 0);
variable flipx : std_logic;
variable pel : std_logic_vector(2 downto 0);
begin
if rising_edge(clk) then
if clk_ena = '1' then
-- 1st stage of pipeline
-- - set tilemap, attribute address
if x(2 downto 0) = "000" then
-- 8x8 tiles, 32x32 tilemap
ctl_o.map_a(9 downto 5) <= y(7 downto 3);
ctl_o.attr_a(9 downto 5) <= y(7 downto 3);
ctl_o.map_a(4 downto 0) <= x(7 downto 3);
ctl_o.attr_a(4 downto 0) <= x(7 downto 3);
end if;
-- 2nd stage of pipeline
-- - set tile address
if x(2 downto 0) = "001" then
ctl_o.tile_a(14) <= '0';
ctl_o.tile_a(13) <= '0';
ctl_o.tile_a(12 downto 11) <= ctl_i.attr_d(6) & ctl_i.attr_d(4);
ctl_o.tile_a(10 downto 3) <= ctl_i.map_d(7 downto 0);
ctl_o.tile_a(2 downto 0) <= y(2 downto 0);
end if;
-- 3rd stage of pipeline
-- - read tile, attribute data from ROM
if x(2 downto 0) = "111" then
attr_d_r := ctl_i.attr_d(7 downto 0);
tile_d_r := ctl_i.tile_d(tile_d_r'range);
elsif stb = '1' then
tile_d_r := tile_d_r(tile_d_r'left-1 downto 0) & '0';
end if;
-- extract R,G,B from colour palette
pel := tile_d_r(tile_d_r'left-16) & tile_d_r(tile_d_r'left-8) & tile_d_r(tile_d_r'left);
ctl_o.pal_a <= "00" & attr_d_r(3 downto 0) & pel(1 downto 0);
ctl_o.set <= '0'; -- default
if hwsel = HW_BATTROAD and pel /= "000" then
-- pal_rgb(0)(7 downto 5) /= "000" or
-- pal_rgb(1)(7 downto 5) /= "000" or
-- pal_rgb(2)(7 downto 5) /= "000" then
-- if graphics_i.bit8(0)(3) = '1' then
ctl_o.set <= '1';
end if;
-- end if;
end if; -- clk_ena
end if; -- rising_edge_clk
end process;
end architecture TILEMAP_2;

View File

@ -53,8 +53,8 @@ begin
bg_rgb;
elsif PACE_VIDEO_NUM_TILEMAPS = 2 generate
rgb_o <= sprite_rgb when sprite_set = '1' and sprite_pri = '1' else
tilemap_ctl_o(1).rgb when tilemap_ctl_o(1).set = '1' else
tilemap_ctl_o(2).rgb when tilemap_ctl_o(2).set = '1' else
tilemap_ctl_o(1).rgb when tilemap_ctl_o(1).set = '1' else
sprite_rgb when sprite_set = '1' else
bg_rgb;
else generate