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 AFILE_DetectFileType(const char *filename) { UBYTE header[4]; int file_length; FILE *fp = fopen(filename, "rb"); if (fp == NULL) return AFILE_ERROR; if (fread(header, 1, 4, fp) != 4) { fclose(fp); return AFILE_ERROR; } switch (header[0]) { case 0: if (header[1] == 0 && (header[2] != 0 || header[3] != 0) /* && file_length < 37 * 1024 */) { fclose(fp); return AFILE_BAS; } break; case 0x1f: if (header[1] == 0x8b) { #ifndef HAVE_LIBZ fclose(fp); Log_print("\"%s\" is a compressed file.", filename); Log_print("This executable does not support compressed files. You can uncompress this file"); Log_print("with an external program that supports gzip (*.gz) files (e.g. gunzip)"); Log_print("and then load into this emulator."); return AFILE_ERROR; #else /* HAVE_LIBZ */ gzFile gzf; fclose(fp); gzf = gzopen(filename, "rb"); if (gzf == NULL) return AFILE_ERROR; if (gzread(gzf, header, 4) != 4) { gzclose(gzf); return AFILE_ERROR; } gzclose(gzf); if (header[0] == 0x96 && header[1] == 0x02) return AFILE_ATR_GZ; if (header[0] == 'A' && header[1] == 'T' && header[2] == 'A' && header[3] == 'R') return AFILE_STATE_GZ; return AFILE_XFD_GZ; #endif /* HAVE_LIBZ */ } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((header[1] >= '0' && header[1] <= '9') || header[1] == ' ') { fclose(fp); return AFILE_LST; } break; case 'A': if (header[1] == 'T' && header[2] == 'A' && header[3] == 'R') { fclose(fp); return AFILE_STATE; } if (header[1] == 'T' && header[2] == '8' && header[3] == 'X') { fclose(fp); return AFILE_ATX; } break; case 'C': if (header[1] == 'A' && header[2] == 'R' && header[3] == 'T') { fclose(fp); return AFILE_CART; } break; case 0x96: if (header[1] == 0x02) { fclose(fp); return AFILE_ATR; } break; case 0xf9: case 0xfa: fclose(fp); return AFILE_DCM; case 0xff: if (header[1] == 0xff && (header[2] != 0xff || header[3] != 0xff)) { fclose(fp); return AFILE_XEX; } break; default: break; } file_length = Util_flen(fp); fclose(fp); /* Detect .pro images */ /* # of sectors is in header */ if ((file_length-16)%(128+12) == 0 && header[0]*256 + header[1] == (file_length-16)/(128+12) && header[2] == 'P') { #ifdef DEBUG_PRO Log_print(".pro file detected"); #endif return AFILE_PRO; } /* 40K or a-power-of-two between 4K and CARTRIDGE_MAX_SIZE */ if (file_length >= 4 * 1024 && file_length <= CARTRIDGE_MAX_SIZE && ((file_length & (file_length - 1)) == 0 || file_length == 40 * 1024)) return AFILE_ROM; /* BOOT_TAPE is a raw file containing a program booted from a tape */ if ((header[1] << 7) == file_length) return AFILE_BOOT_TAPE; if ((file_length & 0x7f) == 0) return AFILE_XFD; if (IMG_TAPE_FileSupported(header)) return AFILE_CAS; return AFILE_ERROR; }
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; }