1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-20 01:34:38 +00:00

IremM62: add Horizon

This commit is contained in:
Gyorgy Szombathelyi 2020-03-06 12:23:36 +01:00
parent fb2ac942da
commit 1de5362bd0
12 changed files with 213 additions and 81 deletions

View File

@ -164,7 +164,7 @@ set_global_assignment -name TOP_LEVEL_ENTITY IremM62_MiST
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8
set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE BALANCED
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON
set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE ON
set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008

View File

@ -0,0 +1,99 @@
<misterromdescription>
<name>Horizon</name>
<mameversion>0216</mameversion>
<setname>horizon</setname>
<manufacturer>Irem</manufacturer>
<rbf>iremm62</rbf>
<rom index="1"><part>5</part></rom>
<rom index="0" zip="horizon.zip" md5="9e4c8423a33f0c5bf558d475d89e041a" type="merged|nonmerged">
<!-- CPU1, 128k -->
<part name="hrza-4e"/>
<part name="hrza-4d"/>
<part name="hrza-4b"/>
<part name="hrza-4b"/>
<part name="hrza-4e"/>
<part name="hrza-4d"/>
<part name="hrza-4b"/>
<part name="hrza-4b"/>
<!-- SND CPU2, 64k -->
<part name="hrza-3f"/>
<part name="hrza-3f"/>
<part name="hrza-3f"/>
<part name="hrza-3f"/>
<!-- GFX1, 128k -->
<group width="32">
<part name="hrzd-4d"/>
<part name="hrzd-4c"/>
<part name="hrzd-4a"/>
<part name="hrzd-4a"/>
</group>
<group width="32">
<part name="hrzd-4d"/>
<part name="hrzd-4c"/>
<part name="hrzd-4a"/>
<part name="hrzd-4a"/>
</group>
<group width="32">
<part name="hrzd-4d"/>
<part name="hrzd-4c"/>
<part name="hrzd-4a"/>
<part name="hrzd-4a"/>
</group>
<group width="32">
<part name="hrzd-4d"/>
<part name="hrzd-4c"/>
<part name="hrzd-4a"/>
<part name="hrzd-4a"/>
</group>
<!-- GFX2, 256k -->
<group width="32">
<part name="hrzb-4k.00"/>
<part name="hrzb-3n.10"/>
<part name="hrzb-4c.20"/>
<part name="hrzb-4c.20"/>
</group>
<group width="32">
<part name="hrzb-4f.01"/>
<part name="hrzb-4n.11"/>
<part name="hrzb-4e.21"/>
<part name="hrzb-4e.21"/>
</group>
<group width="32">
<part name="hrzb-4k.00"/>
<part name="hrzb-3n.10"/>
<part name="hrzb-4c.20"/>
<part name="hrzb-4c.20"/>
</group>
<group width="32">
<part name="hrzb-4f.01"/>
<part name="hrzb-4n.11"/>
<part name="hrzb-4e.21"/>
<part name="hrzb-4e.21"/>
</group>
<!-- GFX3, 64k -->
<part repeat="0x10000">FF</part>
<!-- spr_color_proms, 3*256b -->
<part name="hrzb-1m.r"/>
<part name="hrzb-1n.g"/>
<part name="hrzb-1l.b"/>
<!-- chr_color_proms, 3*256b -->
<part name="hrzd-1d"/>
<part name="hrzd-1c"/>
<part name="hrzd-1e"/>
<!-- fg_color_proms, 3*256b -->
<part repeat="0x300">FF</part>
<!-- spr_height_prom -->
<part name="hrzb-5p"/>
</rom>
</misterromdescription>

View File

