Browse Source

Game DB creation (prelim), FatFS extension

ikari 14 years ago
parent
commit
38812ce99d
13 changed files with 210 additions and 20 deletions
  1. 1 1
      src/config
  2. 22 1
      src/ff.c
  3. 1 0
      src/ff.h
  4. 6 1
      src/fileops.c
  5. 1 0
      src/fileops.h
  6. 127 0
      src/filetypes.c
  7. 22 0
      src/filetypes.h
  8. 8 3
      src/fpga_spi.c
  9. 1 0
      src/fpga_spi.h
  10. 5 2
      src/main.c
  11. 13 12
      src/memory.c
  12. 2 0
      src/smc.c
  13. 1 0
      src/smc.h

+ 1 - 1
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

+ 22 - 1
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 - 0
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

+ 6 - 1
src/fileops.c

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

+ 1 - 0
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);

+ 127 - 0
src/filetypes.c

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

+ 8 - 3
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();
 }

+ 1 - 0
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);

+ 5 - 2
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);
 }

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

+ 2 - 0
src/smc.c

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

+ 1 - 0
src/smc.h

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