diff --git a/pcb/cart/sd2snes18.sch b/pcb/cart/sd2snes18.sch index 1648ed0..5e52ea3 100644 Binary files a/pcb/cart/sd2snes18.sch and b/pcb/cart/sd2snes18.sch differ diff --git a/src/main.c b/src/main.c index 7c0b40e..b7c4021 100644 --- a/src/main.c +++ b/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(); } diff --git a/src/memory.c b/src/memory.c index 115c63f..e22320f 100644 --- a/src/memory.c +++ b/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 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; } diff --git a/src/snes.h b/src/snes.h index 06ffe46..488537d 100644 --- a/src/snes.h +++ b/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);