ikari před 14 roky
rodič
revize
0b46b04dd9
6 změnil soubory, kde provedl 119 přidání a 39 odebrání
  1. binární
      pcb/cart/sd2snes18.sch
  2. 40 24
      src/main.c
  3. 28 0
      src/memory.c
  4. 4 1
      src/memory.h
  5. 45 14
      src/snes.c
  6. 2 0
      src/snes.h

binární
pcb/cart/sd2snes18.sch


+ 40 - 24
src/main.c

@@ -154,40 +154,53 @@ 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, 0); // generate files footprint
-	dprintf("curr dir id = %x\n", curr_dir_id);
 	uint16_t saved_dir_id;
+	get_db_id(&saved_dir_id);
 
+	uint16_t mem_dir_id = sram_readshort(SRAM_DIRID);
+	uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
 	led_pwm();
 
-	if((get_db_id(&saved_dir_id) != FR_OK)	// no database?
-	|| 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, 0);	// then rebuild database
-		sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 2);
-		uint32_t endaddr, direndaddr;
-		sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
-		sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
-		dprintf("%lx %lx\n", endaddr, direndaddr);
-		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);
-	}
+	if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) {
+		uint16_t curr_dir_id = scan_dir(fs_path, 0, 0); // generate files footprint
+		dprintf("curr dir id = %x\n", curr_dir_id);
+
+		led_pwm();
+	
+		if((get_db_id(&saved_dir_id) != FR_OK)	// no database?
+		|| 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, 0);	// then rebuild database
+			sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 2);
+			uint32_t endaddr, direndaddr;
+			sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
+			sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
+			dprintf("%lx %lx\n", endaddr, direndaddr);
+			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("different card, consistent db, loading db...\n");
+			load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
+			load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
+		}
 //	save_sram((uint8_t*)"/debug.smc", 0x400000, 0);	
 //	uart_putc('[');
 //	load_sram((uint8_t*)"/test.srm", SRAM_SAVE_ADDR);
 //	uart_putc(']');
 
