Game DB creation (prelim), FatFS extension

This commit is contained in:
ikari 2009-09-28 09:38:18 +02:00
parent f3e07ff30c
commit 38812ce99d
13 changed files with 210 additions and 20 deletions

View File

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

View File

@ -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;
}
/*-----------------------------------------------------------------------*/

View File

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

View File

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

View File

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

View File

@ -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();
}

View File

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

View File

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

View File

@ -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<size; count++) {
data = spiTransferByte(0);
crc += crc16_update(crc, &data, 1);
}
FPGA_SS_HIGH();
spi_none();
return crc;
}

View File

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

View File

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