1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-19 17:27:59 +00:00

IremM62: add Spelunker 2 and Youjyudn

This commit is contained in:
Gyorgy Szombathelyi 2020-03-12 13:51:27 +01:00
parent 736121d294
commit 6203669ee0
12 changed files with 271 additions and 76 deletions

View File

@ -5,7 +5,7 @@
<manufacturer>Irem</manufacturer>
<rbf>iremm62</rbf>
<rom index="1"><part>0A</part></rom>
<rom index="0" zip="spelunk2.zip" md5="dbd20cd8f5d2555911090e62e4621920" type="merged|nonmerged">
<rom index="0" zip="spelunk2.zip" md5="4cf89df14a6987d1418ffe1fcb397d8e" type="merged|nonmerged">
<!-- CPU1, 128k -->
<part name="sp2-a.4e"/>
<part name="sp2-a.4d"/>
@ -74,7 +74,8 @@
<!--part name="sp2-r.2j"/-->
<!-- fg_color_proms, 3*256b -->
<part repeat="0x300">FF</part>
<part name="sp2-r.2j"/>
<part repeat="0x200">FF</part>
<!-- spr_height_prom -->
<part name="sp2-b.5p"/>

View File

@ -0,0 +1,81 @@
<misterromdescription>
<name>Youjyudn</name>
<mameversion>0216</mameversion>
<setname>youjyudn</setname>
<manufacturer>Irem</manufacturer>
<rbf>iremm62</rbf>
<rom index="1"><part>0B</part></rom>
<rom index="0" zip="youjyudn.zip" md5="065dce1c43e588ff6319a2c2ac0951a8" type="merged|nonmerged">
<!-- CPU1, 128k -->
<part name="yju_a4eb.bin"/>
<part name="yju_a4db.bin"/>
<part repeat="0x8000">FF</part>
<part name="yju_p4cb.0"/>
<part name="yju_p4eb.1"/>
<part repeat="0x8000">FF</part>
<!-- SND CPU2, 64k -->
<part repeat="0xC000">FF</part>
<part name="yju_a3fb.bin"/>
<!-- GFX1, 128k -->
<group width="32">
<part name="yju_p3bb.0"/>
<part name="yju_p1bb.1"/>
<part name="yju_p1cb.2"/>
<part name="yju_p1cb.2"/>
</group>
<!-- GFX2, 256k -->
<group width="32">
<part name="yju_b4ka.00"/>
<part name="yju_b3na.10"/>
<part name="yju_b4ca.20"/>
<part name="yju_b4ca.20"/>
</group>
<group width="32">
<part name="yju_b4fa.01"/>
<part name="yju_b4na.11"/>
<part name="yju_b4ea.21"/>
<part name="yju_b4ea.21"/>
</group>
<group width="32">
<part name="yju_b4ka.00"/>
<part name="yju_b3na.10"/>
<part name="yju_b4ca.20"/>
<part name="yju_b4ca.20"/>
</group>
<group width="32">
<part name="yju_b4fa.01"/>
<part name="yju_b4na.11"/>
<part name="yju_b4ea.21"/>
<part name="yju_b4ea.21"/>
</group>
<!-- GFX3, 64k -->
<group width="32">
<part name="yju_p4lb.2"/>
<part name="yju_p4mb.1"/>
<part name="yju_p4pb.0"/>
<part name="yju_p4pb.0"/>
</group>
<!-- spr_color_proms, 3*256b -->
<part name="yju_b1ma.r"/>
<part name="yju_b1na.g"/>
<part name="yju_b1la.b"/>
<!-- chr_color_proms, 3*256b -->
<part name="yju_p2jb.bpr"/>
<part name="yju_p2kb.bpr"/>
<part name="yju_p2hb.bpr"/>
<!-- fg_color_proms, 3*256b -->
<part repeat="0x300">FF</part>
<!-- spr_height_prom -->
<part name="yju_b-5p.bpr"/>
</rom>
</misterromdescription>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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