diff --git a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon.qsf b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon.qsf index 9c1ea5be..cf4d8427 100644 --- a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon.qsf +++ b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon.qsf @@ -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 \ No newline at end of file diff --git a/Arcade_MiST/Sega Zaxxon Hardware/rtl/Zaxxon_MiST.sv b/Arcade_MiST/Sega Zaxxon Hardware/rtl/Zaxxon_MiST.sv index 43155369..ff945a71 100644 --- a/Arcade_MiST/Sega Zaxxon Hardware/rtl/Zaxxon_MiST.sv +++ b/Arcade_MiST/Sega Zaxxon Hardware/rtl/Zaxxon_MiST.sv @@ -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), diff --git a/Arcade_MiST/Sega Zaxxon Hardware/rtl/zaxxon.vhd b/Arcade_MiST/Sega Zaxxon Hardware/rtl/zaxxon.vhd index 3e08208e..94e4719a 100644 --- a/Arcade_MiST/Sega Zaxxon Hardware/rtl/zaxxon.vhd +++ b/Arcade_MiST/Sega Zaxxon Hardware/rtl/zaxxon.vhd @@ -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',