Game DB creation (prelim), FatFS extension
This commit is contained in:
parent
f3e07ff30c
commit
38812ce99d
@ -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
|
||||
|
||||
23
src/ff.c
23
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
1
src/ff.h
1
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
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
// insert cool lengthy disclaimer here
|
||||
// fileops.c: convenience
|
||||
|
||||
#include <util/delay.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
127
src/filetypes.c
Normal file
127
src/filetypes.c
Normal file
@ -0,0 +1,127 @@
|
||||
// insert cool lengthy disclaimer here
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/delay.h>
|
||||
#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;
|
||||
}
|
||||
22
src/filetypes.h
Normal file
22
src/filetypes.h
Normal file
@ -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
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
23
src/memory.c
23
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,6 +81,7 @@ 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);
|
||||
@ -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<size; count++) {
|
||||
data = spiTransferByte(0);
|
||||
crc += crc16_update(crc, &data, 1);
|
||||
}
|
||||
FPGA_SS_HIGH();
|
||||
spi_none();
|
||||
return crc;
|
||||
}
|
||||
|
||||
@ -60,6 +60,8 @@ void smc_id(snes_romprops_t* props) {
|
||||
for(uint8_t num = 0; num < 6; num++) {
|
||||
file_readblock(header, hdr_addr[num], sizeof(snes_header_t));
|
||||
if(file_res) {
|
||||
dprintf("uh oh... %d\n", file_res);
|
||||
_delay_ms(30);
|
||||
score = 0;
|
||||
} else {
|
||||
score = smc_headerscore(header);
|
||||
|
||||
@ -29,6 +29,7 @@ typedef struct _snes_header {
|
||||
typedef struct _snes_romprops {
|
||||
uint16_t offset; // start of actual ROM image
|
||||
uint8_t mapper_id; // FPGA mapper
|
||||
uint8_t pad1; // for alignment
|
||||
uint32_t expramsize_bytes; // ExpRAM size in bytes
|
||||
uint32_t ramsize_bytes; // CartRAM size in bytes
|
||||
uint32_t romsize_bytes; // ROM size in bytes (rounded up)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user