bool mfm_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { MFMIMG header; MFMTRACKIMG trackdesc; // read header io_generic_read(io, &header, 0, sizeof(header)); int counter = 0; dynamic_buffer trackbuf; for(int track=0; track < header.number_of_track; track++) { for(int side=0; side < header.number_of_side; side++) { // read location of io_generic_read(io, &trackdesc,(header.mfmtracklistoffset)+( counter *sizeof(trackdesc)),sizeof(trackdesc)); trackbuf.resize(trackdesc.mfmtracksize); // actual data read io_generic_read(io, &trackbuf[0], trackdesc.mfmtrackoffset, trackdesc.mfmtracksize); generate_track_from_bitstream(track, side, &trackbuf[0], trackdesc.mfmtracksize*8, image); counter++; } } image->set_variant(floppy_image::DSDD); return true; }
bool mfm_format::load(io_generic *io, floppy_image *image) { MFMIMG header; MFMTRACKIMG trackdesc; UINT8 *trackbuf = 0; int trackbuf_size = 0; // read header io_generic_read(io, &header, 0, sizeof(header)); int counter = 0; for(int track=0; track < header.number_of_track; track++) { for(int side=0; side < header.number_of_side; side++) { // read location of io_generic_read(io, &trackdesc,(header.mfmtracklistoffset)+( counter *sizeof(trackdesc)),sizeof(trackdesc)); if(trackdesc.mfmtracksize > trackbuf_size) { if(trackbuf) global_free(trackbuf); trackbuf_size = trackdesc.mfmtracksize; trackbuf = global_alloc_array(UINT8, trackbuf_size); } // actual data read io_generic_read(io, trackbuf, trackdesc.mfmtrackoffset, trackdesc.mfmtracksize); generate_track_from_bitstream(track, side, trackbuf, trackdesc.mfmtracksize*8, image); counter++; } } if(trackbuf) global_free(trackbuf); return true; }
bool dsk_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { UINT8 header[100]; bool extendformat = FALSE; io_generic_read(io, &header, 0, sizeof(header)); if ( memcmp( header, EXT_FORMAT_HEADER, 16 ) ==0) { extendformat = TRUE; } int heads = header[0x31]; int skip = 1; if (heads==1) { skip = 2; } int tracks = header[0x30]; UINT64 track_offsets[84*2]; int cnt =0; if (!extendformat) { int tmp = 0x100; for (int i=0; i<tracks * heads; i++) { track_offsets[cnt] = tmp; tmp += pick_integer_le(header, 0x32, 2); cnt += skip; } } else { int tmp = 0x100; for (int i=0; i<tracks * heads; i++) { track_offsets[cnt] = tmp; tmp += header[0x34 + i] << 8; cnt += skip; } } int counter = 0; for(int track=0; track < tracks; track++) { for(int side=0; side < heads; side++) { // read location of track_header tr; io_generic_read(io, &tr,track_offsets[(track<<1)+side],sizeof(tr)); //printf("%d,%d %d, %d\n",track,side,tr.track_number, tr.gap3_length); //int sec_location = track_offsets[(track<<1)+side] + 0x100; for(int j=0;j<tr.number_of_sector;j++) { sector_header sector; io_generic_read(io, §or,track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j),sizeof(sector)); //printf("sec %02x %08x\n",sector.sector_id,sec_location); //sec_location += sector.data_lenght; } counter++; } } return FALSE; }
bool mfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { header h; entry entries[84*2]; io_generic_read(io, &h, 0, sizeof(header)); io_generic_read(io, &entries, sizeof(header), h.cyl_count*h.head_count*sizeof(entry)); image->set_variant(h.variant); UINT8 *compressed = 0; int compressed_size = 0; entry *ent = entries; for(unsigned int cyl=0; cyl != h.cyl_count; cyl++) for(unsigned int head=0; head != h.head_count; head++) { if(ent->uncompressed_size == 0) { // Unformatted track image->set_track_size(cyl, head, 0); ent++; continue; } if(ent->compressed_size > compressed_size) { if(compressed) global_free(compressed); compressed_size = ent->compressed_size; compressed = global_alloc_array(UINT8, compressed_size); } io_generic_read(io, compressed, ent->offset, ent->compressed_size); unsigned int cell_count = ent->uncompressed_size/4; image->set_track_size(cyl, head, cell_count); UINT32 *trackbuf = image->get_buffer(cyl, head); uLongf size = ent->uncompressed_size; if(uncompress((Bytef *)trackbuf, &size, compressed, ent->compressed_size) != Z_OK) return false; UINT32 cur_time = 0; for(unsigned int i=0; i != cell_count; i++) { UINT32 next_cur_time = cur_time + (trackbuf[i] & TIME_MASK); trackbuf[i] = (trackbuf[i] & MG_MASK) | cur_time; cur_time = next_cur_time; } if(cur_time != 200000000) return false; ent++; } if(compressed) global_free(compressed); return true; }
bool oric_dsk_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { UINT8 h[256]; UINT8 t[6250+3]; UINT32 stream[100000]; t[6250] = t[6251] = t[6252] = 0; io_generic_read(io, h, 0, 256); int sides = (h[11] << 24) | (h[10] << 16) | (h[ 9] << 8) | h[ 8]; int tracks = (h[15] << 24) | (h[14] << 16) | (h[13] << 8) | h[12]; for(int side=0; side<sides; side++) for(int track=0; track<tracks; track++) { io_generic_read(io, t, 256+6400*(tracks*side + track), 6250); int pos = 0; int sector_size = 128; for(int i=0; i<6250; i++) { if(t[i] == 0xc2 && t[i+1] == 0xc2 && t[i+2] == 0xc2) { raw_w(stream, pos, 16, 0x5224); raw_w(stream, pos, 16, 0x5224); raw_w(stream, pos, 16, 0x5224); i += 2; continue; } if(t[i] == 0xa1 && t[i+1] == 0xa1 && t[i+2] == 0xa1) { raw_w(stream, pos, 16, 0x4489); raw_w(stream, pos, 16, 0x4489); raw_w(stream, pos, 16, 0x4489); int copy; if(t[i+3] == 0xfe) { copy = 7; sector_size = 128 << (t[i+7] & 3); logerror("%02x %x - %02x %02x %02x %02x\n", track, side, t[i+4], t[i+5], t[i+6], t[i+7]); } else if(t[i+3] == 0xfb) copy = sector_size+3; else copy = 0; for(int j=0; j<copy; j++) mfm_w(stream, pos, 8, t[i+3+j]); i += 2+copy; continue; } mfm_w(stream, pos, 8, t[i]); } generate_track_from_levels(track, side, stream, 100000, 0, image); } return true; }
bool esqimg_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { int track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); UINT8 sectdata[10*512]; desc_s sectors[10]; for(int i=0; i<sector_count; i++) { sectors[i].data = sectdata + 512*i; sectors[i].size = 512; sectors[i].sector_id = i; } int track_size = sector_count*512; for(int track=0; track < track_count; track++) { for(int head=0; head < head_count; head++) { io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size); generate_track(esq_10_desc, track, head, sectors, sector_count, 110528, image); } } image->set_variant(floppy_image::DSDD); return true; }
/* track_count = 40; sector_count = 9; // [VT 180] expected_size = 512 * track_count * head_count * sector_count; if (size == expected_size) return; track_count = 40; sector_count = 8; // [DOS] expected_size = 512 * track_count * head_count * sector_count; if (size == expected_size) return; */ track_count = head_count = sector_count = 0; } int rx50img_format::identify(io_generic *io, uint32_t form_factor) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); if(track_count) return 50; return 0; } // /* Sectors are numbered 1 to 10 */ bool rx50img_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); if(track_count == 0) return false; uint8_t sectdata[10*512]; desc_s sectors[10]; for(int i=0; i<sector_count; i++) { sectors[i].data = sectdata + 512*i; sectors[i].size = 512; sectors[i].sector_id = i + 1; // SECTOR_ID +1 <=== } int track_size = sector_count*512; for(int track=0; track < track_count; track++) { for(int head=0; head < head_count; head++) { io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size); generate_track(rx50_10_desc, track, head, sectors, sector_count, 102064, image); // 98480 } } image->set_variant(floppy_image::SSQD); return true; }
bool st_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); uint8_t sectdata[11*512]; desc_s sectors[11]; for(int i=0; i<sector_count; i++) { sectors[i].data = sectdata + 512*i; sectors[i].size = 512; sectors[i].sector_id = i + 1; } int track_size = sector_count*512; for(int track=0; track < track_count; track++) { for(int head=0; head < head_count; head++) { io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size); generate_track(atari_st_fcp_get_desc(track, head, head_count, sector_count), track, head, sectors, sector_count, 100000, image); } } image->set_variant(floppy_image::DSDD); return true; }
int dfi_format::identify(io_generic *io, UINT32 form_factor) { char sign[4]; io_generic_read(io, sign, 0, 4); if (memcmp(sign, "DFER", 4)==0) fatalerror("Old type Discferret image detected; the mess Discferret decoder will not handle this properly, bailing out!\n"); return memcmp(sign, "DFE2", 4) ? 0 : 100; }
bool flex_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { int spt = info.last_sec; int bps = 256; int cell_count = (form_factor == floppy_image::FF_525) ? 50000 : 100000; int offset = 0; int head_num = 1; int total_tracks = info.last_trk+1; bool double_sided = false; if(total_tracks == 40 && spt == 36) double_sided = true; if(total_tracks == 77 && spt == 30) double_sided = true; if(total_tracks == 80 && spt == 40) // 800kB double_sided = true; if(total_tracks == 80 && spt == 72) // 1.44MB double_sided = true; if(spt >= 20) double_sided = true; if(double_sided) { spt = spt / 2; head_num = 2; } for(int track=0; track < total_tracks; track++) for(int head=0;head < head_num;head++) { desc_pc_sector sects[80]; UINT8 sect_data[20000]; int sdatapos = 0; for(int i=0; i<spt; i++) { sects[i].track = track; sects[i].head = head; // no side select? if(head == 0) sects[i].sector = i+1; else sects[i].sector = i+1+spt; sects[i].actual_size = bps; sects[i].size = 1; sects[i].deleted = false; sects[i].bad_crc = false; sects[i].data = §_data[sdatapos]; io_generic_read(io, sects[i].data, offset, bps); offset += bps; sdatapos += bps; } // gap sizes unverified if(total_tracks == 35 && spt == 18 && (track >= 1 && track <= 2)) // handle Gimix Flex 3.6 disk image, which the boot sector loads tracks 1 and 2 as MFM build_wd_track_mfm(track, head, image, cell_count*2, spt, sects, 50, 32, 22); else build_wd_track_fm(track, head, image, cell_count, spt, sects, 24, 16, 11); } return true; }
bool ccvf_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { const format &f = formats[0]; UINT64 size = io_generic_size(io); dynamic_buffer img(size); io_generic_read(io, &img[0], 0, size); std::string ccvf = std::string((const char *)&img[0], size); dynamic_buffer bytes(78720); int start = 0, end = 0; std::string line; UINT32 byteoffs = 0; char hex[3] = {0}; do { end = ccvf.find_first_of(10, start); line.assign(ccvf.substr(start, end)); if (line.find("Compucolor Virtual Floppy Disk Image") != std::string::npos && line.find("Label") != std::string::npos && line.find("Track") != std::string::npos) { for (int byte = 0; byte < 32; byte++) { if (byteoffs==78720) break; hex[0]=line[byte * 2]; hex[1]=line[(byte * 2) + 1]; bytes[byteoffs++] = strtol(hex, nullptr, 16); } } start = end + 1; } while (start > 0 && end != -1); UINT64 pos = 0; int total_size = 200000000/f.cell_size; for(int track=0; track < f.track_count; track++) { std::vector<UINT32> buffer; int offset = 0; for (int i=0; i<1920 && pos<size; i++, pos++) { for (int bit=0; bit<8; bit++) { bit_w(buffer, BIT(bytes[pos], bit), f.cell_size); } } if (offset < total_size) { // pad the remainder of the track with sync int count = total_size-buffer.size(); for (int i=0; i<count;i++) { bit_w(buffer, (track > 0) ? 1 : 0, f.cell_size); } } generate_track_from_levels(track, 0, buffer, 0, image); } image->set_variant(f.variant); return true; }
int td0dsk_t::data_read(UINT8 *buf, UINT16 size) { if (floppy_file_offset + size > io_generic_size(floppy_file) ) { size = io_generic_size(floppy_file) - floppy_file_offset; } io_generic_read(floppy_file,buf,floppy_file_offset,size); floppy_file_offset += size; return size; }
bool ipf_format::load(io_generic *io, floppy_image *image) { UINT32 size = io_generic_size(io); UINT8 *data = global_alloc_array(UINT8, size); io_generic_read(io, data, 0, size); bool res = parse(data, size, image); global_free(data); return res; }
bool apd_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) { uint64_t size = io_generic_size(io); std::vector<uint8_t> img(size); io_generic_read(io, &img[0], 0, size); int err; std::vector<uint8_t> gz_ptr; z_stream d_stream; int inflate_size = (img[size - 1] << 24) | (img[size - 2] << 16) | (img[size - 3] << 8) | img[size - 4]; uint8_t *in_ptr = &img[0]; if (!memcmp(&img[0], GZ_HEADER, sizeof(GZ_HEADER))) { gz_ptr.resize(inflate_size); d_stream.zalloc = nullptr; d_stream.zfree = nullptr; d_stream.opaque = nullptr; d_stream.next_in = in_ptr; d_stream.avail_in = size; d_stream.next_out = &gz_ptr[0]; d_stream.avail_out = inflate_size; err = inflateInit2(&d_stream, MAX_WBITS | 16); if (err != Z_OK) { LOG_FORMATS("inflateInit2 error: %d\n", err); return false; } err = inflate(&d_stream, Z_FINISH); if (err != Z_STREAM_END && err != Z_OK) { LOG_FORMATS("inflate error: %d\n", err); return false; } err = inflateEnd(&d_stream); if (err != Z_OK) { LOG_FORMATS("inflateEnd error: %d\n", err); return false; } size = inflate_size; img = gz_ptr; } int data = 0x7d0; for (int track = 0; track < 166; track++) { uint32_t sdlen = little_endianize_int32(*(uint32_t *)(&img[(track * 12) + 8 + 0x0])); uint32_t ddlen = little_endianize_int32(*(uint32_t *)(&img[(track * 12) + 8 + 0x4])); uint32_t qdlen = little_endianize_int32(*(uint32_t *)(&img[(track * 12) + 8 + 0x8])); if (sdlen > 0) { generate_track_from_bitstream(track / 2, track % 2, &img[data], sdlen, image); data += (sdlen + 7) >> 3; } if (ddlen > 0) { generate_track_from_bitstream(track / 2, track % 2, &img[data], ddlen, image); data += (ddlen + 7) >> 3; }
int cqm_format::identify(io_generic *io, UINT32 form_factor) { UINT8 h[3]; io_generic_read(io, h, 0, 3); if (h[0] == 'C' && h[1] == 'Q' && h[2] == 0x14) return 100; return 0; }
int g64_format::identify(io_generic *io, UINT32 form_factor) { char h[8]; io_generic_read(io, h, 0, 8); if (!memcmp(h, G64_FORMAT_HEADER, 8)) { return 100; } return 0; }
int td0dsk_t::data_read(uint8_t *buf, uint16_t size) { uint64_t image_size = io_generic_size(floppy_file); if (size > image_size - floppy_file_offset) { size = image_size - floppy_file_offset; } io_generic_read(floppy_file,buf,floppy_file_offset,size); floppy_file_offset += size; return size; }
void msa_format::read_header(io_generic *io, UINT16 &sign, UINT16 §, UINT16 &head, UINT16 &strack, UINT16 &etrack) { UINT8 h[10]; io_generic_read(io, h, 0, 10); sign = (h[0] << 8) | h[1]; sect = (h[2] << 8) | h[3]; head = (h[4] << 8) | h[5]; strack = (h[6] << 8) | h[7]; etrack = (h[8] << 8) | h[9]; }
void msa_format::read_header(io_generic *io, uint16_t &sign, uint16_t §, uint16_t &head, uint16_t &strack, uint16_t &etrack) { uint8_t h[10]; io_generic_read(io, h, 0, 10); sign = (h[0] << 8) | h[1]; sect = (h[2] << 8) | h[3]; head = (h[4] << 8) | h[5]; strack = (h[6] << 8) | h[7]; etrack = (h[8] << 8) | h[9]; }
int ccvf_format::identify(io_generic *io, UINT32 form_factor) { char h[36]; io_generic_read(io, h, 0, 36); if(!memcmp(h, "Compucolor Virtual Floppy Disk Image", 36)) return 100; return 0; }
int fdd_format::identify(io_generic *io, UINT32 form_factor) { UINT8 h[7]; io_generic_read(io, h, 0, 7); if (strncmp((const char *)h, "VFD1.0", 6) == 0) return 100; return 0; }
int mfm_format::identify(io_generic *io, UINT32 form_factor) { UINT8 header[7]; io_generic_read(io, &header, 0, sizeof(header)); if ( memcmp( header, MFM_FORMAT_HEADER, 6 ) ==0) { return 100; } return 0; }
int nfd_format::identify(io_generic *io, uint32_t form_factor) { uint8_t h[16]; io_generic_read(io, h, 0, 16); if (strncmp((const char *)h, "T98FDDIMAGE.R0", 14) == 0 || strncmp((const char *)h, "T98FDDIMAGE.R1", 14) == 0) return 100; return 0; }
int imd_format::identify(io_generic *io, UINT32 form_factor) { char h[4]; io_generic_read(io, h, 0, 4); if(!memcmp(h, "IMD ", 4)) return 100; return 0; }
int vdk_format::identify(io_generic *io, uint32_t form_factor) { uint8_t id[2]; io_generic_read(io, id, 0, 2); if (id[0] == 'd' && id[1] == 'k') return 50; else return 0; }
bool vdk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) { uint8_t header[0x100]; io_generic_read(io, header, 0, 0x100); int header_size = header[3] * 0x100 + header[2]; int track_count = header[8]; int head_count = header[9]; int file_offset = header_size; for (int track = 0; track < track_count; track++) { for (int head = 0; head < head_count ; head++) { desc_pc_sector sectors[SECTOR_COUNT]; uint8_t sector_data[SECTOR_COUNT * SECTOR_SIZE]; int sector_offset = 0; for (int i = 0; i < SECTOR_COUNT; i++) { sectors[i].track = track; sectors[i].head = head; sectors[i].sector = FIRST_SECTOR_ID + i; sectors[i].actual_size = SECTOR_SIZE; sectors[i].size = SECTOR_SIZE >> 8; sectors[i].deleted = false; sectors[i].bad_crc = false; sectors[i].data = §or_data[sector_offset]; io_generic_read(io, sectors[i].data, file_offset, SECTOR_SIZE); sector_offset += SECTOR_SIZE; file_offset += SECTOR_SIZE; } build_wd_track_mfm(track, head, image, 100000, SECTOR_COUNT, sectors, 22, 32, 24); } } return true; }
int flex_format::identify(io_generic *io, UINT32 form_factor) { io_generic_read(io, &info, 256 * 2, sizeof(struct sysinfo_sector)); if(((info.last_trk+1) * info.last_sec) * 256 == io_generic_size(io)) { logerror("flex_dsk: %i tracks, %i sectors\n",info.last_trk+1,info.last_sec); return 100; } return 0; }
int fsd_format::identify(io_generic *io, UINT32 form_factor) { UINT8 h[3]; io_generic_read(io, h, 0, 3); if (memcmp(h, "FSD", 3) == 0) { return 100; } LOG_FORMATS("fsd: no match\n"); return 0; }
int mfi_format::identify(io_generic *io) { header h; io_generic_read(io, &h, 0, sizeof(header)); if(memcmp( h.sign, sign, 16 ) == 0 && h.cyl_count > 0 && h.cyl_count <= 84 && h.head_count > 0 && h.head_count <= 2) return 100; return 0; }
int ipf_format::identify(io_generic *io) { static const UINT8 refh[12] = { 0x43, 0x41, 0x50, 0x53, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0xd5, 0x73, 0xba }; UINT8 h[12]; io_generic_read(io, h, 0, 12); if(!memcmp(h, refh, 12)) return 100; return 0; }