// license:BSD-3-Clause // copyright-holders:Nigel Barnes /*************************************************************************** Poly CP/M Disk image format FLEX-POLYSYS image formats are handled in flex_dsk. ***************************************************************************/ #include "poly_dsk.h" #include "ioprocs.h" #include poly_cpm_format::poly_cpm_format() { } const char *poly_cpm_format::name() const noexcept { return "cpm"; } const char *poly_cpm_format::description() const noexcept { return "Poly CP/M disk image"; } const char *poly_cpm_format::extensions() const noexcept { return "cpm"; } bool poly_cpm_format::supports_save() const noexcept { return true; } int poly_cpm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector &variants) const { uint64_t size; if (io.length(size)) return 0; // check for valid sizes if (size == 630784 || size == 622592 || size == 256256) { // check for Poly CP/M boot sector uint8_t boot[16]; auto const [err, actual] = read_at(io, 0, boot, 16); if (!err && (16 == actual) && !memcmp(boot, "\x86\xc3\xb7\x00\x00\x8e\x10\xc0\xbf\x00\x01\xbf\xe0\x60\x00\x00", 16)) { return FIFID_SIZE|FIFID_SIGN; } } return 0; } bool poly_cpm_format::load(util::random_read &io, uint32_t form_factor, const std::vector &variants, floppy_image &image) const { uint64_t size; if (io.length(size) || io.seek(0, SEEK_SET)) return false; int total_tracks, spt, bps, head_num; switch (size) { case 622592: // CP/M 3" disk DSSD total_tracks = 76; spt = 8; bps = 512; head_num = 2; break; case 256256: // CP/M 8" disk SDSD total_tracks = 77; spt = 26; bps = 128; head_num = 1; break; default: // CP/M 8" disk DSSD total_tracks = 77; spt = 8; bps = 512; head_num = 2; break; } int const cell_count = (form_factor == floppy_image::FF_525) ? 50000 : 100000; for (int track = 0; track < total_tracks; track++) for (int head = 0; head < head_num; head++) { desc_pc_sector sects[80]; uint8_t sect_data[20000]; int sdatapos = 0; for (int i = 0; i> 8; sects[i].deleted = false; sects[i].bad_crc = false; sects[i].data = §_data[sdatapos]; /*auto const [err, actual] =*/ read(io, sects[i].data, bps); // FIXME: check for errors and premature EOF sdatapos += bps; } // gap sizes unverified build_wd_track_fm(track, head, image, cell_count, spt, sects, 24, 16, 11); } return true; } const poly_cpm_format FLOPPY_POLY_CPM_FORMAT;