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

Zaxxon: update video hw, add pause

Fix Future Spy in flipped mode
This commit is contained in:
Gyorgy Szombathelyi 2022-11-29 18:57:04 +01:00
parent 28caaf629c
commit 6a730f910c
3 changed files with 109 additions and 60 deletions

View File

@ -40,7 +40,6 @@
# Project-Wide Assignments
# ========================
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
@ -228,4 +227,6 @@ set_global_assignment -name VERILOG_FILE rtl/Sega_Crypt.v
set_global_assignment -name QIP_FILE ../../common/mist/mist.qip
set_global_assignment -name QIP_FILE ../../common/CPU/T80/T80.qip
set_global_assignment -name SIGNALTAP_FILE output_files/zaxx.stp
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
set_global_assignment -name SMART_RECOMPILE ON
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@ -34,6 +34,7 @@ module Zaxxon_MiST(
localparam CONF_STR = {
"ZAXXON;;",
"O2,Rotate Controls,Off,On;",
"O1,Pause,Off,On;",
"O34,Scanlines,Off,25%,50%,75%;",
"O5,Blend,Off,On;",
"O6,Flip,Off,On;",
@ -43,6 +44,7 @@ localparam CONF_STR = {
"V,v2.0.",`BUILD_DATE
};
wire pause = status[1];
wire rotate = status[2];
wire [1:0] scanlines = status[4:3];
wire blend = status[5];
@ -123,7 +125,7 @@ user_io(
wire [15:0] audio_l;
wire hs, vs, cs, hb, vb;
wire blankn;
wire blankn = ~(hb | vb);
wire [2:0] g, r;
wire [1:0] b;
wire [14:0] rom_addr;
@ -226,11 +228,13 @@ wire dl_wr = ioctl_wr && ioctl_addr < 18'h28200;
zaxxon zaxxon(
.clock_24(clk_sys),
.reset(reset),
.pause(pause),
.video_r(r),
.video_g(g),
.video_b(b),
.video_blankn(blankn),
.video_hblank(hb),
.video_vblank(vb),
.video_hs(hs),
.video_vs(vs),
.video_csync(cs),

View File

@ -116,15 +116,18 @@ entity zaxxon is
port(
clock_24 : in std_logic;
reset : in std_logic;
pause : in std_logic;
-- tv15Khz_mode : in std_logic;
video_r : out std_logic_vector(2 downto 0);
video_g : out std_logic_vector(2 downto 0);
video_b : out std_logic_vector(1 downto 0);
video_clk : out std_logic;
video_csync : out std_logic;
video_blankn : out std_logic;
video_hblank : out std_logic;
video_vblank : out std_logic;
video_hs : out std_logic;
video_vs : out std_logic;
video_ce : out std_logic;
audio_out_l : out std_logic_vector(15 downto 0);
audio_out_r : out std_logic_vector(15 downto 0);
@ -177,7 +180,7 @@ architecture struct of zaxxon is
signal hflip : std_logic_vector(8 downto 0) := (others=>'0'); -- horizontal counter flip
signal vflip : std_logic_vector(8 downto 0) := (others=>'0'); -- vertical counter flip
signal hflip2 : std_logic_vector(8 downto 0) := (others=>'0'); -- horizontal counter flip
signal hs_cnt, vs_cnt :std_logic_vector(9 downto 0) ;
signal hsync0, hsync1, hsync2, hsync3, hsync4 : std_logic;
signal top_frame : std_logic := '0';
@ -208,11 +211,15 @@ architecture struct of zaxxon is
signal ch_code : std_logic_vector(7 downto 0);
signal ch_code_r : std_logic_vector(7 downto 0);
signal ch_attr : std_logic_vector(7 downto 0);
signal ch_color : std_logic_vector(3 downto 0);
signal ch_color_r : std_logic_vector(3 downto 0);
signal ch_code_line : std_logic_vector(10 downto 0);
signal ch_bit_nb : integer range 0 to 7;
signal ch_graphx1_do : std_logic_vector( 7 downto 0);
signal ch_graphx1_do_r : std_logic_vector( 7 downto 0);
signal ch_graphx2_do : std_logic_vector( 7 downto 0);
signal ch_graphx2_do_r : std_logic_vector( 7 downto 0);
signal ch_vid : std_logic_vector( 1 downto 0);
signal ch_color_addr : std_logic_vector(7 downto 0);
@ -232,10 +239,16 @@ architecture struct of zaxxon is
signal bg_graphics1_do : std_logic_vector( 7 downto 0);
signal bg_graphics2_do : std_logic_vector( 7 downto 0);
signal bg_graphics3_do : std_logic_vector( 7 downto 0);
signal bg_graphics1_do_r: std_logic_vector( 7 downto 0);
signal bg_graphics2_do_r: std_logic_vector( 7 downto 0);
signal bg_graphics3_do_r: std_logic_vector( 7 downto 0);
signal bg_bit_nb : integer range 0 to 7;
signal bg_color_a : std_logic_vector(3 downto 0);
signal bg_color_r : std_logic_vector(3 downto 0);
signal bg_color : std_logic_vector(3 downto 0);
signal bg_vid : std_logic_vector(2 downto 0);
signal bg_vid : std_logic_vector(2 downto 0);
signal bg_vid_r : std_logic_vector(2 downto 0);
signal bg_code_line : std_logic_vector(9 downto 0);
signal sp_ram_addr : std_logic_vector(7 downto 0);
signal sp_ram_we : std_logic;
@ -278,6 +291,7 @@ architecture struct of zaxxon is
signal sp_buffer_ram_we : std_logic;
signal sp_buffer_ram_di : std_logic_vector(7 downto 0);
signal sp_buffer_ram_do : std_logic_vector(7 downto 0);
signal sp_buffer_ram_do_r : std_logic_vector(7 downto 0);
signal sp_vid : std_logic_vector(7 downto 0);
@ -377,6 +391,9 @@ end process;
pix_ena <= '1' when clock_cnt(1 downto 0) = "01" else '0'; -- (6MHz)
cpu_ena <= '1' when hcnt(0) = '0' and pix_ena = '1' else '0'; -- (3MHz)
video_ce <= pix_ena;
video_clk <= clock_vid;
---------------------------------------
-- Video scanner 384x264 @6.083 MHz --
-- display 256x224 --
@ -384,8 +401,6 @@ cpu_ena <= '1' when hcnt(0) = '0' and pix_ena = '1' else '0'; -- (3MHz)
-- line : 63.13us -> 15.84kHz --
-- frame : 16.67ms -> 60.00Hz --
---------------------------------------
video_hs <= hsync0;
process (reset, clock_vid)
begin
if reset='1' then
@ -413,8 +428,6 @@ begin
-- set syncs position
if hcnt = 170 then -- tune screen H position here
hs_cnt <= (others => '0');
if vcnt = 0 then video_vs <= '0'; end if;
if vcnt = 3 then video_vs <= '1'; end if;
if (vcnt = 248) then -- tune screen V position here
vs_cnt <= (others => '0');
else
@ -424,15 +437,34 @@ begin
else
hs_cnt <= hs_cnt + 1;
end if;
if vs_cnt = 1 then video_vs <= '0';
elsif vs_cnt = 3 then video_vs <= '1';
end if;
-- blanking
video_blankn <= '0';
if (hcnt >= 256+9-5 or hcnt < 128+9-5) and
vcnt >= 17 and vcnt < 240 then video_blankn <= '1';end if;
-- video_blankn <= '0';
-- if (hcnt >= 256+9-5 or hcnt < 128+9-5) and
-- vcnt >= 17 and vcnt < 240 then video_blankn <= '1';end if;
--
if hcnt = 256+9+1 then
video_hblank <= '0';
end if;
if hcnt = 128+9+1 then
video_hblank <= '1';
end if;
if hcnt = 256+9+1 then
video_vblank <= '1';
if vcnt >= 16 and vcnt < 240 then
video_vblank <= '0';
end if;
end if;
-- build syncs pattern (composite)
if hs_cnt = 0 then hsync0 <= '0';
elsif hs_cnt = 29 then hsync0 <= '1';
if hs_cnt = 0 then hsync0 <= '0'; video_hs <= '0';
elsif hs_cnt = 29 then hsync0 <= '1'; video_hs <= '1';
end if;
if hs_cnt = 0 then hsync1 <= '0';
@ -473,8 +505,8 @@ begin
elsif vs_cnt = 10 then video_csync <= hsync1;
elsif vs_cnt = 11 then video_csync <= hsync0;
else video_csync <= hsync0;
end if;
end if;
end if;
end if;
end if;
@ -570,25 +602,27 @@ end process;
-- dmux ch_ram and sp_ram data out --
------------------------------------------
wram_we <= '1' when cpu_mreq_n = '0' and cpu_wr_n = '0' and cpu_addr(15 downto 12 ) = x"6" else '0';
ch_ram_we <= '1' when cpu_mreq_n = '0' and cpu_wr_n = '0' and (cpu_addr and x"E000") = x"8000" and hcnt(0) = '1' else '0';
ch_ram_we <= '1' when cpu_mreq_n = '0' and cpu_wr_n = '0' and (cpu_addr and x"E000") = x"8000" and hcnt(0) = '0' else '0';
sp_ram_we <= '1' when cpu_mreq_n = '0' and cpu_wr_n = '0' and (cpu_addr and x"E000") = x"A000" and hcnt(0) = '1' else '0';
flip <= flip_cpu xor flip_screen;
hflip <= hcnt when flip = '0' else not hcnt;
vflip <= vcnt when flip = '0' else not vcnt;
ch_ram_addr <= cpu_addr(9 downto 0) when hcnt(0) = '1' else vflip(7 downto 3) & hflip(7 downto 3);
ch_ram_addr <= cpu_addr(9 downto 0) when hcnt(0) = '0' else vflip(7 downto 3) & hflip(7 downto 3);
sp_ram_addr <= cpu_addr(7 downto 0) when hcnt(0) = '1' else '0'& hcnt(7 downto 1);
process (clock_vid)
begin
if rising_edge(clock_vid) then
if hcnt(0) = '1' then
ch_ram_do_to_cpu <= ch_ram_do;
sp_ram_do_to_cpu <= sp_ram_do;
else
sp_ram_do_to_sp_machine <= sp_ram_do;
end if;
if hcnt(0) = '0' then
ch_ram_do_to_cpu <= ch_ram_do;
end if;
end if;
end process;
@ -666,9 +700,10 @@ sp_hflip <= sp_code(6) when hwsel = "00" else sp_code(7);
process (clock_vid)
begin
if rising_edge(clock_vid) then
if pix_ena = '0' then
sp_vid <= sp_buffer_ram_do;
sp_buffer_ram_do_r <= sp_buffer_ram_do;
if pix_ena = '1' then
sp_vid <= sp_buffer_ram_do_r;
end if;
if hcnt = 128 then vflip_r <= vflip; end if;
@ -726,9 +761,9 @@ begin
else
if flip = '1' then
sp_bit_hpos_r <= hcnt(7 downto 0) - 5; -- tune sprite position w.r.t. background
sp_bit_hpos_r <= hcnt(7 downto 0) - 8; -- tune sprite position w.r.t. background
else
sp_bit_hpos_r <= hcnt(7 downto 0) - 2; -- tune sprite position w.r.t. background
sp_bit_hpos_r <= hcnt(7 downto 0) - 6; -- tune sprite position w.r.t. background
end if;
end if;
@ -739,45 +774,45 @@ end process;
--------------------
--- char machine ---
--------------------
ch_code <= ch_ram_do;
ch_code_line <= ch_code & vflip(2 downto 0);
ch_color_addr <= vflip(7 downto 5) & hflip(7 downto 3);
process (clock_vid)
begin
if rising_edge(clock_vid) then
if pix_ena = '1' then
if hcnt(2 downto 0) = "010" then
ch_code <= ch_ram_do;
ch_color_addr <= vflip(7 downto 5) & hflip(7 downto 3);
if hcnt(2 downto 0) = "111" then
ch_color_r <= ch_color_do(3 downto 0);
ch_graphx1_do_r <= ch_graphx1_do;
ch_graphx2_do_r <= ch_graphx2_do;
if flip = '1' then ch_bit_nb <= 0; else ch_bit_nb <= 7; end if;
else
if flip = '1' then
ch_bit_nb <= ch_bit_nb + 1;
else
ch_bit_nb <= ch_bit_nb - 1;
end if;
end if;
ch_color <= ch_color_r;
ch_vid <= ch_graphx2_do_r(ch_bit_nb) & ch_graphx1_do_r(ch_bit_nb);
end if;
end if;
end process;
ch_vid <= ch_graphx2_do(ch_bit_nb) & ch_graphx1_do(ch_bit_nb);
--------------------------
--- background machine ---
--------------------------
map_offset_h <= (bg_position & '1') + (x"0" & vflip(7 downto 0)) + 1;
-- count from "00"->"FF" and then continue with "00"->"7F" instead of "80"->"FF"
hflip2 <= hflip xor (not(hcnt(8)) & "0000000") when flip = '1' else hflip;
map_offset_l1 <= not('0' & vflip(7 downto 1)) + (hflip2(7 downto 3) & "111");
map_offset_l1 <= not('0' & vflip(7 downto 1)) + (hflip(7 downto 3) & "111") + 1;
map_offset_l2 <= map_offset_l1 + ('0' & not(flip) & flip & flip & flip & "000");
map_addr <= map_offset_h(11 downto 3) & map_offset_l2(7 downto 3);
@ -785,38 +820,47 @@ map_addr <= map_offset_h(11 downto 3) & map_offset_l2(7 downto 3);
process (clock_vid)
begin
if rising_edge(clock_vid) then
if pix_ena = '1' then
if (not(vflip(3 downto 1)) + hflip(2 downto 0)) = "000" then
bg_graphics_addr(12 downto 3) <= map2_do(1 downto 0) & map1_do; -- bg_code_line
bg_graphics_addr(2 downto 0) <= map_offset_h(2 downto 0);
bg_color_a <= map2_do(7 downto 4);
end if;
if (not(vflip(3 downto 1)) + hflip(2 downto 0)) = "011" then
if hcnt(2 downto 0) = "011" then -- 4H^
bg_color_a <= map2_do(7 downto 4);
bg_graphics_addr(2 downto 0) <= map_offset_h(2 downto 0);
bg_graphics_addr(12 downto 3) <= map2_do(1 downto 0) & map1_do;--bg_code_line;
end if;
if hcnt(2 downto 0) = "111" then -- LD7
bg_color_r <= bg_color_a;
bg_graphics1_do <= bg_graphics_do(7 downto 0);
bg_graphics2_do <= bg_graphics_do(15 downto 8);
bg_graphics3_do <= bg_graphics_do(23 downto 16);
end if;
if (not(vflip(3 downto 1)) + hflip(2 downto 0)) = "111" then
bg_graphics1_do_r <= bg_graphics1_do;
bg_graphics2_do_r <= bg_graphics2_do;
bg_graphics3_do_r <= bg_graphics3_do;
bg_color <= bg_color_r;
bg_color <= bg_color_a;
if flip = '1' then bg_bit_nb <= 0; else bg_bit_nb <= 7; end if;
else
if flip = '1' then
bg_bit_nb <= bg_bit_nb + 1;
else
bg_bit_nb <= bg_bit_nb - 1;
bg_bit_nb <= bg_bit_nb - 1;
end if;
end if;
bg_vid_r <= bg_graphics3_do_r(bg_bit_nb) & bg_graphics2_do_r(bg_bit_nb) & bg_graphics1_do_r(bg_bit_nb);
end if;
end if;
end process;
bg_vid <= bg_graphics3_do(bg_bit_nb) & bg_graphics2_do(bg_bit_nb) & bg_graphics1_do(bg_bit_nb)
when bg_enable = '1' else "000";
bg_vid <= "000" when bg_enable = '0' else
bg_graphics3_do_r(bg_bit_nb) & bg_graphics2_do_r(bg_bit_nb) & bg_graphics1_do_r(bg_bit_nb) when flip = '1' else -- hack
bg_vid_r;
--------------------------------------
-- mux char/background/sprite video --
@ -834,12 +878,12 @@ begin
end if;
if ch_vid /= "00" then
palette_addr <= ch_color_ref & ch_color_do(3 downto 0) & '0' & ch_vid;
palette_addr <= ch_color_ref & ch_color & '0' & ch_vid;
end if;
video_r <= palette_do(2 downto 0);
video_g <= palette_do(5 downto 3);
video_b <= palette_do(7 downto 6);
video_b <= palette_do(7 downto 6);
end if;
@ -857,7 +901,7 @@ port map(
RESET_n => reset_n,
CLK_n => clock_vid,
CLKEN => cpu_ena,
WAIT_n => '1',
WAIT_n => not pause,
INT_n => cpu_irq_n,
NMI_n => '1', --cpu_nmi_n,
BUSRQ_n => '1',