1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-02-03 15:12:39 +00:00

IremM62: some sprite array optimizations (but still consume huge area)

This commit is contained in:
Gyorgy Szombathelyi
2020-03-07 20:44:39 +01:00
parent 12e7c7bea1
commit 52b1f3e594
7 changed files with 59 additions and 58 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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