+		sram_writeshort(curr_dir_id, SRAM_DIRID);
+		sram_writelong(0x12345678, SRAM_SCRATCHPAD);
+	} else {
+		dprintf("same card, 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_rom((uint8_t*)"/sd2snes/menu.bin");
 	set_rom_mask(0x3fffff); // force mirroring off
@@ -229,6 +242,9 @@ int main(void) {
 	dprintf("cmd was %x, going to snes main loop\n", cmd);
 	cmd=0;
 	while(1) {
+		if(get_snes_reset()) {
+			dprintf("RESET\n");
+		}
 		snes_main_loop();
 	}
 

+ 28 - 0
src/memory.c

@@ -17,6 +17,7 @@
 #include "smc.h"
 #include "fpga_spi.h"
 #include "memory.h"
+#include "snes.h"
 
 char* hex = "0123456789ABCDEF";
 
@@ -48,6 +49,16 @@ uint8_t sram_readbyte(uint32_t addr) {
 	return val;
 }
 
+void sram_writeshort(uint16_t val, uint32_t addr) {
+	set_avr_addr(addr);
+	spi_fpga();
+	spiTransferByte(0x91); // WRITE
+	spiTransferByte(val&0xff);		// 7-0
+	spiTransferByte((val>>8)&0xff);		// 15-8
+	spiTransferByte(0x00); // dummy
+	spi_none();
+}
+
 void sram_writelong(uint32_t val, uint32_t addr) {
 	set_avr_addr(addr);
 	spi_fpga();
@@ -60,6 +71,18 @@ void sram_writelong(uint32_t val, uint32_t addr) {
 	spi_none();
 }
 
+uint16_t sram_readshort(uint32_t addr) {
+	set_avr_addr(addr);
+	spi_fpga();
+	spiTransferByte(0x81);
+	spiTransferByte(0x00);
+
+	uint32_t val = spiTransferByte(0x00);
+	val |= ((uint32_t)spiTransferByte(0x00)<<8);
+	spi_none();
+	return val;
+}
+
 uint32_t sram_readlong(uint32_t addr) {
 	set_avr_addr(addr);
 	spi_fpga();
@@ -227,12 +250,17 @@ uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) {
 	uint32_t count;
 	uint16_t crc;
 	crc=0;
+	crc_valid=1;
 	set_avr_addr(base_addr);
 	spi_fpga();
 	spiTransferByte(0x81);
 	spiTransferByte(0x00);
 	for(count=0; count<size; count++) {
 		data = spiTransferByte(0);
+		if(get_snes_reset()) {
+			crc_valid = 0;
+			break;
+		}
 		crc += crc16_update(crc, &data, 1);
 	}
 	spi_none();

+ 4 - 1
src/memory.h

@@ -10,15 +10,18 @@
 #define SRAM_CMD_ADDR (0x601004L)
 #define SRAM_FD_ADDR (0x601000L)
 #define SRAM_SAVE_ADDR (0x600000L)
-#define SRAM_SCRATCHPAD (0x7FFFF0L)
+#define SRAM_SCRATCHPAD (0x7FFF00L)
+#define SRAM_DIRID (0x7FFFF0L)
 #define SRAM_RELIABILITY_SCORE (0x100)
 
 	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);
+	uint16_t sram_readshort(uint32_t addr);
 	uint32_t sram_readlong(uint32_t addr);
 	void sram_writebyte(uint8_t val, uint32_t addr);
+	void sram_writeshort(uint16_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);

+ 45 - 14
src/snes.c

@@ -31,34 +31,60 @@ void snes_init() {
 void snes_reset(int state) {
 	if(state) {
 		DDRD |= _BV(PD6);	// /RESET pin -> out
-		PORTD &= ~_BV(PD6); // /RESET = 0
-		PORTD |= _BV(PD5);  // RESET_DIR = 1;
+		PORTD &= ~_BV(PD6);	// /RESET = 0
+		PORTD |= _BV(PD5);	// RESET_DIR = 1;
 	} else {
-		PORTD &= ~_BV(PD5); // RESET_DIR = 0;
-		DDRD &= ~_BV(PD6);  // /RESET pin -> in
-		PORTD |= _BV(PD6);  // /RESET = 1
+		PORTD &= ~_BV(PD5);	// RESET_DIR = 0;
+		DDRD &= ~_BV(PD6);	// /RESET pin -> in
+		PORTD |= _BV(PD6);	// /RESET = pullup
 	}
 }
 
+/*
+ * gets the SNES reset state.
+ *
+ * returns: 1 when reset, 0 when not reset
+ */
+uint8_t get_snes_reset() {
+//	DDRD &= ~_BV(PD6);	// /RESET pin -> in
+//	PORTD &= ~_BV(PD5);	// RESET_DIR (external buffer) = 0
+	return !(PIND & _BV(PD6));
+}
+
 /*
  * SD2SNES main loop.
  * monitors SRAM changes and other things
  */
+uint32_t diffcount = 0, samecount = 0;
 void snes_main_loop() {
 	if(initloop) {
 		saveram_crc_old = calc_sram_crc(saveram_base_addr, saveram_size);
 		initloop=0;
 	}
 	saveram_crc = calc_sram_crc(saveram_base_addr, saveram_size);
-	if(saveram_crc != saveram_crc_old) {
-		uart_putc('U');
-		uart_puthexshort(saveram_crc);
-		uart_putcrlf();
-		set_busy_led(1);
-		save_sram((uint8_t*)"/test.srm", saveram_size, saveram_base_addr);
-		set_busy_led(0);
+	if(crc_valid) {
+		if(saveram_crc != saveram_crc_old) {
+			if(samecount) {
+				diffcount=1;
+			} else {
+				diffcount++;
+			}
+			samecount=0;
+		}
+		if(saveram_crc == saveram_crc_old) {
+			samecount++;
+		}
+		if(diffcount>=1 && samecount==3) {
+			uart_putc('U');
+			uart_puthexshort(saveram_crc);
+			uart_putcrlf();
+			set_busy_led(1);
+			save_sram((uint8_t*)"/test.srm", saveram_size, saveram_base_addr);
+			set_busy_led(0);
+		}
+		saveram_crc_old = saveram_crc;
 	}
-	saveram_crc_old = saveram_crc;
+	dprintf("valid=%d diffcount=%ld samecount=%ld\n", crc_valid, diffcount, samecount);
 }
 
 /*
@@ -69,7 +95,12 @@ uint8_t menu_main_loop() {
 	uint8_t cmd = 0;
 	sram_writebyte(0, SRAM_CMD_ADDR);
 	while(!cmd) {
-		cmd = sram_readbyte(SRAM_CMD_ADDR);
+		if(!get_snes_reset()) {
+			cmd = sram_readbyte(SRAM_CMD_ADDR);
+		}
+		if(get_snes_reset()) {
+			cmd = 0;
+		}
 	}
 	return cmd;
 }

+ 2 - 0
src/snes.h

@@ -4,9 +4,11 @@
 
 #ifndef SNES_H
 #define SNES_H
+uint8_t crc_valid;
 
 void snes_init(void);
 void snes_reset(int state);
+uint8_t get_snes_reset(void);
 void snes_main_loop(void);
 uint8_t menu_main_loop(void);
 void get_selected_name(uint8_t* lfn);