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; }
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; }
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; } }
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; }