From 4645083652b0659b44bcc13feebf7b8bcea1705c Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Thu, 12 Mar 2020 18:53:04 +0100 Subject: [PATCH] IremM62: add 2nd tilemap backround, Battle Road is fully working now --- .../IremM62 Hardware/meta/Battle Road.mra | 9 +- .../rtl/iremm62_video_controller.vhd | 3 +- Arcade_MiST/IremM62 Hardware/rtl/pace.vhd | 8 +- Arcade_MiST/IremM62 Hardware/rtl/platform.vhd | 38 +++++-- .../IremM62 Hardware/rtl/platform_pkg.vhd | 2 +- Arcade_MiST/IremM62 Hardware/rtl/sdram.sv | 26 +++-- .../IremM62 Hardware/rtl/target_top.vhd | 8 +- .../IremM62 Hardware/rtl/tilemapctl.vhd | 100 +++++++++++++++++- .../IremM62 Hardware/rtl/video_mixer.vhd | 2 +- 9 files changed, 165 insertions(+), 31 deletions(-) diff --git a/Arcade_MiST/IremM62 Hardware/meta/Battle Road.mra b/Arcade_MiST/IremM62 Hardware/meta/Battle Road.mra index e1a1e3f2..4f87b99c 100644 --- a/Arcade_MiST/IremM62 Hardware/meta/Battle Road.mra +++ b/Arcade_MiST/IremM62 Hardware/meta/Battle Road.mra @@ -5,7 +5,7 @@ Irem iremm62 6 - + @@ -106,16 +106,16 @@ - + - + @@ -129,7 +129,8 @@ - FF + + FF diff --git a/Arcade_MiST/IremM62 Hardware/rtl/iremm62_video_controller.vhd b/Arcade_MiST/IremM62 Hardware/rtl/iremm62_video_controller.vhd index 99b2e4c7..4e39b3a7 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/iremm62_video_controller.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/iremm62_video_controller.vhd @@ -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'; diff --git a/Arcade_MiST/IremM62 Hardware/rtl/pace.vhd b/Arcade_MiST/IremM62 Hardware/rtl/pace.vhd index 24da3b44..799a2951 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/pace.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/pace.vhd @@ -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 diff --git a/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd b/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd index 03e32216..24826006 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd @@ -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 diff --git a/Arcade_MiST/IremM62 Hardware/rtl/platform_pkg.vhd b/Arcade_MiST/IremM62 Hardware/rtl/platform_pkg.vhd index e6dea694..2d480471 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/platform_pkg.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/platform_pkg.vhd @@ -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; diff --git a/Arcade_MiST/IremM62 Hardware/rtl/sdram.sv b/Arcade_MiST/IremM62 Hardware/rtl/sdram.sv index 3c68bc50..71eab1ea 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/sdram.sv +++ b/Arcade_MiST/IremM62 Hardware/rtl/sdram.sv @@ -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 diff --git a/Arcade_MiST/IremM62 Hardware/rtl/target_top.vhd b/Arcade_MiST/IremM62 Hardware/rtl/target_top.vhd index 4539e3d3..d0989d42 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/target_top.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/target_top.vhd @@ -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; diff --git a/Arcade_MiST/IremM62 Hardware/rtl/tilemapctl.vhd b/Arcade_MiST/IremM62 Hardware/rtl/tilemapctl.vhd index d1173ed3..ddc2535b 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/tilemapctl.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/tilemapctl.vhd @@ -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; diff --git a/Arcade_MiST/IremM62 Hardware/rtl/video_mixer.vhd b/Arcade_MiST/IremM62 Hardware/rtl/video_mixer.vhd index fb4b4aa4..123a3410 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/video_mixer.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/video_mixer.vhd @@ -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