diff --git a/Arcade_MiST/Atari Tetris/rtl/FPGA_ATetris.v b/Arcade_MiST/Atari Tetris/rtl/FPGA_ATetris.v index 16afec24..b7759450 100644 --- a/Arcade_MiST/Atari Tetris/rtl/FPGA_ATetris.v +++ b/Arcade_MiST/Atari Tetris/rtl/FPGA_ATetris.v @@ -24,7 +24,13 @@ module FPGA_ATetris input [7:0] PRDT, output [15:0] CRAD, - input [15:0] CRDT + input [15:0] CRDT, + + input NVRAM_CLK, + input [8:0] NVRAM_A, + input [7:0] NVRAM_D, + input NVRAM_WE, + output [7:0] NVRAM_Q ); // INP = {`SELFT,`COIN2,`COIN1,`P2LF,`P2RG,`P2DW,`P2RO,`P1LF,`P1RG,`P1DW,`P1RO}; @@ -66,7 +72,7 @@ ATETRIS_ROMAXS romaxs(RST,MCLK,CPUCE,CPUAD,PRAD,PRDV); // RAMs wire [7:0] RMDT; wire RMDV; -ATETRIS_RAMS rams(MCLK,CPUAD,CPUWR,CPUDO,RMDT,RMDV); +ATETRIS_RAMS rams(MCLK,CPUAD,CPUWR,CPUDO,RMDT,RMDV,NVRAM_CLK,NVRAM_A,NVRAM_D,NVRAM_WE,NVRAM_Q); // Video @@ -164,7 +170,13 @@ module ATETRIS_RAMS input CPUWR, input [7:0] CPUDO, output [7:0] RMDT, - output RMDV + output RMDV, + + input NVRAM_CLK, + input [8:0] NVRAM_A, + input [7:0] NVRAM_D, + input NVRAM_WE, + output [7:0] NVRAM_Q ); // WorkRAM @@ -188,16 +200,24 @@ wire NVDV = (CPUAD[15:10]==6'b0010_01); // $24xx-$27xx wire [7:0] NVDT; //RAM_B #(9,255) nvram(DEVCL,CPUAD,NVDV,CPUWR,CPUDO,NVDT); -spram#( - .init_file("nvinit.hex"), - .widthad_a(9), - .width_a(8)) +dpram#( + .init_file("rtl/nvinit.mif"), + .data_width_g(8), + .addr_width_g(9)) nvram( - .address(CPUAD), - .clock(MCLK), - .data(CPUDO), - .wren(CPUWR & NVDV), - .q(NVDT) + // CPU side + .clk_a_i(MCLK), + .en_a_i(1'b1), + .addr_a_i(CPUAD), + .data_a_i(CPUDO), + .we_i(CPUWR & NVDV), + .data_a_o(NVDT), + // IO Controller side + .clk_b_i(NVRAM_CLK), + .addr_b_i(NVRAM_A), + .data_b_o(NVRAM_Q), + .data_b_i(NVRAM_D), + .we_b_i(NVRAM_WE) ); DSEL4x8 dsel(RMDV,RMDT, @@ -253,7 +273,7 @@ reg [8:0] pVPT; always @(posedge MCLK) begin if (tWDTR) WDT <= 0; else if (pVPT!=VP) begin - if (VP==0) WDT <= (WDT==8) ? 14 : (WDT+1); + if (VP==0) WDT <= (WDT==8) ? 4'd14 : (WDT+1); pVPT <= VP; end end diff --git a/Arcade_MiST/Atari Tetris/rtl/Tetris_MiST.sv b/Arcade_MiST/Atari Tetris/rtl/Tetris_MiST.sv index 0c359596..e16c40ca 100644 --- a/Arcade_MiST/Atari Tetris/rtl/Tetris_MiST.sv +++ b/Arcade_MiST/Atari Tetris/rtl/Tetris_MiST.sv @@ -32,11 +32,12 @@ module Tetris_MiST( `include "rtl/build_id.v" localparam CONF_STR = { - "TETRIS;ROM;", + "TETRIS;;", "O2,Service,Off,On;", "O34,Scanlines,Off,25%,50%,75%;", "O5,Blend,Off,On;", "O6,Joystick Swap,Off,On;", + "R512,Save NVRAM;", "T0,Reset;", "V,v1.0.",`BUILD_DATE }; @@ -46,7 +47,7 @@ wire joyswap = status[6]; wire rotate = 0; wire blend = status[5]; -assign LED = ~ioctl_downl; +assign LED = ~(ioctl_downl | ioctl_upl); assign SDRAM_CLK = clk_sd; assign SDRAM_CKE = 1; assign AUDIO_R = AUDIO_L; @@ -100,21 +101,26 @@ wire [15:0] rom_do; wire [15:0] gfx_addr; wire [15:0] gfx_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( - .clk_sys ( clk_sd ), + .clk_sys ( clk_sd ), .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; @@ -154,7 +160,7 @@ always @(posedge clk_sd) 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 @@ -196,7 +202,13 @@ FPGA_ATetris FPGA_ATetris( .PRDT(rom_addr[0] ? rom_do[15:8] : rom_do[7:0]), .CRAD(gfx_addr), - .CRDT(gfx_do) + .CRDT(gfx_do), + + .NVRAM_CLK(clk_sd), + .NVRAM_A(ioctl_addr[8:0]), + .NVRAM_D(ioctl_dout), + .NVRAM_Q(ioctl_din), + .NVRAM_WE(ioctl_wr && ioctl_index == 8'hff) ); wire PCLK; diff --git a/Arcade_MiST/Atari Tetris/rtl/dpram.vhd b/Arcade_MiST/Atari Tetris/rtl/dpram.vhd index 9ab46487..a20c5c79 100644 --- a/Arcade_MiST/Atari Tetris/rtl/dpram.vhd +++ b/Arcade_MiST/Atari Tetris/rtl/dpram.vhd @@ -8,8 +8,9 @@ use ieee.std_logic_1164.all; entity dpram is generic ( - addr_width_g : integer := 8; - data_width_g : integer := 8 + addr_width_g : integer := 8; + data_width_g : integer := 8; + init_file : string := "" ); port ( clk_a_i : in std_logic; @@ -20,7 +21,9 @@ port ( data_a_o : out std_logic_vector(data_width_g-1 downto 0); clk_b_i : in std_logic; addr_b_i : in std_logic_vector(addr_width_g-1 downto 0); - data_b_o : out std_logic_vector(data_width_g-1 downto 0) + data_b_o : out std_logic_vector(data_width_g-1 downto 0); + we_b_i : in std_logic := '0'; + data_b_i : in std_logic_vector(data_width_g-1 downto 0) := (others => '0') ); end dpram; @@ -33,6 +36,8 @@ architecture rtl of dpram is type ram_t is array (natural range 2**addr_width_g-1 downto 0) of std_logic_vector(data_width_g-1 downto 0); signal ram_q : ram_t; + attribute ram_init_file : string; + attribute ram_init_file of ram_q : signal is init_file; begin @@ -51,7 +56,10 @@ begin mem_b: process (clk_b_i) begin if rising_edge(clk_b_i) then - data_b_o <= ram_q(to_integer(unsigned(addr_b_i))); + if we_b_i = '1' then + ram_q(to_integer(unsigned(addr_b_i))) <= data_b_i; + end if; + data_b_o <= ram_q(to_integer(unsigned(addr_b_i))); end if; end process mem_b; diff --git a/Arcade_MiST/Atari Tetris/rtl/nvinit.mif b/Arcade_MiST/Atari Tetris/rtl/nvinit.mif new file mode 100644 index 00000000..a5508835 --- /dev/null +++ b/Arcade_MiST/Atari Tetris/rtl/nvinit.mif @@ -0,0 +1,32 @@ +-- http://srecord.sourceforge.net/ +-- +-- Generated automatically by srec_cat -o --mif +-- +DEPTH = 512; +WIDTH = 8; +ADDRESS_RADIX = HEX; +DATA_RADIX = HEX; +CONTENT BEGIN +0000: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0018: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0030: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0048: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0060: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0078: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0090: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +00A8: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +00C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +00D8: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +00F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0108: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0120: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0138: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0150: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0168: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0180: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +0198: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +01B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +01C8: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +01E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +01F8: FF FF FF FF FF FF FF FF; +END;