From 66b0f0350e04c1f62f194838ca4ae941efcc8564 Mon Sep 17 00:00:00 2001 From: ikari Date: Mon, 7 Sep 2009 10:47:51 +0200 Subject: [PATCH] basic ROM & SRAM mirroring [refactoring needed] --- src/Makefile | 2 +- src/fileops.c | 20 ++++++++++-- src/fileops.h | 2 ++ src/fpga_spi.c | 22 ++++++++++++-- src/fpga_spi.h | 3 ++ src/main.c | 1 - src/memory.c | 64 ++++++++++++++++++++++++++++++++++----- src/uart.c | 7 +++++ src/uart.h | 1 + verilog/sd2snes/address.v | 12 +++++--- verilog/sd2snes/avr_cmd.v | 30 ++++++++++++++++-- verilog/sd2snes/main.v | 10 ++++-- 12 files changed, 151 insertions(+), 23 deletions(-) diff --git a/src/Makefile b/src/Makefile index aa7604d..4979872 100644 --- a/src/Makefile +++ b/src/Makefile @@ -100,7 +100,7 @@ FORMAT = ihex TARGET = $(OBJDIR)/sd2snes # 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) SRC += uart.c diff --git a/src/fileops.c b/src/fileops.c index 6f8f1cb..3755b2b 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -1,5 +1,5 @@ -// insert cool lenghty disclaimer here -// fileops.c: fatfs wrapping for convenience +// insert cool lengthy disclaimer here +// fileops.c: convenience #include "config.h" #include "uart.h" @@ -29,3 +29,19 @@ UINT file_write() { file_res = f_write(&file_handle, file_buf, sizeof(file_buf), &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; +} diff --git a/src/fileops.h b/src/fileops.h index 604fb44..27881ea 100644 --- a/src/fileops.h +++ b/src/fileops.h @@ -15,4 +15,6 @@ void file_open(char* filename, BYTE flags); void file_close(void); UINT file_read(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 diff --git a/src/fpga_spi.c b/src/fpga_spi.c index 41d6ce9..0d7ff44 100644 --- a/src/fpga_spi.c +++ b/src/fpga_spi.c @@ -6,8 +6,9 @@ cmd param function ============================================= - 00 bb[hh[ll]] set address to 0xbbhhll - 2s - set SRAM size to s + 00 bb[hh[ll]] set address to 0xbb0000, 0xbbhh00, or 0xbbhhll + 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 0=HiROM, 1=LoROM 80 - read with increment @@ -50,3 +51,20 @@ void set_avr_addr(uint32_t address) { 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(); +} diff --git a/src/fpga_spi.h b/src/fpga_spi.h index 40a7d71..568ab62 100644 --- a/src/fpga_spi.h +++ b/src/fpga_spi.h @@ -8,3 +8,6 @@ void fpga_spi_test(void); void spi_fpga(void); void spi_sd(void); void set_avr_addr(uint32_t); +void set_saveram_mask(uint32_t); +void set_rom_mask(uint32_t); + diff --git a/src/main.c b/src/main.c index e42bbe3..c0f62c1 100644 --- a/src/main.c +++ b/src/main.c @@ -174,7 +174,6 @@ int main(void) { load_sram("/test.srm"); uart_putc(']'); set_busy_led(0); - set_avr_mapper(0); set_avr_ena(1); _delay_ms(100); uart_puts_P(PSTR("SNES GO!")); diff --git a/src/memory.c b/src/memory.c index 346209d..e33d261 100644 --- a/src/memory.c +++ b/src/memory.c @@ -1,5 +1,5 @@ -// insert cool lenghty disclaimer here -// memory.c: ROM+RAM operations +// insert cool lengthy disclaimer here +// memory.c: SRAM operations #include #include @@ -14,24 +14,53 @@ #include "fpga_spi.h" #include "avrcompat.h" #include "led.h" +#include "filetypes.h" +#include "fpga_spi.h" 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) { // TODO Mapper, Mirroring, Bankselect -// snes_rom_properties_t romprops; + snes_romprops_t romprops; // set_avr_bank(0); UINT bytes_read; DWORD filesize; UINT count=0; file_open(filename, FA_READ); filesize = file_handle.fsize; + smc_id(&romprops); if(file_res) { uart_putc('?'); uart_putc(0x30+file_res); return 0; } -// snes_rom_id(&romprops, &file_handle); + f_lseek(&file_handle, romprops.offset); for(;;) { FPGA_SS_HIGH(); SPI_SS_LOW(); @@ -46,14 +75,35 @@ uint32_t load_rom(char* filename) { } for(int j=0; j 0x20) -// && (file_buf[j] < ('z'+1)) ? file_buf[j]:'.'); -// _delay_ms(2); } spiTransferByte(0x00); // dummy tx for increment+write pulse FPGA_SS_HIGH(); } 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; } diff --git a/src/uart.c b/src/uart.c index f4adf01..264af05 100644 --- a/src/uart.c +++ b/src/uart.c @@ -72,6 +72,13 @@ void uart_puthex(uint8_t num) { 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) { uint16_t i; uint8_t j; diff --git a/src/uart.h b/src/uart.h index 4f821b9..385e26b 100644 --- a/src/uart.h +++ b/src/uart.h @@ -35,6 +35,7 @@ void uart_init(void); unsigned char uart_getc(void); void uart_putc(char c); 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_flush(void); void uart_puts_P(prog_char *text); diff --git a/verilog/sd2snes/address.v b/verilog/sd2snes/address.v index 45b3276..bf07f0b 100644 --- a/verilog/sd2snes/address.v +++ b/verilog/sd2snes/address.v @@ -31,7 +31,9 @@ module address( output IS_ROM, // address mapped as ROM? input [23:0] AVR_ADDR, // allow address to be set externally 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; @@ -80,11 +82,11 @@ assign IS_ROM = ( (MAPPER == 3'b000) ? ( (!SNES_ADDR[22] assign SRAM_ADDR_FULL = (MODE) ? AVR_ADDR : ((MAPPER == 3'b000) ? - (IS_SAVERAM ? SNES_ADDR[14:0] - 15'h6000 - : (SNES_ADDR[22:0] & 23'b00111111111111111111111)) + (IS_SAVERAM ? (SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK + : (SNES_ADDR[22:0] & ROM_MASK)) :(MAPPER == 3'b001) ? - (IS_SAVERAM ? SNES_ADDR[14:0] - : {1'b0, SNES_ADDR[22:16], SNES_ADDR[14:0]}) + (IS_SAVERAM ? SNES_ADDR[14:0] & SAVERAM_MASK + : {1'b0, SNES_ADDR[22:16], SNES_ADDR[14:0]} & ROM_MASK) : 21'b0); assign SRAM_BANK = SRAM_ADDR_FULL[22:21]; diff --git a/verilog/sd2snes/avr_cmd.v b/verilog/sd2snes/avr_cmd.v index e06fd62..1d8a8d2 100644 --- a/verilog/sd2snes/avr_cmd.v +++ b/verilog/sd2snes/avr_cmd.v @@ -36,7 +36,9 @@ module avr_cmd( output [23:0] addr_out, output [3:0] mapper, input endmessage, - input startmessage + input startmessage, + output [23:0] saveram_mask_out, + output [23:0] rom_mask_out ); reg [3:0] MAPPER_BUF; @@ -49,6 +51,10 @@ reg [7:0] AVR_DATA_IN_BUF; reg [1:0] avr_nextaddr_buf; 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; initial begin @@ -58,8 +64,6 @@ end always @(posedge clk) begin if (cmd_ready) begin case (cmd_data[7:4]) - 4'h2: - SRAM_SIZE_BUF <= cmd_data[3:0]; 4'h3: MAPPER_BUF <= cmd_data[3:0]; 4'h8: @@ -78,6 +82,24 @@ always @(posedge clk) begin 32'h4: ADDR_OUT_BUF[7:0] <= param_data; 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: AVR_DATA_IN_BUF <= avr_data_in; 4'h9: @@ -114,5 +136,7 @@ assign addr_out = ADDR_OUT_BUF; assign avr_data_out = AVR_DATA_OUT_BUF; assign avr_mapper = MAPPER_BUF; assign avr_sram_size = SRAM_SIZE_BUF; +assign rom_mask_out = ROM_MASK; +assign saveram_mask_out = SAVERAM_MASK; endmodule diff --git a/verilog/sd2snes/main.v b/verilog/sd2snes/main.v index 36ca342..095b86e 100644 --- a/verilog/sd2snes/main.v +++ b/verilog/sd2snes/main.v @@ -65,6 +65,8 @@ wire [7:0] avr_data_out; wire [7:0] AVR_IN_DATA; wire [7:0] AVR_OUT_DATA; wire [3:0] MAPPER; +wire [23:0] SAVERAM_MASK; +wire [23:0] ROM_MASK; spi snes_spi(.clk(CLK2), .MOSI(SPI_MOSI), @@ -100,7 +102,9 @@ avr_cmd snes_avr_cmd( .spi_data_out(spi_input_data), .addr_out(AVR_ADDR), .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), @@ -145,7 +149,9 @@ address snes_addr( .IS_SAVERAM(IS_SAVERAM), .IS_ROM(IS_ROM), .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),