diff --git a/src/config b/src/config index 6bae32e..e402dff 100644 --- a/src/config +++ b/src/config @@ -35,7 +35,7 @@ CONFIG_UART_BAUDRATE=38400 CONFIG_UART_BUF_SHIFT=7 CONFIG_HARDWARE_NAME=sd2snes CONFIG_SD_AUTO_RETRIES=10 -CONFIG_SD_DATACRC=y +#CONFIG_SD_DATACRC=y CONFIG_EEPROM_SIZE=512 CONFIG_EEPROM_OFFSET=512 CONFIG_MAX_PARTITIONS=1 diff --git a/src/ff.c b/src/ff.c index da8ec95..0eb4e36 100644 --- a/src/ff.c +++ b/src/ff.c @@ -1488,7 +1488,6 @@ FRESULT f_open ( dir[DIR_Attr] = 0; /* Reset attribute */ ps = get_fattime(); ST_DWORD(&dir[DIR_CrtTime], ps); /* Created time */ - sync(fs); /* not sure if this is needed in all cases, but kept */ mode |= FA__WRITTEN; /* Set file changed flag */ } } @@ -1504,6 +1503,8 @@ FRESULT f_open ( } fp->dir_sect = FSBUF.sect; /* Pointer to the directory entry */ + /* Moved sync from mode & FA_CREATE_ALWAYS because it can reset FSBUF.sect */ + sync(fs); /* not sure if this is needed in all cases, but kept */ fp->dir_ptr = dir; #endif fp->flag = mode; /* File access mode */ @@ -1533,6 +1534,26 @@ FRESULT l_opencluster ( return FR_OK; } +FRESULT l_openfilebycluster ( + FATFS *fs, /* Pointer to file system object */ + FIL *fp, /* Pointer to the blank file object */ + const UCHAR *path, + DWORD clust, /* Cluster number to be opened */ + DWORD fsize /* File size to be assumed */ +) +{ + auto_mount(&path, &fs, 0); + fp->flag = FA_READ; + fp->org_clust = clust; + fp->fsize = fsize; + fp->fptr = 0; + fp->csect = 1; + fp->fs = fs; + + return FR_OK; +} + + /*-----------------------------------------------------------------------*/ diff --git a/src/ff.h b/src/ff.h index b761a1f..6f44794 100644 --- a/src/ff.h +++ b/src/ff.h @@ -315,6 +315,7 @@ FRESULT f_chdir (const UCHAR*); /* Change current di /* Low Level functions */ FRESULT l_opendir(FATFS* fs, DWORD cluster, DIR *dirobj); /* Open an existing directory by its start cluster */ FRESULT l_opencluster(FATFS *fs, FIL *fp, DWORD clust); /* Open a cluster by number as a read-only file */ +FRESULT l_openfilebycluster(FATFS *fs, FIL *fp, const UCHAR *path, DWORD clust, DWORD fsize); /* Open a file by its start cluster using supplied file size */ FRESULT l_getfree (FATFS*, const UCHAR*, DWORD*, DWORD); /* Get number of free clusters on the drive, limited */ #if _USE_STRFUNC diff --git a/src/fileops.c b/src/fileops.c index 6797290..cef3734 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -1,6 +1,7 @@ // insert cool lengthy disclaimer here // fileops.c: convenience +#include #include "config.h" #include "uart.h" #include "ff.h" @@ -14,6 +15,9 @@ void file_init() { f_mount(0, &fatfs); } +void file_open_by_filinfo(FILINFO* fno) { + file_res = l_openfilebycluster(&fatfs, &file_handle, (UCHAR*)"", fno->clust, fno->fsize); +} void file_open(char* filename, BYTE flags) { file_res = f_open(&file_handle, (unsigned char*)filename, flags); } @@ -37,8 +41,9 @@ UINT file_write() { 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; + if(file_res) { dprintf("no lseek %d\n", file_res); _delay_ms(30); return 0;} file_res = f_read(&file_handle, buf, size, &bytes_read); + if(file_res) { dprintf("no read %d\n", file_res); _delay_ms(30); } return bytes_read; } diff --git a/src/fileops.h b/src/fileops.h index 27881ea..2974dfc 100644 --- a/src/fileops.h +++ b/src/fileops.h @@ -12,6 +12,7 @@ FRESULT file_res; void file_init(void); void file_open(char* filename, BYTE flags); +void file_open_by_filinfo(FILINFO* fno); void file_close(void); UINT file_read(void); UINT file_write(void); diff --git a/src/filetypes.c b/src/filetypes.c new file mode 100644 index 0000000..8865f2b --- /dev/null +++ b/src/filetypes.c @@ -0,0 +1,127 @@ +// insert cool lengthy disclaimer here + +#include +#include +#include +#include +#include "config.h" +#include "uart.h" +#include "filetypes.h" +#include "ff.h" +#include "smc.h" +#include "fileops.h" +#include "crc16.h" +#include "memory.h" + +uint16_t scan_dir(char* path, char mkdb) { + DIR dir; + FILINFO fno; + FRESULT res; + int len; + unsigned char* fn; + static unsigned char lfn[256]; + static unsigned char depth = 0; + static uint16_t crc; + static uint32_t db_tgt; + if(depth==0) { + crc = 0; + db_tgt = 0x600010; + } +// dprintf("path=%s depth=%d ptr=%lx\n", path, depth, db_tgt); +// _delay_ms(50); + fno.lfn = lfn; + res = f_opendir(&dir, (unsigned char*)path); + if (res == FR_OK) { + len = strlen((char*)path); + for (;;) { + res = f_readdir(&dir, &fno); + if (res != FR_OK || fno.fname[0] == 0) break; + fn = *fno.lfn ? fno.lfn : fno.fname; +// dprintf("%s\n", fn); +// _delay_ms(100); + if (*fn == '.') continue; + if (fno.fattrib & AM_DIR) { + path[len]='/'; + strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len); + depth++; + scan_dir(path, mkdb); + depth--; + path[len]=0; +// if (res != FR_OK) { +// break; +// } + } else { + SNES_FTYPE type = determine_filetype((char*)fn); + if(type != TYPE_UNKNOWN) { + if(mkdb) { + snes_romprops_t romprops; + path[len]='/'; + strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len); + switch(type) { + case TYPE_SMC: + file_open_by_filinfo(&fno); + if(file_res){ + dprintf("ZOMG NOOOO %d\n", file_res); + _delay_ms(30); + } + smc_id(&romprops); + file_close(); + dprintf("%lx\n", db_tgt); +// _delay_ms(30); + sram_writeblock((uint8_t*)&romprops, db_tgt, sizeof(romprops)); + sram_writeblock(path, db_tgt + sizeof(romprops), 256); + db_tgt += 0x140; + break; + case TYPE_UNKNOWN: + default: + break; + } + path[len]=0; +// dprintf("%s ", path); +// _delay_ms(30); + } + unsigned char* sfn = fno.fname; + while(*sfn != 0) { + crc += crc16_update(crc, sfn++, 1); + } + } +// dprintf("%s/%s\n", path, fn); +// _delay_ms(50); +// _delay_ms(10); + } + } + } else uart_putc(0x30+res); +// dprintf("%x\n", crc); +// _delay_ms(50); + sram_writeblock(&db_tgt, 0x600004, sizeof(db_tgt)); + return crc; +} + + +SNES_FTYPE determine_filetype(char* filename) { + char* ext = strrchr(filename, '.'); + if(ext == NULL) + return TYPE_UNKNOWN; + if(!strcasecmp_P(ext+1, PSTR("SMC"))) { + return TYPE_SMC; + }/* later + if(!strcasecmp_P(ext+1, PSTR("SRM"))) { + return TYPE_SRM; + } + if(!strcasecmp_P(ext+1, PSTR("SPC"))) { + return TYPE_SPC; + }*/ + return TYPE_UNKNOWN; +} + +FRESULT get_db_id(uint16_t* id) { + file_open("/sd2snes/sd2snes.db", FA_READ); + if(file_res == FR_OK) { + file_readblock(id, 0, 2); +/* XXX */ *id=0xdead; + file_close(); + } else { + *id=0xdead; + } + return file_res; +} diff --git a/src/filetypes.h b/src/filetypes.h new file mode 100644 index 0000000..b8229d0 --- /dev/null +++ b/src/filetypes.h @@ -0,0 +1,22 @@ +// insert cool lengthy disclaimer here +// filetypes.h: fs scanning and file identification + +#ifndef FILETYPES_H +#define FILETYPES_H + +#include "ff.h" +typedef enum { + TYPE_UNKNOWN = 0, /* 0 */ + TYPE_SMC, /* 1 */ + TYPE_SRM, /* 2 */ + TYPE_SPC /* 3 */ +} SNES_FTYPE; + + +char fs_path[256]; +SNES_FTYPE determine_filetype(char* filename); +//uint32_t scan_fs(); +uint16_t scan_dir(char* path, char mkdb); +FRESULT get_db_id(uint16_t*); + +#endif diff --git a/src/fpga_spi.c b/src/fpga_spi.c index 0d7ff44..d7affbf 100644 --- a/src/fpga_spi.c +++ b/src/fpga_spi.c @@ -37,6 +37,11 @@ void spi_sd(void) { SPI_SS_LOW(); } +void spi_none(void) { + FPGA_SS_HIGH(); + SPI_SS_HIGH(); +} + void fpga_spi_init(void) { DDRC = _BV(PC7); FPGA_SS_HIGH(); @@ -48,7 +53,7 @@ void set_avr_addr(uint32_t address) { spiTransferByte((address>>16)&0xff); spiTransferByte((address>>8)&0xff); spiTransferByte((address)&0xff); - spi_sd(); + spi_none(); } void set_saveram_mask(uint32_t mask) { @@ -57,7 +62,7 @@ void set_saveram_mask(uint32_t mask) { spiTransferByte((mask>>16)&0xff); spiTransferByte((mask>>8)&0xff); spiTransferByte((mask)&0xff); - spi_sd(); + spi_none(); } void set_rom_mask(uint32_t mask) { @@ -66,5 +71,5 @@ void set_rom_mask(uint32_t mask) { spiTransferByte((mask>>16)&0xff); spiTransferByte((mask>>8)&0xff); spiTransferByte((mask)&0xff); - spi_sd(); + spi_none(); } diff --git a/src/fpga_spi.h b/src/fpga_spi.h index 568ab62..c5ece17 100644 --- a/src/fpga_spi.h +++ b/src/fpga_spi.h @@ -7,6 +7,7 @@ void fpga_spi_init(void); void fpga_spi_test(void); void spi_fpga(void); void spi_sd(void); +void spi_none(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 de6100c..9252e0d 100644 --- a/src/main.c +++ b/src/main.c @@ -170,7 +170,10 @@ int main(void) { _delay_ms(50); curr_dir_id = scan_dir(fs_path, 1); // then rebuild database sram_writeblock(&curr_dir_id, 0x600000, 2); - save_sram("/sd2snes/sd2snes.db", 0x10000, 0x600000); + uint32_t endaddr; + sram_readblock(&endaddr, 0x600004, 4); + dprintf("%lx\n", endaddr); + save_sram("/sd2snes/sd2snes.db", endaddr-0x600000, 0x600000); dprintf("done\n"); } @@ -211,7 +214,7 @@ while(1) { } // set_avr_bank(3); } - spi_sd(); + spi_none(); } while(1); } diff --git a/src/memory.c b/src/memory.c index 325c2fd..18c1f4e 100644 --- a/src/memory.c +++ b/src/memory.c @@ -29,20 +29,22 @@ void sram_readblock(void* buf, uint32_t addr, uint16_t size) { while(count--) { *(tgt++) = spiTransferByte(0x00); } - spi_sd(); + spi_none(); } void sram_writeblock(void* buf, uint32_t addr, uint16_t size) { - uint16_t count=size; - uint8_t* src = buf; + uint16_t count=size>>1; + uint16_t* src = buf; set_avr_addr(addr); spi_fpga(); spiTransferByte(0x91); // WRITE while(count--) { - spiTransferByte(*src++); + spiTransferByte((*src)>>8); + spiTransferByte((*src)&0xff); + src++; } spiTransferByte(0x00); // dummy - spi_sd(); + spi_none(); } uint32_t load_rom(char* filename) { @@ -79,13 +81,14 @@ uint32_t load_rom(char* filename) { FPGA_SS_HIGH(); } file_close(); + spi_none(); set_avr_mapper(romprops.mapper_id); uart_puthex(romprops.header.map); uart_putc(0x30+romprops.mapper_id); uint32_t rammask; uint32_t rommask; - + if(filesize > (romprops.romsize_bytes + romprops.offset)) { romprops.romsize_bytes <<= 1; } @@ -141,7 +144,7 @@ void save_sram(char* filename, uint32_t sram_size, uint32_t base_addr) { uint32_t count = 0; uint32_t num = 0; - spi_sd(); + spi_none(); file_open(filename, FA_CREATE_ALWAYS | FA_WRITE); if(file_res) { uart_putc(0x30+file_res); @@ -155,7 +158,7 @@ void save_sram(char* filename, uint32_t sram_size, uint32_t base_addr) { file_buf[j] = spiTransferByte(0x00); count++; } - spi_sd(); + spi_none(); num = file_write(); if(file_res) { uart_putc(0x30+file_res); @@ -171,15 +174,13 @@ uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) { uint16_t crc; crc=0; set_avr_addr(base_addr); - SPI_SS_HIGH(); - FPGA_SS_HIGH(); - FPGA_SS_LOW(); + spi_fpga(); spiTransferByte(0x81); spiTransferByte(0x00); for(count=0; count