/* Load a FLASH upgrade (.tib/.9xu/.89u). Note: an image must have been loaded before calling this function. */ int ti68k_load_upgrade(const char *filename) { IMG_INFO tib; int err; IMG_INFO *img = &img_infos; if(!img_loaded) return -1; // No filename, exits if(!strcmp(g_basename(filename), "")) return 0; //ERR_CANT_OPEN; memset(&tib, 0, sizeof(IMG_INFO)); err = ti68k_get_tib_infos(filename, &tib, !0); if(err) { free(img->data); tiemu_info(_("Unable to get information on FLASH upgrade: <%s>"), filename); return err; } ti68k_display_tib_infos(&tib); // Allow upgrade ? if(tib.calc_type != img->calc_type) { free(tib.data); return ERR_CANT_UPGRADE; } tib.has_boot = 1; // still bootable memset(tihw.rom+SPP, 0xff, tihw.rom_size-SPP); // clear FLASH memcpy(tihw.rom+SPP, tib.data+SPP, tib.size-SPP); free(tib.data); strcpy(tihw.rom_version, tib.version); img_loaded = 2; img_changed = 2; return 0; }
gint display_import_romversion_dbox(void) { const gchar *filename; char *dstname; int err; // get filename filename = create_fsel(inst_paths.base_dir, NULL, "*.rom;*.89u;*.9xu;*.v2u;*.tib", FALSE); if (!filename) return 0; if(ti68k_is_a_rom_file(filename)) { err = ti68k_convert_rom_to_image(filename, inst_paths.img_dir, &dstname); handle_error(); g_free(dstname); } else if(ti68k_is_a_tib_file(filename)) { IMG_INFO infos = { 0 }; int err = ti68k_get_tib_infos(filename, &infos, 0); int hw_type = HW2; if(infos.calc_type == TI92p || infos.calc_type == TI89) { int ret = msg_box3(_("HW type"), _("The FLASH upgrade can be imported as HW1 or HW2. Please choose..."), "HW1", "HW2", "Default"); if(ret == BUTTON1) hw_type = HW1; else if(ret == BUTTON2) hw_type = HW2; } // fake rom err = ti68k_convert_tib_to_image(filename, inst_paths.img_dir, &dstname, hw_type); handle_error(); g_free(dstname); } return 0; }
int import_romversion(const char *filename) { char *dstname; int err; if(ti68k_is_a_rom_file(filename)) { err = ti68k_convert_rom_to_image(filename, inst_paths.img_dir, &dstname); handle_error(); g_free(dstname); } else if(ti68k_is_a_tib_file(filename)) { #ifdef _MSC_VER IMG_INFO infos = {0}; #else IMG_INFO infos = {}; #endif int hw_type = HW2; err = ti68k_get_tib_infos(filename, &infos, 0); handle_error(); if (!err) { if(infos.calc_type == TI92p || infos.calc_type == TI89) { int ret = msg_box3(_("HW type"), _("The FLASH upgrade can be imported as HW1 or HW2. Please choose..."), "HW1", "HW2", "Default"); if(ret == BUTTON1) hw_type = HW1; else if(ret == BUTTON2) hw_type = HW2; } else if(infos.calc_type == TI89t) { int ret = msg_box3(_("HW type"), _("The FLASH upgrade can be imported as HW3 or HW4. Please choose..."), "HW3", "HW4", "Default"); hw_type = HW3; // default is HW3 for the Titanium, there's no Titanium HW2 if(ret == BUTTON1) hw_type = HW3; else if(ret == BUTTON2) hw_type = HW4; } } // fake rom err = ti68k_convert_tib_to_image(filename, inst_paths.img_dir, &dstname, hw_type); handle_error(); g_free(dstname); } else { msg_box1(_("Error"), _("This is not a valid file")); return -1; } return 0; }
/* Convert an romdump into image and replace SPP by upgrade. The resulting image has boot block. */ int ti68k_merge_rom_and_tib_to_image(const char *srcname1, const char *srcname2, const char *dirname, char **dstname) { FILE *f; int err; IMG_INFO img; char *ext; gchar *basename; int real_size; *dstname = NULL; // No filename, exits if(!strcmp(g_basename(srcname1), "")) return ERR_CANT_OPEN; if(!strcmp(g_basename(srcname2), "")) return ERR_CANT_OPEN; // Preload romdump memset(&img, 0, sizeof(IMG_INFO)); err = ti68k_get_rom_infos(srcname1, &img, !0); if(err) { free(img.data); tiemu_info(_("Unable to get information on ROM dump: %s"), srcname1); return err; } ti68k_display_rom_infos(&img); // Save size real_size = img.size; // Load upgrade err = ti68k_get_tib_infos(srcname2, &img, !0); if(err) { free(img.data); tiemu_info(_("Unable to get information on ROM dump: %s"), srcname2); return err; } ti68k_display_tib_infos(&img); // Create destination file basename = g_path_get_basename(srcname1); ext = strrchr(basename, '.'); *ext='\0'; strcat(basename, ".img"); *dstname = g_strconcat(dirname, basename, NULL); g_free(basename); // Restore size img.size = real_size; // Open dest file f = fopen(*dstname, "wb"); if(f == NULL) { tiemu_warning("Unable to open this file: <%s>\n", *dstname); return ERR_CANT_OPEN; } // Fill header strcpy(img.signature, IMG_SIGN); img.header_size = sizeof(IMG_INFO); img.revision = IMG_REV; img.has_boot = 1; // Write file if (fwrite(&img, 1, sizeof(IMG_INFO), f) < sizeof(IMG_INFO) || fwrite(img.data, sizeof(char), img.size, f) < (size_t)img.size) { tiemu_warning("Failed to write to file: <%s>\n", *dstname); fclose(f); return ERR_CANT_OPEN; } // Close file if (fclose(f)) { tiemu_warning("Failed to close file: <%s>\n", *dstname); return ERR_CANT_OPEN; } return 0; }
/* Convert an upgrade into an image. The image has neither boot block nor certificate. */ int ti68k_convert_tib_to_image(const char *srcname, const char *dirname, char **dstname, int hw_type) { FILE *f; int err; IMG_INFO img; char *ext; gchar *basename; int i, j; int num_blocks, last_block; int real_size; HW_PARM_BLOCK hwpb; *dstname = NULL; // No filename, exits if(!strcmp(g_basename(srcname), "")) return ERR_CANT_OPEN; // Preload upgrade memset(&img, 0, sizeof(IMG_INFO)); err = ti68k_get_tib_infos(srcname, &img, !0); if(err) { free(img.data); tiemu_info(_("Unable to get information on FLASH upgrade: <%s>"), srcname); return err; } ti68k_display_tib_infos(&img); // Create destination file basename = g_path_get_basename(srcname); ext = strrchr(basename, '.'); *ext='\0'; strcat(basename, ".img"); *dstname = g_strconcat(dirname, basename, NULL); g_free(basename); // Open dest file f = fopen(*dstname, "wb"); if(f == NULL) { tiemu_warning("Unable to open this file: <%s>\n", *dstname); return ERR_CANT_OPEN; } // Fill header strcpy(img.signature, IMG_SIGN); img.header_size = sizeof(IMG_INFO); img.revision = IMG_REV; real_size = img.size - SPP; img.size = ti68k_get_rom_size(img.calc_type); img.hw_type = hw_type; if(hw_type == -1) { if(img.calc_type == TI89t) img.hw_type = HW3; //default else if(img.calc_type == TI89 || img.calc_type == TI92p || img.calc_type == V200) img.hw_type = HW2; // default } // Write header if (fwrite(&img, 1, sizeof(IMG_INFO), f) < sizeof(IMG_INFO)) { tiemu_warning("Failed to write to file: <%s>\n", *dstname); fclose(f); return ERR_CANT_OPEN; } // Write boot block memcpy(img.data, &img.data[SPP + BO], 256); if (fwrite(img.data, 1, 256, f) < 256) { tiemu_warning("Failed to write to file: <%s>\n", *dstname); fclose(f); return ERR_CANT_OPEN; } // Write hardware param block // fill structure hwpb.len = 24; switch(img.calc_type) { case TI89: hwpb.hardwareID = HWID_TI89; hwpb.hardwareRevision = img.hw_type - 1; break; case TI92p: hwpb.hardwareID = HWID_TI92P; hwpb.hardwareRevision = img.hw_type - 1; break; case V200: hwpb.hardwareID = HWID_V200; hwpb.hardwareRevision = 2; break; case TI89t: hwpb.hardwareID = HWID_TI89T; hwpb.hardwareRevision = 2; break; } hwpb.bootMajor = hwpb.bootRevision = hwpb.bootBuild = 1; hwpb.gateArray = img.hw_type; ti68k_put_hw_param_block((uint8_t *)img.data, img.rom_base, &hwpb); // write filler if (fputc(0xfe, f) < 0 || fputc(0xed, f) < 0 || fputc(0xba, f) < 0 || fputc(0xbe, f) < 0 //fwrite(&hwpb, 1hwpb.len+2, f); // write address (pointer) || fputc(0x00, f) < 0 || fputc(img.rom_base, f) < 0 || fputc(0x01, f) < 0 || fputc(0x08, f) < 0 // write structure || fputc(MSB(hwpb.len), f) < 0 || fputc(LSB(hwpb.len), f) < 0 || fputc(MSB(MSW(hwpb.hardwareID)), f) < 0 || fputc(LSB(MSW(hwpb.hardwareID)), f) < 0 || fputc(MSB(LSW(hwpb.hardwareID)), f) < 0 || fputc(LSB(LSW(hwpb.hardwareID)), f) < 0 || fputc(MSB(MSW(hwpb.hardwareRevision)), f) < 0 || fputc(LSB(MSW(hwpb.hardwareRevision)), f) < 0 || fputc(MSB(LSW(hwpb.hardwareRevision)), f) < 0 || fputc(LSB(LSW(hwpb.hardwareRevision)), f) < 0 || fputc(MSB(MSW(hwpb.bootMajor)), f) < 0 || fputc(LSB(MSW(hwpb.bootMajor)), f) < 0 || fputc(MSB(LSW(hwpb.bootMajor)), f) < 0 || fputc(LSB(LSW(hwpb.bootMajor)), f) < 0 || fputc(MSB(MSW(hwpb.hardwareRevision)), f) < 0 || fputc(LSB(MSW(hwpb.hardwareRevision)), f) < 0 || fputc(MSB(LSW(hwpb.hardwareRevision)), f) < 0 || fputc(LSB(LSW(hwpb.hardwareRevision)), f) < 0 || fputc(MSB(MSW(hwpb.bootBuild)), f) < 0 || fputc(LSB(MSW(hwpb.bootBuild)), f) < 0 || fputc(MSB(LSW(hwpb.bootBuild)), f) < 0 || fputc(LSB(LSW(hwpb.bootBuild)), f) < 0 || fputc(MSB(MSW(hwpb.gateArray)), f) < 0 || fputc(LSB(MSW(hwpb.gateArray)), f) < 0 || fputc(MSB(LSW(hwpb.gateArray)), f) < 0 || fputc(LSB(LSW(hwpb.gateArray)), f) < 0) { tiemu_warning("Failed to write to file: <%s>\n", *dstname); fclose(f); return ERR_CANT_OPEN; } // Fill with 0xff up-to System Part for(i = 0x108 + hwpb.len+2; i < SPP; i++) if (fputc(0xff, f) < 0) { tiemu_warning("Failed to write to file: <%s>\n", *dstname); fclose(f); return ERR_CANT_OPEN; } // Copy FLASH upgrade at 0x12000 (SPP) num_blocks = real_size / 65536; for(i = 0; i < num_blocks; i++ ) { tiemu_info("."); fflush(stdout); if (fwrite(&img.data[65536 * i + SPP], sizeof(char), 65536, f) < 65536) { tiemu_warning("Failed to write to file: <%s>\n", *dstname); fclose(f); return ERR_CANT_OPEN; } } last_block = real_size % 65536; if (fwrite(&img.data[65536 * i + SPP], sizeof(char), last_block, f) < (size_t)last_block) { tiemu_warning("Failed to write to file: <%s>\n", *dstname); fclose(f); return ERR_CANT_OPEN; } tiemu_info(""); tiemu_info("Completing to %iMB size\n", img.size >> 20); for(j = SPP + real_size; j < img.size; j++) if (fputc(0xff, f) < 0) { tiemu_warning("Failed to write to file: <%s>\n", *dstname); fclose(f); return ERR_CANT_OPEN; } // Close file if (fclose(f)) { tiemu_warning("Failed to close file: <%s>\n", *dstname); return ERR_CANT_OPEN; } return 0; }