diff --git a/Arcade_MiST/IremM62 Hardware/meta/Spelunker 2.mra b/Arcade_MiST/IremM62 Hardware/meta/Spelunker 2.mra index fbd36ea1..e5bac53a 100644 --- a/Arcade_MiST/IremM62 Hardware/meta/Spelunker 2.mra +++ b/Arcade_MiST/IremM62 Hardware/meta/Spelunker 2.mra @@ -5,7 +5,7 @@ Irem iremm62 0A - + @@ -74,7 +74,8 @@ - FF + + FF diff --git a/Arcade_MiST/IremM62 Hardware/meta/Youjyudn.mra b/Arcade_MiST/IremM62 Hardware/meta/Youjyudn.mra new file mode 100644 index 00000000..43dbbed0 --- /dev/null +++ b/Arcade_MiST/IremM62 Hardware/meta/Youjyudn.mra @@ -0,0 +1,81 @@ + + Youjyudn + 0216 + youjyudn + Irem + iremm62 + 0B + + + + + FF + + + + FF + + + FF + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FF + + + + + + diff --git a/Arcade_MiST/IremM62 Hardware/rtl/Graphics.VHD b/Arcade_MiST/IremM62 Hardware/rtl/Graphics.VHD index 9414ce4a..0beb114e 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/Graphics.VHD +++ b/Arcade_MiST/IremM62 Hardware/rtl/Graphics.VHD @@ -14,7 +14,7 @@ use work.platform_variant_pkg.all; entity Graphics is port ( - hwsel : in integer; + hwsel : in HWSEL_t; hires : in std_logic; sprite_prom : in prom_a(0 to 31); @@ -77,6 +77,7 @@ begin ( -- clocking etc video_i => video_i, + hwsel => hwsel, hires => hires, -- video data signals (in) diff --git a/Arcade_MiST/IremM62 Hardware/rtl/iremm62_video_controller.vhd b/Arcade_MiST/IremM62 Hardware/rtl/iremm62_video_controller.vhd index 7acb218f..99b2e4c7 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/iremm62_video_controller.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/iremm62_video_controller.vhd @@ -4,12 +4,14 @@ use ieee.numeric_std.all; library work; use work.video_controller_pkg.all; +use work.platform_variant_pkg.all; entity iremm62_video_controller is port ( -- clocking etc video_i : in from_VIDEO_t; + hwsel : in HWSEL_t; hires : in std_logic; -- video input data @@ -33,7 +35,9 @@ architecture SYN of iremm62_video_controller is signal vcnt : unsigned(8 downto 0); signal hsync : std_logic; signal vsync : std_logic; - signal hblank : std_logic; + signal hblank : std_logic; -- hblank mux + signal hblank1 : std_logic; -- normal hblank + signal hblank2 : std_logic; -- shifted hblank for some games signal vblank : std_logic; begin @@ -67,18 +71,26 @@ begin if reset = '1' then hsync <= '0'; vsync <= '0'; - hblank <= '1'; + hblank1 <= '1'; + hblank2 <= '1'; vblank <= '1'; elsif rising_edge(clk) and clk_ena = '1' then -- display blank if hcnt = "00"&x"FF" then - hblank <= '0'; + hblank1 <= '0'; if vcnt = '1'&x"00" then vblank <= '0'; end if; end if; if (hires = '0' and hcnt = "01"&x"FF") or hcnt = "10"&x"7F" then - hblank <= '1'; + hblank1 <= '1'; + end if; + -- alternate blanking to hide hscroll garbage + if hcnt = "01"&x"07" then + hblank2 <= '0'; + end if; + if hcnt = "00"&x"87" then + hblank2 <= '1'; if vcnt = '1'&x"FF" then vblank <= '1'; end if; @@ -110,6 +122,7 @@ 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; 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 db242cdf..24da3b44 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/pace.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/pace.vhd @@ -17,9 +17,9 @@ entity PACE is -- clocks and resets clkrst_i : in from_CLKRST_t; cpu_clk_en_i : in std_logic; - + -- hardware variant - hwsel : in integer; + hwsel : in HWSEL_t; hires : in std_logic; -- misc I/O @@ -112,7 +112,7 @@ begin cpu_clk_en_i => cpu_clk_en_i, hwsel => hwsel, - + -- misc inputs and outputs buttons_i => buttons_i, switches_i => switches_i, diff --git a/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd b/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd index 7e4bb47e..03e32216 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd @@ -22,7 +22,7 @@ entity platform is clkrst_i : in from_CLKRST_t; cpu_clk_en_i : in std_logic; - hwsel : in integer; + hwsel : in HWSEL_t; -- misc I/O buttons_i : in from_BUTTONS_t; @@ -128,6 +128,13 @@ architecture SYN of platform is signal sp_pal_b_wr : std_logic; signal sprite_pal_a : std_logic_vector(7 downto 0); signal tilemap1_pal_a : std_logic_vector(7 downto 0); + signal pal_r_q : std_logic_vector(7 downto 0); + signal pal_g_q : std_logic_vector(7 downto 0); + signal pal_b_q : std_logic_vector(7 downto 0); + + signal pal2_r_wr : std_logic; + signal pal2_r_q : std_logic_vector(7 downto 0); + signal tilemap2_pal_a : std_logic_vector(7 downto 0); -- other signals signal rst_platform : std_logic; @@ -147,7 +154,9 @@ architecture SYN of platform is signal kidniki_bank : std_logic_vector(3 downto 0); signal kidniki_gfxbank: std_logic; + signal spelunk2_palbank : std_logic_vector(1 downto 0); signal spelunkr_palbank : std_logic; + signal spelunk2_bank1 : std_logic_vector(1 downto 0); begin @@ -187,12 +196,12 @@ begin -- chip select logic -- ROM $0000-$7FFF - -- $0000-$9FFF - LDRUN2, KIDNIKI, SPELUNKR - -- $0000-$BFFF - LDRUN3,4, HORIZON + -- $0000-$9FFF - LDRUN2, KIDNIKI, SPELUNKR, SPELUNK2 + -- $0000-$BFFF - LDRUN3,4, HORIZON, YOUJYUDN -- $A000-$BFFF - BATTROAD rom_cs <= '1' when STD_MATCH(cpu_a, "0---------------") else - '1' when (hwsel = HW_LDRUN2 or hwsel = HW_KIDNIKI or hwsel = HW_SPELUNKR) and cpu_a(15 downto 13) = "100" else - '1' when (hwsel = HW_LDRUN3 or hwsel = HW_LDRUN4 or hwsel = HW_HORIZON) and cpu_a(15 downto 14) = "10" else + '1' when (hwsel = HW_LDRUN2 or hwsel = HW_KIDNIKI or hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2) and cpu_a(15 downto 13) = "100" else + '1' when (hwsel = HW_LDRUN3 or hwsel = HW_LDRUN4 or hwsel = HW_HORIZON or hwsel = HW_YOUJYUDN) and cpu_a(15 downto 14) = "10" else '1' when hwsel = HW_BATTROAD and cpu_a(15 downto 13) = "101" else '0'; @@ -222,8 +231,8 @@ begin STD_MATCH(cpu_a, X"D"&"-----------1") else '0'; - -- Text RAM $C800-$CFFF - BATTROAD, SPELUNKR, SPELUNK2, $D000-$DFFF - KIDNIKI, $A000-$AFFF - LOTLOT - textram_cs <= '1' when (hwsel = HW_BATTROAD or hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2) and + -- Text RAM $C800-$CFFF - BATTROAD, SPELUNKR, SPELUNK2, YOUJYUDN $D000-$DFFF - KIDNIKI, $A000-$AFFF - LOTLOT + textram_cs <= '1' when (hwsel = HW_BATTROAD or hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 or hwsel = HW_YOUJYUDN) and cpu_a(15 downto 11) = x"C"&'1' else '1' when hwsel = HW_KIDNIKI and cpu_a(15 downto 12) = x"D" else @@ -319,6 +328,9 @@ begin '1' & kidniki_bank(2 downto 0) & cpu_a(12 downto 0) when hwsel = HW_BATTROAD and cpu_a(15 downto 13) = "101" else (kidniki_bank(3 downto 0) + "100") & cpu_a(12 downto 0) when hwsel = HW_KIDNIKI and cpu_a(15 downto 13) = "100" and kidniki_bank(3 downto 2) /= "11" else "10" & kidniki_bank(1 downto 0) & cpu_a(12 downto 0) when hwsel = HW_SPELUNKR and cpu_a(15 downto 13) = "100" else + "010" & spelunk2_bank1 & cpu_a(11 downto 0) when hwsel = HW_SPELUNK2 and cpu_a(15 downto 12) = x"8" else + '1' & kidniki_bank & cpu_a(11 downto 0) when hwsel = HW_SPELUNK2 and cpu_a(15 downto 12) = x"9" else + "10" & kidniki_bank(0) & cpu_a(13 downto 0) when hwsel = HW_YOUJYUDN and cpu_a(15 downto 14) = "10" else '0' & cpu_a(15 downto 0); -- Lode Runner 2 bank switching - some kind of protection, only the level number is used to select bank 0 or 1 at $8000 @@ -334,12 +346,13 @@ begin kidniki_bank <= (others => '0'); kidniki_gfxbank <= '0'; spelunkr_palbank <= '0'; + spelunk2_bank1 <= (others => '0'); elsif rising_edge(clk_sys) then if cpu_clk_en = '1' and cpu_io_wr = '1' then case cpu_a(7 downto 0) is when X"80" => ld2_bankr1 <= cpu_d_o(5 downto 0); when X"81" => ld2_bankr2 <= cpu_d_o; - when X"83" => if hwsel = HW_BATTROAD then kidniki_bank <= cpu_d_o(3 downto 0); end if; + when X"83" => if hwsel = HW_BATTROAD or hwsel = HW_YOUJYUDN then kidniki_bank <= cpu_d_o(3 downto 0); end if; when X"84" => if hwsel = HW_KIDNIKI then kidniki_gfxbank <= cpu_d_o(0); end if; -- Kidniki banks: 0-7, C-F, 8-B not used when X"85" => if hwsel = HW_KIDNIKI then kidniki_bank <= cpu_d_o(3) & (not cpu_d_o(3) and cpu_d_o(2)) & cpu_d_o(1 downto 0); end if; @@ -361,6 +374,10 @@ begin if cpu_a = x"c800" and hwsel = HW_LDRUN4 then ld24_bank <= cpu_d_o(0); end if; + if cpu_a = x"d003" and hwsel = HW_SPELUNK2 then + kidniki_bank <= cpu_d_o(5 downto 2); + spelunk2_bank1 <= cpu_d_o(7 downto 6); + end if; if cpu_a = x"d004" and hwsel = HW_SPELUNKR then kidniki_bank(1 downto 0) <= cpu_d_o(1 downto 0); end if; @@ -447,6 +464,7 @@ begin m62_vscroll <= (others => '0'); m62_vscroll2 <= (others => '0'); m62_topbottom_mask <= '0'; + spelunk2_palbank <= "00"; elsif rising_edge(clk_sys) then if hwsel = HW_LOTLOT then m62_hscroll <= std_logic_vector(to_signed(-64, m62_hscroll'length)); @@ -470,15 +488,22 @@ begin if hwsel = HW_SPELUNKR then m62_vscroll(15 downto 8) <= cpu_d_o; end if; + if hwsel = HW_SPELUNK2 then + m62_hscroll(7 downto 0) <= cpu_d_o; + end if; when x"D002" => if hwsel = HW_SPELUNKR then m62_hscroll(7 downto 0) <= cpu_d_o; end if; + if hwsel = HW_SPELUNK2 then + m62_vscroll(8) <= cpu_d_o(0); + m62_hscroll(8) <= cpu_d_o(1); + spelunk2_palbank <= cpu_d_o(3 downto 2); + end if; when x"D003" => if hwsel = HW_SPELUNKR then m62_hscroll(15 downto 8) <= cpu_d_o; end if; - when others => null; end case; @@ -491,12 +516,14 @@ begin end if; -- background 1 hscroll if (hwsel = HW_LDRUN4 and cpu_a(7 downto 0) = x"82") or - ((hwsel = HW_BATTROAD or hwsel = HW_KIDNIKI) and cpu_a(7 downto 0) = x"81") then + ((hwsel = HW_BATTROAD or hwsel = HW_KIDNIKI) and cpu_a(7 downto 0) = x"81") or + (hwsel = HW_YOUJYUDN and cpu_a(7 downto 0) = x"80") then m62_hscroll(15 downto 8) <= cpu_d_o; end if; if (hwsel = HW_LDRUN4 and cpu_a(7 downto 0) = x"83") or (hwsel = HW_BATTROAD and cpu_a(7 downto 0) = x"82") or - (hwsel = HW_KIDNIKI and cpu_a(7 downto 0) = x"80") then + (hwsel = HW_KIDNIKI and cpu_a(7 downto 0) = x"80") or + (hwsel = HW_YOUJYUDN and cpu_a(7 downto 0) = x"81") then m62_hscroll(7 downto 0) <= cpu_d_o; end if; if hwsel = HW_LDRUN3 and cpu_a(7 downto 0) = x"81" then @@ -529,8 +556,9 @@ begin -- external background ROMs gfx1_addr <= - '0' & tilemap_i(1).tile_a(14 downto 0) when hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 else + '0' & tilemap_i(1).tile_a(14 downto 0) when hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 or hwsel = HW_YOUJYUDN else '0' & kidniki_gfxbank & tilemap_i(1).tile_a(13 downto 0); + tilemap_o(1).tile_d(23 downto 0) <= gfx1_do(7 downto 0) & gfx1_do(15 downto 8) & gfx1_do(23 downto 16); -- internal background ROMs @@ -687,9 +715,22 @@ begin -- tilemap 1 palette address tilemap1_pal_a <= spelunkr_palbank & tilemap_i(1).pal_a(6 downto 0) when hwsel = HW_SPELUNKR else + spelunk2_palbank(0) & tilemap_i(1).pal_a(6 downto 0) when hwsel = HW_SPELUNK2 else '0' & tilemap_i(1).pal_a(6 downto 0) when hwsel = HW_BATTROAD else tilemap_i(1).pal_a(7 downto 0); + -- Spelunk2 uses 512 entries/palette in an odd way: + -- - red and green are stored in the first two ROMs, using the first and second half bytes + -- - blue is stored in the third and fourth ROMs, using the second half byte + + tilemap_o(1).rgb.r(9 downto 2) <= pal_g_q(3 downto 0) & pal_g_q(3 downto 0) when hwsel = HW_SPELUNK2 and spelunk2_palbank(1) = '1' else + pal_r_q(3 downto 0) & pal_r_q(3 downto 0); + tilemap_o(1).rgb.g(9 downto 2) <= pal_r_q(7 downto 4) & pal_r_q(7 downto 4) when hwsel = HW_SPELUNK2 and spelunk2_palbank(1) = '0' else + pal_g_q(7 downto 4) & pal_g_q(7 downto 4) when hwsel = HW_SPELUNK2 and spelunk2_palbank(1) = '1' else + pal_g_q(3 downto 0) & pal_g_q(3 downto 0); + tilemap_o(1).rgb.b(9 downto 2) <= pal2_r_q(3 downto 0) & pal2_r_q(3 downto 0) when hwsel = HW_SPELUNK2 and spelunk2_palbank(1) = '1' else + pal_b_q(3 downto 0) & pal_b_q(3 downto 0); + -- tilemap 1 palettes pal_r : entity work.dpram generic map @@ -703,14 +744,14 @@ begin clock_b => clk_sys, address_b => dl_addr(7 downto 0), wren_b => pal_r_wr, - data_b => dl_data(3 downto 0) & dl_data(3 downto 0), + data_b => dl_data, q_b => open, clock_a => not clk_video, address_a => tilemap1_pal_a, wren_a => '0', data_a => (others => 'X'), - q_a => tilemap_o(1).rgb.r(9 downto 2) + q_a => pal_r_q ); pal_r_wr <= '1' when dl_wr = '1' and dl_addr(11 downto 8) = x"3" else '0'; -- 300-3FF @@ -726,14 +767,14 @@ begin clock_b => clk_sys, address_b => dl_addr(7 downto 0), wren_b => pal_g_wr, - data_b => dl_data(3 downto 0) & dl_data(3 downto 0), + data_b => dl_data, q_b => open, clock_a => not clk_video, address_a => tilemap1_pal_a, wren_a => '0', data_a => (others => 'X'), - q_a => tilemap_o(1).rgb.g(9 downto 2) + q_a => pal_g_q ); pal_g_wr <= '1' when dl_wr = '1' and dl_addr(11 downto 8) = x"4" else '0'; -- 400-4FF @@ -749,17 +790,47 @@ begin clock_b => clk_sys, address_b => dl_addr(7 downto 0), wren_b => pal_b_wr, - data_b => dl_data(3 downto 0) & dl_data(3 downto 0), + data_b => dl_data, q_b => open, clock_a => not clk_video, address_a => tilemap1_pal_a, wren_a => '0', data_a => (others => 'X'), - q_a => tilemap_o(1).rgb.b(9 downto 2) + q_a => pal_b_q ); pal_b_wr <= '1' when dl_wr = '1' and dl_addr(11 downto 8) = x"5" else '0'; -- 500-5FF + -- 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 2 palettes + pal2_r : entity work.dpram + generic map + ( + init_file => "", + widthad_a => 8, + widthad_b => 8 + ) + port map + ( + clock_b => clk_sys, + address_b => dl_addr(7 downto 0), + wren_b => pal2_r_wr, + data_b => dl_data, + q_b => open, + + clock_a => not clk_video, + address_a => tilemap2_pal_a, + wren_a => '0', + data_a => (others => 'X'), + q_a => pal2_r_q + ); + pal2_r_wr <= '1' when dl_wr = '1' and dl_addr(11 downto 8) = x"6" else '0'; -- 600-6FF + + -- sprite palette address sprite_pal_a <= '0' & sprite_i.pal_a(6 downto 0) when hwsel = HW_LDRUN or hwsel = HW_LDRUN2 or diff --git a/Arcade_MiST/IremM62 Hardware/rtl/platform_variant_pkg.vhd b/Arcade_MiST/IremM62 Hardware/rtl/platform_variant_pkg.vhd index 728a190e..0fa48fe8 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/platform_variant_pkg.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/platform_variant_pkg.vhd @@ -20,6 +20,9 @@ package platform_variant_pkg is constant HW_LOTLOT : integer := 8; constant HW_SPELUNKR : integer := 9; constant HW_SPELUNK2 : integer := 10; + constant HW_YOUJYUDN : integer := 11; + + subtype HWSEL_t is integer range 0 to 11; type rom_a is array (natural range <>) of string; diff --git a/Arcade_MiST/IremM62 Hardware/rtl/sprite_array.vhd b/Arcade_MiST/IremM62 Hardware/rtl/sprite_array.vhd index db2e40d8..807353ce 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/sprite_array.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/sprite_array.vhd @@ -21,7 +21,7 @@ entity sprite_array is ( reset : in std_logic; - hwsel : in integer; + hwsel : in HWSEL_t; hires : in std_logic; sprite_prom : in prom_a(0 to 31); diff --git a/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg.vhd b/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg.vhd index 8c1fcbd0..f81083cc 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg.vhd @@ -60,7 +60,7 @@ package sprite_pkg is port ( reset : in std_logic; - hwsel : integer; + hwsel : HWSEL_t; hires : in std_logic; sprite_prom : in prom_a(0 to 31); diff --git a/Arcade_MiST/IremM62 Hardware/rtl/spritectl.vhd b/Arcade_MiST/IremM62 Hardware/rtl/spritectl.vhd index 4e1218f9..fd04f715 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/spritectl.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/spritectl.vhd @@ -18,9 +18,9 @@ entity spritectl is ); port ( - hwsel : in integer range 0 to 15; + hwsel : in HWSEL_t; hires : in std_logic; - + -- sprite registers reg_i : in from_SPRITE_REG_t; diff --git a/Arcade_MiST/IremM62 Hardware/rtl/target_top.vhd b/Arcade_MiST/IremM62 Hardware/rtl/target_top.vhd index 72e0792d..4539e3d3 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/target_top.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/target_top.vhd @@ -11,12 +11,12 @@ use work.platform_variant_pkg.all; entity target_top is port( clock_sys : in std_logic; - vid_clk_en : out std_logic; - clk_aud : in std_logic; + vid_clk_en : out std_logic; + clk_aud : in std_logic; reset_in : in std_logic; - hwsel : in integer; + hwsel : in HWSEL_t; audio_out : out std_logic_vector(11 downto 0); - usr_coin1 : in std_logic; + usr_coin1 : in std_logic; usr_coin2 : in std_logic; usr_service : in std_logic; usr_start1 : in std_logic; @@ -77,7 +77,7 @@ architecture SYN of target_top is begin - hires <= '0' when hwsel = HW_KUNGFUM or hwsel = HW_HORIZON or hwsel = HW_BATTROAD else '1'; + hires <= '0' when hwsel = HW_KUNGFUM or hwsel = HW_HORIZON or hwsel = HW_BATTROAD or hwsel = HW_YOUJYUDN else '1'; process(clock_sys) begin if rising_edge(clock_sys) then @@ -140,18 +140,18 @@ Sound_Board : entity work.Sound_Board dbg_cpu_addr => open ); -pace_inst : entity work.pace +pace_inst : entity work.pace port map( - clkrst_i => clkrst_i, - cpu_clk_en_i => cpu_clk_en, + clkrst_i => clkrst_i, + cpu_clk_en_i => cpu_clk_en, hwsel => hwsel, - hires => hires, + hires => hires, buttons_i => buttons_i, switches_i => switches_i, inputs_i => inputs_i, video_i => video_i, video_o => video_o, - sound_data_o => sound_data, + sound_data_o => sound_data, platform_i => platform_i, platform_o => platform_o, diff --git a/Arcade_MiST/IremM62 Hardware/rtl/tilemapctl.vhd b/Arcade_MiST/IremM62 Hardware/rtl/tilemapctl.vhd index 8a02dec6..d1173ed3 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/tilemapctl.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/tilemapctl.vhd @@ -14,18 +14,18 @@ use work.video_controller_pkg.all; -- -- Tile data is 2 BPP. -- -entity tilemapCtl is +entity tilemapCtl is generic ( DELAY : integer ); - port + port ( reset : in std_logic; - hwsel : in integer; + hwsel : in HWSEL_t; hires : in std_logic; - -- video control signals + -- video control signals video_ctl : in from_VIDEO_CTL_t; -- tilemap controller signals @@ -64,8 +64,9 @@ begin x <= std_logic_vector(unsigned(video_ctl.x) - 256 + 128) when unsigned(y) < 6*8 and HWSEL = HW_KUNGFUM else std_logic_vector(unsigned(video_ctl.x) - 256 + unsigned(hscroll(8 downto 0)) + 64) when hires = '1' else std_logic_vector(unsigned(video_ctl.x) - 256 + unsigned(hscroll(8 downto 0)) + 128); - y <= std_logic_vector(unsigned(video_ctl.y) - 256 + unsigned(vscroll(8 downto 0)) + 128) when hwsel = HW_SPELUNKR else - std_logic_vector(unsigned(video_ctl.y) - 256 + unsigned(vscroll(8 downto 0))); -- when rot_en = '0' else video_ctl.x; + y <= std_logic_vector(unsigned(video_ctl.y) - 256 + unsigned(vscroll(8 downto 0)) + 128) when hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 else + std_logic_vector(unsigned(video_ctl.y) - 256 + unsigned(vscroll(8 downto 0))); + -- generate pixel process (clk, clk_ena) @@ -81,48 +82,72 @@ begin -- 1st stage of pipeline -- - set tilemap, attribute address - if hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 then - -- 64x64 tilemap - ctl_o.map_a(11) <= y(8); - ctl_o.attr_a(11) <= y(8); - else - ctl_o.map_a(11) <= '0'; - ctl_o.attr_a(11) <= '0'; + if x(2 downto 0) = "000" then + if hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 then + -- 64x64 tilemap + ctl_o.map_a(11) <= y(8); + ctl_o.attr_a(11) <= y(8); + else + ctl_o.map_a(11) <= '0'; + ctl_o.attr_a(11) <= '0'; + end if; + if hwsel = HW_YOUJYUDN then + -- 8x16 tiles, 64x16 tilemap + ctl_o.map_a(10 downto 6) <= '0' & y(7 downto 4); + ctl_o.attr_a(10 downto 6) <= '0' & y(7 downto 4); + else + -- 8x8 tiles, 64x32(64) tilemap + ctl_o.map_a(10 downto 6) <= y(7 downto 3); + ctl_o.attr_a(10 downto 6) <= y(7 downto 3); + end if; + ctl_o.map_a(5 downto 0) <= x(8 downto 3); + ctl_o.attr_a(5 downto 0) <= x(8 downto 3); end if; - ctl_o.map_a(10 downto 6) <= y(7 downto 3); - ctl_o.map_a(5 downto 0) <= x(8 downto 3); - ctl_o.attr_a(10 downto 6) <= y(7 downto 3); - ctl_o.attr_a(5 downto 0) <= x(8 downto 3); -- 2nd stage of pipeline -- - set tile address - if x(2 downto 0) = "010" then - if hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 then + if x(2 downto 0) = "001" then + if hwsel = HW_SPELUNKR then ctl_o.tile_a(14) <= ctl_i.attr_d(5); + elsif hwsel = HW_SPELUNK2 then + ctl_o.tile_a(14) <= ctl_i.attr_d(7); + elsif hwsel = HW_YOUJYUDN then + ctl_o.tile_a(14) <= '1'; -- first half of the ROMs are empty else ctl_o.tile_a(14) <= '0'; end if; - if hwsel = HW_LDRUN4 or hwsel = HW_HORIZON then - ctl_o.tile_a(13) <= ctl_i.attr_d(5); - elsif hwsel = HW_KIDNIKI or hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 then - ctl_o.tile_a(13) <= ctl_i.attr_d(7); + + if hwsel = HW_YOUJYUDN then + ctl_o.tile_a(13 downto 12) <= ctl_i.attr_d(6 downto 5); + ctl_o.tile_a(11 downto 4) <= ctl_i.map_d(7 downto 0); + ctl_o.tile_a(3 downto 0) <= y(3 downto 0); else - ctl_o.tile_a(13) <= '0'; + if hwsel = HW_LDRUN4 or hwsel = HW_HORIZON then + ctl_o.tile_a(13) <= ctl_i.attr_d(5); + elsif hwsel = HW_KIDNIKI or hwsel = HW_SPELUNKR then + ctl_o.tile_a(13) <= ctl_i.attr_d(7); + elsif hwsel = HW_SPELUNK2 then + ctl_o.tile_a(13) <= ctl_i.attr_d(6); + else + ctl_o.tile_a(13) <= '0'; + end if; + if hwsel = HW_BATTROAD or hwsel = HW_SPELUNKR then + ctl_o.tile_a(12 downto 11) <= ctl_i.attr_d(6) & ctl_i.attr_d(4); + elsif hwsel = HW_KIDNIKI then + ctl_o.tile_a(12 downto 11) <= ctl_i.attr_d(6 downto 5); + elsif hwsel = HW_SPELUNK2 then + ctl_o.tile_a(12 downto 11) <= ctl_i.attr_d(5 downto 4); + else + ctl_o.tile_a(12 downto 11) <= ctl_i.attr_d(7 downto 6); + end if; + 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; - if hwsel = HW_BATTROAD or hwsel = HW_SPELUNKR or hwsel = HW_SPELUNK2 then - ctl_o.tile_a(12 downto 11) <= ctl_i.attr_d(6) & ctl_i.attr_d(4); - elsif hwsel = HW_KIDNIKI then - ctl_o.tile_a(12 downto 11) <= ctl_i.attr_d(6 downto 5); - else - ctl_o.tile_a(12 downto 11) <= ctl_i.attr_d(7 downto 6); - end if; - 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) = "100" then + if x(2 downto 0) = "111" then attr_d_r := ctl_i.attr_d(7 downto 0); if hwsel = HW_KUNGFUM or hwsel = HW_LOTLOT or