diff --git a/src/Makefile b/src/Makefile index d776b2e..4431e1f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -55,7 +55,7 @@ TARGET = $(OBJDIR)/sd2snes # List C source files here. (C dependencies are automatically generated.) -SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c cli.c xmodem.c irq.c rle.c sdnative.c +SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c cli.c xmodem.c irq.c rle.c sdnative.c msu1.c # List Assembler source files here. diff --git a/src/cli.c b/src/cli.c index dec6438..1eddea9 100644 --- a/src/cli.c +++ b/src/cli.c @@ -57,8 +57,8 @@ static char *curchar; /* Word lists */ static char command_words[] = - "cd\0reset\0dir\0ls\0test\0resume\0loadrom\0loadraw\0put\0d4\0vmode\0mapper\0"; -enum { CMD_CD = 0, CMD_RESET, CMD_DIR, CMD_LS, CMD_TEST, CMD_RESUME, CMD_LOADROM, CMD_LOADRAW, CMD_PUT, CMD_D4, CMD_VMODE, CMD_MAPPER }; + "cd\0reset\0dir\0ls\0test\0resume\0loadrom\0loadraw\0saveraw\0put\0d4\0vmode\0mapper\0"; +enum { CMD_CD = 0, CMD_RESET, CMD_DIR, CMD_LS, CMD_TEST, CMD_RESUME, CMD_LOADROM, CMD_LOADRAW, CMD_SAVERAW, CMD_PUT, CMD_D4, CMD_VMODE, CMD_MAPPER }; /* ------------------------------------------------------------------------- */ /* Parse functions */ @@ -151,7 +151,7 @@ static int8_t parse_wordlist(char *wordlist) { cur++; c = *ptr; } while (c != 0); - + if (matched) { char *tmp = curchar; @@ -296,6 +296,13 @@ static void cmd_loadrom(void) { snes_reset(0); } +static void cmd_saveraw(void) { + uint32_t address = parse_unsigned(0,16777216); + uint32_t length = parse_unsigned(0,16777216); + set_mcu_ovr(0); + save_sram((uint8_t*)curchar, length, address); +} + static void cmd_d4(void) { int32_t hz; @@ -451,6 +458,10 @@ void cli_loop(void) { cmd_loadrom(); break; + case CMD_SAVERAW: + cmd_saveraw(); + break; + case CMD_D4: cmd_d4(); break; diff --git a/src/config.h b/src/config.h index 68320e7..b059e8c 100644 --- a/src/config.h +++ b/src/config.h @@ -3,6 +3,7 @@ // #define DEBUG_SD // #define DEBUG_IRQ +#define DEBUG_MSU1 #define VER "0.0.1(NSFW)" #define IN_AHBRAM __attribute__ ((section(".ahbram"))) @@ -28,7 +29,7 @@ #define SD_SUPPLY_VOLTAGE (1L<<21) /* 3.3V - 3.4V */ #define CONFIG_SD_BLOCKTRANSFER 1 #define CONFIG_SD_AUTO_RETRIES 10 -// #define SD_CHANGE_VECT +// #define SD_CHANGE_VECT // #define CONFIG_SD_DATACRC 1 diff --git a/src/fpga_spi.c b/src/fpga_spi.c index ce0adcf..f085de1 100644 --- a/src/fpga_spi.c +++ b/src/fpga_spi.c @@ -27,7 +27,7 @@ SPI commands - cmd param function + cmd param function ============================================= 0t bbhhll set address to 0xbbhhll t = target @@ -50,12 +50,15 @@ 60 sssseeee set SD DMA partial transfer start+end ssss = start offset (msb first) eeee = end offset (msb first) - - 80 - read with increment (RAM only) - 81 - read w/o increment (RAM only) - 90 {xx}* write xx with increment (RAM only) - 91 {xx}* write xx w/o increment (RAM only) + 8p - read (RAM only) + p: 0 = no increment after read + 1 = increment after read + + 9p {xx}* write xx + p: tt-i + tt = target (see above) + i = increment (see above) E0 ssrr set MSU-1 status register (=FPGA status byte 2) ss = bits to set in status register (1=set) @@ -64,17 +67,17 @@ E1 - pause DAC E2 - resume/play DAC E3 - reset DAC playback pointer (0) - E4 - reset MSU read pointer (0) + E4 hhll set MSU read pointer F0 - receive test token (to see if FPGA is alive) - F1 - receive status + F1 - receive status (2 bytes) F2 - get MSU data address (32bit, MSB first) F3 - get MSU audio track no. (16bit, MSB first) F4 - get MSU volume (8bit) FE - get SNES master clock frequency (32bit, MSB first) - FF {xx]* echo (returns the sent data in the next byte) + FF {xx}* echo (returns the sent data in the next byte) */ #include diff --git a/src/main.c b/src/main.c index 5ca6812..44f58c1 100644 --- a/src/main.c +++ b/src/main.c @@ -24,6 +24,7 @@ #include "sdnative.h" #include "crc.h" #include "smc.h" +#include "msu1.h" #define EMC0TOGGLE (3<<4) #define MR0R (1<<1) @@ -68,7 +69,6 @@ int main(void) { LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */ led_pwm(); sdn_init(); - fpga_spi_init(); printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY); file_init(); cic_init(0); @@ -81,415 +81,219 @@ led_pwm(); LPC_TIM3->TCR=1; fpga_init(); fpga_rompgm(); -restart: - if(disk_state == DISK_CHANGED) { - sdn_init(); - newcard = 1; - } - load_bootrle(SRAM_MENU_ADDR); - set_saveram_mask(0x1fff); - set_rom_mask(0x3fffff); - set_mapper(0x7); - set_mcu_ovr(0); - snes_reset(0); - delay_ms(15); /* allow CIC to settle */ - while(get_cic_state() == CIC_FAIL) { - rdyled(0); - readled(0); - writeled(0); - delay_ms(500); - rdyled(1); - readled(1); - writeled(1); - delay_ms(500); - } - /* some sanity checks */ - uint8_t card_go = 0; - while(!card_go) { - if(disk_status(0) & (STA_NOINIT|STA_NODISK)) { - snes_bootprint(" No Card! \0"); - while(disk_status(0) & (STA_NOINIT|STA_NODISK)); - delay_ms(200); + while(1) { + set_mcu_ovr(1); + if(disk_state == DISK_CHANGED) { + sdn_init(); + newcard = 1; } - file_open((uint8_t*)"/sd2snes/menu.bin", FA_READ); - if(file_status != FILE_OK) { - snes_bootprint(" /sd2snes/menu.bin not found! \0"); - while(disk_status(0) == RES_OK); - } else { - card_go = 1; - } - file_close(); - } - snes_bootprint(" Loading ... \0"); - if(get_cic_state() == CIC_PAIR) { - printf("PAIR MODE ENGAGED!\n"); - cic_pair(CIC_PAL, CIC_NTSC); - } - rdyled(1); - readled(0); - writeled(0); - /* exclusive mode */ - set_mcu_ovr(1); - - *fs_path=0; - uint32_t saved_dir_id; - get_db_id(&saved_dir_id); + load_bootrle(SRAM_MENU_ADDR); + set_saveram_mask(0x1fff); + set_rom_mask(0x3fffff); + set_mapper(0x7); + set_mcu_ovr(0); + snes_reset(0); + delay_ms(15); /* allow CIC to settle */ - uint32_t mem_dir_id = sram_readlong(SRAM_DIRID); - uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD); - printf("mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id); - if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id) || (newcard)) { - newcard = 0; - /* generate fs footprint (interesting files only) */ - uint32_t curr_dir_id = scan_dir(fs_path, 0, 0); - printf("curr dir id = %lx\n", curr_dir_id); - /* files changed or no database found? */ - if((get_db_id(&saved_dir_id) != FR_OK) - || saved_dir_id != curr_dir_id) { - /* rebuild database */ - printf("saved dir id = %lx\n", saved_dir_id); - printf("rebuilding database..."); - snes_bootprint(" rebuilding database ... \0"); - curr_dir_id = scan_dir(fs_path, 1, 0); - sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 4); - uint32_t endaddr, direndaddr; - sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4); - sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4); - printf("%lx %lx\n", endaddr, direndaddr); - printf("sorting database..."); - snes_bootprint(" sorting database ... \0"); - sort_all_dir(direndaddr); - printf("done\n"); - snes_bootprint(" saving database ... \0"); - 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); - printf("done\n"); - } else { - printf("saved dir id = %lx\n", saved_dir_id); - printf("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); - } - sram_writelong(curr_dir_id, SRAM_DIRID); - sram_writelong(0x12345678, SRAM_SCRATCHPAD); - } else { - printf("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); - } - /* load menu */ - fpga_pgm((uint8_t*)"/main.bit.rle"); - - uart_putc('('); - load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR); - /* force memory size + mapper */ - set_rom_mask(0x3fffff); - set_mapper(0x7); - uart_putc(')'); - uart_putcrlf(); - - sram_writebyte(0, SRAM_CMD_ADDR); - - /* shared mode */ - set_mcu_ovr(0); - - printf("SNES GO!\n"); - snes_reset(1); - delay_ms(1); - snes_reset(0); - - uint8_t cmd = 0; - uint32_t filesize=0; - sram_writebyte(32, SRAM_CMD_ADDR); - printf("test sram\n"); - while(!sram_reliable()); - printf("ok\n"); -//while(1) { -// delay_ms(1000); -// printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk()); -//} -//sram_hexdump(SRAM_DB_ADDR, 0x200); -//sram_hexdump(SRAM_MENU_ADDR, 0x400); - while(!cmd) { - cmd=menu_main_loop(); -// cmd = 1; - printf("cmd: %d\n", cmd); - sleep_ms(50); - uart_putc('-'); - switch(cmd) { - case SNES_CMD_LOADROM: - get_selected_name(file_lfn); - set_mcu_ovr(1); -// strcpy((char*)file_lfn, "/mon.smc"); - printf("Selected name: %s\n", file_lfn); - filesize = load_rom(file_lfn, SRAM_ROM_ADDR); - if(romprops.ramsize_bytes) { - strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm"); - printf("SRM file: %s\n", file_lfn); - load_sram(file_lfn, SRAM_SAVE_ADDR); - } else { - printf("No SRAM\n"); - } - set_mcu_ovr(0); - snes_reset(1); - delay_ms(10); - snes_reset(0); - break; - case SNES_CMD_SETRTC: - cmd=0; /* stay in loop */ - break; - default: - printf("unknown cmd: %d\n", cmd); - cmd=0; /* unknown cmd: stay in loop */ - break; - } - } - printf("cmd was %x, going to snes main loop\n", cmd); - -/* MSU1 STUFF, GET ME OUTTA HERE */ - FIL durr; -// open MSU file - strcpy((char*)file_buf, (char*)file_lfn); - strcpy(strrchr((char*)file_buf, (int)'.'), ".msu"); - printf("MSU datafile: %s\n", file_buf); - printf("f_open result: %d\n", f_open(&durr, (const TCHAR*)file_buf, FA_READ)); - UINT bytes_read = 1024; - UINT bytes_read2 = 1; - set_dac_vol(0x00); - spi_set_speed(SSP_CLK_DIVISOR_FAST); - while(fpga_status() & 0x4000); - uint16_t fpga_status_prev = fpga_status(); - uint16_t fpga_status_now = fpga_status(); - uint16_t dac_addr = 0; - uint16_t msu_addr = 0; - uint8_t msu_repeat = 0; - uint16_t msu_track = 0; - uint32_t msu_offset = 0; - - uint32_t msu_page1_start = 0x0000; - uint32_t msu_page2_start = 0x2000; - uint32_t msu_page_size = 0x2000; - - set_msu_addr(0x0); - msu_reset(0x0); - ff_sd_offload=1; - sd_offload_tgt=2; - f_lseek(&durr, 0L); - ff_sd_offload=1; - sd_offload_tgt=2; - f_read(&durr, file_buf, 16384, &bytes_read2); - - set_dac_addr(dac_addr); - dac_pause(); - dac_reset(); -/* audio_start, data_start, volume_start, audio_ctrl[1:0], ctrl_start */ -while(1){ - fpga_status_now = fpga_status(); - if(fpga_status_now & 0x0020) { - char suffix[11]; - - /* get trackno */ - msu_track = get_msu_track(); - printf("Audio requested! Track=%d\n", msu_track); - - /* open file */ - f_close(&file_handle); - snprintf(suffix, sizeof(suffix), "-%d.wav", msu_track); - strcpy((char*)file_buf, (char*)file_lfn); - strcpy(strrchr((char*)file_buf, (int)'.'), suffix); - printf("filename: %s\n", file_buf); - f_open(&file_handle, (const TCHAR*)file_buf, FA_READ); - ff_sd_offload=1; - sd_offload_tgt=1; - f_lseek(&file_handle, 44L); - set_dac_addr(0); - dac_pause(); - dac_reset(); - ff_sd_offload=1; - sd_offload_tgt=1; - f_read(&file_handle, file_buf, 2048, &bytes_read); - - /* clear busy bit */ - set_msu_status(0x00, 0x20); /* set no bits, reset bit 5 */ - } - - if(fpga_status_now & 0x0010) { - /* get address */ - msu_offset=get_msu_offset(); - printf("Data requested! Offset=%08lx page1=%08lx page2=%08lx\n", msu_offset, msu_page1_start, msu_page2_start); - if( ((msu_offset < msu_page1_start) - || (msu_offset >= msu_page1_start + msu_page_size)) - && ((msu_offset < msu_page2_start) - || (msu_offset >= msu_page2_start + msu_page_size))) { - printf("offset %08lx out of range (%08lx-%08lx, %08lx-%08lx), reload\n", msu_offset, msu_page1_start, - msu_page1_start+msu_page_size-1, msu_page2_start, msu_page2_start+msu_page_size-1); - /* cache miss */ - /* fill buffer */ - set_msu_addr(0x0); - sd_offload_tgt=2; - ff_sd_offload=1; - printf("seek to %08lx, res = %d\n", msu_offset, f_lseek(&durr, msu_offset)); - sd_offload_tgt=2; - ff_sd_offload=1; - printf("read res = %d\n", f_read(&durr, file_buf, 16384, &bytes_read2)); - printf("read %d bytes\n", bytes_read2); - msu_reset(0x0); - msu_page1_start = msu_offset; - msu_page2_start = msu_offset + msu_page_size; - } else { - if (msu_offset >= msu_page1_start && msu_offset <= msu_page1_start + msu_page_size) { - msu_reset(0x0000 + msu_offset - msu_page1_start); - printf("inside page1, new offset: %08lx\n", 0x0000 + msu_offset-msu_page1_start); - if(!(msu_page2_start == msu_page1_start + msu_page_size)) { - set_msu_addr(0x2000); - sd_offload_tgt=2; - ff_sd_offload=1; - f_read(&durr, file_buf, 8192, &bytes_read2); - printf("next page dirty (was: %08lx), loaded page2 (start now: ", msu_page2_start); - msu_page2_start = msu_page1_start + msu_page_size; - printf("%08lx)\n", msu_page2_start); - } - } else if (msu_offset >= msu_page2_start && msu_offset <= msu_page2_start + msu_page_size) { - printf("inside page2, new offset: %08lx\n", 0x2000 + msu_offset-msu_page2_start); - msu_reset(0x2000 + msu_offset - msu_page2_start); - if(!(msu_page1_start == msu_page2_start + msu_page_size)) { - set_msu_addr(0x0); - sd_offload_tgt=2; - ff_sd_offload=1; - f_read(&durr, file_buf, 8192, &bytes_read2); - printf("next page dirty (was: %08lx), loaded page1 (start now: ", msu_page1_start); - msu_page1_start = msu_page2_start + msu_page_size; - printf("%08lx)\n", msu_page1_start); - } - } else printf("!!!WATWATWAT!!!\n"); - } - /* clear busy bit */ - set_msu_status(0x00, 0x10); - } - - if(fpga_status_now & 0x0001) { - if(fpga_status_now & 0x0004) { - msu_repeat = 1; - set_msu_status(0x04, 0x01); /* set bit 2, reset bit 0 */ - printf("Repeat set!\n"); - } else { - msu_repeat = 0; - set_msu_status(0x00, 0x05); /* set no bits, reset bit 0+2 */ - printf("Repeat clear!\n"); - } - - if(fpga_status_now & 0x0002) { - printf("PLAY!\n"); - set_msu_status(0x02, 0x01); /* set bit 0, reset bit 1 */ - dac_play(); - } else { - printf("PAUSE!\n"); - set_msu_status(0x00, 0x03); /* set no bits, reset bit 1+0 */ - dac_pause(); - } - } - - /* Audio buffer refill */ - if((fpga_status_now & 0x4000) != (fpga_status_prev & 0x4000)) { - if(fpga_status_now & 0x4000) { - dac_addr = 0x0; - } else { - dac_addr = 0x400; - } - set_dac_addr(dac_addr); - sd_offload_tgt=1; - ff_sd_offload=1; - f_read(&file_handle, file_buf, 1024, &bytes_read); - } - - /* Data buffer refill */ - if((fpga_status_now & 0x2000) != (fpga_status_prev & 0x2000)) { - printf("data\n"); - if(fpga_status_now & 0x2000) { - msu_addr = 0x0; - msu_page1_start = msu_page2_start + msu_page_size; - } else { - msu_addr = 0x2000; - msu_page2_start = msu_page1_start + msu_page_size; - } - set_msu_addr(msu_addr); - sd_offload_tgt=2; - ff_sd_offload=1; - printf("data buffer refilled. res=%d page1=%08lx page2=%08lx\n", f_read(&durr, file_buf, 8192, &bytes_read2), msu_page1_start, msu_page2_start); - } - fpga_status_prev = fpga_status_now; - - /* handle loop / end */ - if(bytes_read<1024) { - ff_sd_offload=0; - sd_offload=0; - if(msu_repeat) { - printf("loop\n"); - ff_sd_offload=1; - sd_offload_tgt=1; - f_lseek(&file_handle, 44L); - ff_sd_offload=1; - sd_offload_tgt=1; - f_read(&file_handle, file_buf, 1024 - bytes_read, &bytes_read); - } else { - set_msu_status(0x00, 0x02); /* clear play bit */ - } - bytes_read=1024; - } -} - -/* END OF MSU1 STUFF */ - - cmd=0; - uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0; - uint16_t reset_count=0; - while(fpga_test() == FPGA_TEST_TOKEN) { - cli_entrycheck(); - sleep_ms(250); - sram_reliable(); - printf("%s ", get_cic_statename(get_cic_state())); - snes_reset_now=get_snes_reset(); - if(snes_reset_now) { - if(!snes_reset_prev) { - printf("RESET BUTTON DOWN\n"); - snes_reset_state=1; - reset_count=0; - } - } else { - if(snes_reset_prev) { - printf("RESET BUTTON UP\n"); - snes_reset_state=0; - } - } - if(snes_reset_state) { - reset_count++; - } else { - sram_reliable(); - snes_main_loop(); - } - if(reset_count>4) { - reset_count=0; - set_mcu_ovr(1); - snes_reset(1); - delay_ms(1); - if(romprops.ramsize_bytes && fpga_test() == FPGA_TEST_TOKEN) { - writeled(1); - save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR); - writeled(0); - } + while(get_cic_state() == CIC_FAIL) { + rdyled(0); + readled(0); + writeled(0); + delay_ms(500); rdyled(1); readled(1); writeled(1); - snes_reset(0); - while(get_snes_reset()); - snes_reset(1); - delay_ms(200); - goto restart; + delay_ms(500); } - snes_reset_prev = snes_reset_now; + /* some sanity checks */ + uint8_t card_go = 0; + while(!card_go) { + if(disk_status(0) & (STA_NOINIT|STA_NODISK)) { + snes_bootprint(" No Card! \0"); + while(disk_status(0) & (STA_NOINIT|STA_NODISK)); + delay_ms(200); + } + file_open((uint8_t*)"/sd2snes/menu.bin", FA_READ); + if(file_status != FILE_OK) { + snes_bootprint(" /sd2snes/menu.bin not found! \0"); + while(disk_status(0) == RES_OK); + } else { + card_go = 1; + } + file_close(); + } + snes_bootprint(" Loading ... \0"); + if(get_cic_state() == CIC_PAIR) { + printf("PAIR MODE ENGAGED!\n"); + cic_pair(CIC_PAL, CIC_NTSC); + } + rdyled(1); + readled(0); + writeled(0); + /* exclusive mode */ + set_mcu_ovr(1); + + *fs_path=0; + uint32_t saved_dir_id; + get_db_id(&saved_dir_id); + + uint32_t mem_dir_id = sram_readlong(SRAM_DIRID); + uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD); + printf("mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id); + if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id) || (newcard)) { + newcard = 0; + /* generate fs footprint (interesting files only) */ + uint32_t curr_dir_id = scan_dir(fs_path, 0, 0); + printf("curr dir id = %lx\n", curr_dir_id); + /* files changed or no database found? */ + if((get_db_id(&saved_dir_id) != FR_OK) + || saved_dir_id != curr_dir_id) { + /* rebuild database */ + printf("saved dir id = %lx\n", saved_dir_id); + printf("rebuilding database..."); + snes_bootprint(" rebuilding database ... \0"); + curr_dir_id = scan_dir(fs_path, 1, 0); + sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 4); + uint32_t endaddr, direndaddr; + sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4); + sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4); + printf("%lx %lx\n", endaddr, direndaddr); + printf("sorting database..."); + snes_bootprint(" sorting database ... \0"); + sort_all_dir(direndaddr); + printf("done\n"); + snes_bootprint(" saving database ... \0"); + 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); + printf("done\n"); + } else { + printf("saved dir id = %lx\n", saved_dir_id); + printf("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); + } + sram_writelong(curr_dir_id, SRAM_DIRID); + sram_writelong(0x12345678, SRAM_SCRATCHPAD); + } else { + printf("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); + } + /* load menu */ + fpga_pgm((uint8_t*)"/main.bit.rle"); + + uart_putc('('); + load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR); + /* force memory size + mapper */ + set_rom_mask(0x3fffff); + set_mapper(0x7); + uart_putc(')'); + uart_putcrlf(); + + sram_writebyte(0, SRAM_CMD_ADDR); + + /* shared mode */ + set_mcu_ovr(0); + + printf("SNES GO!\n"); + snes_reset(1); + delay_ms(1); + snes_reset(0); + + uint8_t cmd = 0; + uint32_t filesize=0; + sram_writebyte(32, SRAM_CMD_ADDR); + printf("test sram\n"); + while(!sram_reliable()); + printf("ok\n"); + //while(1) { + // delay_ms(1000); + // printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk()); + //} + //sram_hexdump(SRAM_DB_ADDR, 0x200); + //sram_hexdump(SRAM_MENU_ADDR, 0x400); + while(!cmd) { + cmd=menu_main_loop(); + // cmd = 1; + printf("cmd: %d\n", cmd); + sleep_ms(50); + uart_putc('-'); + switch(cmd) { + case SNES_CMD_LOADROM: + get_selected_name(file_lfn); + set_mcu_ovr(1); + // strcpy((char*)file_lfn, "/msu1/msu1vid_ikari_01/msu1vid.sfc"); + printf("Selected name: %s\n", file_lfn); + filesize = load_rom(file_lfn, SRAM_ROM_ADDR); + if(romprops.ramsize_bytes) { + strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm"); + printf("SRM file: %s\n", file_lfn); + load_sram(file_lfn, SRAM_SAVE_ADDR); + } else { + printf("No SRAM\n"); + } + set_mcu_ovr(0); + snes_reset(1); + delay_ms(10); + snes_reset(0); + break; + case SNES_CMD_SETRTC: + cmd=0; /* stay in loop */ + break; + default: + printf("unknown cmd: %d\n", cmd); + cmd=0; /* unknown cmd: stay in loop */ + break; + } + } + printf("cmd was %x, going to snes main loop\n", cmd); + + /* always try MSU1 for now */ + if(msu1_entrycheck_and_loop()) { + prepare_reset(); + continue; + } + + cmd=0; + uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0; + uint16_t reset_count=0; + while(fpga_test() == FPGA_TEST_TOKEN) { + cli_entrycheck(); + sleep_ms(250); + sram_reliable(); + printf("%s ", get_cic_statename(get_cic_state())); + snes_reset_now=get_snes_reset(); + if(snes_reset_now) { + if(!snes_reset_prev) { + printf("RESET BUTTON DOWN\n"); + snes_reset_state=1; + reset_count=0; + } + } else { + if(snes_reset_prev) { + printf("RESET BUTTON UP\n"); + snes_reset_state=0; + } + } + if(snes_reset_state) { + reset_count++; + } else { + sram_reliable(); + snes_main_loop(); + } + if(reset_count>4) { + reset_count=0; + prepare_reset(); + break; + } + snes_reset_prev = snes_reset_now; + } + /* fpga test fail: panic */ + if(fpga_test() != FPGA_TEST_TOKEN){ + led_panic(); + } + /* else reset */ } - /* fpga test fail: panic */ - led_panic(); } diff --git a/src/memory.c b/src/memory.c index be2adc6..d5285a8 100644 --- a/src/memory.c +++ b/src/memory.c @@ -59,7 +59,7 @@ void sram_hexdump(uint32_t addr, uint32_t len) { void sram_writebyte(uint8_t val, uint32_t addr) { set_mcu_addr(addr); FPGA_SELECT(); - FPGA_TX_BYTE(0x91); /* WRITE */ + FPGA_TX_BYTE(0x98); /* WRITE */ FPGA_TX_BYTE(val); FPGA_TX_BYTE(0x00); /* dummy */ FPGA_DESELECT(); @@ -68,7 +68,7 @@ void sram_writebyte(uint8_t val, uint32_t addr) { uint8_t sram_readbyte(uint32_t addr) { set_mcu_addr(addr); FPGA_SELECT(); - FPGA_TX_BYTE(0x81); /* READ */ + FPGA_TX_BYTE(0x88); /* READ */ FPGA_TX_BYTE(0x00); /* dummy */ uint8_t val = FPGA_TXRX_BYTE(0x00); FPGA_DESELECT(); @@ -78,7 +78,7 @@ uint8_t sram_readbyte(uint32_t addr) { void sram_writeshort(uint16_t val, uint32_t addr) { set_mcu_addr(addr); FPGA_SELECT(); - FPGA_TX_BYTE(0x91); /* WRITE */ + FPGA_TX_BYTE(0x98); /* WRITE */ FPGA_TX_BYTE(val&0xff); FPGA_TX_BYTE((val>>8)&0xff); FPGA_TX_BYTE(0x00); /* dummy */ @@ -88,7 +88,7 @@ void sram_writeshort(uint16_t val, uint32_t addr) { void sram_writelong(uint32_t val, uint32_t addr) { set_mcu_addr(addr); FPGA_SELECT(); - FPGA_TX_BYTE(0x91); /* WRITE */ + FPGA_TX_BYTE(0x98); /* WRITE */ FPGA_TX_BYTE(val&0xff); FPGA_TX_BYTE((val>>8)&0xff); FPGA_TX_BYTE((val>>16)&0xff); @@ -100,7 +100,7 @@ void sram_writelong(uint32_t val, uint32_t addr) { uint16_t sram_readshort(uint32_t addr) { set_mcu_addr(addr); FPGA_SELECT(); - FPGA_TX_BYTE(0x81); + FPGA_TX_BYTE(0x88); FPGA_TX_BYTE(0x00); uint32_t val = FPGA_TXRX_BYTE(0x00); val |= ((uint32_t)FPGA_TXRX_BYTE(0x00)<<8); @@ -111,7 +111,7 @@ uint16_t sram_readshort(uint32_t addr) { uint32_t sram_readlong(uint32_t addr) { set_mcu_addr(addr); FPGA_SELECT(); - FPGA_TX_BYTE(0x81); + FPGA_TX_BYTE(0x88); FPGA_TX_BYTE(0x00); uint32_t val = FPGA_TXRX_BYTE(0x00); val |= ((uint32_t)FPGA_TXRX_BYTE(0x00)<<8); @@ -124,7 +124,7 @@ uint32_t sram_readlong(uint32_t addr) { void sram_readlongblock(uint32_t* buf, uint32_t addr, uint16_t count) { set_mcu_addr(addr); FPGA_SELECT(); - FPGA_TX_BYTE(0x81); + FPGA_TX_BYTE(0x88); FPGA_TX_BYTE(0x00); uint16_t i=0; while(i (romprops.romsize_bytes + romprops.offset)) { romprops.romsize_bytes <<= 1; } @@ -241,7 +241,7 @@ uint32_t load_sram(uint8_t* filename, uint32_t base_addr) { bytes_read = file_read(); if (file_res || !bytes_read) break; FPGA_SELECT(); - FPGA_TX_BYTE(0x91); + FPGA_TX_BYTE(0x98); for(int j=0; jFIOCLR, SNES_RESET_BIT) = 1; /* reset the SNES */ - snes_reset(1); + snes_reset(1); } /* @@ -106,7 +125,7 @@ void snes_main_loop() { diffcount=0; writeled(1); save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR); - didnotsave=0; + didnotsave=0; writeled(0); } saveram_crc_old = saveram_crc; diff --git a/src/snes.h b/src/snes.h index caef0e5..977eb22 100644 --- a/src/snes.h +++ b/src/snes.h @@ -32,6 +32,7 @@ uint8_t crc_valid; +void prepare_reset(void); void snes_init(void); void snes_reset(int state); uint8_t get_snes_reset(void); diff --git a/verilog/sd2snes/avr_cmd.v b/verilog/sd2snes/avr_cmd.v index fe986e9..956c13d 100644 --- a/verilog/sd2snes/avr_cmd.v +++ b/verilog/sd2snes/avr_cmd.v @@ -164,6 +164,8 @@ always @(posedge clk) begin SD_DMA_TGTr <= cmd_data[1:0]; SD_DMA_PARTIALr <= cmd_data[2]; end + 4'h8: SD_DMA_TGTr <= 2'b00; + 4'h9: SD_DMA_TGTr <= cmd_data[1:0]; // 4'hE: // select memory unit endcase @@ -283,7 +285,7 @@ always @(posedge clk) begin endcase endcase end - if (SD_DMA_NEXTADDR | (mcu_nextaddr & (cmd_data[7:5] == 3'h4) && (cmd_data[0]) && (spi_byte_cnt > (32'h1+cmd_data[4])))) begin + if (SD_DMA_NEXTADDR | (mcu_nextaddr & (cmd_data[7:5] == 3'h4) && (cmd_data[3]) && (spi_byte_cnt > (32'h1+cmd_data[4])))) begin case (SD_DMA_TGTr) 2'b00: ADDR_OUT_BUF <= ADDR_OUT_BUF + 1; 2'b01: DAC_ADDR_OUT_BUF <= DAC_ADDR_OUT_BUF + 1; diff --git a/verilog/sd2snes/dac_test.v b/verilog/sd2snes/dac_test.v index 790c82c..982c7a9 100644 --- a/verilog/sd2snes/dac_test.v +++ b/verilog/sd2snes/dac_test.v @@ -47,7 +47,7 @@ reg vol_valid; reg[2:0] sysclk_sreg; wire sysclk_rising = (sysclk_sreg[2:1] == 2'b01); -reg [16:0] interpol_count; +reg [25:0] interpol_count; reg interpol_overflow; always @(posedge clkin) begin @@ -110,12 +110,12 @@ always @(posedge clkin) begin interpol_overflow <= 0; interpol_count <= 0; end else if(sysclk_rising) begin - if(interpol_count > 65437) begin - interpol_count <= interpol_count + 135 - 65573; + if(interpol_count > 59378938) begin + interpol_count <= interpol_count + 122500 - 59501439; dac_address_r <= dac_address_r + play_r; interpol_overflow <= 1; end else begin - interpol_count <= interpol_count + 135; + interpol_count <= interpol_count + 122500; interpol_overflow <= 0; end end diff --git a/verilog/sd2snes/ipcore_dir/dac_buf.xise b/verilog/sd2snes/ipcore_dir/dac_buf.xise index d198247..f973c82 100644 --- a/verilog/sd2snes/ipcore_dir/dac_buf.xise +++ b/verilog/sd2snes/ipcore_dir/dac_buf.xise @@ -36,330 +36,27 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - -