void cmd_sreset(void) { if(*curchar != 0) { int32_t resetstate; resetstate = parse_unsigned(0,1,10); snes_reset(resetstate); } else { snes_reset(1); delay_ms(20); snes_reset(0); } }
void prepare_reset() { 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); } rdyled(1); readled(1); writeled(1); snes_reset(0); while(get_snes_reset()); snes_reset(1); fpga_dspx_reset(1); delay_ms(200); }
void Utility::modifySystemState(system_state_t systemState) { fileBrowser->close(); //avoid edge case oddities (eg movie playback window still open from previous game) state.resetHistory(); //do not allow rewinding past a destructive system action movie.stop(); //movies cannot continue to record after destructive system actions video.clear(); audio.clear(); switch(systemState) { case LoadCartridge: { if(application.cartridgeLoaded == true) break; application.cartridgeLoaded = true; cartridge.loadCheats(); application.power = true; application.pause = false; snes_power(); showMessage(string() << "Loaded " << cartridge.name << (cartridge.patchApplied ? ", and applied UPS patch." : ".")); mainWindow->setWindowTitle(string() << cartridge.name << " - " << ProgramName); #if defined(DEBUGGER) debugger->echo(string() << "Loaded " << cartridge.name << ".<br>"); #endif } break; case UnloadCartridge: { if(application.cartridgeLoaded == false) break; //no cart to unload? application.cartridgeLoaded = false; cartridge.saveCheats(); cartridge.saveMemory(); //save memory to disk snes_unload_cartridge(); //deallocate memory application.power = false; application.pause = true; showMessage(string() << "Unloaded " << cartridge.name << "."); mainWindow->setWindowTitle(string() << ProgramName); } break; case PowerOn: { if(application.cartridgeLoaded == false || application.power == true) break; application.power = true; application.pause = false; snes_power(); showMessage("Power on."); } break; case PowerOff: { if(application.cartridgeLoaded == false || application.power == false) break; application.power = false; application.pause = true; showMessage("Power off."); } break; case PowerCycle: { if(application.cartridgeLoaded == false) break; application.power = true; application.pause = false; snes_power(); showMessage("System power was cycled."); } break; case Reset: { if(application.cartridgeLoaded == false || application.power == false) break; application.pause = false; snes_reset(); showMessage("System was reset."); } break; } mainWindow->syncUi(); #if defined(DEBUGGER) debugger->modifySystemState(systemState); debugger->synchronize(); #endif cheatEditorWindow->synchronize(); cheatFinderWindow->synchronize(); stateManagerWindow->reload(); }
void snes_init() { /* put reset level on reset pin */ BITBAND(SNES_RESET_REG->FIOCLR, SNES_RESET_BIT) = 1; /* reset the SNES */ snes_reset(1); }
void snes_reset_pulse() { snes_reset(1); delay_ms(SNES_RESET_PULSELEN_MS); snes_reset(0); }
uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) { UINT bytes_read; DWORD filesize; UINT count=0; tick_t ticksstart, ticks_total=0; ticksstart=getticks(); printf("%s\n", filename); file_open(filename, FA_READ); if(file_res) { uart_putc('?'); uart_putc(0x30+file_res); return 0; } filesize = file_handle.fsize; smc_id(&romprops); file_close(); /* reconfigure FPGA if necessary */ if(romprops.fpga_conf) { printf("reconfigure FPGA with %s...\n", romprops.fpga_conf); fpga_pgm((uint8_t*)romprops.fpga_conf); } set_mcu_addr(base_addr); file_open(filename, FA_READ); f_lseek(&file_handle, romprops.offset); for(;;) { ff_sd_offload=1; sd_offload_tgt=0; bytes_read = file_read(); if (file_res || !bytes_read) break; if(!(count++ % 512)) { uart_putc('.'); } } file_close(); set_mapper(romprops.mapper_id); printf("rom header map: %02x; mapper id: %d\n", romprops.header.map, romprops.mapper_id); ticks_total=getticks()-ticksstart; printf("%u ticks total\n", ticks_total); if(romprops.mapper_id==3) { printf("BSX Flash cart image\n"); printf("attempting to load BSX BIOS /sd2snes/bsxbios.bin...\n"); load_sram_offload((uint8_t*)"/sd2snes/bsxbios.bin", 0x800000); printf("Type: %02x\n", romprops.header.destcode); set_bsx_regs(0xc0, 0x3f); uint16_t rombase; if(romprops.header.ramsize & 1) { rombase = 0xff00; // set_bsx_regs(0x36, 0xc9); } else { rombase = 0x7f00; // set_bsx_regs(0x34, 0xcb); } sram_writebyte(0x33, rombase+0xda); sram_writebyte(0x00, rombase+0xd4); sram_writebyte(0xfc, rombase+0xd5); set_fpga_time(0x0220110301180530LL); } uint32_t rammask; uint32_t rommask; while(filesize > (romprops.romsize_bytes + romprops.offset)) { romprops.romsize_bytes <<= 1; } if(romprops.header.ramsize == 0) { rammask = 0; } else { rammask = romprops.ramsize_bytes - 1; } rommask = romprops.romsize_bytes - 1; printf("ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize, rommask); set_saveram_mask(rammask); set_rom_mask(rommask); readled(0); if(flags & LOADROM_WITH_SRAM) { if(romprops.ramsize_bytes) { strcpy(strrchr((char*)filename, (int)'.'), ".srm"); printf("SRM file: %s\n", filename); load_sram(filename, SRAM_SAVE_ADDR); } else { printf("No SRAM\n"); } } printf("check MSU..."); if(msu1_check(filename)) { romprops.fpga_features |= FEAT_MSU1; romprops.has_msu1 = 1; } else { romprops.has_msu1 = 0; } printf("done\n"); romprops.fpga_features |= FEAT_SRTC; fpga_set_features(romprops.fpga_features); if(flags & LOADROM_WITH_RESET) { fpga_dspx_reset(1); snes_reset(1); delay_ms(10); snes_reset(0); fpga_dspx_reset(0); } return (uint32_t)filesize; }
void emuthread() { for(;;) { switch(s_EmulationControl.command) { case eMessage_CMD_init: snes_init(); break; case eMessage_CMD_power: snes_power(); break; case eMessage_CMD_reset: snes_reset(); break; case eMessage_CMD_term: snes_term(); break; case eMessage_CMD_unload_cartridge: snes_unload_cartridge(); break; case eMessage_CMD_load_cartridge_normal: EMUTHREAD_handleCommand_LoadCartridgeNormal(); break; case eMessage_CMD_load_cartridge_super_game_boy: EMUTHREAD_handleCommand_LoadCartridgeSuperGameBoy(); break; case eMessage_CMD_serialize: EMUTHREAD_handle_CMD_serialize(); break; case eMessage_CMD_unserialize: EMUTHREAD_handle_CMD_unserialize(); break; case eMessage_CMD_run: SIG_FlushAudio(); //we could avoid this if we saved the current thread before jumping back to co_control, instead of always jumping back to co_emu //in effect, we're scrambling the scheduler //EDIT - well, we changed that, but.. we still want this probably, for debugging and stuff for(;;) { SNES::scheduler.sync = SNES::Scheduler::SynchronizeMode::None; SNES::scheduler.clearExitReason(); SNES::scheduler.enter(); if(SNES::scheduler.exit_reason() == SNES::Scheduler::ExitReason::FrameEvent) { SNES::video.update(); break; } //not used yet if(SNES::scheduler.exit_reason() == SNES::Scheduler::ExitReason::DebuggerEvent) break; } SIG_FlushAudio(); break; } s_EmulationControl.exitReason = eEmulationExitReason_CMD_Complete; SETCONTROL; } }
int main(void) { LPC_GPIO2->FIODIR = BV(4) | BV(5); LPC_GPIO1->FIODIR = BV(23) | BV(SNES_CIC_PAIR_BIT); BITBAND(SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT) = 1; LPC_GPIO0->FIODIR = BV(16); /* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */ LPC_PINCON->PINSEL1 = BV(18) | BV(19) | BV(20) | BV(21) /* UART3 */ | BV(3) | BV(5); /* SSP0 (FPGA) except SS */ LPC_PINCON->PINSEL0 = BV(31); /* SSP0 */ /* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */ /* pull-down CIC data lines */ LPC_PINCON->PINMODE0 = BV(0) | BV(1) | BV(2) | BV(3); clock_disconnect(); snes_init(); snes_reset(1); power_init(); timer_init(); uart_init(); fpga_spi_init(); spi_preinit(); led_init(); /* do this last because the peripheral init()s change PCLK dividers */ clock_init(); LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */ led_pwm(); sdn_init(); printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY); printf("PCONP=%lx\n", LPC_SC->PCONP); file_init(); cic_init(0); /* setup timer (fpga clk) */ LPC_TIM3->CTCR=0; LPC_TIM3->EMR=EMC0TOGGLE; LPC_TIM3->MCR=MR0R; LPC_TIM3->MR0=1; LPC_TIM3->TCR=1; fpga_init(); char *testnames[11] = { "SD ", "USB ", "RTC ", "CIC ", "FPGA ", "RAM ", "CLK ", "DAC ", "SNES IRQ", "SNES RAM", "SNES PA "}; char *teststate_names [3] = { "no run", "\x1b[32;1mPassed\x1b[m", "\x1b[31;1mFAILED\x1b[m" }; int testresults[11] = { NO_RUN, NO_RUN, NO_RUN, NO_RUN, NO_RUN, NO_RUN, NO_RUN, NO_RUN, NO_RUN, NO_RUN, NO_RUN }; testresults[TEST_SD] = test_sd(); //testresults[TEST_USB] = test_usb(); testresults[TEST_RTC] = test_rtc(); delay_ms(209); testresults[TEST_CIC] = test_cic(); testresults[TEST_FPGA] = test_fpga(); testresults[TEST_RAM] = test_mem(); printf("Loading SNES test ROM\n=====================\n"); load_rom((uint8_t*)"/sd2snes/test.bin", 0, LOADROM_WITH_RESET); printf("\n\n\n"); delay_ms(1000); testresults[TEST_CLK] = test_clk(); fpga_set_bram_addr(0x1fff); fpga_write_bram_data(0x01); // tell SNES test program to continue uint8_t snestest_irq_state, snestest_pa_state, snestest_mem_state, snestest_mem_bank; uint8_t snestest_irq_done = 0, snestest_pa_done = 0, snestest_mem_done = 0; uint8_t last_irq_state = 0x77, last_pa_state = 0x77, last_mem_state = 0x77, last_mem_bank = 0x77; uint32_t failed_addr = 0; while(!(snestest_irq_done & snestest_pa_done & snestest_mem_done)) { fpga_set_bram_addr(0); snestest_irq_state = fpga_read_bram_data(); snestest_mem_state = fpga_read_bram_data(); snestest_pa_state = fpga_read_bram_data(); snestest_mem_bank = fpga_read_bram_data(); if(snestest_irq_state != last_irq_state || snestest_mem_state != last_mem_state || snestest_pa_state != last_pa_state || snestest_mem_bank != last_mem_bank) { printf("SNES test status: IRQ: %02x PA: %02x MEM: %02x/%02x\r", snestest_irq_state, snestest_pa_state, snestest_mem_state, snestest_mem_bank); } last_irq_state = snestest_irq_state; last_mem_state = snestest_mem_state; last_pa_state = snestest_pa_state; last_mem_bank = snestest_mem_bank; if(snestest_pa_state != 0x00) snestest_pa_done = 1; if(snestest_irq_state != 0x00) snestest_irq_done = 1; if(snestest_mem_state == 0xff || snestest_mem_state == 0x5a) snestest_mem_done = 1; cli_entrycheck(); } printf("\n"); if(snestest_pa_state == 0xff) testresults[TEST_SNES_PA] = FAILED; else testresults[TEST_SNES_PA] = PASSED; if(snestest_irq_state == 0xff) testresults[TEST_SNES_IRQ] = FAILED; else testresults[TEST_SNES_IRQ] = PASSED; if(snestest_mem_state == 0xff) { testresults[TEST_SNES_RAM] = FAILED; fpga_set_bram_addr(4); failed_addr = fpga_read_bram_data(); failed_addr |= fpga_read_bram_data() << 8; failed_addr |= fpga_read_bram_data() << 16; printf("SNES MEM test FAILED (failed address: %06lx)\n", failed_addr); } else testresults[TEST_SNES_RAM] = PASSED; printf("\n\nTEST SUMMARY\n============\n\n"); printf("Test Result\n----------------\n"); int testcount; for(testcount=0; testcount < 11; testcount++) { printf("%s %s\n", testnames[testcount], teststate_names[testresults[testcount]]); } cli_loop(); while(1); }