mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-19 09:18:02 +00:00
Merge pull request #105 from gyurco/cmossave
NVRAM save for MCR/Defender/Robotron cores
This commit is contained in:
commit
916bf8bee4
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
#**************************************************************
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user