ikari 14 years ago
parent
commit
c685f9a09f
13 changed files with 170 additions and 54 deletions
  1. 7 5
      snes/main.a65
  2. 1 1
      src/Makefile
  3. 1 0
      src/config
  4. 1 1
      src/fileops.c
  5. 2 1
      src/fileops.h
  6. 29 24
      src/filetypes.c
  7. 1 1
      src/fpga.c
  8. 1 1
      src/fpga.h
  9. 43 9
      src/main.c
  10. 47 5
      src/memory.c
  11. 14 3
      src/memory.h
  12. 21 3
      src/snes.c
  13. 2 0
      src/snes.h

+ 7 - 5
snes/main.a65

@@ -8,15 +8,17 @@ GAME_MAIN:
 	jsr setup_hdma
 	jsr tests
 	jsr colortest
-	lda #$01
+	lda #$00
 	sta @$306000
-	inc
+	lda #$50
 	sta @$306001
-	inc
+	lda #$11
 	sta @$306002
-	inc
+	lda #$00
 	sta @$306003
-	
+	lda #$01
+	sta @$306004
+	cli
 	jmp @infloop	;infinite loop in WRAM
 
 colortest:

+ 1 - 1
src/Makefile

@@ -343,7 +343,7 @@ endif
 # Uncomment the following if you want avrdude's erase cycle counter.
 # Note that this counter needs to be initialized first using -Yn,
 # see avrdude manual.
-#AVRDUDE_ERASE_COUNTER = -y
+AVRDUDE_ERASE_COUNTER = -y
 
 # Uncomment the following if you do /not/ wish a verification to be
 # performed after programming the device.

+ 1 - 0
src/config

@@ -39,3 +39,4 @@ CONFIG_SD_AUTO_RETRIES=10
 CONFIG_EEPROM_SIZE=512
 CONFIG_EEPROM_OFFSET=512
 CONFIG_MAX_PARTITIONS=1
+CONFIG_DEADLOCK_ME_HARDER=y

+ 1 - 1
src/fileops.c

