예제 #1
0
int CART_Insert(const char *filename)
{
	FILE *fp;
	int len;
	int type;
	UBYTE header[16];

	/* remove currently inserted cart */
	CART_Remove();

	/* open file */
	fp = fopen(filename, "rb");
	if (fp == NULL) {
		return CART_CANT_OPEN;
  }
	/* check file length */
	len = Util_flen(fp);
	Util_rewind(fp);

	/* Save Filename for state save */
	strcpy(cart_filename, filename);

	/* if full kilobytes, assume it is raw image */
	if ((len & 0x3ff) == 0) {
		/* alloc memory and read data */
		cart_image = (UBYTE *) malloc(len);
		fread(cart_image, 1, len, fp);
		fclose(fp);
		/* find cart type */
		cart_type = CART_NONE;
		len >>= 10;	/* number of kilobytes */
		for (type = 1; type <= CART_LAST_SUPPORTED; type++)
			if (cart_kb[type] == len) {
				if (cart_type == CART_NONE)
					cart_type = type;
				else {
					return len;	/* more than one cartridge type of such length - user must select */
        }
			}
		if (cart_type != CART_NONE) {
			CART_Start();
			return 0;	/* ok */
		}
    if (cart_image) free(cart_image);
		cart_image = NULL;
		return CART_BAD_FORMAT;
	}
예제 #2
0
int SYSROM_SetPath(char const *filename, int num, ...)
{
	va_list ap;
	int len;
	ULONG crc;
	int retval = SYSROM_OK;
	FILE *f = fopen(filename, "rb");

	if (f == NULL)
		return SYSROM_ERROR;

	len = Util_flen(f);
	/* Don't proceed to CRC computation if the file has invalid size. */
	if (!IsLengthAllowed(len)) {
		fclose(f);
		return SYSROM_BADSIZE;
	}
	Util_rewind(f);
	if (!CRC32_FromFile(f, &crc)) {
		fclose(f);
		return SYSROM_ERROR;
	}
	fclose(f);

	va_start(ap, num);
	while (num > 0) {
		int id = va_arg(ap, int);
		--num;
		if (len != SYSROM_roms[id].size) {
			retval = SYSROM_BADSIZE;
			continue;
		}
		if (SYSROM_roms[id].crc32 != CRC_NULL && crc != SYSROM_roms[id].crc32) {
			retval = SYSROM_BADCRC;
			continue;
		}
		strcpy(SYSROM_roms[id].filename, filename);
		ClearUnsetFlag(id);
		retval = SYSROM_OK;
		break;
	}
	va_end(ap);
	return retval;
}
예제 #3
0
int SIO_Mount(int diskno, const char *filename, int b_open_readonly)
{
	FILE *f = NULL;
	UnitStatus status = ReadWrite;
	struct ATR_Header header;

	/* avoid overruns in sio_filename[] */
	if (strlen(filename) >= FILENAME_MAX)
		return FALSE;

	/* release previous disk */
	SIO_Dismount(diskno);

	/* open file */
	if (!b_open_readonly)
		f = Util_fopen(filename, "rb+", sio_tmpbuf[diskno - 1]);
	if (f == NULL) {
		f = Util_fopen(filename, "rb", sio_tmpbuf[diskno - 1]);
		if (f == NULL)
			return FALSE;
		status = ReadOnly;
	}

	/* read header */
	if (fread(&header, 1, sizeof(struct ATR_Header), f) != sizeof(struct ATR_Header)) {
		fclose(f);
		return FALSE;
	}

	/* detect compressed image and uncompress */
	switch (header.magic1) {
	case 0xf9:
	case 0xfa:
		/* DCM */
		{
			FILE *f2 = Util_tmpopen(sio_tmpbuf[diskno - 1]);
			if (f2 == NULL)
				return FALSE;
			Util_rewind(f);
			if (!CompressedFile_DCMtoATR(f, f2)) {
				Util_fclose(f2, sio_tmpbuf[diskno - 1]);
				fclose(f);
				return FALSE;
			}
			fclose(f);
			f = f2;
		}
		Util_rewind(f);
		if (fread(&header, 1, sizeof(struct ATR_Header), f) != sizeof(struct ATR_Header)) {
			Util_fclose(f, sio_tmpbuf[diskno - 1]);
			return FALSE;
		}
		status = ReadOnly;
		/* XXX: status = b_open_readonly ? ReadOnly : ReadWrite; */
		break;
	case 0x1f:
		if (header.magic2 == 0x8b) {
			/* ATZ/ATR.GZ, XFZ/XFD.GZ */
			fclose(f);
			f = Util_tmpopen(sio_tmpbuf[diskno - 1]);
			if (f == NULL)
				return FALSE;
			if (!CompressedFile_ExtractGZ(filename, f)) {
				Util_fclose(f, sio_tmpbuf[diskno - 1]);
				return FALSE;
			}
			Util_rewind(f);
			if (fread(&header, 1, sizeof(struct ATR_Header), f) != sizeof(struct ATR_Header)) {
				Util_fclose(f, sio_tmpbuf[diskno - 1]);
				return FALSE;
			}
			status = ReadOnly;
			/* XXX: status = b_open_readonly ? ReadOnly : ReadWrite; */
		}
		break;
	default:
		break;
	}

	boot_sectors_type[diskno - 1] = BOOT_SECTORS_LOGICAL;

	if (header.magic1 == MAGIC1 && header.magic2 == MAGIC2) {
		/* ATR (may be temporary from DCM or ATR/ATR.GZ) */
		header_size[diskno - 1] = 16;

		sectorsize[diskno - 1] = (header.secsizehi << 8) + header.secsizelo;
		if (sectorsize[diskno - 1] != 128 && sectorsize[diskno - 1] != 256) {
			Util_fclose(f, sio_tmpbuf[diskno - 1]);
			return FALSE;
		}

		if (header.writeprotect != 0 && !ignore_header_writeprotect)
			status = ReadOnly;

		/* ATR header contains length in 16-byte chunks. */
		/* First compute number of 128-byte chunks
		   - it's number of sectors on single density disk */
		sectorcount[diskno - 1] = ((header.hiseccounthi << 24)
			+ (header.hiseccountlo << 16)
			+ (header.seccounthi << 8)
			+ header.seccountlo) >> 3;

		/* Fix number of sectors if double density */
		if (sectorsize[diskno - 1] == 256) {
			if ((sectorcount[diskno - 1] & 1) != 0)
				/* logical (128-byte) boot sectors */
				sectorcount[diskno - 1] += 3;
			else {
				/* 256-byte boot sectors */
				/* check if physical or SIO2PC: physical if there's
				   a non-zero byte in bytes 0x190-0x30f of the ATR file */
				UBYTE buffer[0x180];
				int i;
				fseek(f, 0x190, SEEK_SET);
				if (fread(buffer, 1, 0x180, f) != 0x180) {
					Util_fclose(f, sio_tmpbuf[diskno - 1]);
					return FALSE;
				}
				boot_sectors_type[diskno - 1] = BOOT_SECTORS_SIO2PC;
				for (i = 0; i < 0x180; i++)
					if (buffer[i] != 0) {
						boot_sectors_type[diskno - 1] = BOOT_SECTORS_PHYSICAL;
						break;
					}
			}
			sectorcount[diskno - 1] >>= 1;
		}
	}
예제 #4
0
int SYSROM_FindInDir(char const *directory, int only_if_not_set)
{
	DIR *dir;
	struct dirent *entry;

	if (only_if_not_set && num_unset_roms == 0)
		/* No unset ROM paths left. */
		return TRUE;

	if ((dir = opendir(directory)) == NULL)
		return FALSE;

	while ((entry = readdir(dir)) != NULL) {
		char full_filename[FILENAME_MAX];
		FILE *file;
		int len;
		int id;
		ULONG crc;
		int matched_crc = FALSE;
		Util_catpath(full_filename, directory, entry->d_name);
		if ((file = fopen(full_filename, "rb")) == NULL)
			/* Ignore non-readable files (e.g. directories). */
			continue;

		len = Util_flen(file);
		/* Don't proceed to CRC computation if the file has invalid size. */
		if (!IsLengthAllowed(len)){
			fclose(file);
			continue;
		}
		Util_rewind(file);

		if (!CRC32_FromFile(file, &crc)) {
			fclose(file);
			continue;
		}
		fclose(file);

		/* Match ROM image by CRC. */
		for (id = 0; id < SYSROM_SIZE; ++id) {
			if ((!only_if_not_set || SYSROM_roms[id].unset)
			    && SYSROM_roms[id].size == len
			    && SYSROM_roms[id].crc32 != CRC_NULL && SYSROM_roms[id].crc32 == crc) {
				strcpy(SYSROM_roms[id].filename, full_filename);
				ClearUnsetFlag(id);
				matched_crc = TRUE;
				break;
			}
		}

		if (!matched_crc) {
			/* Match custom ROM image by name. */
			char *c = entry->d_name;
			while (*c != 0) {
				*c = (char)tolower(*c);
				++c;
			}

			id = MatchByName(entry->d_name, len, only_if_not_set);
			if (id >= 0){
				strcpy(SYSROM_roms[id].filename, full_filename);
				ClearUnsetFlag(id);
			}
		}
	}

	closedir(dir);
	return TRUE;
}