diff --git a/snes/menu.a65 b/snes/menu.a65 index 7dcd57e..a973930 100644 --- a/snes/menu.a65 +++ b/snes/menu.a65 @@ -111,6 +111,9 @@ menu_updates: lda #$20 and pad1trig+1 bne key_select + lda #$80 + and pad1trig + bne key_a bra menuupd_out key_down jsr menu_key_down @@ -127,6 +130,9 @@ key_left key_b jsr menu_key_b bra menuupd_out +key_a + jsr menu_key_a + bra menuupd_out key_select jsr menu_key_select bra menuupd_out @@ -335,9 +341,9 @@ menu_key_left: sbc listdisp sec sbc listdisp + bcc + cmp dirstart_addr bcc + - bmi + - sta dirptr_addr sep #$20 : .as rts @@ -383,6 +389,18 @@ do_setup448 jsr setup_448 rts +menu_key_a: + rep #$20 : .al + lda dirstart_addr + beq skip_key_a + sta dirptr_addr + lda #$0000 + sta menu_sel + bra select_item +skip_key_a + sep #$20 : .as + rts + select_item: rep #$20 : .al lda menu_sel @@ -425,6 +443,10 @@ select_file: sep #$20 : .as lda #$01 sta @AVR_CMD + lda #$00 + sta @$4200 + cli + jsl @infloop rts select_dir: ; y = direntry ptr diff --git a/src/filetypes.c b/src/filetypes.c index 4d99450..b026b04 100644 --- a/src/filetypes.c +++ b/src/filetypes.c @@ -83,6 +83,13 @@ uint16_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) { if (res == FR_OK) { if(pass && parent_tgt) { // write backlink to parent dir + // switch to next bank if record does not fit in current bank + if((db_tgt&0xffff) > ((0x10000-(sizeof(next_subdir_tgt)+sizeof(len)+4))&0xffff)) { + dprintf("switch! old=%lx ", db_tgt); + db_tgt &= 0xffff0000; + db_tgt += 0x00010000; + dprintf("new=%lx\n", db_tgt); + } sram_writelong(parent_tgt, db_tgt); sram_writebyte(0, db_tgt+sizeof(next_subdir_tgt)); sram_writeblock("../\0", db_tgt+sizeof(next_subdir_tgt)+sizeof(len), 4); @@ -121,6 +128,12 @@ uint16_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) { // save element: // - path name // - pointer to sub dir structure + if((db_tgt&0xffff) > ((0x10000-(sizeof(next_subdir_tgt) + sizeof(len) + pathlen + 2))&0xffff)) { + dprintf("switch! old=%lx ", db_tgt); + db_tgt &= 0xffff0000; + db_tgt += 0x00010000; + dprintf("new=%lx\n", db_tgt); + } dprintf(" Saving dir descriptor to %lX, tgt=%lX, path=%s\n", db_tgt, next_subdir_tgt, path); // _delay_ms(100); sram_writelong(next_subdir_tgt, db_tgt); @@ -161,6 +174,12 @@ uint16_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) { // 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); + if((db_tgt&0xffff) > ((0x10000-(sizeof(romprops) + sizeof(len) + pathlen + 1))&0xffff)) { + dprintf("switch! old=%lx ", db_tgt); + db_tgt &= 0xffff0000; + db_tgt += 0x00010000; + dprintf("new=%lx\n", db_tgt); + } sram_writelong(db_tgt, dir_tgt); // sram_writeblock((uint8_t*)&db_tgt, dir_tgt, sizeof(db_tgt)); dir_tgt += 4; diff --git a/src/fpga.c b/src/fpga.c index f790645..388e490 100644 --- a/src/fpga.c +++ b/src/fpga.c @@ -106,10 +106,16 @@ void fpga_pgm(uint8_t* filename) { } void set_avr_ena(uint8_t val) { - if(val) { + if(val) { // shared mode PORTD |= _BV(PD7); - } else { + // Disable SPI double speed mode -> clock = f/4 + SPSR = 0; + dprintf("SPI slow\n"); + } else { // avr only PORTD &= ~_BV(PD7); + // Enable SPI double speed mode -> clock = f/2 + SPSR = _BV(SPI2X); + dprintf("SPI fast\n"); } } diff --git a/src/led.c b/src/led.c index fd431ca..d60cb30 100644 --- a/src/led.c +++ b/src/led.c @@ -84,5 +84,7 @@ void led_pwm() { } void led_std() { + set_busy_led(0); TCCR0A = 0; + TCCR0B = 0; } diff --git a/src/main.c b/src/main.c index 8558e80..8ec0a03 100644 --- a/src/main.c +++ b/src/main.c @@ -151,6 +151,8 @@ int main(void) { fpga_spi_init(); uart_putc('!'); _delay_ms(100); + +restart: set_avr_ena(0); snes_reset(1); @@ -160,14 +162,11 @@ int main(void) { uint16_t mem_dir_id = sram_readshort(SRAM_DIRID); uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD); - led_pwm(); 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); @@ -201,6 +200,9 @@ int main(void) { load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR); load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR); } + + led_pwm(); + uart_putc('('); load_rom((uint8_t*)"/sd2snes/menu.bin"); set_rom_mask(0x3fffff); // force mirroring off @@ -229,9 +231,13 @@ int main(void) { set_avr_ena(0); dprintf("Selected name: %s\n", file_lfn); load_rom(file_lfn); - strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm"); - dprintf("SRM file: %s\n", file_lfn); - load_sram(file_lfn, SRAM_SAVE_ADDR); + if(romprops.ramsize_bytes) { + strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm"); + dprintf("SRM file: %s\n", file_lfn); + load_sram(file_lfn, SRAM_SAVE_ADDR); + } else { + dprintf("No SRAM\n"); + } set_avr_ena(1); snes_reset(1); _delay_ms(100); @@ -247,12 +253,45 @@ int main(void) { dprintf("cmd was %x, going to snes main loop\n", cmd); led_std(); cmd=0; + uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0; + uint16_t reset_count=0; while(1) { - if(get_snes_reset()) { - dprintf("RESET\n"); + snes_reset_now=get_snes_reset(); + if(snes_reset_now) { + if(!snes_reset_prev) { + dprintf("RESET BUTTON DOWN\n"); + snes_reset_state=1; + // reset reset counter + reset_count=0; + } + } else { + if(snes_reset_prev) { + dprintf("RESET BUTTON UP\n"); + snes_reset_state=0; + } } - sram_reliable(); - snes_main_loop(); + if(snes_reset_state) { + _delay_ms(10); + reset_count++; + } else { + sram_reliable(); + snes_main_loop(); + } + if(reset_count>100) { + reset_count=0; + led_std(); + set_avr_ena(0); + snes_reset(1); + if(romprops.ramsize_bytes) { + set_busy_led(1); + save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR); + set_busy_led(0); + } + _delay_ms(1000); + set_busy_led(1); + goto restart; + } + snes_reset_prev = snes_reset_now; } diff --git a/src/memory.c b/src/memory.c index 8eb1b52..aabcb83 100644 --- a/src/memory.c +++ b/src/memory.c @@ -124,7 +124,6 @@ void sram_writeblock(void* buf, uint32_t addr, uint16_t size) { } uint32_t load_rom(uint8_t* filename) { - snes_romprops_t romprops; set_avr_bank(0); UINT bytes_read; DWORD filesize; @@ -269,6 +268,7 @@ uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) { uint8_t sram_reliable() { uint16_t score=0; + uint32_t val; // uint32_t val = sram_readlong(SRAM_SCRATCHPAD); uint8_t result = 0; /* while(score=maxscore) { score_idx=num; @@ -81,7 +94,7 @@ void smc_id(snes_romprops_t* props) { } // restore the chosen one - dprintf("winner is %d\n", score_idx); +// dprintf("winner is %d\n", score_idx); // _delay_ms(30); file_readblock(header, hdr_addr[score_idx], sizeof(snes_header_t)); switch(header->map & 0xef) { @@ -118,6 +131,11 @@ void smc_id(snes_romprops_t* props) { props->ramsize_bytes = (uint32_t)1024 << header->ramsize; props->romsize_bytes = (uint32_t)1024 << header->romsize; props->expramsize_bytes = (uint32_t)1024 << header->expramsize; +// dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); + if(props->ramsize_bytes > 32768 || props->ramsize_bytes < 2048) { + props->ramsize_bytes = 0; + } +// dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); f_lseek(&file_handle, 0); } diff --git a/src/smc.h b/src/smc.h index c19a96b..5f7c070 100644 --- a/src/smc.h +++ b/src/smc.h @@ -39,9 +39,4 @@ typedef struct _snes_romprops { void smc_id(snes_romprops_t*); uint8_t smc_headerscore(snes_header_t*); - -/*pedef struct { - -}*/ - #endif diff --git a/src/snes.c b/src/snes.c index f35decf..a6de9c8 100644 --- a/src/snes.c +++ b/src/snes.c @@ -11,11 +11,10 @@ #include "fileops.h" #include "ff.h" #include "led.h" - +#include "smc.h" uint8_t initloop=1; uint32_t saveram_crc, saveram_crc_old; -uint32_t saveram_size = 8192; // sane default uint32_t saveram_base_addr = 0x600000; // chip 3 void snes_init() { DDRD |= _BV(PD5); // PD5 = RESET_DIR @@ -55,14 +54,15 @@ uint8_t get_snes_reset() { * SD2SNES main loop. * monitors SRAM changes and other things */ -uint32_t diffcount = 0, samecount = 0; +uint32_t diffcount = 0, samecount = 0, didnotsave = 0; uint8_t sram_valid = 0; void snes_main_loop() { + if(!romprops.ramsize_bytes)return; if(initloop) { - saveram_crc_old = calc_sram_crc(saveram_base_addr, saveram_size); + saveram_crc_old = calc_sram_crc(saveram_base_addr, romprops.ramsize_bytes); initloop=0; } - saveram_crc = calc_sram_crc(saveram_base_addr, saveram_size); + saveram_crc = calc_sram_crc(saveram_base_addr, romprops.ramsize_bytes); sram_valid = sram_reliable(); if(crc_valid && sram_valid) { if(saveram_crc != saveram_crc_old) { @@ -70,23 +70,33 @@ void snes_main_loop() { diffcount=1; } else { diffcount++; + didnotsave++; } samecount=0; } if(saveram_crc == saveram_crc_old) { samecount++; } - if(diffcount>=1 && samecount==3) { + if(diffcount>=1 && samecount==5) { uart_putc('U'); uart_puthexshort(saveram_crc); uart_putcrlf(); set_busy_led(1); - save_sram(file_lfn, saveram_size, saveram_base_addr); + save_sram(file_lfn, romprops.ramsize_bytes, saveram_base_addr); set_busy_led(0); + didnotsave=0; + } + if(didnotsave>50) { + diffcount=0; + uart_putc('V'); + set_busy_led(1); + save_sram(file_lfn, romprops.ramsize_bytes, saveram_base_addr); + didnotsave=0; + set_busy_led(0); } saveram_crc_old = saveram_crc; } - dprintf("crc_valid=%d sram_valid=%d diffcount=%ld samecount=%ld\n", crc_valid, sram_valid, diffcount, samecount); + dprintf("crc_valid=%d sram_valid=%d diffcount=%ld samecount=%ld, didnotsave=%ld\n", crc_valid, sram_valid, diffcount, samecount, didnotsave); } /*