@@ -18,7 +18,7 @@ void file_init() {
 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) {
+void file_open(uint8_t* filename, BYTE flags) {
 	file_res = f_open(&file_handle, (unsigned char*)filename, flags);
 }
 

+ 2 - 1
src/fileops.h

@@ -9,9 +9,10 @@ BYTE file_buf[512];
 FATFS fatfs;
 FIL file_handle;
 FRESULT file_res;
+uint8_t file_lfn[256];
 
 void file_init(void);
-void file_open(char* filename, BYTE flags);
+void file_open(uint8_t* filename, BYTE flags);
 void file_open_by_filinfo(FILINFO* fno);
 void file_close(void);
 UINT file_read(void);

+ 29 - 24
src/filetypes.c

@@ -12,6 +12,7 @@
 #include "fileops.h"
 #include "crc16.h"
 #include "memory.h"
+#include "led.h"
 
 uint16_t scan_flat(const char* path) {
 	DIR dir;
@@ -34,9 +35,8 @@ uint16_t scan_dir(char* path, char mkdb) {
 	DIR dir;
 	FILINFO fno;
 	FRESULT res;
-	int len;
+	uint8_t len;
 	unsigned char* fn;
-	static unsigned char lfn[256];
 	static unsigned char depth = 0;
 	static uint16_t crc;
 	static uint32_t db_tgt;
@@ -50,12 +50,12 @@ uint16_t scan_dir(char* path, char mkdb) {
 
 	if(depth==0) {
 		crc = 0;
-		db_tgt = SRAM_WORK_ADDR+0x200;
-		dir_tgt = SRAM_WORK_ADDR+0x100000;
+		db_tgt = SRAM_DB_ADDR+0x10;
+		dir_tgt = SRAM_DIR_ADDR;
 		dprintf("root dir @%lx\n", dir_tgt);
 	}	
 	
-	fno.lfn = lfn;
+	fno.lfn = file_lfn;
 	numentries=0;
 	dir_tgt_next=0;
 	for(pass = 0; pass < 2; pass++) {
@@ -65,11 +65,11 @@ uint16_t scan_dir(char* path, char mkdb) {
 			if(dir_tgt_next > dir_end) {
 				dir_end = dir_tgt_next;
 			}
-			dprintf("path=%s depth=%d ptr=%lx entries=%d next subdir @%lx\n", path, depth, db_tgt, numentries, dir_tgt_next);
-			_delay_ms(50);
+//			dprintf("path=%s depth=%d ptr=%lx entries=%d next subdir @%lx\n", path, depth, db_tgt, numentries, dir_tgt_next);
+//			_delay_ms(50);
 			if(mkdb) {
-				dprintf("d=%d Saving %lX to Address %lX  [end]\n", depth, 0L, dir_tgt_next - 4);
-				_delay_ms(50);	
+//				dprintf("d=%d Saving %lX to Address %lX  [end]\n", depth, 0L, dir_tgt_next - 4);
+//				_delay_ms(50);	
 				sram_writelong(0L, dir_tgt_next - 4);
 			}
 		}
@@ -77,6 +77,7 @@ uint16_t scan_dir(char* path, char mkdb) {
 		if (res == FR_OK) {
 			len = strlen((char*)path);
 			for (;;) {
+				toggle_busy_led();
 				res = f_readdir(&dir, &fno);
 				if (res != FR_OK || fno.fname[0] == 0) {
 					if(pass) {
@@ -97,21 +98,23 @@ uint16_t scan_dir(char* path, char mkdb) {
 						dir_tgt_save = dir_tgt;
 						dir_tgt = dir_tgt_next;
 						if(mkdb) {
+							uint16_t pathlen = strlen(path);
 							// write element pointer to current dir structure
-							dprintf("d=%d Saving %lX to Address %lX  [dir]\n", depth, db_tgt, dir_tgt_save);
-							_delay_ms(50);
-							sram_writelong(db_tgt, dir_tgt_save);
+//							dprintf("d=%d Saving %lX to Address %lX  [dir]\n", depth, db_tgt, dir_tgt_save);
+//							_delay_ms(50);
+							sram_writelong(db_tgt|((uint32_t)0x80<<24), dir_tgt_save);
 //							sram_writeblock((uint8_t*)&db_tgt, dir_tgt_save, sizeof(dir_tgt_save));
 
 							// save element:
 							//  - path name
 							//  - pointer to sub dir structure
-							dprintf("    Saving dir descriptor to %lX, tgt=%lX, path=%s\n", db_tgt, dir_tgt, path);
-							_delay_ms(100);
-							sram_writeblock(path, db_tgt, 256);
-							sram_writelong(dir_tgt|((uint32_t)0x80<<24), db_tgt+256);
+//							dprintf("    Saving dir descriptor to %lX, tgt=%lX, path=%s\n", db_tgt, dir_tgt, path);
+//							_delay_ms(100);
+							sram_writelong(dir_tgt, db_tgt);
+							sram_writebyte(len+1, db_tgt+sizeof(dir_tgt));
+							sram_writeblock(path, db_tgt+sizeof(dir_tgt)+sizeof(len), pathlen + 1);
 //							sram_writeblock((uint8_t*)&dir_tgt, db_tgt+256, sizeof(dir_tgt));
-							db_tgt += 0x200;
+							db_tgt += sizeof(dir_tgt) + sizeof(len) + pathlen + 1;
 						}
 						scan_dir(path, mkdb);
 						dir_tgt = dir_tgt_save + 4;
@@ -129,6 +132,7 @@ uint16_t scan_dir(char* path, char mkdb) {
 								snes_romprops_t romprops;
 								path[len]='/';
 								strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
+								uint16_t pathlen = strlen(path);
 								switch(type) {
 									case TYPE_SMC:
 										file_open_by_filinfo(&fno);
@@ -140,8 +144,8 @@ uint16_t scan_dir(char* path, char mkdb) {
 										file_close();
 		//								_delay_ms(30);
 										// write element pointer to current dir structure
-										dprintf("d=%d Saving %lX to Address %lX  [file]\n", depth, db_tgt, dir_tgt);
-										_delay_ms(50);
+//										dprintf("d=%d Saving %lX to Address %lX  [file]\n", depth, db_tgt, dir_tgt);
+//										_delay_ms(50);
 										sram_writelong(db_tgt, dir_tgt);
 //										sram_writeblock((uint8_t*)&db_tgt, dir_tgt, sizeof(db_tgt));
 										dir_tgt += 4;
@@ -149,8 +153,9 @@ uint16_t scan_dir(char* path, char mkdb) {
 										//  - SNES header information
 										//  - file name
 										sram_writeblock((uint8_t*)&romprops, db_tgt, sizeof(romprops));
-										sram_writeblock(path, db_tgt + sizeof(romprops), 256);
-										db_tgt += 0x200;
+										sram_writebyte(len+1, db_tgt + sizeof(romprops));
+										sram_writeblock(path, db_tgt + sizeof(romprops) + sizeof(len), pathlen + 1);
+										db_tgt += sizeof(romprops) + sizeof(len) + pathlen + 1;
 										break;
 									case TYPE_UNKNOWN:
 									default:
@@ -175,8 +180,8 @@ uint16_t scan_dir(char* path, char mkdb) {
 	}
 //	dprintf("%x\n", crc);
 //	_delay_ms(50);
-	sram_writeblock(&db_tgt, SRAM_WORK_ADDR+4, sizeof(db_tgt));
-	sram_writeblock(&dir_end, SRAM_WORK_ADDR+8, sizeof(dir_end));
+	sram_writeblock(&db_tgt, SRAM_DB_ADDR+4, sizeof(db_tgt));
+	sram_writeblock(&dir_end, SRAM_DB_ADDR+8, sizeof(dir_end));
 	return crc;
 }
 
@@ -198,7 +203,7 @@ SNES_FTYPE determine_filetype(char* filename) {
 }
 
 FRESULT get_db_id(uint16_t* id) {
-	file_open("/sd2snes/sd2snes.db", FA_READ);
+	file_open((uint8_t*)"/sd2snes/sd2snes.db", FA_READ);
 	if(file_res == FR_OK) {
 		file_readblock(id, 0, 2);
 /* XXX */// *id=0xdead;

+ 1 - 1
src/fpga.c

@@ -67,7 +67,7 @@ void fpga_postinit() {
 	DDRD |= _BV(PD7);	// turn PD7 into output
 }
 
-void fpga_pgm(char* filename) {
+void fpga_pgm(uint8_t* filename) {
 	int MAXRETRIES = 10;
 	int retries = MAXRETRIES;
 	do {

+ 1 - 1
src/fpga.h

@@ -7,7 +7,7 @@
 
 void fpga_init(void);
 void fpga_postinit(void);
-void fpga_pgm(char* filename);
+void fpga_pgm(uint8_t* filename);
 
 void set_avr_read(uint8_t val);
 void set_avr_write(uint8_t val);

+ 43 - 9
src/main.c

@@ -145,7 +145,7 @@ int main(void) {
 	f_mount(0,&fatfs);
 	uart_putc('W');
 	fpga_init();
-	fpga_pgm("/sd2snes/main.bit");
+	fpga_pgm((uint8_t*)"/sd2snes/main.bit");
 	_delay_ms(100);
 	set_pwr_led(1);
 	fpga_spi_init();
@@ -154,34 +154,43 @@ int main(void) {
 	set_avr_ena(0);
 	snes_reset(1);
 
+	sram_writelong(0x12345678, SRAM_SCRATCHPAD);
 	*fs_path=0;
 	uint16_t curr_dir_id = scan_dir(fs_path, 0); // generate files footprint
 	dprintf("curr dir id = %x\n", curr_dir_id);
 	uint16_t saved_dir_id;
 	if((get_db_id(&saved_dir_id) != FR_OK)	// no database?
-	|| 1 /*saved_dir_id != curr_dir_id*/) {	// files changed? // XXX
+	|| 1 || saved_dir_id != curr_dir_id) {	// files changed? // XXX
 		dprintf("saved dir id = %x\n", saved_dir_id);
 		_delay_ms(50);
 		dprintf("rebuilding database...");
 		_delay_ms(50);
 		curr_dir_id = scan_dir(fs_path, 1);	// then rebuild database
-		sram_writeblock(&curr_dir_id, SRAM_WORK_ADDR, 2);
+		sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 2);
 		uint32_t endaddr, direndaddr;
-		sram_readblock(&endaddr, SRAM_WORK_ADDR+4, 4);
-		sram_readblock(&direndaddr, SRAM_WORK_ADDR+8, 4);
+		sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
+		sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
 		dprintf("%lx %lx\n", endaddr, direndaddr);
-		save_sram("/sd2snes/sd2snes.db", endaddr-SRAM_WORK_ADDR, SRAM_WORK_ADDR);
-		save_sram("/sd2snes/sd2snes.dir", direndaddr-(SRAM_WORK_ADDR+0x100000), SRAM_WORK_ADDR+0x100000);
+		save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
+		save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
 		dprintf("done\n"); 
+		sram_hexdump(SRAM_DB_ADDR, 0x400);
+	} else {
+		dprintf("loading db...\n");
+		load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
+		load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
 	}
+	
 	uart_putc('[');
-	load_sram("/test.srm");
+	load_sram((uint8_t*)"/test.srm", SRAM_SAVE_ADDR);
 	uart_putc(']');
 
 	uart_putc('(');
-	load_rom("/test.smc");
+	load_rom((uint8_t*)"/test.smc");
 	uart_putc(')');
 
+	sram_writebyte(0, SRAM_CMD_ADDR);
+
 	set_busy_led(0);
 	set_avr_ena(1);
 
@@ -189,7 +198,32 @@ int main(void) {
 	uart_puts_P(PSTR("SNES GO!\n"));
 	snes_reset(0);
 
+	uint8_t cmd = 0;
+
+	while(!sram_reliable());
 
+	while(!cmd) {
+		cmd=menu_main_loop();
+		switch(cmd) {
+			case 0x01: // SNES_CMD_LOADROM:
+				get_selected_name(file_lfn);
+				_delay_ms(100);
+//				snes_reset(1);
+				set_avr_ena(0);
+				dprintf("%s\n", file_lfn);
+				load_rom(file_lfn);
+				set_avr_ena(1);
+				snes_reset(1);
+				_delay_ms(100);
+				snes_reset(0);
+				break;
+			default:
+			break;
+		}
+		
+	}
+	dprintf("cmd was %x, going to snes main loop\n", cmd);
+	cmd=0;
 	while(1) {
 		snes_main_loop();
 	}

+ 47 - 5
src/memory.c

@@ -16,9 +16,38 @@
 #include "led.h"
 #include "smc.h"
 #include "fpga_spi.h"
+#include "memory.h"
 
 char* hex = "0123456789ABCDEF";
 
+void sram_hexdump(uint32_t addr, uint32_t len) {
+	static uint8_t buf[16];
+	uint32_t ptr;
+	for(ptr=0; ptr < len; ptr += 16) {
+		sram_readblock((void*)buf, ptr+addr, 16);
+		uart_trace(buf, 0, 16);
+	}
+}
+
+void sram_writebyte(uint8_t val, uint32_t addr) {
+	set_avr_addr(addr);
+	spi_fpga();
+	spiTransferByte(0x91); // WRITE
+	spiTransferByte(val);
+	spiTransferByte(0x00); // dummy
+	spi_none();
+}
+
+uint8_t sram_readbyte(uint32_t addr) {
+	set_avr_addr(addr);
+	spi_fpga();
+	spiTransferByte(0x81); // READ
+	spiTransferByte(0x00); // dummy
+	uint8_t val = spiTransferByte(0x00);
+	spi_none();
+	return val;
+}
+
 void sram_writelong(uint32_t val, uint32_t addr) {
 	set_avr_addr(addr);
 	spi_fpga();
@@ -41,7 +70,7 @@ uint32_t sram_readlong(uint32_t addr) {
 	val |= ((uint32_t)spiTransferByte(0x00)<<8);
 	val |= ((uint32_t)spiTransferByte(0x00)<<16);
 	val |= ((uint32_t)spiTransferByte(0x00)<<24);
-	
+	spi_none();
 	return val;
 }
 
@@ -71,7 +100,7 @@ void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
 	spi_none();
 }
 
-uint32_t load_rom(char* filename) {
+uint32_t load_rom(uint8_t* filename) {
 	snes_romprops_t romprops;
 	set_avr_bank(0);
 	UINT bytes_read;
@@ -138,8 +167,8 @@ uint32_t load_rom(char* filename) {
 	return (uint32_t)filesize;
 }
 
-uint32_t load_sram(char* filename) {
-	set_avr_bank(3);
+uint32_t load_sram(uint8_t* filename, uint32_t base_addr) {
+	set_avr_addr(base_addr);
 	UINT bytes_read;
 	DWORD filesize;
 	file_open(filename, FA_READ);
@@ -164,7 +193,7 @@ uint32_t load_sram(char* filename) {
 }
 
 
-void save_sram(char* filename, uint32_t sram_size, uint32_t base_addr) {
+void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
     uint32_t count = 0;
 	uint32_t num = 0;
 
@@ -208,3 +237,16 @@ uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) {
 	spi_none();
 	return crc;
 }
+
+uint8_t sram_reliable() {
+	uint16_t score=0;
+	uint32_t val = sram_readlong(SRAM_SCRATCHPAD);
+	while(score<SRAM_RELIABILITY_SCORE) {
+		if(sram_readlong(SRAM_SCRATCHPAD)==val) {
+			score++;
+		} else {
+			score=0;
+		}
+	}
+	return 1;
+}

+ 14 - 3
src/memory.h

@@ -5,13 +5,24 @@
 #define MEMORY_H
 
 #define SRAM_WORK_ADDR	(0x100000L)
+#define SRAM_DB_ADDR (0x080000L)
+#define SRAM_DIR_ADDR (0x300000L)
+#define SRAM_CMD_ADDR (0x600004L)
+#define SRAM_FD_ADDR (0x600000L)
+#define SRAM_SAVE_ADDR (0x600000L)
+#define SRAM_SCRATCHPAD (0x7FFFF0L)
+#define SRAM_RELIABILITY_SCORE (0x100)
 
-	uint32_t load_rom(char* filename);
-	uint32_t load_sram(char* filename);
+	uint32_t load_rom(uint8_t* filename);
+	uint32_t load_sram(uint8_t* filename, uint32_t base_addr);
+	void sram_hexdump(uint32_t addr, uint32_t len);
+	uint8_t sram_readbyte(uint32_t addr);
 	uint32_t sram_readlong(uint32_t addr);
+	void sram_writebyte(uint8_t val, uint32_t addr);
 	void sram_writelong(uint32_t val, uint32_t addr);
 	void sram_readblock(void* buf, uint32_t addr, uint16_t size);
 	void sram_writeblock(void* buf, uint32_t addr, uint16_t size);
-	void save_sram(char* filename, uint32_t sram_size, uint32_t base_addr);
+	void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr);
 	uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size);
+	uint8_t sram_reliable(void);
 #endif

+ 21 - 3
src/snes.c

@@ -42,12 +42,11 @@ void snes_reset(int state) {
 
 /*
  * SD2SNES main loop.
- * monitors SRAM changes, menu selections and other things
+ * monitors SRAM changes and other things
  */
 void snes_main_loop() {
 	if(initloop) {
 		saveram_crc_old = calc_sram_crc(saveram_base_addr, saveram_size);
-		save_sram("/test.srm", saveram_size, saveram_base_addr);
 		initloop=0;
 	}
 	saveram_crc = calc_sram_crc(saveram_base_addr, saveram_size);
@@ -56,8 +55,27 @@ void snes_main_loop() {
 		uart_puthexshort(saveram_crc);
 		uart_putcrlf();
 		set_busy_led(1);
-		save_sram("/test.srm", saveram_size, saveram_base_addr);
+		save_sram((uint8_t*)"/test.srm", saveram_size, saveram_base_addr);
 		set_busy_led(0);
 	}
 	saveram_crc_old = saveram_crc;
 }
+
+/*
+ * SD2SNES menu loop.
+ * monitors menu selection. return when selection was made.
+ */
+uint8_t menu_main_loop() {
+	uint8_t cmd = 0;
+	sram_writebyte(0, SRAM_CMD_ADDR);
+	while(!cmd) {
+		cmd = sram_readbyte(SRAM_CMD_ADDR);
+	}
+	return cmd;
+}
+
+void get_selected_name(uint8_t* fn) {
+	uint32_t addr = sram_readlong(SRAM_FD_ADDR);
+	dprintf("fd addr=%lX\n", addr);
+	sram_readblock(fn, addr+0x41, 256);
+}

+ 2 - 0
src/snes.h

@@ -8,4 +8,6 @@
 void snes_init(void);
 void snes_reset(int state);
 void snes_main_loop(void);
+uint8_t menu_main_loop(void);
+void get_selected_name(uint8_t* lfn);
 #endif