/* 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(char *filename) { FILE *f; IMG_INFO img; SAV_INFO sav; Ti68kHardware thw; int ret; long pos; int i; // No filename, exits if(!strcmp(filename, "")) return 0; // Open file printl(0, "loading state image: %s\n", g_basename(filename)); f = fopen(filename, "rb"); if(f == NULL) return ERR_CANT_OPEN; // Compare image infos with current image fread(&img, 1, sizeof(IMG_INFO), f); if(memcmp(&img, &img_infos, sizeof(IMG_INFO) - sizeof(char *))) return ERR_INVALID_STATE; // Determine state image revision for backwards compatibility pos = ftell(f); fread(&sav.revision, sizeof(sav.revision), 1, f); fread(&sav.size, sizeof(sav.revision), 1, f); fseek(f, pos, SEEK_SET); if(sav.revision != SAV_REVISION) return ERR_INVALID_STATE; // Load state image infos fread(&sav, 1, sizeof(SAV_INFO), f); // 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.io_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, 32); // 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); // Update UAE structures m68k_setpc(m68k_getpc()); MakeFromSR(); fclose(f); 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; }