gint display_save_state_dbox(void) { const gchar *filename; int err; gchar *file_basename; gchar *dot; gchar *pattern; // get filename file_basename = g_path_get_basename(params.rom_file); dot = strrchr(file_basename, '.'); if(dot != NULL) *dot = '\0'; pattern = g_strconcat(file_basename, ".sav", NULL); g_free(file_basename); filename = create_fsel(inst_paths.img_dir, pattern, (char *)"*.sav", TRUE); g_free(pattern); if (!filename) return 0; g_free(params.sav_file); params.sav_file = g_strdup(filename); err = ti68k_state_save(params.sav_file); handle_error(); if(!rcfile_exist()) { rcfile_write(); #ifdef __WIN32__ msg_box1(_("Information"), _("You do not seem to have saved your settings. Configuration file saved (in tiemu.ini).")); #else msg_box1(_("Information"), _("You do not seem to have saved your settings. Configuration file saved (in ~/.tiemu).")); #endif } 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; }