basic ROM & SRAM mirroring [refactoring needed]
This commit is contained in:
@@ -100,7 +100,7 @@ FORMAT = ihex
|
|||||||
TARGET = $(OBJDIR)/sd2snes
|
TARGET = $(OBJDIR)/sd2snes
|
||||||
|
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
# List C source files here. (C dependencies are automatically generated.)
|
||||||
SRC = main.c ff.c utils.c timer.c led.c diskio.c sdcard.c spi.c crc7.c snes.c fpga.c memory.c crc16.c fileops.c fpga_spi.c
|
SRC = main.c ff.c utils.c timer.c led.c diskio.c sdcard.c spi.c crc7.c snes.c fpga.c memory.c crc16.c fileops.c fpga_spi.c filetypes.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_UART_DEBUG),y)
|
ifeq ($(CONFIG_UART_DEBUG),y)
|
||||||
SRC += uart.c
|
SRC += uart.c
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// insert cool lenghty disclaimer here
|
// insert cool lengthy disclaimer here
|
||||||
// fileops.c: fatfs wrapping for convenience
|
// fileops.c: convenience
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
@@ -29,3 +29,19 @@ UINT file_write() {
|
|||||||
file_res = f_write(&file_handle, file_buf, sizeof(file_buf), &bytes_written);
|
file_res = f_write(&file_handle, file_buf, sizeof(file_buf), &bytes_written);
|
||||||
return bytes_written;
|
return bytes_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT file_readblock(void* buf, uint32_t addr, uint16_t size) {
|
||||||
|
UINT bytes_read;
|
||||||
|
file_res = f_lseek(&file_handle, addr);
|
||||||
|
if(file_res) return 0;
|
||||||
|
file_res = f_read(&file_handle, buf, size, &bytes_read);
|
||||||
|
return bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT file_writeblock(void* buf, uint32_t addr, uint16_t size) {
|
||||||
|
UINT bytes_written;
|
||||||
|
file_res = f_lseek(&file_handle, addr);
|
||||||
|
if(file_res) return 0;
|
||||||
|
file_res = f_write(&file_handle, buf, size, &bytes_written);
|
||||||
|
return bytes_written;
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,4 +15,6 @@ void file_open(char* filename, BYTE flags);
|
|||||||
void file_close(void);
|
void file_close(void);
|
||||||
UINT file_read(void);
|
UINT file_read(void);
|
||||||
UINT file_write(void);
|
UINT file_write(void);
|
||||||
|
UINT file_readblock(void* buf, uint32_t addr, uint16_t size);
|
||||||
|
UINT file_writeblock(void* buf, uint32_t addr, uint16_t size);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
|
|
||||||
cmd param function
|
cmd param function
|
||||||
=============================================
|
=============================================
|
||||||
00 bb[hh[ll]] set address to 0xbbhhll
|
00 bb[hh[ll]] set address to 0xbb0000, 0xbbhh00, or 0xbbhhll
|
||||||
2s - set SRAM size to s
|
10 bbhhll set SNES input address mask to 0xbbhhll
|
||||||
|
2s bbhhll set SRAM address mask for chip #s to 0xbbhhll
|
||||||
3m - set mapper to m
|
3m - set mapper to m
|
||||||
0=HiROM, 1=LoROM
|
0=HiROM, 1=LoROM
|
||||||
80 - read with increment
|
80 - read with increment
|
||||||
@@ -50,3 +51,20 @@ void set_avr_addr(uint32_t address) {
|
|||||||
spi_sd();
|
spi_sd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_saveram_mask(uint32_t mask) {
|
||||||
|
spi_fpga();
|
||||||
|
spiTransferByte(0x20);
|
||||||
|
spiTransferByte((mask>>16)&0xff);
|
||||||
|
spiTransferByte((mask>>8)&0xff);
|
||||||
|
spiTransferByte((mask)&0xff);
|
||||||
|
spi_sd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_rom_mask(uint32_t mask) {
|
||||||
|
spi_fpga();
|
||||||
|
spiTransferByte(0x10);
|
||||||
|
spiTransferByte((mask>>16)&0xff);
|
||||||
|
spiTransferByte((mask>>8)&0xff);
|
||||||
|
spiTransferByte((mask)&0xff);
|
||||||
|
spi_sd();
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,3 +8,6 @@ void fpga_spi_test(void);
|
|||||||
void spi_fpga(void);
|
void spi_fpga(void);
|
||||||
void spi_sd(void);
|
void spi_sd(void);
|
||||||
void set_avr_addr(uint32_t);
|
void set_avr_addr(uint32_t);
|
||||||
|
void set_saveram_mask(uint32_t);
|
||||||
|
void set_rom_mask(uint32_t);
|
||||||
|
|
||||||
|
|||||||
@@ -174,7 +174,6 @@ int main(void) {
|
|||||||
load_sram("/test.srm");
|
load_sram("/test.srm");
|
||||||
uart_putc(']');
|
uart_putc(']');
|
||||||
set_busy_led(0);
|
set_busy_led(0);
|
||||||
set_avr_mapper(0);
|
|
||||||
set_avr_ena(1);
|
set_avr_ena(1);
|
||||||
_delay_ms(100);
|
_delay_ms(100);
|
||||||
uart_puts_P(PSTR("SNES GO!"));
|
uart_puts_P(PSTR("SNES GO!"));
|
||||||
|
|||||||
64
src/memory.c
64
src/memory.c
@@ -1,5 +1,5 @@
|
|||||||
// insert cool lenghty disclaimer here
|
// insert cool lengthy disclaimer here
|
||||||
// memory.c: ROM+RAM operations
|
// memory.c: SRAM operations
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
@@ -14,24 +14,53 @@
|
|||||||
#include "fpga_spi.h"
|
#include "fpga_spi.h"
|
||||||
#include "avrcompat.h"
|
#include "avrcompat.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
|
#include "filetypes.h"
|
||||||
|
#include "fpga_spi.h"
|
||||||
|
|
||||||
char* hex = "0123456789ABCDEF";
|
char* hex = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
void sram_readblock(void* buf, uint32_t addr, uint16_t size) {
|
||||||
|
uint16_t count=size;
|
||||||
|
void* tgt = buf;
|
||||||
|
set_avr_addr(addr);
|
||||||
|
spi_fpga();
|
||||||
|
spiTransferByte(0x81); // READ
|
||||||
|
spiTransferByte(0x00); // dummy
|
||||||
|
while(count--) {
|
||||||
|
*((uint8_t*)tgt++) = spiTransferByte(0x00);
|
||||||
|
}
|
||||||
|
spi_sd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
|
||||||
|
uint16_t count=size;
|
||||||
|
void* src = buf;
|
||||||
|
set_avr_addr(addr);
|
||||||
|
spi_fpga();
|
||||||
|
spiTransferByte(0x91); // WRITE
|
||||||
|
while(count--) {
|
||||||
|
spiTransferByte(*((uint8_t*)src++));
|
||||||
|
}
|
||||||
|
spiTransferByte(0x00); // dummy
|
||||||
|
spi_sd();
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t load_rom(char* filename) {
|
uint32_t load_rom(char* filename) {
|
||||||
// TODO Mapper, Mirroring, Bankselect
|
// TODO Mapper, Mirroring, Bankselect
|
||||||
// snes_rom_properties_t romprops;
|
snes_romprops_t romprops;
|
||||||
// set_avr_bank(0);
|
// set_avr_bank(0);
|
||||||
UINT bytes_read;
|
UINT bytes_read;
|
||||||
DWORD filesize;
|
DWORD filesize;
|
||||||
UINT count=0;
|
UINT count=0;
|
||||||
file_open(filename, FA_READ);
|
file_open(filename, FA_READ);
|
||||||
filesize = file_handle.fsize;
|
filesize = file_handle.fsize;
|
||||||
|
smc_id(&romprops);
|
||||||
if(file_res) {
|
if(file_res) {
|
||||||
uart_putc('?');
|
uart_putc('?');
|
||||||
uart_putc(0x30+file_res);
|
uart_putc(0x30+file_res);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// snes_rom_id(&romprops, &file_handle);
|
f_lseek(&file_handle, romprops.offset);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
FPGA_SS_HIGH();
|
FPGA_SS_HIGH();
|
||||||
SPI_SS_LOW();
|
SPI_SS_LOW();
|
||||||
@@ -46,14 +75,35 @@ uint32_t load_rom(char* filename) {
|
|||||||
}
|
}
|
||||||
for(int j=0; j<bytes_read; j++) {
|
for(int j=0; j<bytes_read; j++) {
|
||||||
spiTransferByte(file_buf[j]);
|
spiTransferByte(file_buf[j]);
|
||||||
// uart_putc((file_buf[j] > 0x20)
|
|
||||||
// && (file_buf[j] < ('z'+1)) ? file_buf[j]:'.');
|
|
||||||
// _delay_ms(2);
|
|
||||||
}
|
}
|
||||||
spiTransferByte(0x00); // dummy tx for increment+write pulse
|
spiTransferByte(0x00); // dummy tx for increment+write pulse
|
||||||
FPGA_SS_HIGH();
|
FPGA_SS_HIGH();
|
||||||
}
|
}
|
||||||
file_close();
|
file_close();
|
||||||
|
set_avr_mapper(romprops.mapper_id);
|
||||||
|
uart_puthex(romprops.header.map);
|
||||||
|
uart_putc(0x30+romprops.mapper_id);
|
||||||
|
|
||||||
|
uint32_t rammask;
|
||||||
|
uint32_t rommask;
|
||||||
|
if(romprops.header.ramsize == 0) {
|
||||||
|
rammask = 0;
|
||||||
|
} else {
|
||||||
|
rammask = ((uint32_t)1024 << (romprops.header.ramsize)) - 1;
|
||||||
|
}
|
||||||
|
rommask = ((uint32_t)1024 << (romprops.header.romsize)) - 1;
|
||||||
|
|
||||||
|
uart_putc(' ');
|
||||||
|
uart_puthex(romprops.header.ramsize);
|
||||||
|
uart_putc('-');
|
||||||
|
uart_puthexlong(rammask);
|
||||||
|
uart_putc(' ');
|
||||||
|
uart_puthex(romprops.header.romsize);
|
||||||
|
uart_putc('-');
|
||||||
|
uart_puthexlong(rommask);
|
||||||
|
set_saveram_mask(rammask);
|
||||||
|
set_rom_mask(rommask);
|
||||||
|
|
||||||
return (uint32_t)filesize;
|
return (uint32_t)filesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,13 @@ void uart_puthex(uint8_t num) {
|
|||||||
uart_putc('a'+tmp-10);
|
uart_putc('a'+tmp-10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uart_puthexlong(uint32_t num) {
|
||||||
|
uart_puthex((num>>24)&0xff);
|
||||||
|
uart_puthex((num>>16)&0xff);
|
||||||
|
uart_puthex((num>>8)&0xff);
|
||||||
|
uart_puthex(num&0xff);
|
||||||
|
}
|
||||||
|
|
||||||
void uart_trace(void *ptr, uint16_t start, uint16_t len) {
|
void uart_trace(void *ptr, uint16_t start, uint16_t len) {
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint8_t j;
|
uint8_t j;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ void uart_init(void);
|
|||||||
unsigned char uart_getc(void);
|
unsigned char uart_getc(void);
|
||||||
void uart_putc(char c);
|
void uart_putc(char c);
|
||||||
void uart_puthex(uint8_t num);
|
void uart_puthex(uint8_t num);
|
||||||
|
void uart_puthexlong(uint32_t num);
|
||||||
void uart_trace(void *ptr, uint16_t start, uint16_t len);
|
void uart_trace(void *ptr, uint16_t start, uint16_t len);
|
||||||
void uart_flush(void);
|
void uart_flush(void);
|
||||||
void uart_puts_P(prog_char *text);
|
void uart_puts_P(prog_char *text);
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ module address(
|
|||||||
output IS_ROM, // address mapped as ROM?
|
output IS_ROM, // address mapped as ROM?
|
||||||
input [23:0] AVR_ADDR, // allow address to be set externally
|
input [23:0] AVR_ADDR, // allow address to be set externally
|
||||||
input ADDR_WRITE,
|
input ADDR_WRITE,
|
||||||
output SRAM_ADDR0
|
output SRAM_ADDR0,
|
||||||
|
input [23:0] SAVERAM_MASK,
|
||||||
|
input [23:0] ROM_MASK
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [22:0] SRAM_ADDR_BUF;
|
reg [22:0] SRAM_ADDR_BUF;
|
||||||
@@ -80,11 +82,11 @@ assign IS_ROM = ( (MAPPER == 3'b000) ? ( (!SNES_ADDR[22]
|
|||||||
|
|
||||||
assign SRAM_ADDR_FULL = (MODE) ? AVR_ADDR
|
assign SRAM_ADDR_FULL = (MODE) ? AVR_ADDR
|
||||||
: ((MAPPER == 3'b000) ?
|
: ((MAPPER == 3'b000) ?
|
||||||
(IS_SAVERAM ? SNES_ADDR[14:0] - 15'h6000
|
(IS_SAVERAM ? (SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK
|
||||||
: (SNES_ADDR[22:0] & 23'b00111111111111111111111))
|
: (SNES_ADDR[22:0] & ROM_MASK))
|
||||||
:(MAPPER == 3'b001) ?
|
:(MAPPER == 3'b001) ?
|
||||||
(IS_SAVERAM ? SNES_ADDR[14:0]
|
(IS_SAVERAM ? SNES_ADDR[14:0] & SAVERAM_MASK
|
||||||
: {1'b0, SNES_ADDR[22:16], SNES_ADDR[14:0]})
|
: {1'b0, SNES_ADDR[22:16], SNES_ADDR[14:0]} & ROM_MASK)
|
||||||
: 21'b0);
|
: 21'b0);
|
||||||
|
|
||||||
assign SRAM_BANK = SRAM_ADDR_FULL[22:21];
|
assign SRAM_BANK = SRAM_ADDR_FULL[22:21];
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ module avr_cmd(
|
|||||||
output [23:0] addr_out,
|
output [23:0] addr_out,
|
||||||
output [3:0] mapper,
|
output [3:0] mapper,
|
||||||
input endmessage,
|
input endmessage,
|
||||||
input startmessage
|
input startmessage,
|
||||||
|
output [23:0] saveram_mask_out,
|
||||||
|
output [23:0] rom_mask_out
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [3:0] MAPPER_BUF;
|
reg [3:0] MAPPER_BUF;
|
||||||
@@ -49,6 +51,10 @@ reg [7:0] AVR_DATA_IN_BUF;
|
|||||||
reg [1:0] avr_nextaddr_buf;
|
reg [1:0] avr_nextaddr_buf;
|
||||||
wire avr_nextaddr;
|
wire avr_nextaddr;
|
||||||
|
|
||||||
|
reg [1:0] SRAM_MASK_IDX;
|
||||||
|
reg [23:0] SAVERAM_MASK;
|
||||||
|
reg [23:0] ROM_MASK;
|
||||||
|
|
||||||
assign spi_data_out = AVR_DATA_IN_BUF;
|
assign spi_data_out = AVR_DATA_IN_BUF;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
@@ -58,8 +64,6 @@ end
|
|||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (cmd_ready) begin
|
if (cmd_ready) begin
|
||||||
case (cmd_data[7:4])
|
case (cmd_data[7:4])
|
||||||
4'h2:
|
|
||||||
SRAM_SIZE_BUF <= cmd_data[3:0];
|
|
||||||
4'h3:
|
4'h3:
|
||||||
MAPPER_BUF <= cmd_data[3:0];
|
MAPPER_BUF <= cmd_data[3:0];
|
||||||
4'h8:
|
4'h8:
|
||||||
@@ -78,6 +82,24 @@ always @(posedge clk) begin
|
|||||||
32'h4:
|
32'h4:
|
||||||
ADDR_OUT_BUF[7:0] <= param_data;
|
ADDR_OUT_BUF[7:0] <= param_data;
|
||||||
endcase
|
endcase
|
||||||
|
4'h1:
|
||||||
|
case (spi_byte_cnt)
|
||||||
|
32'h2:
|
||||||
|
ROM_MASK[23:16] <= param_data;
|
||||||
|
32'h3:
|
||||||
|
ROM_MASK[15:8] <= param_data;
|
||||||
|
32'h4:
|
||||||
|
ROM_MASK[7:0] <= param_data;
|
||||||
|
endcase
|
||||||
|
4'h2:
|
||||||
|
case (spi_byte_cnt)
|
||||||
|
32'h2:
|
||||||
|
SAVERAM_MASK[23:16] <= param_data;
|
||||||
|
32'h3:
|
||||||
|
SAVERAM_MASK[15:8] <= param_data;
|
||||||
|
32'h4:
|
||||||
|
SAVERAM_MASK[7:0] <= param_data;
|
||||||
|
endcase
|
||||||
4'h8:
|
4'h8:
|
||||||
AVR_DATA_IN_BUF <= avr_data_in;
|
AVR_DATA_IN_BUF <= avr_data_in;
|
||||||
4'h9:
|
4'h9:
|
||||||
@@ -114,5 +136,7 @@ assign addr_out = ADDR_OUT_BUF;
|
|||||||
assign avr_data_out = AVR_DATA_OUT_BUF;
|
assign avr_data_out = AVR_DATA_OUT_BUF;
|
||||||
assign avr_mapper = MAPPER_BUF;
|
assign avr_mapper = MAPPER_BUF;
|
||||||
assign avr_sram_size = SRAM_SIZE_BUF;
|
assign avr_sram_size = SRAM_SIZE_BUF;
|
||||||
|
assign rom_mask_out = ROM_MASK;
|
||||||
|
assign saveram_mask_out = SAVERAM_MASK;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ wire [7:0] avr_data_out;
|
|||||||
wire [7:0] AVR_IN_DATA;
|
wire [7:0] AVR_IN_DATA;
|
||||||
wire [7:0] AVR_OUT_DATA;
|
wire [7:0] AVR_OUT_DATA;
|
||||||
wire [3:0] MAPPER;
|
wire [3:0] MAPPER;
|
||||||
|
wire [23:0] SAVERAM_MASK;
|
||||||
|
wire [23:0] ROM_MASK;
|
||||||
|
|
||||||
spi snes_spi(.clk(CLK2),
|
spi snes_spi(.clk(CLK2),
|
||||||
.MOSI(SPI_MOSI),
|
.MOSI(SPI_MOSI),
|
||||||
@@ -100,7 +102,9 @@ avr_cmd snes_avr_cmd(
|
|||||||
.spi_data_out(spi_input_data),
|
.spi_data_out(spi_input_data),
|
||||||
.addr_out(AVR_ADDR),
|
.addr_out(AVR_ADDR),
|
||||||
.endmessage(spi_endmessage),
|
.endmessage(spi_endmessage),
|
||||||
.startmessage(spi_startmessage)
|
.startmessage(spi_startmessage),
|
||||||
|
.saveram_mask_out(SAVERAM_MASK),
|
||||||
|
.rom_mask_out(ROM_MASK)
|
||||||
);
|
);
|
||||||
|
|
||||||
my_dcm snes_dcm(.CLKIN(CLKIN),
|
my_dcm snes_dcm(.CLKIN(CLKIN),
|
||||||
@@ -145,7 +149,9 @@ address snes_addr(
|
|||||||
.IS_SAVERAM(IS_SAVERAM),
|
.IS_SAVERAM(IS_SAVERAM),
|
||||||
.IS_ROM(IS_ROM),
|
.IS_ROM(IS_ROM),
|
||||||
.AVR_ADDR(AVR_ADDR),
|
.AVR_ADDR(AVR_ADDR),
|
||||||
.SRAM_ADDR0(SRAM_ADDR0)
|
.SRAM_ADDR0(SRAM_ADDR0),
|
||||||
|
.SAVERAM_MASK(SAVERAM_MASK),
|
||||||
|
.ROM_MASK(ROM_MASK)
|
||||||
);
|
);
|
||||||
|
|
||||||
data snes_data(.CLK(CLK2),
|
data snes_data(.CLK(CLK2),
|
||||||
|
|||||||
Reference in New Issue
Block a user