int fs_load_state(const char *filename) { int err; g_free(params.sav_file); params.sav_file = g_strdup(filename); err = ti68k_state_load(params.sav_file); if(err == ERR_STATE_MATCH) { gchar *rf, *tf; int ret = msg_box2(_("Warning"), _("The state image you are attempting to load does not match the current running image. Press OK if you want TiEmu to automatically load the corresponding image or Cancel to abort.")); if(ret == BUTTON2) //cancel return 0; ti68k_state_parse(filename, &rf, &tf); if(!ti68k_is_a_img_file(rf)) return 0; // Set tib file and image g_free(params.tib_file); params.tib_file = tf; g_free(params.rom_file); params.rom_file = rf; // Restart engine by exiting the GTK loop while(gtk_events_pending()) gtk_main_iteration(); gtk_main_quit(); } else handle_error(); return 0; }
/* Scan the command line, extract arguments and init variables */ int scan_cmdline(int argc, char **argv) { int cnt; char *p; char msg[80]; int import = 0; char *rom = NULL; char *tib = NULL; char *sav = NULL; char *fn = NULL; //for(cnt = 0; cnt < argc; cnt++) // fprintf(stdout, "%i: [%s]\n", cnt, argv[cnt]); /* Parses list of arguments */ for(cnt=1; cnt<argc; cnt++) { p = argv[cnt]; #ifdef __WIN32__ if(!stricmp(p, "/RegServer") || !stricmp(p, "-RegServer") || !stricmp(p, "--RegServer")) { char *p; ITypeLib *tlb; char szModule[512]; wchar_t tlbname[512]; HMODULE hModule = GetModuleHandle(NULL); DWORD dwResult = GetModuleFileName(hModule, szModule, sizeof(szModule)); if (!dwResult) exit(1); p = szModule + strlen(szModule) - 4; if (stricmp(p,".exe")) exit(1); strcpy(++p,"tlb"); mbstowcs(tlbname, szModule, strlen(szModule)+1); if (RegisterServer(&CLSID_TiEmuOLE, "TiEmu OLE Interface", "TiEmu.TiEmuOLE", "TiEmu.TiEmuOLE.1", NULL) || LoadTypeLib(tlbname, &tlb)) exit(1); else { if (RegisterTypeLib(tlb, tlbname, NULL)) { tlb->lpVtbl->Release(tlb); exit(1); } else { tlb->lpVtbl->Release(tlb); fprintf(stdout, "TiEmu OLE Interface successfully registered."); exit(0); } } } if(!stricmp(p, "/UnregServer") || !stricmp(p, "-UnregServer") || !stricmp(p, "--UnregServer")) { if (UnregisterServer(&CLSID_TiEmuOLE, "TiEmu.TiEmuOLE", "TiEmu.TiEmuOLE.1") || UnRegisterTypeLib(&LIBID_TiEmuOLELib, 1, 0, 0, SYS_WIN32)) exit(1); else { fprintf(stdout, "TiEmu OLE Interface successfully unregistered."); exit(0); } } if(!stricmp(p, "/Embedding") || !stricmp(p, "-Embedding") || !stricmp(p, "--Embedding")) { // VB runs it with this option. continue; } #endif if(*p == '-') { // a long option (like --help) p++; } else { fn = g_strdup(p); // a filename //g_free(params.rom_file); //params.rom_file = g_strdup(p); } strcpy(msg, p); if(strexact(msg, "-import")) import = !0; if(strstr(msg, "rom=")) rom = g_strdup(msg + 4); if(strstr(msg, "tib=")) tib = g_strdup(msg + 4); if(strstr(msg, "sav=")) sav = g_strdup(msg + 4); if(strstr(msg, "send=")) file_to_send = g_strdup(msg + 5); if(strexact(msg, "-help") || strexact(msg, "h")) help(); if(strexact(msg, "-version") || strexact(msg, "v")) exit(0); } /* */ if(fn && ti68k_is_a_rom_file(fn)) rom = fn; else if(fn && ti68k_is_a_tib_file(fn)) tib = fn; else if(fn && ti68k_is_a_sav_file(fn)) sav = fn; /* And process them */ if(rom && ti68k_is_a_rom_file(rom)) { gchar *dstname; int err = ti68k_convert_rom_to_image(rom, inst_paths.img_dir, &dstname); if(err) { tiemu_err(err, NULL); exit(-1); } if(import) exit(0); g_free(params.rom_file); params.rom_file = dstname; g_free(params.sav_file); params.sav_file = g_strdup(""); } if(tib && ti68k_is_a_tib_file(tib)) { gchar *dstname; int err = ti68k_convert_tib_to_image(tib, inst_paths.img_dir, &dstname, -1); if(err) { tiemu_err(err, NULL); exit(-1); } if(import) exit(0); g_free(params.rom_file); params.rom_file = dstname; g_free(params.sav_file); params.sav_file = g_strdup(""); } if(sav && !fn) // for compatibility { g_free(params.sav_file); params.sav_file = g_strdup(sav); } if(sav && ti68k_is_a_sav_file(sav) && fn) { gchar *rf, *tf; ti68k_state_parse(sav, &rf, &tf); if(!ti68k_is_a_img_file(rf)) return 0; g_free(params.rom_file); params.rom_file = rf; g_free(params.tib_file); params.tib_file = tf; g_free(params.sav_file); params.sav_file = g_strdup(sav); } return 0; }
/* Must be done between init_hardware and M68000_run. Typically called after initLib68k. This function (re)load the state of the calculator. It automagically determine the state file format. Return an error code if an error occured, 0 otherwise */ int ti68k_state_load(const char *filename) { FILE *f; IMG_INFO img; SAV_INFO sav; Ti68kHardware thw; int ret; long pos; int i; gchar *rf=NULL, *tf=NULL; // No filename, exits if(!strcmp(filename, "")) return 0; // Open file tiemu_info(_("loading state image: %s"), g_basename(filename)); f = fopen(filename, "rb"); if(f == NULL) return ERR_CANT_OPEN_STATE; // Load ROM image header fread(&img, 1, sizeof(IMG_INFO), f); // Determine state image revision and load state image header pos = ftell(f); fread(&sav.revision, sizeof(sav.revision), 1, f); fread(&sav.size, sizeof(sav.revision), 1, f); fseek(f, pos, SEEK_SET); fread(&sav, 1, sav.size, f); if(sav.revision < SAV_MINI) { fclose(f); return ERR_REVISION_MATCH; } // Does not accept state image different of emulator image if(ti68k_state_parse(filename, &rf, &tf) < 0) { if (rf) g_free(rf); if (tf) g_free(tf); return ERR_STATE_MATCH; } if (rf) g_free(rf); if (tf) g_free(tf); // Compare image infos with current image if(memcmp(&img, &img_infos, sizeof(IMG_INFO) - sizeof(char *))) return ERR_HEADER_MATCH; // Load internal hardware (registers and special flags) ret = fseek(f, sav.regs_offset, SEEK_SET); fread(®s, sizeof(regs), 1, f); // Load I/O ports state ret = fseek(f, sav.io_offset, SEEK_SET); fread(tihw.io , tihw.io_size, 1, f); fread(tihw.io2, tihw.io2_size, 1, f); fread(tihw.io3, tihw.io3_size, 1, f); // Load RAM content ret = fseek(f, sav.ram_offset, SEEK_SET); fread(tihw.ram, tihw.ram_size, 1, f); // Load extra infos ret = fseek(f, sav.misc_offset, SEEK_SET); fread(&thw, sizeof(Ti68kHardware), 1, f); tihw.on_off = thw.on_off; tihw.lcd_adr = thw.lcd_adr; tihw.contrast = thw.contrast; tihw.protect = thw.protect; tihw.archive_limit = thw.archive_limit; memcpy(tihw.ram_exec, thw.ram_exec, sizeof(tihw.ram_exec)); tihw.rtc3_beg = thw.rtc3_beg; tihw.rtc3_load = thw.rtc3_load; rtc3_state_load(); // Load modified FLASH segments ret = fseek(f, sav.rom_offset, SEEK_SET); for(i=0; i<wsm.nblocks; i++) { fread(&wsm.changed[i], sizeof(int), 1, f); if(wsm.changed[i]) fread(&tihw.rom[i<<16], 1, 65536, f); } // Load bkpts ti68k_bkpt_clear_access(); ti68k_bkpt_clear_range(); ti68k_bkpt_clear_address(); ti68k_bkpt_clear_exception(); ti68k_bkpt_clear_pgmentry(); ret = fseek(f, sav.bkpts_offset, SEEK_SET); load_bkpt(f, &bkpts.code); load_bkpt(f, &bkpts.exception); load_bkpt(f, &bkpts.pgmentry); load_bkpt(f, &bkpts.mem_rb); load_bkpt(f, &bkpts.mem_rw); load_bkpt(f, &bkpts.mem_rl); load_bkpt(f, &bkpts.mem_wb); load_bkpt(f, &bkpts.mem_ww); load_bkpt(f, &bkpts.mem_wl); load_bkpt2(f, &bkpts.mem_rng_r); load_bkpt2(f, &bkpts.mem_rng_w); if(sav.revision >= 21) load_bkpt3(f, &bkpts.bits); // Update UAE structures m68k_setpc(m68k_getpc()); MakeFromSR(); fclose(f); // Update SAV file to latest revision if(sav.revision < SAV_REVISION) { ti68k_state_save(filename); } return 0; }