@ -7,25 +7,27 @@ USE altera_mf.all;
ENTITY dpram IS
GENERIC
(
init_file : string := "";
init_file : string := "";
--numwords_a : natural;
widthad_a : natural;
width_a : natural := 8;
outdata_reg_a : string := "UNREGISTERED";
outdata_reg_b : string := "UNREGISTERED"
widthad_a : natural;
width_a : natural := 8;
widthad_b : natural;
width_b : natural := 8;
outdata_reg_a : string := "UNREGISTERED";
outdata_reg_b : string := "UNREGISTERED"
);
PORT
(
address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (widthad_b-1 DOWNTO 0);
clock_a : IN STD_LOGIC ;
clock_b : IN STD_LOGIC ;
data_a : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (width_b-1 DOWNTO 0);
wren_a : IN STD_LOGIC := '1';
wren_b : IN STD_LOGIC := '1';
q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0)
q_b : OUT STD_LOGIC_VECTOR (width_b-1 DOWNTO 0)
);
END dpram;
@ -33,7 +35,7 @@ END dpram;
ARCHITECTURE SYN OF dpram IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
SIGNAL sub_wire1 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
SIGNAL sub_wire1 : STD_LOGIC_VECTOR (width_b-1 DOWNTO 0);
@ -72,17 +74,17 @@ ARCHITECTURE SYN OF dpram IS
wren_b : IN STD_LOGIC ;
clock1 : IN STD_LOGIC ;
address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (widthad_b-1 DOWNTO 0);
q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (width_b-1 DOWNTO 0);
data_a : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0)
data_b : IN STD_LOGIC_VECTOR (width_b-1 DOWNTO 0)
);
END COMPONENT;
BEGIN
q_a <= sub_wire0(width_a-1 DOWNTO 0);
q_b <= sub_wire1(width_a-1 DOWNTO 0);
q_b <= sub_wire1(width_b-1 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
@ -96,19 +98,19 @@ BEGIN
intended_device_family => "Cyclone III",
lpm_type => "altsyncram",
numwords_a => 2**widthad_a,
numwords_b => 2**widthad_a,
numwords_b => 2**widthad_b,
operation_mode => "BIDIR_DUAL_PORT",
outdata_aclr_a => "NONE",
outdata_aclr_b => "NONE",
outdata_reg_a => outdata_reg_a,
outdata_reg_b => outdata_reg_a,
outdata_reg_b => outdata_reg_b,
power_up_uninitialized => "FALSE",
read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ",
read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ",
widthad_a => widthad_a,
widthad_b => widthad_a,
widthad_b => widthad_b,
width_a => width_a,
width_b => width_a,
width_b => width_b,
width_byteena_a => 1,
width_byteena_b => 1,
wrcontrol_wraddress_reg_b => "CLOCK1"

View File

@ -76,6 +76,7 @@ architecture SYN of PACE is
signal to_graphics : to_GRAPHICS_t;
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;
begin
@ -127,7 +128,6 @@ begin
sprite_i => from_sprite_ctl,
sprite_o => to_sprite_ctl,
spr0_hit => spr0_hit,
graphics_i => from_graphics,
graphics_o => to_graphics,

View File

@ -56,8 +56,8 @@ entity platform is
platform_o : out to_PLATFORM_IO_t;
dl_addr : in std_logic_vector(11 downto 0);
dl_data : in std_logic_vector(7 downto 0);
dl_wr : in std_logic;
dl_data : in std_logic_vector(7 downto 0);
dl_wr : in std_logic;
cpu_rom_addr : out std_logic_vector(16 downto 0);
cpu_rom_do : in std_logic_vector(7 downto 0);
@ -99,7 +99,6 @@ architecture SYN of platform is
signal snd_cs : std_logic;
-- RAM signals
signal wram_cs : std_logic;
signal wram_wr : std_logic;
@ -174,13 +173,16 @@ begin
-- chip select logic
-- ROM $0000-$7FFF
-- $0000-$9FFF - LDRUN2
-- $0000-$BFFF - LDRUN3,4
-- $0000-$BFFF - LDRUN3,4, HORIZON
rom_cs <= '1' when STD_MATCH(cpu_a, "0---------------") else
'1' when hwsel = HW_LDRUN2 and cpu_a(15 downto 13) = "100" else
'1' when (hwsel = HW_LDRUN3 or hwsel = HW_LDRUN4) and cpu_a(15 downto 14) = "10" else
'1' when (hwsel = HW_LDRUN3 or hwsel = HW_LDRUN4 or hwsel = HW_HORIZON) and cpu_a(15 downto 14) = "10" else
'0';
-- SPRITE $C000-$C0FF
sprite_cs <= '1' when STD_MATCH(cpu_a, X"C0"& "--------") else '0';
-- $C000-$C1FF - HORIZON
sprite_cs <= '1' when cpu_a(15 downto 8) = x"C0" else
'1' when cpu_a(15 downto 9) = x"C"&"000" and hwsel = HW_HORIZON else
'0';
-- VRAM/CRAM $D000-$DFFF
vram_cs <= '1' when hwsel = HW_KUNGFUM and
STD_MATCH(cpu_a, X"D"&"0-----------") else
@ -235,7 +237,7 @@ begin
-- sprite registers
sprite_reg_o.clk <= clk_sys;
sprite_reg_o.clk_ena <= clk_3M072_en;
sprite_reg_o.a <= cpu_a(7 downto 0);
sprite_reg_o.a <= cpu_a(8 downto 0) when hwsel = HW_HORIZON else '0' & cpu_a(7 downto 0);
sprite_reg_o.d <= cpu_d_o;
sprite_reg_o.wr <= sprite_cs and cpu_mem_wr;
@ -379,7 +381,35 @@ begin
signal m62_hscroll : std_logic_vector(15 downto 0);
signal m62_vscroll : std_logic_vector(15 downto 0);
signal m62_topbottom_mask: std_logic;
signal scrollram_d_o : std_logic_vector(15 downto 0);
signal scrollram_wr : std_logic;
begin
horizon_scrollram_inst : entity work.dpram
generic map
(
init_file => "",
widthad_a => 5,
width_a => 16,
widthad_b => 6,
width_b => 8
)
port map
(
clock_b => clk_sys,
address_b => cpu_a(5 downto 0),
wren_b => scrollram_wr,
data_b => cpu_d_o,
q_b => open,
clock_a => clk_video,
address_a => tilemap_i(1).map_a(10 downto 6),
wren_a => '0',
data_a => (others => 'X'),
q_a => scrollram_d_o
);
scrollram_wr <= '1' when cpu_mem_wr = '1' and cpu_a(15 downto 6) = X"C8"&"00" else '0';
process (clk_sys, rst_sys)
begin
if rst_sys = '1' then
@ -419,11 +449,11 @@ begin
end if;
end if; -- rising_edge(clk_sys)
end process;
graphics_o.bit16(0) <= m62_hscroll;
graphics_o.bit16(0) <= scrollram_d_o when hwsel = HW_HORIZON else m62_hscroll;
graphics_o.bit16(1) <= m62_vscroll;
end block BLK_SCROLL;
BLK_GFX_ROMS : block
type gfx_rom_d_a is array(M62_CHAR_ROM'range) of std_logic_vector(7 downto 0);
@ -509,7 +539,8 @@ begin
generic map
(
init_file => "",
widthad_a => 11
widthad_a => 11,
widthad_b => 11
)
port map
(
@ -531,7 +562,8 @@ begin
generic map
(
init_file => "",
widthad_a => 11
widthad_a => 11,
widthad_b => 11
)
port map
(
@ -570,7 +602,8 @@ begin
generic map
(
init_file => "",
widthad_a => 8
widthad_a => 8,
widthad_b => 8
)
port map
(
@ -592,7 +625,8 @@ begin
generic map
(
init_file => "",
widthad_a => 8
widthad_a => 8,
widthad_b => 8
)
port map
(
@ -614,7 +648,8 @@ begin
generic map
(
init_file => "",
widthad_a => 8
widthad_a => 8,
widthad_b => 8
)
port map
(
@ -637,7 +672,8 @@ begin
generic map
(
init_file => "",
widthad_a => 8
widthad_a => 8,
widthad_b => 8
)
port map
(
@ -659,7 +695,8 @@ begin
generic map
(
init_file => "",
widthad_a => 8
widthad_a => 8,
widthad_b => 8
)
port map
(
@ -681,7 +718,8 @@ begin
generic map
(
init_file => "",
widthad_a => 8
widthad_a => 8,
widthad_b => 8
)
port map
(

View File

@ -48,7 +48,7 @@ package platform_pkg is
constant PACE_VIDEO_NUM_BITMAPS : natural := 0;
constant PACE_VIDEO_NUM_TILEMAPS : natural := 1;
constant PACE_VIDEO_NUM_SPRITES : natural := 32;
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;
constant PACE_VIDEO_L_CROP : integer := 8;

View File

@ -14,7 +14,8 @@ package platform_variant_pkg is
constant HW_LDRUN3 : integer := 2;
constant HW_LDRUN4 : integer := 3;
constant HW_KUNGFUM : integer := 4;
constant HW_BATTROAD : integer := 5;
constant HW_HORIZON : integer := 5;
constant HW_BATTROAD : integer := 6;
type rom_a is array (natural range <>) of string;

View File

@ -59,7 +59,6 @@ architecture SYN of sprite_array is
signal ctl_o : ctl_o_a_t(0 to N_SPRITES-1);
signal ld_r : std_logic_vector(N_SPRITES-1 downto 0);
signal ld_ena : std_logic;
begin
-- Sprite Data Load Arbiter
@ -72,27 +71,22 @@ begin
-- enable must be 1 clock behind address to latch data after fetch
--ld_r <= (N_SPRITES-1 => '1', others => '0');
-- make ISE 9.2.03i happy...
ld_ena <= '1';
ld_r(ld_r'left) <= '1';
ld_r(ld_r'left-1 downto 0) <= (others => '0');
i := 0;
elsif rising_edge(clk) and clk_ena = '1' then
if video_ctl.hblank = '0' then
ld_ena <= '1';
i := 0;
ld_r(ld_r'left) <= '1';
ld_r(ld_r'left-1 downto 0) <= (others => '0');
else
ld_ena <= not ld_ena;
if ld_ena = '1' then
ld_r <= ld_r(ld_r'left-1 downto 0) & ld_r(ld_r'left);
if i = N_SPRITES-1 then
i := 0;
else
i := i + 1;
end if;
row_a <= ctl_o(i).a;
ld_r <= ld_r(ld_r'left-1 downto 0) & ld_r(ld_r'left);
if (i = 31 and hwsel /= HW_HORIZON) or i = N_SPRITES-1 then
i := 0;
else
i := i + 1;
end if;
row_a <= ctl_o(i).a;
end if;
end if;
end process;

View File

@ -11,7 +11,7 @@ use work.platform_variant_pkg.all;
package sprite_pkg is
subtype SPRITE_N_t is std_logic_vector(11 downto 0);
subtype SPRITE_A_t is std_logic_vector(7 downto 0);
subtype SPRITE_A_t is std_logic_vector(8 downto 0);
subtype SPRITE_D_t is std_logic_vector(7 downto 0);
type from_SPRITE_REG_t is record
@ -33,7 +33,7 @@ package sprite_pkg is
end record;
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_A_t is std_logic_vector(15 downto 0);

View File

@ -18,7 +18,7 @@ entity spritectl is
);
port
(
hwsel : in integer;
hwsel : in integer range 0 to 15;
-- sprite registers
reg_i : in from_SPRITE_REG_t;
@ -39,8 +39,6 @@ architecture SYN of spritectl is
alias clk : std_logic is video_ctl.clk;
alias clk_ena : std_logic is video_ctl.clk_ena;
signal flipData : std_logic_vector(47 downto 0); -- flipped row data
signal ld_r : std_logic;
signal left_d : std_logic;
signal rowStore : std_logic_vector(47 downto 0); -- saved row of spt to show during visibile period
@ -49,7 +47,6 @@ begin
process (clk, clk_ena, left_d, reg_i)
-- variable rowStore : std_logic_vector(47 downto 0); -- saved row of spt to show during visibile period
variable pel : std_logic_vector(2 downto 0);
variable x : unsigned(video_ctl.x'range);
variable y : unsigned(video_ctl.y'range);
@ -57,20 +54,14 @@ begin
variable xMat : boolean; -- raster in between left edge and end of line
variable height : unsigned(6 downto 0);
-- the width of rowCount determines the scanline multipler
-- - eg. (4 downto 0) is 1:1
-- (5 downto 0) is 2:1 (scan-doubling)
-- variable rowCount : unsigned(3+PACE_VIDEO_V_SCALE downto 0);
-- alias row : unsigned(4 downto 0) is
-- rowCount(rowCount'left downto rowCount'left-4);
variable rowCount : unsigned(height'range);
alias row : unsigned(rowCount'range) is rowCount;
-- 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);
begin
if rising_edge(clk) then
@ -101,7 +92,7 @@ begin
-- start counting sprite row
rowCount := (others => '0');
yMat := true;
elsif row = height then
elsif rowCount = height then
yMat := false;
end if;
@ -134,16 +125,16 @@ begin
if ld_r = '0' and ctl_i.ld = '1' then
left_d <= not left_d; -- switch sprite half
if yMat then
if left_d = '0' then
if left_d = '1' then
-- store first half of the sprite line data
flipData(39 downto 32) <= ctl_i.d(23 downto 16);
flipData(23 downto 16) <= ctl_i.d(15 downto 8);
flipData(7 downto 0) <= ctl_i.d(7 downto 0);
rowStore(39 downto 32) <= ctl_i.d(23 downto 16);
rowStore(23 downto 16) <= ctl_i.d(15 downto 8);
rowStore( 7 downto 0) <= ctl_i.d( 7 downto 0);
else
-- load sprite data
rowStore(47 downto 32) <= flip_1(flipData(39 downto 32) & ctl_i.d(23 downto 16), reg_i.xflip);
rowStore(31 downto 16) <= flip_1(flipData(23 downto 16) & ctl_i.d(15 downto 8), reg_i.xflip);
rowStore(15 downto 0) <= flip_1(flipData( 7 downto 0) & ctl_i.d( 7 downto 0), reg_i.xflip);
rowStore(47 downto 40) <= ctl_i.d(23 downto 16);
rowStore(31 downto 24) <= ctl_i.d(15 downto 8);
rowStore(15 downto 8) <= ctl_i.d( 7 downto 0);
end if;
else
rowStore <= (others => '0');
@ -166,10 +157,17 @@ begin
if xMat then
-- shift in next pixel
pel := rowStore(rowStore'left-32) & rowStore(rowStore'left-16) & rowStore(rowStore'left);
rowStore(47 downto 32) <= rowStore(46 downto 32) & '0';
rowStore(31 downto 16) <= rowStore(30 downto 16) & '0';
rowStore(15 downto 0) <= rowStore(14 downto 0) & '0';
if reg_i.xflip = '1' then
pel := rowStore(rowStore'right) & rowStore(rowStore'right+16) & rowStore(rowStore'right+32);
rowStore(47 downto 32) <= '0' & rowStore(47 downto 33);
rowStore(31 downto 16) <= '0' & rowStore(31 downto 17);
rowStore(15 downto 0) <= '0' & rowStore(15 downto 1);
else
pel := rowStore(rowStore'left-32) & rowStore(rowStore'left-16) & rowStore(rowStore'left);
rowStore(47 downto 32) <= rowStore(46 downto 32) & '0';
rowStore(31 downto 16) <= rowStore(30 downto 16) & '0';
rowStore(15 downto 0) <= rowStore(14 downto 0) & '0';
end if;
end if;
end if;
@ -202,9 +200,9 @@ begin
ctl_o.a(14 downto 5) <= code;
ctl_o.a(4) <= left_d;
if reg_i.yflip = '0' then
ctl_o.a(3 downto 0) <= std_logic_vector(row(3 downto 0));
ctl_o.a(3 downto 0) <= std_logic_vector(rowCount(3 downto 0));
else
ctl_o.a(3 downto 0) <= not std_logic_vector(row(3 downto 0));
ctl_o.a(3 downto 0) <= not std_logic_vector(rowCount(3 downto 0));
end if;
end process;

View File

@ -30,7 +30,7 @@ begin
begin
if rising_edge(clk) then
if clk_ena = '1' then
if reg_i.a(7 downto 3) = std_logic_vector(to_unsigned(INDEX, 5)) then
if reg_i.a(8 downto 3) = std_logic_vector(to_unsigned(INDEX, 6)) then
if reg_i.wr = '1' then
case reg_i.a(2 downto 0) is
when "000" =>

View File

@ -88,7 +88,7 @@ begin
-- 2nd stage of pipeline
-- - set tile address
if x(2 downto 0) = "010" then
if hwsel = HW_LDRUN4 then
if hwsel = HW_LDRUN4 or hwsel = HW_HORIZON then
ctl_o.tile_a(13) <= ctl_i.attr_d(5);
else
ctl_o.tile_a(13) <= '0';