1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-03-09 20:18:22 +00:00

Atari Tetris: add NVRAM support

This commit is contained in:
Gyorgy Szombathelyi
2021-04-05 21:56:17 +02:00
parent 36b9eb0b5d
commit df2ed06631
4 changed files with 95 additions and 23 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;