bool cbm_crt_read_data(core_file* file, UINT8 *roml, UINT8 *romh) { offs_t roml_offset = 0; offs_t romh_offset = 0; core_fseek(file, CRT_HEADER_LENGTH, SEEK_SET); while (!core_feof(file)) { cbm_crt_chip chip; core_fread(file, &chip, CRT_CHIP_LENGTH); UINT16 address = pick_integer_be(chip.start_address, 0, 2); UINT16 size = pick_integer_be(chip.image_size, 0, 2); switch (address) { case 0x8000: core_fread(file, roml + roml_offset, size); roml_offset += size; break; case 0xa000: core_fread(file, romh + romh_offset, size); romh_offset += size; break; case 0xe000: core_fread(file, romh + romh_offset, size); romh_offset += size; break; } } return true; }
bool cbm_crt_read_data(util::core_file &file, UINT8 *roml, UINT8 *romh) { UINT32 roml_offset = 0; UINT32 romh_offset = 0; file.seek(CRT_HEADER_LENGTH, SEEK_SET); while (!file.eof()) { cbm_crt_chip chip; file.read(&chip, CRT_CHIP_LENGTH); UINT16 address = pick_integer_be(chip.start_address, 0, 2); UINT16 size = pick_integer_be(chip.image_size, 0, 2); switch (address) { case 0x8000: file.read(roml + roml_offset, size); roml_offset += size; break; case 0xa000: file.read(romh + romh_offset, size); romh_offset += size; break; case 0xe000: file.read(romh + romh_offset, size); romh_offset += size; break; } } return true; }
bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, int *exrom, int *game) { // read the header cbm_crt_header header; core_fread(file, &header, CRT_HEADER_LENGTH); if (memcmp(header.signature, CRT_SIGNATURE, 16) != 0) return false; UINT16 hardware = pick_integer_be(header.hardware, 0, 2); *exrom = header.exrom; *game = header.game; if (LOG) { logerror("Name: %s\n", header.name); logerror("Hardware: %04x\n", hardware); logerror("Slot device: %s\n", CRT_C64_SLOT_NAMES[hardware]); logerror("EXROM: %u\n", header.exrom); logerror("GAME: %u\n", header.game); } // determine ROM region lengths while (!core_feof(file)) { cbm_crt_chip chip; core_fread(file, &chip, CRT_CHIP_LENGTH); UINT16 address = pick_integer_be(chip.start_address, 0, 2); UINT16 size = pick_integer_be(chip.image_size, 0, 2); UINT16 type = pick_integer_be(chip.chip_type, 0, 2); if (LOG) { logerror("CHIP Address: %04x\n", address); logerror("CHIP Size: %04x\n", size); logerror("CHIP Type: %04x\n", type); } switch (address) { case 0x8000: *roml_size += size; break; case 0xa000: *romh_size += size; break; case 0xe000: *romh_size += size; break; default: logerror("Invalid CHIP loading address!\n"); break; } core_fseek(file, size, SEEK_CUR); } return true; }
static int os9_interpret_dirent(void *entry, char **filename, UINT32 *lsn, int *corrupt) { int i; char *entry_b = (char *) entry; *filename = NULL; *lsn = 0; if (corrupt) *corrupt = FALSE; if (entry_b[28] != '\0') { if (corrupt) *corrupt = TRUE; } for (i = 0; (i < 28) && !(entry_b[i] & 0x80); i++) ; entry_b[i] &= 0x7F; entry_b[i+1] = '\0'; *lsn = pick_integer_be(entry, 29, 3); if (strcmp(entry_b, ".") && strcmp(entry_b, "..")) *filename = entry_b; return *filename != NULL; }
const char * cbm_crt_get_card(core_file *file) { // read the header cbm_crt_header header; core_fread(file, &header, CRT_HEADER_LENGTH); if (memcmp(header.signature, CRT_SIGNATURE, 16) == 0) { UINT16 hardware = pick_integer_be(header.hardware, 0, 2); return CRT_C64_SLOT_NAMES[hardware]; } return NULL; }
std::string cbm_crt_get_card(util::core_file &file) { // read the header cbm_crt_header header; file.read(&header, CRT_HEADER_LENGTH); if (memcmp(header.signature, CRT_SIGNATURE, 16) == 0) { UINT16 hardware = pick_integer_be(header.hardware, 0, 2); return std::string(CRT_C64_SLOT_NAMES[hardware]); } return std::string(); }
void cbm_crt_get_card(astring &result, core_file *file) { // read the header cbm_crt_header header; core_fread(file, &header, CRT_HEADER_LENGTH); if (memcmp(header.signature, CRT_SIGNATURE, 16) == 0) { UINT16 hardware = pick_integer_be(header.hardware, 0, 2); result.cpy(CRT_C64_SLOT_NAMES[hardware]); return; } result.reset(); }
static UINT32 identify_attribute(struct imgtooltest_state *state, xml_data_node *node, imgtool_attribute *value) { xml_attribute_node *attr_node; UINT32 attribute; attr_node = xml_get_attribute(node, "name"); if (!attr_node) { state->m_failed = 1; error_missingattribute("name"); return 0; } if (!strcmp(attr_node->value, "mac_file_type")) attribute = IMGTOOLATTR_INT_MAC_TYPE; else if (!strcmp(attr_node->value, "mac_file_creator")) attribute = IMGTOOLATTR_INT_MAC_CREATOR; else { error_missingattribute("name"); return 0; } attr_node = xml_get_attribute(node, "value"); if (!attr_node) { state->m_failed = 1; error_missingattribute("value"); return 0; } switch(attribute) { case IMGTOOLATTR_INT_MAC_TYPE: case IMGTOOLATTR_INT_MAC_CREATOR: if (strlen(attr_node->value) != 4) { state->m_failed = 1; error_missingattribute("value"); return 0; } value->i = pick_integer_be(attr_node->value, 0, 4); break; } return attribute; }
static imgtoolerr_t os9_decode_file_header(imgtool_image *image, int lsn, struct os9_fileinfo *info) { imgtoolerr_t err; UINT32 attributes, count; int max_entries, i; const os9_diskinfo *disk_info; UINT8 header[256]; disk_info = os9_get_diskinfo(image); err = os9_read_lsn(image, lsn, 0, header, sizeof(header)); if (err) return err; info->lsn = lsn; attributes = pick_integer_be(header, 0, 1); info->owner_id = pick_integer_be(header, 1, 2); info->link_count = pick_integer_be(header, 8, 1); info->file_size = pick_integer_be(header, 9, 4); info->directory = (attributes & 0x80) ? 1 : 0; info->non_sharable = (attributes & 0x40) ? 1 : 0; info->public_execute = (attributes & 0x20) ? 1 : 0; info->public_write = (attributes & 0x10) ? 1 : 0; info->public_read = (attributes & 0x08) ? 1 : 0; info->user_execute = (attributes & 0x04) ? 1 : 0; info->user_write = (attributes & 0x02) ? 1 : 0; info->user_read = (attributes & 0x01) ? 1 : 0; if (info->directory && (info->file_size % 32 != 0)) return IMGTOOLERR_CORRUPTIMAGE; /* read all sector map entries */ max_entries = (disk_info->sector_size - 16) / 5; max_entries = MIN(max_entries, ARRAY_LENGTH(info->sector_map) - 1); for (i = 0; i < max_entries; i++) { lsn = pick_integer_be(header, 16 + (i * 5) + 0, 3); count = pick_integer_be(header, 16 + (i * 5) + 3, 2); if (count <= 0) break; info->sector_map[i].lsn = lsn; info->sector_map[i].count = count; } info->sector_map[i].lsn = 0; info->sector_map[i].count = 0; return IMGTOOLERR_SUCCESS; }
static imgtoolerr_t os9_diskimage_nextenum(imgtool_directory *enumeration, imgtool_dirent *ent) { struct os9_direnum *os9enum; UINT32 lsn, index; imgtoolerr_t err; UINT8 dir_entry[32]; char filename[29]; struct os9_fileinfo file_info; imgtool_image *image; image = imgtool_directory_image(enumeration); os9enum = os9_get_dirinfo(enumeration); do { /* check for EOF */ if (os9enum->index >= os9enum->dir_info.file_size) { ent->eof = 1; return IMGTOOLERR_SUCCESS; } /* locate the LSN and offset for this directory entry */ index = os9enum->index; lsn = os9_lookup_lsn(image, &os9enum->dir_info, &index); /* read the directory entry out of the lSN */ err = os9_read_lsn(image, lsn, index, dir_entry, sizeof(dir_entry)); if (err) return err; if (dir_entry[0]) { /* read the file or directory name */ pick_string(dir_entry, 0, 28, filename); /* we have certain expectations of the directory contents; the * first directory entry should be "..", the second ".", and * subsequent entries should never be "." or ".." */ switch(os9enum->index) { case 0: if (strcmp(filename, "..")) imgtool_warn("First entry in directory should be \"..\" and not \"%s\"", filename); break; case 32: if (strcmp(filename, ".")) imgtool_warn("Second entry in directory should be \".\" and not \"%s\"", filename); break; default: if (!strcmp(filename, ".") || !strcmp(filename, "..")) imgtool_warn("Directory entry %d should not be \"%s\"", index / 32, filename); break; } /* if the filename is ".", the file should point to the current directory */ if (!strcmp(filename, ".") && (pick_integer_be(dir_entry, 29, 3) != os9enum->dir_info.lsn)) { imgtool_warn("Directory \".\" does not point back to same directory"); } } else { /* no more directory entries */ filename[0] = '\0'; } /* move on to the next directory entry */ os9enum->index += 32; } while(!filename[0] || !strcmp(filename, ".") || !strcmp(filename, "..")); /* read file attributes */ lsn = pick_integer_be(dir_entry, 29, 3); err = os9_decode_file_header(imgtool_directory_image(enumeration), lsn, &file_info); if (err) return err; /* fill out imgtool_dirent structure */ snprintf(ent->filename, ARRAY_LENGTH(ent->filename), "%s", filename); snprintf(ent->attr, ARRAY_LENGTH(ent->attr), "%c%c%c%c%c%c%c%c", file_info.directory ? 'd' : '-', file_info.non_sharable ? 's' : '-', file_info.public_execute ? 'x' : '-', file_info.public_write ? 'w' : '-', file_info.public_read ? 'r' : '-', file_info.user_execute ? 'x' : '-', file_info.user_write ? 'w' : '-', file_info.user_read ? 'r' : '-'); ent->directory = file_info.directory; ent->corrupt = (dir_entry[28] != 0); ent->filesize = file_info.file_size; return IMGTOOLERR_SUCCESS; }
static imgtoolerr_t os9_diskimage_open(imgtool_image *image, imgtool_stream *stream) { imgtoolerr_t err; floperr_t ferr; os9_diskinfo *info; UINT32 track_size_in_sectors, i; //, attributes; UINT8 header[256]; UINT32 allocation_bitmap_lsns; UINT8 b, mask; info = os9_get_diskinfo(image); ferr = floppy_read_sector(imgtool_floppy(image), 0, 0, 1, 0, header, sizeof(header)); if (ferr) return imgtool_floppy_error(ferr); info->total_sectors = pick_integer_be(header, 0, 3); track_size_in_sectors = pick_integer_be(header, 3, 1); info->allocation_bitmap_bytes = pick_integer_be(header, 4, 2); info->cluster_size = pick_integer_be(header, 6, 2); info->root_dir_lsn = pick_integer_be(header, 8, 3); info->owner_id = pick_integer_be(header, 11, 2); // attributes = pick_integer_be(header, 13, 1); info->disk_id = pick_integer_be(header, 14, 2); info->format_flags = pick_integer_be(header, 16, 1); info->sectors_per_track = pick_integer_be(header, 17, 2); info->bootstrap_lsn = pick_integer_be(header, 21, 3); info->bootstrap_size = pick_integer_be(header, 24, 2); info->sector_size = pick_integer_be(header, 104, 2); info->sides = (info->format_flags & 0x01) ? 2 : 1; info->double_density = (info->format_flags & 0x02) ? 1 : 0; info->double_track = (info->format_flags & 0x04) ? 1 : 0; info->quad_track_density = (info->format_flags & 0x08) ? 1 : 0; info->octal_track_density = (info->format_flags & 0x10) ? 1 : 0; pick_string(header, 31, 32, info->name); if (info->sector_size == 0) info->sector_size = 256; /* does the root directory and allocation bitmap collide? */ allocation_bitmap_lsns = (info->allocation_bitmap_bytes + info->sector_size - 1) / info->sector_size; if (1 + allocation_bitmap_lsns > info->root_dir_lsn) return IMGTOOLERR_CORRUPTIMAGE; /* is the allocation bitmap too big? */ info->allocation_bitmap = (UINT8*)imgtool_image_malloc(image, info->allocation_bitmap_bytes); if (!info->allocation_bitmap) return IMGTOOLERR_OUTOFMEMORY; memset(info->allocation_bitmap, 0, info->allocation_bitmap_bytes); /* sectors per track and track size don't jive? */ if (info->sectors_per_track != track_size_in_sectors) return IMGTOOLERR_CORRUPTIMAGE; /* zero sectors per track? */ if (info->sectors_per_track == 0) return IMGTOOLERR_CORRUPTIMAGE; /* do we have an odd number of sectors? */ if (info->total_sectors % info->sectors_per_track) return IMGTOOLERR_CORRUPTIMAGE; /* read the allocation bitmap */ for (i = 0; i < allocation_bitmap_lsns; i++) { err = os9_read_lsn(image, 1 + i, 0, &info->allocation_bitmap[i * info->sector_size], MIN(info->allocation_bitmap_bytes - (i * info->sector_size), info->sector_size)); if (err) return err; } /* check to make sure that the allocation bitmap and root sector are reserved */ for (i = 0; i <= allocation_bitmap_lsns; i++) { b = info->allocation_bitmap[i / 8]; mask = 1 << (7 - (i % 8)); if ((b & mask) == 0) return IMGTOOLERR_CORRUPTIMAGE; } return IMGTOOLERR_SUCCESS; }
static imgtoolerr_t macbinary_writefile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, option_resolution *opts) { static const UINT32 attrs[] = { IMGTOOLATTR_TIME_CREATED, IMGTOOLATTR_TIME_LASTMODIFIED, IMGTOOLATTR_INT_MAC_TYPE, IMGTOOLATTR_INT_MAC_CREATOR, IMGTOOLATTR_INT_MAC_FINDERFLAGS, IMGTOOLATTR_INT_MAC_COORDX, IMGTOOLATTR_INT_MAC_COORDY, IMGTOOLATTR_INT_MAC_FINDERFOLDER, IMGTOOLATTR_INT_MAC_SCRIPTCODE, IMGTOOLATTR_INT_MAC_EXTENDEDFLAGS, 0 }; imgtoolerr_t err; imgtool_image *image = imgtool_partition_image(partition); UINT8 header[128]; UINT32 datafork_size; UINT32 resourcefork_size; UINT64 total_size; UINT32 creation_time; UINT32 lastmodified_time; //int version; imgtool_attribute attr_values[10]; UINT32 type_code; UINT32 creator_code; UINT16 finder_flags; UINT16 coord_x; UINT16 coord_y; UINT16 finder_folder; UINT8 script_code = 0; UINT8 extended_flags = 0; /* read in the header */ memset(header, 0, sizeof(header)); stream_read(sourcef, header, sizeof(header)); /* check magic and zero fill bytes */ if (header[0] != 0x00) return IMGTOOLERR_CORRUPTFILE; if (header[74] != 0x00) return IMGTOOLERR_CORRUPTFILE; if (header[82] != 0x00) return IMGTOOLERR_CORRUPTFILE; datafork_size = pick_integer_be(header, 83, 4); resourcefork_size = pick_integer_be(header, 87, 4); total_size = stream_size(sourcef); /* size of a MacBinary header is always 128 bytes */ if (total_size - pad128(datafork_size) - pad128(resourcefork_size) != 128) return IMGTOOLERR_CORRUPTFILE; /* check filename length byte */ if ((header[1] <= 0x00) || (header[1] > 0x3F)) return IMGTOOLERR_CORRUPTFILE; /* check the CRC */ if (pick_integer_be(header, 124, 2) != ccitt_crc16(0, header, 124)) { /* the CRC does not match; this file is MacBinary I */ //version = 1; } else if (pick_integer_be(header, 102, 4) != 0x6D42494E) { /* did not see 'mBIN'; this file is MacBinary II */ if (header[122] < 0x81) return IMGTOOLERR_CORRUPTFILE; if (header[123] < 0x81) return IMGTOOLERR_CORRUPTFILE; //version = 2; } else { /* we did see 'mBIN'; this file is MacBinary III */ if (header[122] < 0x82) return IMGTOOLERR_CORRUPTFILE; if (header[123] < 0x81) return IMGTOOLERR_CORRUPTFILE; //version = 3; } type_code = pick_integer_be(header, 65, 4); creator_code = pick_integer_be(header, 69, 4); finder_flags = pick_integer_be(header, 73, 1) << 8; coord_x = pick_integer_be(header, 75, 2); coord_y = pick_integer_be(header, 77, 2); finder_folder = pick_integer_be(header, 79, 2); creation_time = pick_integer_be(header, 91, 4); lastmodified_time = pick_integer_be(header, 95, 4); if (image) { /* write out both forks */ err = write_fork(partition, filename, "", sourcef, sizeof(header), datafork_size, opts); if (err) return err; err = write_fork(partition, filename, "RESOURCE_FORK", sourcef, sizeof(header) + pad128(datafork_size), resourcefork_size, opts); if (err) return err; /* set up attributes */ attr_values[0].t = mac_crack_time(creation_time); attr_values[1].t = mac_crack_time(lastmodified_time); attr_values[2].i = type_code; attr_values[3].i = creator_code; attr_values[4].i = finder_flags; attr_values[5].i = coord_x; attr_values[6].i = coord_y; attr_values[7].i = finder_folder; attr_values[8].i = script_code; attr_values[9].i = extended_flags; err = imgtool_partition_put_file_attributes(partition, filename, attrs, attr_values); if (err) return err; } return IMGTOOLERR_SUCCESS; }