Пример #1
0
/*
	Try to get some information on the ROM dump:
	- size
	- ROM base address
	- FLASH/EPROM
	- soft version
	- calc type
*/
int ti68k_get_img_infos(const char *filename, IMG_INFO *ri)
{
	FILE *f;

	// No filename, exits
	if(!strcmp(g_basename(filename), ""))
	   return ERR_CANT_OPEN;

	// Check file
	if(!ti68k_is_a_img_file(filename))
	{
		tiemu_warning("Images must have '.img' extension (%s).\n",
			filename);
		return ERR_CANT_OPEN;
	}
	
	// Open dest file
  	f = fopen(filename, "rb");
  	if(f == NULL)
    {
      	tiemu_warning("Unable to open this file: <%s>\n", filename);
      	return ERR_CANT_OPEN;
    }
    
    // Read header
    if (fread(ri, sizeof(IMG_INFO), 1, f) < 1)
    {
      tiemu_warning("Failed to read from file: <%s>\n", filename);
      fclose(f);
      return ERR_CANT_OPEN;
    }

    if(strcmp(ri->signature, IMG_SIGN) || ri->size > 4*MB)
    {
      tiemu_warning("Bad image: <%s>\n", filename);
      return ERR_INVALID_UPGRADE;
    }

    // Close file
    if (fclose(f))
    {
      tiemu_warning("Failed to close file: <%s>\n", filename);
      return ERR_CANT_OPEN;
    }
    
    return 0;
}
Пример #2
0
/*
    Returns the first found image
*/
int ti68k_find_image(const char *dirname, char **dst_name)
{
    GDir *dir;
	GError *error = NULL;
	G_CONST_RETURN gchar *dirent;
    int ret = 0;
    char *filename;
    
    if(dst_name != NULL)
	    *dst_name = NULL;

    // Search for *.img files and convert them
	dir = g_dir_open(dirname, 0, &error);
	if (dir == NULL) 
	{
		tiemu_warning(_("Opendir error"));
      	return ERR_CANT_OPEN_DIR;
	}

    filename = NULL;

    while ((dirent = g_dir_read_name(dir)) != NULL) 
	{
  		if (dirent[0] == '.') 
  			continue;

        if(!ti68k_is_a_img_file(dirent))
            continue;

        filename = g_strconcat(dirname, dirent, NULL);
        ret = !0;
        break;
    }

    g_dir_close(dir);

    if(dst_name != NULL)
        *dst_name = filename;

    return ret;
}
Пример #3
0
/* 
   Print an error msg 
*/
static void stop (int line)
{
	tiemu_warning(_("Configuration file error at line %i."), line);
}
Пример #4
0
/*
  	Scan images in a given directory and write list into img_list.txt.
*/
int ti68k_scan_images(const char *dirname, const char *filename)
{
	FILE *file;
	IMG_INFO img;
	GDir *dir;
	GError *error = NULL;
	G_CONST_RETURN gchar *dirent;
	gchar *path, *str;
	int ret;
	struct stat f_info;
  	char *line[7];

  	tiemu_info(_("Scanning images/upgrades... "));

	// Create file (and overwrite)
	file = fopen(filename, "wt");
    if(file == NULL)
	{
	  	tiemu_warning(_("Unable to open this file: <%s>"), filename);
	  	return ERR_CANT_OPEN;
	} 	

  	// List all files available in the directory
	dir = g_dir_open(dirname, 0, &error);
	if (dir == NULL) 
	{
		tiemu_warning(_("Opendir error"));
      	return ERR_CANT_OPEN_DIR;
	}
  
	while ((dirent = g_dir_read_name(dir)) != NULL) 
	{
  		if (dirent[0] == '.') 
  			continue;
   
	  	path = g_strconcat(dirname, dirent, NULL);
	  	
		ret = stat(path, &f_info);
		if(ret == -1)
		{
			tiemu_warning(_("Can not stat: <%s>"), dirent);
	      	perror("stat: ");
		}
		else
		{
			if(ti68k_is_a_img_file(path))
			{
				memset(&img, 0, sizeof(IMG_INFO));
				ret = ti68k_get_img_infos(path, &img);
				if(ret)
				{
					tiemu_warning(_("Can not get ROM/update info: <%s>"), path);
					break;
				}
			}
            else
				continue;

			str = g_strdup_printf("%iKB", (int)(img.size >> 10));

		  	line[0] = (char *)dirent;
		  	line[1] = (char *)ti68k_calctype_to_string(img.calc_type);
	  		line[2] = img.version;
	  		line[3] = (char *)ti68k_romtype_to_string(img.flash);
	  		line[4] = str;
			line[5] = img.has_boot ? _("yes") : _("no");
			line[6] = (char *)ti68k_hwtype_to_string(img.hw_type);
	  
		  	fprintf(file, "%s,%s,%s,%s,%s,%s,%s\n", 
		  			line[0], line[1], line[2], 
		  			line[3], line[4], line[5], line[6]);
			g_free(str);
		}
	  	g_free(path);
    }      

	// Close
	g_dir_close(dir);
  
  	fclose(file);
  	tiemu_info(_("Done."));
  
  	return 0;
}
Пример #5
0
/*
    Search for ROM dumps or FLASH upgrades in a given directory 
	and converts them into images (note: original file is deleted !).
*/
int ti68k_scan_files(const char *src_dir, const char *dst_dir, int erase)
{
    GDir *dir;
	GError *error = NULL;
	G_CONST_RETURN gchar *dirent;
    gchar *path;
    int ret;
    gchar *dstname;

    // Search for  files and convert them
	dir = g_dir_open(src_dir, 0, &error);
	if (dir == NULL) 
	{
		tiemu_warning(_("Opendir error"));
      	return ERR_CANT_OPEN_DIR;
	}

    while ((dirent = g_dir_read_name(dir)) != NULL) 
	{
  		if (dirent[0] == '.') 
  			continue;

        path = g_strconcat(src_dir, dirent, NULL);

        if(ti68k_is_a_rom_file(path))
        {
            ret = ti68k_convert_rom_to_image(path, dst_dir, &dstname);
			if(ret)
				{
					g_free(dstname);
					g_free(path);
					return ret;
						}

            if(erase)
                unlink(path);

            g_free(dstname);
        }

		if(ti68k_is_a_tib_file(path))
        {
            ret = ti68k_convert_tib_to_image(path, dst_dir, &dstname, -1);
			if(ret)
				{
					g_free(dstname);
					g_free(path);
				return ret;
					}

            if(erase)
                unlink(path);

            g_free(dstname);
        }

        g_free(path);
    }

    g_dir_close(dir);

    return 0;
}
Пример #6
0
/*
  	This function loads an image.
*/
int ti68k_load_image(const char *filename)
{
	IMG_INFO *img = &img_infos;
  	FILE *f;  	
  	int err;

	// Clear infos
	memset(img, 0, sizeof(IMG_INFO));

	// No filename, exits
	if(!strcmp(g_basename(filename), ""))
	   return ERR_CANT_OPEN;

	// Load infos
	err = ti68k_get_img_infos(filename, img);
  	if(err)
    {
      	tiemu_info(_("Unable to get information on image: %s"), filename);
      	return err;
    }
	ti68k_display_img_infos(img);
	
	// Open file
	f = fopen(filename, "rb");
	if(f == NULL)
	{
		tiemu_warning("Unable to open this file: <%s>\n", filename);
		return ERR_CANT_OPEN;
	}

	// Read pure data
	if (fseek(f, img->header_size, SEEK_SET))
	{
		tiemu_warning("Failed to read from file: <%s>\n", filename);
		fclose(f);
		return ERR_CANT_OPEN;
	}

	img->data = malloc(img->size + 4);
	if(img->data == NULL)
		return ERR_MALLOC;
	if (fread(img->data, 1, img->size, f) < (size_t)img->size)
	{
		tiemu_warning("Failed to read from file: <%s>\n", filename);
		fclose(f);
		return ERR_CANT_OPEN;
	}

#if 1
	{
		HW_PARM_BLOCK hwblock;

		ti68k_get_hw_param_block((uint8_t *)img->data, img->rom_base, 
					 &hwblock);
		ti68k_display_hw_param_block(&hwblock);
	}
#endif

	if (fclose(f))
	{
		tiemu_warning("Failed to close file: <%s>\n", filename);
		return ERR_CANT_OPEN;
	}

	img_loaded = 1;
	img_changed = 1;

	return 0;
}
Пример #7
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;
}
Пример #8
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;
}
Пример #9
0
/*
  	Convert a romdump into an image.
	This kind of image is complete (boot & certificate).
*/
int ti68k_convert_rom_to_image(const char *srcname, const char *dirname, char **dstname)
{
  	FILE *f; 
  	int err;
	IMG_INFO img;
	char *ext;
	gchar *basename;

	*dstname = NULL;

	// No filename, exits
	if(!strcmp(g_basename(srcname), ""))
	   return ERR_CANT_OPEN;

	// Preload romdump
	memset(&img, 0, sizeof(IMG_INFO));
	err = ti68k_get_rom_infos(srcname, &img, !0);
	if(err)
    {
	    free(img.data);
      	tiemu_info(_("Unable to get information on ROM dump: %s"), srcname);
      	return err;
    }
	ti68k_display_rom_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;
    }

	// Some V200 and TI89 Titanium ROMs are half the size
	if((img.size < 4*MB) && (img.calc_type == V200 || img.calc_type == TI89t))
	{
		img.size = 4*MB;
		img.data = realloc(img.data, 4*MB + 4);
		tiemu_info(_("Completing image to 4 MB!"));
		memset(img.data + 2*MB, 0xff, 2*MB);
	}

	// Fill header
	strcpy(img.signature, IMG_SIGN);
	img.header_size = sizeof(IMG_INFO);
    img.revision = IMG_REV;

	// Write file
	if (fwrite(&img, 1, sizeof(IMG_INFO), f) < (size_t)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;
}
Пример #10
0
/*
	Try to get some information on the ROM dump:
	- size
	- ROM base address
	- FLASH/EPROM
	- soft version
	- calc type
*/
int ti68k_get_img_infos(const char *filename, IMG_INFO *ri)
{
	FILE *f;
	IMG_INFO32 ri32;
	IMG_INFO64 ri64;

	// No filename, exits
	if(!strcmp(g_basename(filename), ""))
	   return ERR_CANT_OPEN;

	// Check file
	if(!ti68k_is_a_img_file(filename))
	{
		tiemu_warning("Images must have '.img' extension (%s).\n",
			filename);
		return ERR_CANT_OPEN;
	}
	
	// Open dest file
  	f = fopen(filename, "rb");
  	if(f == NULL)
    {
      	tiemu_warning("Unable to open this file: <%s>\n", filename);
      	return ERR_CANT_OPEN;
    }
    
    // Read header
    if (fread(&ri32, sizeof(IMG_INFO32), 1, f) < 1)
    {
      tiemu_warning("Failed to read from file: <%s>\n", filename);
      fclose(f);
      return ERR_CANT_OPEN;
    }
    *ri = ri32;

	// below is patch from Lionel
    if(strcmp(ri->signature, IMG_SIGN) || ri->size > 4*MB || ri->calc_type > CALC_MAX
       || ri->header_size == 0 || ri->hw_type > 4 || ri->rom_base == 0)
    {
      // In addition to plain invalid files, this may happen if the image was
      // created on a 64-bit platform with TIEmu <= 3.03.
      // Try to read an IMG_INFO structure as it used to be written by those
      // 64-bit platforms.
      fseek(f, 0, SEEK_SET);
      if (fread(&ri64, sizeof(IMG_INFO64), 1, f) < 1)
      {
        tiemu_warning("Failed to read from file: <%s>\n", filename);
        fclose(f);
        return ERR_CANT_OPEN;
      }
      else {
        memcpy(ri->signature, &(ri64.signature), sizeof(ri64.signature));
        ri->revision = (int32_t)(ri64.revision);
        ri->header_size = (int32_t)(ri64.header_size);

        ri->calc_type = ri64.calc_type;
        memcpy(ri->version, &(ri64.version), sizeof(ri64.version));
        ri->flash = ri64.flash;
        ri->has_boot = ri64.has_boot;
        ri->size = (int32_t)(ri64.size);
        ri->hw_type = ri64.hw_type;
        ri->rom_base = ri64.rom_base;
          
        if(strcmp(ri->signature, IMG_SIGN) || ri->size > 4*MB || ri->calc_type > CALC_MAX
           || ri->header_size == 0 || ri->hw_type > 4 || ri->rom_base == 0)
        {
          // Nope, it still doesn't seem to be a TIEmu image.
          tiemu_warning("Bad image: <%s>\n", filename);
          return ERR_INVALID_UPGRADE;
        }
        else {
          tiemu_info("Found a reasonably valid 64-bit IMG_INFO in <%s>\n", filename);
        }
      }
    }

    // Close file
    if (fclose(f))
    {
      tiemu_warning("Failed to close file: <%s>\n", filename);
      return ERR_CANT_OPEN;
    }
    
    return 0;
}