diff --git a/Arcade_MiST/IremM62 Hardware/rtl/Graphics.VHD b/Arcade_MiST/IremM62 Hardware/rtl/Graphics.VHD index ba392e2e..fee8080e 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/Graphics.VHD +++ b/Arcade_MiST/IremM62 Hardware/rtl/Graphics.VHD @@ -27,6 +27,7 @@ entity Graphics is sprite_ctl_i : in to_SPRITE_CTL_t; sprite_ctl_o : out from_SPRITE_CTL_t; spr0_hit : out std_logic; + sprite_rgb : in RGB_t; graphics_i : in to_GRAPHICS_t; graphics_o : out from_GRAPHICS_t; @@ -113,7 +114,7 @@ begin ( bitmap_ctl_o => bitmap_ctl_o_s, tilemap_ctl_o => tilemap_ctl_o_s, - sprite_rgb => sprite_ctl_i.rgb, + sprite_rgb => sprite_rgb, sprite_set => sprite_ctl_o_s.set, sprite_pri => sprite_pri, diff --git a/Arcade_MiST/IremM62 Hardware/rtl/pace.vhd b/Arcade_MiST/IremM62 Hardware/rtl/pace.vhd index 76a3cef4..8e333564 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/pace.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/pace.vhd @@ -78,6 +78,7 @@ architecture SYN of PACE is signal from_graphics : from_GRAPHICS_t; signal sprite_prom : prom_a(0 to 31); signal sprite_no : integer range 0 to PACE_VIDEO_NUM_SPRITES-1; + signal sprite_rgb : RGB_t; begin @@ -129,6 +130,7 @@ begin sprite_i => from_sprite_ctl, sprite_o => to_sprite_ctl, spr0_hit => spr0_hit, + sprite_rgb => sprite_rgb, graphics_i => from_graphics, graphics_o => to_graphics, @@ -167,6 +169,7 @@ begin sprite_ctl_i => to_sprite_ctl, sprite_ctl_o => from_sprite_ctl, spr0_hit => spr0_hit, + sprite_rgb => sprite_rgb, graphics_i => to_graphics, graphics_o => from_graphics, diff --git a/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd b/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd index 9b44a6ea..6419b504 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/platform.vhd @@ -43,6 +43,7 @@ entity platform is sprite_i : in from_SPRITE_CTL_t; sprite_o : out to_SPRITE_CTL_t; spr0_hit : in std_logic; + sprite_rgb : out RGB_t; -- various graphics information graphics_i : in from_GRAPHICS_t; @@ -124,6 +125,7 @@ architecture SYN of platform is signal sp_pal_r_wr : std_logic; signal sp_pal_g_wr : std_logic; signal sp_pal_b_wr : std_logic; + signal sprite_pal_a : std_logic_vector(7 downto 0); -- other signals signal rst_platform : std_logic; @@ -737,6 +739,14 @@ begin ); pal_b_wr <= '1' when dl_wr = '1' and dl_addr(11 downto 8) = x"5" else '0'; -- 500-5FF + sprite_pal_a <= '0' & sprite_i.pal_a(6 downto 0) when + hwsel = HW_LDRUN or + hwsel = HW_LDRUN2 or + hwsel = HW_LDRUN3 or + hwsel = HW_LDRUN4 or + hwsel = HW_BATTROAD + else sprite_i.pal_a; + -- sprite palettes sp_pal_r : entity work.dpram generic map @@ -754,10 +764,10 @@ begin q_b => open, clock_a => not clk_video, - address_a => sprite_i.pal_a, + address_a => sprite_pal_a, wren_a => '0', data_a => (others => '0'), - q_a => sprite_o.rgb.r(9 downto 2) + q_a => sprite_rgb.r(9 downto 2) ); sp_pal_r_wr <= '1' when dl_wr = '1' and dl_addr(11 downto 8) = x"0" else '0'; -- 000-0FF @@ -777,10 +787,10 @@ begin q_b => open, clock_a => not clk_video, - address_a => sprite_i.pal_a, + address_a => sprite_pal_a, wren_a => '0', data_a => (others => '0'), - q_a => sprite_o.rgb.g(9 downto 2) + q_a => sprite_rgb.g(9 downto 2) ); sp_pal_g_wr <= '1' when dl_wr = '1' and dl_addr(11 downto 8) = x"1" else '0'; -- 100-1FF @@ -800,10 +810,10 @@ begin q_b => open, clock_a => not clk_video, - address_a => sprite_i.pal_a, + address_a => sprite_pal_a, wren_a => '0', data_a => (others => '0'), - q_a => sprite_o.rgb.b(9 downto 2) + q_a => sprite_rgb.b(9 downto 2) ); sp_pal_b_wr <= '1' when dl_wr = '1' and dl_addr(11 downto 8) = x"2" else '0'; -- 200-2FF diff --git a/Arcade_MiST/IremM62 Hardware/rtl/sprite_array.vhd b/Arcade_MiST/IremM62 Hardware/rtl/sprite_array.vhd index 86c13077..99b1129c 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/sprite_array.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/sprite_array.vhd @@ -96,7 +96,6 @@ begin ctl_i(i).ld <= ld_r(i); ctl_i(i).height <= sprite_prom(to_integer(unsigned(reg_o(i).n(9 downto 5)))); ctl_i(i).d <= row_d; - ctl_i(i).rgb <= (others => (others => '0')); end generate GEN_ROW_D; -- Sprite Priority Encoder diff --git a/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg.vhd b/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg.vhd index 349dff16..960322b7 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg.vhd @@ -34,14 +34,13 @@ package sprite_pkg is function NULL_TO_SPRITE_REG return to_SPRITE_REG_t; - subtype SPRITE_ROW_D_t is std_logic_vector(63 downto 0); + subtype SPRITE_ROW_D_t is std_logic_vector(23 downto 0); subtype SPRITE_ROW_A_t is std_logic_vector(15 downto 0); type to_SPRITE_CTL_t is record ld : std_logic; d : SPRITE_ROW_D_t; height : integer range 0 to 3; - rgb : RGB_t; end record; type from_SPRITE_CTL_t is record diff --git a/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg_body.vhd b/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg_body.vhd index beed41d5..5105ef5c 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg_body.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/sprite_pkg_body.vhd @@ -11,7 +11,7 @@ package body sprite_pkg is function NULL_TO_SPRITE_CTL return to_SPRITE_CTL_t is begin - return ('0', (others => '0'), 0, (others => (others => '0'))); + return ('0', (others => '0'), 0); end function NULL_TO_SPRITE_CTL; function flip_row diff --git a/Arcade_MiST/IremM62 Hardware/rtl/spritectl.vhd b/Arcade_MiST/IremM62 Hardware/rtl/spritectl.vhd index 5f3304f4..16f0833c 100644 --- a/Arcade_MiST/IremM62 Hardware/rtl/spritectl.vhd +++ b/Arcade_MiST/IremM62 Hardware/rtl/spritectl.vhd @@ -41,35 +41,35 @@ architecture SYN of spritectl is signal ld_r : std_logic; signal left_d : std_logic; + signal hblank_r : std_logic; signal rowStore : std_logic_vector(47 downto 0); -- saved row of spt to show during visibile period + signal rowCount : unsigned(5 downto 0); + -- which part of the sprite is being drawn + alias segment : unsigned(1 downto 0) is rowCount(5 downto 4); begin - process (clk, clk_ena, left_d, reg_i) + process (clk, clk_ena, left_d, rowCount, reg_i) - variable pel : std_logic_vector(2 downto 0); - variable x : unsigned(video_ctl.x'range); - variable y : unsigned(video_ctl.y'range); - variable yMat : boolean; -- raster is between first and last line of sprite - variable xMat : boolean; -- raster in between left edge and end of line + variable pel : std_logic_vector(2 downto 0); + variable x : unsigned(video_ctl.x'range); + variable y : unsigned(video_ctl.y'range); + variable xMat : boolean; -- raster in between left edge and end of line + variable yMat : boolean; -- raster is between first and last line of sprite - variable height : unsigned(6 downto 0); + variable height : unsigned(1 downto 0); - variable rowCount : unsigned(height'range); - -- which part of the sprite is being drawn - alias segment : unsigned(1 downto 0) is rowCount(5 downto 4); - - variable code : std_logic_vector(9 downto 0); - variable pal_i : std_logic_vector(7 downto 0); + variable code : std_logic_vector(9 downto 0); begin if rising_edge(clk) then if clk_ena = '1' then ld_r <= ctl_i.ld; + hblank_r <= video_ctl.hblank; if video_ctl.hblank = '1' then - x := unsigned(reg_i.x) - video_ctl.video_h_offset + PACE_VIDEO_PIPELINE_DELAY - 3; + x := unsigned(reg_i.x) - video_ctl.video_h_offset + PACE_VIDEO_PIPELINE_DELAY - 2; y := 256 + 128 - 18 - unsigned(reg_i.y); -- hande sprite height, placement @@ -77,23 +77,33 @@ begin case ctl_i.height is when 1 => -- double height - height := to_unsigned(2*16,height'length); y := y - 16; when 2 => -- quadruple height - height := to_unsigned(4*16,height'length); y := y - 3*16; when others => - height := to_unsigned(16,height'length); + null; end case; - -- do this 1st because we don't have many clocks - if y = unsigned(video_ctl.y) then - -- start counting sprite row - rowCount := (others => '0'); - yMat := true; - elsif rowCount = height then - yMat := false; + height := to_unsigned(ctl_i.height,2); + height(0) := height (0) or height(1); + + -- count row at start of hblank + if hblank_r = '0' then + if y = unsigned(video_ctl.y) then + -- start counting sprite row + rowCount <= (others => '0'); + yMat := true; + elsif rowCount = height & "1111" then + yMat := false; + else + rowCount <= rowCount + 1; + end if; + + -- stop sprites wrapping from bottom of screen + if y = 0 then + yMat := false; + end if; end if; case ctl_i.height is @@ -115,14 +125,8 @@ begin null; end case; - xMat := false; - -- stop sprites wrapping from bottom of screen - if y = 0 then - yMat := false; - end if; - - -- sprites not visible before row 16 if ld_r = '0' and ctl_i.ld = '1' then + xMat := false; left_d <= not left_d; -- switch sprite half if yMat then if left_d = '1' then @@ -147,12 +151,7 @@ begin if video_ctl.stb = '1' then if x = unsigned(video_ctl.x) then - -- count up at left edge of sprite - rowCount := rowCount + 1; - -- start of sprite - --if unsigned(x) /= 0 and unsigned(x) < 240 then xMat := true; - --end if; end if; if xMat then @@ -172,17 +171,7 @@ begin end if; - if hwsel = HW_LDRUN or - hwsel = HW_LDRUN2 or - hwsel = HW_LDRUN3 or - hwsel = HW_LDRUN4 or - hwsel = HW_BATTROAD then - pal_i := '0' & reg_i.colour(3 downto 0) & pel; - else - pal_i := reg_i.colour(4 downto 0) & pel; - end if; - --pal_i := "000" & std_logic_vector(to_unsigned(INDEX,5)); - ctl_o.pal_a <= pal_i; + ctl_o.pal_a <= reg_i.colour(4 downto 0) & pel; -- set pixel transparency based on match ctl_o.set <= '0';