diff --git a/Arcade_MiST/Midway MCR 2/MCR2/README.txt b/Arcade_MiST/Midway MCR 2/MCR2/README.txt index 2afe03e4..1c84ed26 100644 --- a/Arcade_MiST/Midway MCR 2/MCR2/README.txt +++ b/Arcade_MiST/Midway MCR 2/MCR2/README.txt @@ -16,6 +16,11 @@ -- Copy the ROM files to the root of the SD Card. -- -- MRA utilty: https://github.com/sebdel/mra-tools-c +-- +-- Some games are storing settings/high scores in a non-volatile RAM. It can be saved to +-- the SD Card with the "Save NVRAM" option in the OSD menu. It'll be restored when +-- the core is loaded next time. +-- --------------------------------------------------------------------------------- -- DE10_lite Top level for Satan Hollow (Midway MCR) by Dar (darfpga@aol.fr) (19/10/2019) -- http://darfpga.blogspot.fr diff --git a/Arcade_MiST/Midway MCR 2/MCR2/rtl/MCR2_MiST.sv b/Arcade_MiST/Midway MCR 2/MCR2/rtl/MCR2_MiST.sv index 11173d70..d6add4b2 100644 --- a/Arcade_MiST/Midway MCR 2/MCR2/rtl/MCR2_MiST.sv +++ b/Arcade_MiST/Midway MCR 2/MCR2/rtl/MCR2_MiST.sv @@ -52,13 +52,14 @@ module MCR2_MiST( wire [6:0] core_mod; localparam CONF_STR = { - `CORE_NAME,";ROM;", + `CORE_NAME,";;", "O2,Rotate Controls,Off,On;", "O5,Blend,Off,On;", "O6,Swap Joysticks,Off,On;", "O4,Spinner speed,Low,High;", "DIP;", "O7,Service,Off,On;", + "R2048,Save NVRAM;", "T0,Reset;", "V,v2.0.",`BUILD_DATE }; @@ -202,10 +203,12 @@ wire [15:0] rom_do; wire [13:0] snd_addr; wire [15:0] snd_do; wire ioctl_downl; +wire ioctl_upl; wire [7:0] ioctl_index; wire ioctl_wr; wire [24:0] ioctl_addr; wire [7:0] ioctl_dout; +wire [7:0] ioctl_din; /* ROM structure 00000 - 0BFFF 48k CPU1 @@ -219,11 +222,14 @@ data_io data_io( .SPI_SCK ( SPI_SCK ), .SPI_SS2 ( SPI_SS2 ), .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), .ioctl_download( ioctl_downl ), + .ioctl_upload ( ioctl_upl ), .ioctl_index ( ioctl_index ), .ioctl_wr ( ioctl_wr ), .ioctl_addr ( ioctl_addr ), - .ioctl_dout ( ioctl_dout ) + .ioctl_dout ( ioctl_dout ), + .ioctl_din ( ioctl_din ) ); reg port1_req, port2_req; sdram sdram( @@ -261,7 +267,7 @@ always @(posedge clk_sys) begin ioctl_wr_last <= ioctl_wr; if (ioctl_downl) begin - if (~ioctl_wr_last && ioctl_wr) begin + if (~ioctl_wr_last && ioctl_wr && ioctl_index == 0) begin port1_req <= ~port1_req; port2_req <= ~port2_req; end @@ -310,8 +316,10 @@ satans_hollow satans_hollow( .snd_rom_do ( snd_addr[0] ? snd_do[15:8] : snd_do[7:0] ), .dl_addr ( ioctl_addr[16:0]), - .dl_wr ( ioctl_wr ), - .dl_data ( ioctl_dout ) + .dl_wr ( ioctl_wr && ioctl_index == 0 ), + .dl_data ( ioctl_dout ), + .up_data ( ioctl_din ), + .cmos_wr ( ioctl_wr && ioctl_index == 8'hff ) ); wire vs_out; diff --git a/Arcade_MiST/Midway MCR 2/MCR2/rtl/satans_hollow.vhd b/Arcade_MiST/Midway MCR 2/MCR2/rtl/satans_hollow.vhd index beaf5ba0..ccf8d6cf 100644 --- a/Arcade_MiST/Midway MCR 2/MCR2/rtl/satans_hollow.vhd +++ b/Arcade_MiST/Midway MCR 2/MCR2/rtl/satans_hollow.vhd @@ -169,7 +169,9 @@ port( dl_addr : in std_logic_vector(16 downto 0); dl_wr : in std_logic; - dl_data : in std_logic_vector( 7 downto 0) + dl_data : in std_logic_vector( 7 downto 0); + up_data : out std_logic_vector(7 downto 0); + cmos_wr : in std_logic ); end satans_hollow; @@ -673,14 +675,19 @@ cpu_rom_addr <= cpu_addr(15 downto 0); cpu_rom_rd <= '1' when cpu_mreq_n = '0' and cpu_rd_n = '0' and cpu_addr(15 downto 12) < X"C" else '0'; -- working RAM 0xC000-0xC7FF + mirroring adresses -wram : entity work.cmos_ram +wram : entity work.dpram generic map( dWidth => 8, aWidth => 11) port map( - clk => clock_vidn, - we => wram_we, - addr => cpu_addr(10 downto 0), - d => cpu_do, - q => wram_do + clk_a => clock_vidn, + addr_a => cpu_addr(10 downto 0), + d_a => cpu_do, + we_a => wram_we, + q_a => wram_do, + clk_b => clock_vid, + we_b => cmos_wr, + addr_b => dl_addr(10 downto 0), + d_b => dl_data, + q_b => up_data ); -- video RAM 0xE800-0xEFFF + mirroring adresses diff --git a/Arcade_MiST/Midway MCR 3/README.txt b/Arcade_MiST/Midway MCR 3/README.txt index a8985032..6fea4d30 100644 --- a/Arcade_MiST/Midway MCR 3/README.txt +++ b/Arcade_MiST/Midway MCR 3/README.txt @@ -71,6 +71,10 @@ Copy the ROM files to the root of the SD Card. MRA utilty: https://github.com/sebdel/mra-tools-c +Some games are storing settings/high scores in a non-volatile RAM. It can be saved to +the SD Card with the "Save NVRAM" option in the OSD menu. It'll be restored when +the core is loaded next time. + Based on Darfpga's work: --------------------------------------------------------------------------------- -- DE10_lite Top level for Timber (Midway MCR) by Dar (darfpga@aol.fr) (22/11/2019) diff --git a/Arcade_MiST/Midway MCR 3/rtl/MCR3_MiST.sv b/Arcade_MiST/Midway MCR 3/rtl/MCR3_MiST.sv index 65c17508..e7b7061d 100644 --- a/Arcade_MiST/Midway MCR 3/rtl/MCR3_MiST.sv +++ b/Arcade_MiST/Midway MCR 3/rtl/MCR3_MiST.sv @@ -54,12 +54,13 @@ module MCR3_MiST( wire [6:0] core_mod; localparam CONF_STR = { - `CORE_NAME,";ROM;", + `CORE_NAME,";;", "O2,Rotate Controls,Off,On;", "O5,Blend,Off,On;", "O6,Swap Joystick,Off,On;", "DIP;", "O7,Service,Off,On;", + "R2048,Save NVRAM;", "T0,Reset;", "V,v1.1.",`BUILD_DATE }; @@ -220,10 +221,12 @@ user_io( ); wire ioctl_downl; +wire ioctl_upl; wire [7:0] ioctl_index; wire ioctl_wr; wire [24:0] ioctl_addr; wire [7:0] ioctl_dout; +wire [7:0] ioctl_din; /* ROM structure: @@ -249,10 +252,12 @@ data_io #(.ROM_DIRECT_UPLOAD(1)) data_io( .SPI_DI ( SPI_DI ), .SPI_DO ( SPI_DO ), .ioctl_download( ioctl_downl ), + .ioctl_upload ( ioctl_upl ), .ioctl_index ( ioctl_index ), .ioctl_wr ( ioctl_wr ), .ioctl_addr ( ioctl_addr ), - .ioctl_dout ( ioctl_dout ) + .ioctl_dout ( ioctl_dout ), + .ioctl_din ( ioctl_din ) ); wire [15:0] rom_addr; @@ -328,7 +333,7 @@ always @(posedge clk_sys) begin ioctl_wr_last <= ioctl_wr; if (ioctl_downl) begin - if (~ioctl_wr_last && ioctl_wr) begin + if (~ioctl_wr_last && ioctl_wr && ioctl_index == 0) begin port1_req <= ~port1_req; port2_req <= ~port2_req; end @@ -397,9 +402,11 @@ mcr3 mcr3 ( .sp_addr ( sp_addr ), .sp_graphx32_do ( sp_do ), - .dl_addr(ioctl_addr-gfx1_offset), - .dl_data(ioctl_dout), - .dl_wr(ioctl_wr) + .dl_addr ( ioctl_addr-(ioctl_index == 0 ? gfx1_offset : 0) ), + .dl_data ( ioctl_dout ), + .dl_wr ( ioctl_wr && ioctl_index == 0 ), + .up_data ( ioctl_din ), + .cmos_wr ( ioctl_wr && ioctl_index == 8'hff ) ); wire vs_out; diff --git a/Arcade_MiST/Midway MCR 3/rtl/mcr3.vhd b/Arcade_MiST/Midway MCR 3/rtl/mcr3.vhd index 0ea8fa7f..2348fc32 100644 --- a/Arcade_MiST/Midway MCR 3/rtl/mcr3.vhd +++ b/Arcade_MiST/Midway MCR 3/rtl/mcr3.vhd @@ -174,7 +174,9 @@ port( -- internal ROM download dl_addr : in std_logic_vector(18 downto 0); dl_data : in std_logic_vector(7 downto 0); - dl_wr : in std_logic + dl_wr : in std_logic; + up_data : out std_logic_vector(7 downto 0); + cmos_wr : in std_logic ); end mcr3; @@ -741,14 +743,19 @@ begin end process; -- working RAM 0xE000-0xE7FF -wram : entity work.cmos_ram +wram : entity work.dpram generic map( dWidth => 8, aWidth => 11) port map( - clk => clock_vidn, - we => wram_we, - addr => cpu_addr(10 downto 0), - d => cpu_do, - q => wram_do + clk_a => clock_vidn, + addr_a => cpu_addr(10 downto 0), + d_a => cpu_do, + we_a => wram_we, + q_a => wram_do, + clk_b => clock_vid, + we_b => cmos_wr, + addr_b => dl_addr(10 downto 0), + d_b => dl_data, + q_b => up_data ); -- video RAM 0xF000-0xF7FF diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/README.txt b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/README.txt index a84f2a73..05bccbd0 100644 --- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/README.txt +++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/README.txt @@ -23,7 +23,10 @@ C SPACE : Shift X Z : Oil Y X : Smoke - +-- The settings in the service mode can be preserved by choosing the "Save NVRAM" +-- option in the OSD menu. It'll be saved to a .RAM file, and restored when the core +-- is loaded. +-- --------------------------------------------------------------------------------- -- DE10_lite Top level for Spy hunter (Midway MCR) by Dar (darfpga@aol.fr) (06/12/2019) -- http://darfpga.blogspot.fr diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.qsf b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.qsf index 1166b57b..7a8b80e7 100644 --- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.qsf +++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.qsf @@ -41,7 +41,7 @@ # ======================== 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 LAST_QUARTUS_VERSION "13.1 SP4.26" set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" # Pin & Location Assignments @@ -214,7 +214,7 @@ set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name ENABLE_SIGNALTAP OFF -set_global_assignment -name USE_SIGNALTAP_FILE output_files/csd.stp +set_global_assignment -name USE_SIGNALTAP_FILE output_files/cmos.stp set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" @@ -241,4 +241,6 @@ set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip set_global_assignment -name VHDL_FILE ../../../common/Sound/ym2149/vol_table_array.vhd set_global_assignment -name VHDL_FILE ../../../common/Sound/ym2149/YM2149.vhd set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip +set_global_assignment -name SIGNALTAP_FILE output_files/cmos.stp +set_location_assignment PIN_90 -to SPI_SS4 set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.sdc b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.sdc index e1813b4a..25ca3af5 100644 --- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.sdc +++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.sdc @@ -88,11 +88,11 @@ set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_ # Set Output Delay #************************************************************** -set_output_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}] -set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_L}] -set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_R}] -set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {LED}] -set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {VGA_*}] +set_output_delay -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}] +set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_L}] +set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_R}] +set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {LED}] +set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {VGA_*}] set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] @@ -116,6 +116,9 @@ set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks set_multicycle_path -to {VGA_*[*]} -setup 2 set_multicycle_path -to {VGA_*[*]} -hold 1 +set_multicycle_path -from [get_clocks $sys_clk] -to [get_clocks $sdram_clk] -setup 2 +set_multicycle_path -from [get_clocks $sys_clk] -to [get_clocks $sdram_clk] -hold 1 + #************************************************************** # Set Maximum Delay #************************************************************** diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/SpyHunter_MiST.sv b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/SpyHunter_MiST.sv index dda40f9f..b8f5518c 100644 --- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/SpyHunter_MiST.sv +++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/SpyHunter_MiST.sv @@ -26,10 +26,11 @@ module SpyHunter_MiST( output AUDIO_L, output AUDIO_R, input SPI_SCK, - output SPI_DO, + inout SPI_DO, input SPI_DI, input SPI_SS2, input SPI_SS3, + input SPI_SS4, input CONF_DATA0, input CLOCK_27, output [12:0] SDRAM_A, @@ -54,6 +55,7 @@ localparam CONF_STR = { "O6,Service,Off,On;", "O8,Demo Sounds,Off,On;", "O9,Show Lamps,Off,On;", + "R2048,Save NVRAM;", "T0,Reset;", "V,v1.1.",`BUILD_DATE }; @@ -91,7 +93,8 @@ wire [7:0] key_code; wire key_strobe; user_io #( - .STRLEN(($size(CONF_STR)>>3))) + .STRLEN(($size(CONF_STR)>>3)), + .ROM_DIRECT_UPLOAD(1'b1)) user_io( .clk_sys (clk_sys ), .conf_str (CONF_STR ), @@ -121,21 +124,29 @@ wire [15:0] csd_do; wire [14:0] sp_addr; wire [31:0] sp_do; wire ioctl_downl; +wire ioctl_upl; wire [7:0] ioctl_index; wire ioctl_wr; wire [24:0] ioctl_addr; wire [7:0] ioctl_dout; +wire [7:0] ioctl_din; -data_io data_io( +data_io #( + .ROM_DIRECT_UPLOAD(1'b1)) +data_io( .clk_sys ( clk_sys ), .SPI_SCK ( SPI_SCK ), .SPI_SS2 ( SPI_SS2 ), + .SPI_SS4 ( SPI_SS4 ), .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), .ioctl_download( ioctl_downl ), + .ioctl_upload ( ioctl_upl ), .ioctl_index ( ioctl_index ), .ioctl_wr ( ioctl_wr ), .ioctl_addr ( ioctl_addr ), - .ioctl_dout ( ioctl_dout ) + .ioctl_dout ( ioctl_dout ), + .ioctl_din ( ioctl_din ) ); // ROM structure: @@ -200,7 +211,7 @@ always @(posedge clk_sys) begin ioctl_wr_last <= ioctl_wr; if (ioctl_downl) begin - if (~ioctl_wr_last && ioctl_wr) begin + if (~ioctl_wr_last && ioctl_wr && ioctl_index == 0) begin port1_req <= ~port1_req; port2_req <= ~port2_req; end @@ -281,7 +292,9 @@ spy_hunter spy_hunter( .sp_graphx32_do ( sp_do ), .dl_addr ( ioctl_addr[18:0]), .dl_data ( ioctl_dout ), - .dl_wr ( ioctl_wr ) + .dl_wr ( ioctl_wr && ioctl_index == 0 ), + .up_data ( ioctl_din ), + .cmos_wr ( ioctl_wr && ioctl_index == 8'hff ) ); wire vs_out; diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter.vhd b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter.vhd index 36bfc47f..9099b961 100644 --- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter.vhd +++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter.vhd @@ -185,6 +185,8 @@ port( dl_addr : in std_logic_vector(18 downto 0); dl_data : in std_logic_vector(7 downto 0); dl_wr : in std_logic; + up_data : out std_logic_vector(7 downto 0); + cmos_wr : in std_logic; dbg_cpu_addr : out std_logic_vector(15 downto 0) ); @@ -938,14 +940,19 @@ port map ( --); -- working RAM F000-F7FF 2Ko -wram : entity work.cmos_ram +wram : entity work.dpram generic map( dWidth => 8, aWidth => 11) port map( - clk => clock_vidn, - we => wram_we, - addr => cpu_addr(10 downto 0), - d => cpu_do, - q => wram_do + clk_a => clock_vidn, + addr_a => cpu_addr(10 downto 0), + d_a => cpu_do, + we_a => wram_we, + q_a => wram_do, + clk_b => clock_vid, + we_b => cmos_wr, + addr_b => dl_addr(10 downto 0), + d_b => dl_data, + q_b => up_data ); -- char RAM E800-EBFF 1Ko + mirroring 0400 diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/ReadMe.txt b/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/ReadMe.txt index 57f083ff..a2db5f0d 100644 --- a/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/ReadMe.txt +++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/ReadMe.txt @@ -13,6 +13,10 @@ -- -- MRA utility: https://github.com/sebdel/mra-tools-c/ -- +-- Defender stores its settings and the high score table in a non-volatile RAM. +-- It can be saved to the SD Card with the "Save NVRAM" OSD option, and it'll +-- be restored next time the core is loaded. +-- --------------------------------------------------------------------------------- -- A simulation model of Williams 6809 hardware -- by Dar (darfpga@aol.fr) diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/Defender_MiST.sv b/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/Defender_MiST.sv index 042e85af..8b25a995 100644 --- a/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/Defender_MiST.sv +++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/Defender_MiST.sv @@ -37,11 +37,12 @@ module Defender_MiST( `define CORE_NAME "DEFENDER" localparam CONF_STR = { - `CORE_NAME,";ROM;", + `CORE_NAME,";;", "O2,Rotate Controls,Off,On;", "O34,Scanlines,Off,25%,50%,75%;", "O5,Blend,Off,On;", "DIP;", + "R256,Save NVRAM;", "T0,Reset;", "V,v1.2.",`BUILD_DATE }; @@ -185,10 +186,12 @@ user_io( ); wire ioctl_downl; +wire ioctl_upl; wire [7:0] ioctl_index; wire ioctl_wr; wire [24:0] ioctl_addr; wire [7:0] ioctl_dout; +wire [7:0] ioctl_din; /* ROM Structure: @@ -201,11 +204,14 @@ data_io data_io ( .SPI_SCK ( SPI_SCK ), .SPI_SS2 ( SPI_SS2 ), .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), .ioctl_download( ioctl_downl ), + .ioctl_upload ( ioctl_upl ), .ioctl_index ( ioctl_index ), .ioctl_wr ( ioctl_wr ), .ioctl_addr ( ioctl_addr ), - .ioctl_dout ( ioctl_dout ) + .ioctl_dout ( ioctl_dout ), + .ioctl_din ( ioctl_din ) ); reg port1_req, port2_req; @@ -252,7 +258,7 @@ always @(posedge clk_sys) begin reg snd_vma_r, snd_vma_r2; ioctl_wr_last <= ioctl_wr; - if (ioctl_downl) begin + if (ioctl_downl && ioctl_index == 0) begin if (~ioctl_wr_last && ioctl_wr) begin port1_req <= ~port1_req; port2_req <= ~port2_req; @@ -306,7 +312,9 @@ defender defender ( .dl_clock ( clk_sys ), .dl_addr ( ioctl_addr[15:0] ), .dl_data ( ioctl_dout ), - .dl_wr ( ioctl_wr ) + .dl_wr ( ioctl_wr && ioctl_index == 0 ), + .up_data ( ioctl_din ), + .cmos_wr ( ioctl_wr && ioctl_index == 8'hff ) ); mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(11)) mist_video( diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/defender.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/defender.vhd index c90a5751..73170768 100644 --- a/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/defender.vhd +++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Defender Hardware/rtl/defender.vhd @@ -153,7 +153,9 @@ port( dl_clock : in std_logic; dl_addr : in std_logic_vector(15 downto 0); dl_data : in std_logic_vector( 7 downto 0); - dl_wr : in std_logic + dl_wr : in std_logic; + up_data : out std_logic_vector(7 downto 0); + cmos_wr : in std_logic ); end defender; @@ -567,14 +569,19 @@ port map( ); -- cmos ram -cmos_ram : entity work.defender_cmos_ram +cmos_ram : entity work.dpram generic map( dWidth => 4, aWidth => 8) port map( - clk => clock_6, - we => cmos_we, - addr => cpu_addr(7 downto 0), - d => cpu_do(3 downto 0), - q => cmos_do + clk_a => clock_6, + we_a => cmos_we, + addr_a => cpu_addr(7 downto 0), + d_a => cpu_do(3 downto 0), + q_a => cmos_do, + clk_b => dl_clock, + we_b => cmos_wr, + addr_b => dl_addr(7 downto 0), + d_b => dl_data(3 downto 0), + q_b => up_data(3 downto 0) ); -- cpu to video addr decoder diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/README.md b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/README.md index 3f9997d5..a87f74e4 100644 --- a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/README.md +++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/README.md @@ -19,7 +19,8 @@ Usage: Note: the MRA files contains a dump of the CMOS RAM. It will be included in the generated ROM file. Change it for permanent settings (search for the format online). It's possible to change these values -inside the core, with turning on "Auto-up" switch, and activate the "Advance" trigger in the OSD. +inside the core, with turning on "Auto-up" switch, and activate the "Advance" trigger in the OSD. Then +it's possible to save these settings and high scores into a RAM file via the "Save NVRAM" OSD item. Refer to the arcade's user manual for further info. diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/RobotronFPGA_MiST.sv b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/RobotronFPGA_MiST.sv index 6ed7ffa4..799c6117 100644 --- a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/RobotronFPGA_MiST.sv +++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/RobotronFPGA_MiST.sv @@ -42,13 +42,14 @@ module RobotronFPGA_MiST( `define CORE_NAME "ROBOTRON" localparam CONF_STR = { - `CORE_NAME,";ROM;", + `CORE_NAME,";;", "O2,Rotate Controls,Off,On;", "O34,Scanlines,Off,25%,50%,75%;", "O5,Blend,Off,On;", "O6,Swap Joysticks,Off,On;", "O7,Auto up,Off,On;", "T8,Advance;", + "R1024,Save NVRAM;", "T0,Reset;", "V,v1.0.",`BUILD_DATE }; @@ -263,10 +264,12 @@ user_io( ); wire ioctl_downl; +wire ioctl_upl; wire [7:0] ioctl_index; wire ioctl_wr; wire [24:0] ioctl_addr; wire [7:0] ioctl_dout; +wire [7:0] ioctl_din; /* ROM Structure: @@ -282,14 +285,18 @@ data_io data_io ( .SPI_SCK ( SPI_SCK ), .SPI_SS2 ( SPI_SS2 ), .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), .ioctl_download( ioctl_downl ), + .ioctl_upload ( ioctl_upl ), .ioctl_index ( ioctl_index ), .ioctl_wr ( ioctl_wr ), .ioctl_addr ( ioctl_addr ), - .ioctl_dout ( ioctl_dout ) + .ioctl_dout ( ioctl_dout ), + .ioctl_din ( ioctl_din ) ); reg port1_req; +wire [15:0] port1_do; wire [23:1] mem_addr; wire [15:0] mem_do; wire [15:0] mem_di; @@ -316,7 +323,7 @@ sdram #(.MHZ(96)) sdram( .port1_ds ( 2'b11 ), .port1_we ( ioctl_downl ), .port1_d ( {ioctl_dout[7:4], ioctl_dout[7:4], ioctl_dout[3:0], ioctl_dout[3:0]} ), - .port1_q ( ), + .port1_q ( port1_do ), // CPU/video access .cpu1_addr ( ioctl_downl ? 17'h1ffff : sdram_addr ), @@ -333,12 +340,18 @@ sdram #(.MHZ(96)) sdram( wire [17:1] sdram_addr = ~romcs ? {1'b0, mem_addr[16], ~mem_addr[16] & mem_addr[15], mem_addr[14:1]} : { 1'b1, mem_addr[16:1] }; // IOCTL address to SDRAM address: -// D000-D3FF -> 1CC00-1CFFF (CMOS), otherwise direct mapping +// D000-D3FF (ROM) or 000-3FFF (RAM) -> 1CC00-1CFFF (CMOS), otherwise direct mapping -wire [22:0] downl_addr = (ioctl_addr[22:10] == { 7'h0, 4'hD, 2'b00 }) ? { 1'b1, 4'hC, 2'b11, ioctl_addr[9:0] } : ioctl_addr[22:0]; +wire [22:0] downl_addr = + ((ioctl_index == 0 && ioctl_addr[22:10] == { 7'h0, 4'hD, 2'b00 }) || ioctl_index == 8'hff) ? { 1'b1, 4'hC, 2'b11, ioctl_addr[9:0] } : + ioctl_addr[22:0]; + +assign ioctl_din = { port1_do[11:8], port1_do[3:0] }; always @(posedge clk_mem) begin reg ioctl_wr_last = 0; + reg [9:0] cmos_addr; + reg ioctl_upl_d; ioctl_wr_last <= ioctl_wr; if (ioctl_downl) begin @@ -346,6 +359,14 @@ always @(posedge clk_mem) begin port1_req <= ~port1_req; end end + + ioctl_upl_d <= ioctl_upl; + cmos_addr <= ioctl_addr[9:0]; + if (ioctl_upl) begin + if (cmos_addr != ioctl_addr[9:0] || !ioctl_upl_d) begin + port1_req <= ~port1_req; + end + end end reg reset = 1; @@ -378,7 +399,8 @@ robotron_soc robotron_soc ( .blitter_sc2 ( blitter_sc2 ), .sinistar ( sinistar ), - .speedball ( speedball ), + .speedball ( speedball ), + .pause ( ioctl_upl ), .BTN ( BTN ), .SIN_FIRE ( ~m_fireA & ~m_fire2A ), .SIN_BOMB ( ~m_fireB & ~m_fire2B ), @@ -403,7 +425,7 @@ robotron_soc robotron_soc ( .dl_clock ( clk_mem ), .dl_addr ( ioctl_addr[16:0] ), .dl_data ( ioctl_dout ), - .dl_wr ( ioctl_wr ) + .dl_wr ( ioctl_wr && ioctl_index == 0 ) ); mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(11)) mist_video( diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/robotron_cpu/robotron_cpu.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/robotron_cpu/robotron_cpu.vhd index 582bd55b..eaf101a9 100644 --- a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/robotron_cpu/robotron_cpu.vhd +++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/robotron_cpu/robotron_cpu.vhd @@ -40,6 +40,7 @@ entity robotron_cpu is blitter_sc2 : in std_logic; sinistar : in std_logic; speedball : in std_logic; + pause : in std_logic; -- MC6809 signals A : in std_logic_vector(15 downto 0); Dout : in std_logic_vector(7 downto 0); @@ -1017,7 +1018,7 @@ begin -- on Q falling edge. Present once per processor clock, -- on Q rising edge -- just because. RESET_N <= not mpu_reset; - HALT_N <= not mpu_halt; + HALT_N <= not (mpu_halt or pause); IRQ_N <= not mpu_irq; FIRQ_N <= not mpu_firq; NMI_N <= not mpu_nmi; diff --git a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/robotron_soc.vhd b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/robotron_soc.vhd index cc84a484..2a5fe9c3 100644 --- a/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/robotron_soc.vhd +++ b/Arcade_MiST/Williams 6809 rev.1 Hardware/Robotron Hardware/rtl/robotron_soc.vhd @@ -35,6 +35,7 @@ entity robotron_soc is port ( clock : in std_logic; -- 12MHz clock_snd : in std_logic; -- 0.89MHz + pause : in std_logic; -- Cellular RAM / StrataFlash MemOE : out std_logic; @@ -172,6 +173,7 @@ port map ( blitter_sc2 => blitter_sc2, sinistar => sinistar, speedball => speedball, + pause => pause, A => cpu_a, Dout => cpu_dout, Din => cpu_din, diff --git a/common/mist/data_io.v b/common/mist/data_io.v index 8941fe45..7e14f129 100644 --- a/common/mist/data_io.v +++ b/common/mist/data_io.v @@ -28,18 +28,20 @@ module data_io input SPI_SS2, input SPI_SS4, input SPI_DI, - input SPI_DO, // yes, SPI_DO is input when SS4 active + inout SPI_DO, input clkref_n, // assert ioctl_wr one cycle after clkref stobe (negative active) // ARM -> FPGA download output reg ioctl_download = 0, // signal indicating an active download + output reg ioctl_upload = 0, // signal indicating an active upload output reg [7:0] ioctl_index, // menu index used to upload the file ([7:6] - extension index, [5:0] - menu index) // Note: this is also set for user_io mounts. // Valid when ioctl_download = 1 or when img_mounted strobe is active in user_io. output reg ioctl_wr, // strobe indicating ioctl_dout valid output reg [24:0] ioctl_addr, output reg [7:0] ioctl_dout, + input [7:0] ioctl_din, output reg [23:0] ioctl_fileext, // file extension output reg [31:0] ioctl_filesize // file size ); @@ -51,23 +53,41 @@ parameter ROM_DIRECT_UPLOAD = 0; reg [7:0] data_w; reg [7:0] data_w2 = 0; +reg [3:0] cnt; reg rclk = 0; reg rclk2 = 0; reg addr_reset = 0; reg downloading_reg = 0; +reg uploading_reg = 0; +reg reg_do; localparam DIO_FILE_TX = 8'h53; localparam DIO_FILE_TX_DAT = 8'h54; localparam DIO_FILE_INDEX = 8'h55; localparam DIO_FILE_INFO = 8'h56; +localparam DIO_FILE_RX = 8'h57; +localparam DIO_FILE_RX_DAT = 8'h58; + +assign SPI_DO = reg_do; // data_io has its own SPI interface to the io controller +always@(negedge SPI_SCK or posedge SPI_SS2) begin : SPI_TRANSMITTER + reg [7:0] dout_r; + + if(SPI_SS2) begin + reg_do <= 1'bZ; + end else begin + if (cnt == 15) dout_r <= ioctl_din; + reg_do <= dout_r[~cnt[2:0]]; + end +end + + always@(posedge SPI_SCK, posedge SPI_SS2) begin : SPI_RECEIVER reg [6:0] sbuf; - reg [7:0] cmd; - reg [3:0] cnt; - reg [5:0] bytecnt; reg [24:0] addr; + reg [7:0] cmd; + reg [5:0] bytecnt; if(SPI_SS2) begin bytecnt <= 0; @@ -84,37 +104,53 @@ always@(posedge SPI_SCK, posedge SPI_SS2) begin : SPI_RECEIVER // finished command byte if(cnt == 7) cmd <= {sbuf, SPI_DI}; - // prepare/end transmission - if((cmd == DIO_FILE_TX) && (cnt == 15)) begin - // prepare - if(SPI_DI) begin - addr_reset <= ~addr_reset; - downloading_reg <= 1; - end else begin - downloading_reg <= 0; + if(cnt == 15) begin + case (cmd) + // prepare/end transmission + DIO_FILE_TX: begin + // prepare + if(SPI_DI) begin + addr_reset <= ~addr_reset; + downloading_reg <= 1; + end else begin + downloading_reg <= 0; + end end - end - // command 0x54: UIO_FILE_TX - if((cmd == DIO_FILE_TX_DAT) && (cnt == 15)) begin - data_w <= {sbuf, SPI_DI}; - rclk <= ~rclk; - end + DIO_FILE_RX: begin + // prepare + if(SPI_DI) begin + addr_reset <= ~addr_reset; + uploading_reg <= 1; + end else begin + uploading_reg <= 0; + end + end - // expose file (menu) index - if((cmd == DIO_FILE_INDEX) && (cnt == 15)) ioctl_index <= {sbuf, SPI_DI}; + // command 0x57: DIO_FILE_RX_DAT + // command 0x54: DIO_FILE_TX_DAT + DIO_FILE_RX_DAT, + DIO_FILE_TX_DAT: begin + data_w <= {sbuf, SPI_DI}; + rclk <= ~rclk; + end - // receiving FAT directory entry (mist-firmware/fat.h - DIRENTRY) - if((cmd == DIO_FILE_INFO) && (cnt == 15)) begin - bytecnt <= bytecnt + 1'd1; - case (bytecnt) - 8'h08: ioctl_fileext[23:16] <= {sbuf, SPI_DI}; - 8'h09: ioctl_fileext[15: 8] <= {sbuf, SPI_DI}; - 8'h0A: ioctl_fileext[ 7: 0] <= {sbuf, SPI_DI}; - 8'h1C: ioctl_filesize[ 7: 0] <= {sbuf, SPI_DI}; - 8'h1D: ioctl_filesize[15: 8] <= {sbuf, SPI_DI}; - 8'h1E: ioctl_filesize[23:16] <= {sbuf, SPI_DI}; - 8'h1F: ioctl_filesize[31:24] <= {sbuf, SPI_DI}; + // expose file (menu) index + DIO_FILE_INDEX: ioctl_index <= {sbuf, SPI_DI}; + + // receiving FAT directory entry (mist-firmware/fat.h - DIRENTRY) + DIO_FILE_INFO: begin + bytecnt <= bytecnt + 1'd1; + case (bytecnt) + 8'h08: ioctl_fileext[23:16] <= {sbuf, SPI_DI}; + 8'h09: ioctl_fileext[15: 8] <= {sbuf, SPI_DI}; + 8'h0A: ioctl_fileext[ 7: 0] <= {sbuf, SPI_DI}; + 8'h1C: ioctl_filesize[ 7: 0] <= {sbuf, SPI_DI}; + 8'h1D: ioctl_filesize[15: 8] <= {sbuf, SPI_DI}; + 8'h1E: ioctl_filesize[23:16] <= {sbuf, SPI_DI}; + 8'h1F: ioctl_filesize[31:24] <= {sbuf, SPI_DI}; + endcase + end endcase end end @@ -162,7 +198,7 @@ always@(posedge clk_sys) begin : DATA_OUT reg rclk2D, rclk2D2; reg addr_resetD, addr_resetD2; - reg wr_int, wr_int_direct; + reg wr_int, wr_int_direct, rd_int; reg [24:0] addr; reg [31:0] filepos; @@ -179,7 +215,13 @@ always@(posedge clk_sys) begin : DATA_OUT wr_int_direct <= 0; end + if (!uploading_reg) begin + ioctl_upload <= 0; + rd_int <= 0; + end + if (~clkref_n) begin + rd_int <= 0; wr_int <= 0; wr_int_direct <= 0; if (wr_int || wr_int_direct) begin @@ -188,17 +230,26 @@ always@(posedge clk_sys) begin : DATA_OUT addr <= addr + 1'd1; ioctl_addr <= addr; end + if (rd_int) begin + ioctl_addr <= ioctl_addr + 1'd1; + end end // detect transfer start from the SPI receiver if(addr_resetD ^ addr_resetD2) begin addr <= START_ADDR; + ioctl_addr <= START_ADDR; filepos <= 0; - ioctl_download <= 1; + ioctl_download <= downloading_reg; + ioctl_upload <= uploading_reg; end // detect new byte from the SPI receiver - if (rclkD ^ rclkD2) wr_int <= 1; + if (rclkD ^ rclkD2) begin + wr_int <= downloading_reg; + rd_int <= uploading_reg; + end + // direct transfer receiver if (rclk2D ^ rclk2D2 && filepos != ioctl_filesize) begin filepos <= filepos + 1'd1; wr_int_direct <= 1; diff --git a/common/mist/mist.vhd b/common/mist/mist.vhd index 38fa2924..0dfa2860 100644 --- a/common/mist/mist.vhd +++ b/common/mist/mist.vhd @@ -30,7 +30,7 @@ port ( joystick_4 : out std_logic_vector(31 downto 0); joystick_analog_0 : out std_logic_vector(15 downto 0); joystick_analog_1 : out std_logic_vector(15 downto 0); - status : out std_logic_vector(31 downto 0); + status : out std_logic_vector(63 downto 0); switches : out std_logic_vector(1 downto 0); buttons : out std_logic_vector(1 downto 0); scandoubler_disable : out std_logic; diff --git a/common/mist/user_io.v b/common/mist/user_io.v index 609f6d49..25cf9c4c 100644 --- a/common/mist/user_io.v +++ b/common/mist/user_io.v @@ -47,8 +47,11 @@ module user_io #(parameter STRLEN=0, parameter PS2DIV=100, parameter ROM_DIRECT_ output scandoubler_disable, output ypbpr, output no_csync, - output reg [31:0] status, + output reg [63:0] status, output reg [6:0] core_mod, // core variant, sent before the config string is requested + // RTC data from IO controller + // sec, min, hour, date, month, year, day (BCD) + output reg [63:0] rtc, // connection to sd card emulation input [31:0] sd_lba, @@ -497,12 +500,14 @@ always @(posedge clk_sys) begin : cmd_block 8'h15: status <= spi_byte_in; - // status, 32bit version - 8'h1e: if(abyte_cnt<5) status[(abyte_cnt-1)<<3 +:8] <= spi_byte_in; + // status, 64bit version + 8'h1e: if(abyte_cnt<9) status[(abyte_cnt-1)<<3 +:8] <= spi_byte_in; // core variant 8'h21: core_mod <= spi_byte_in[6:0]; + // RTC + 8'h22: if(abyte_cnt<9) rtc[(abyte_cnt-1)<<3 +:8] <= spi_byte_in; endcase end end