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; }
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 g64_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { UINT64 size = io_generic_size(io); dynamic_buffer img(size); io_generic_read(io, &img[0], 0, size); if (img[POS_VERSION]) { throw emu_fatalerror("g64_format: Unsupported version %u", img[POS_VERSION]); } int track_count = img[POS_TRACK_COUNT]; int head = 0; for (int track = 0; track < track_count; track++) { int cylinder = track % TRACK_COUNT; if (track == TRACK_COUNT) head = 1; UINT32 tpos = POS_TRACK_OFFSET + (track * 4); UINT32 spos = tpos + (track_count * 4); UINT32 dpos = pick_integer_le(&img[0], tpos, 4); if (!dpos) continue; if (dpos > size) throw emu_fatalerror("g64_format: Track %u offset %06x out of bounds", track, dpos); UINT32 speed_zone = pick_integer_le(&img[0], spos, 4); if (speed_zone > 3) throw emu_fatalerror("g64_format: Unsupported variable speed zones on track %d", track); UINT16 track_bytes = pick_integer_le(&img[0], dpos, 2); int track_size = track_bytes * 8; LOG_FORMATS("head %u track %u offs %u size %u cell %ld\n", head, cylinder, dpos, track_bytes, 200000000L/track_size); generate_track_from_bitstream(cylinder, head, &img[dpos+2], track_size, image); } if (!head) image->set_variant(floppy_image::SSSD); else image->set_variant(floppy_image::DSSD); return true; }
bool g64_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { UINT64 size = io_generic_size(io); UINT8 *img = global_alloc_array(UINT8, size); io_generic_read(io, img, 0, size); if (img[VERSION]) { throw emu_fatalerror("g64_format: Unsupported version %u", img[VERSION]); } int track_count = img[TRACK_COUNT]; int head = 0; for (int track = 0; track < track_count; track++) { offs_t track_offset = pick_integer_le(img, TRACK_OFFSET + (track * 4), 4); if (!track_offset) continue; if (track_offset > size) throw emu_fatalerror("g64_format: Track %u offset %06x out of bounds", track, track_offset); offs_t speed_zone = pick_integer_le(img, SPEED_ZONE + (track * 4), 4); if (speed_zone > 3) throw emu_fatalerror("g64_format: Unsupported variable speed zones on track %d", track); UINT16 track_bytes = pick_integer_le(img, track_offset, 2); int track_size = track_bytes * 8; LOG_FORMATS("track %u size %u cell %ld\n", track, track_size, 200000000L/track_size); generate_track_from_bitstream(track, head, &img[track_offset+2], track_size, image); } global_free(img); image->set_variant(floppy_image::SSSD); return true; }