diff --git a/devices/floppy/floppyimg.cpp b/devices/floppy/floppyimg.cpp index 47e1db3..af50df4 100644 --- a/devices/floppy/floppyimg.cpp +++ b/devices/floppy/floppyimg.cpp @@ -21,7 +21,8 @@ along with this program. If not, see . /** @file Support for reading and writing of various floppy images. */ -#include "floppyimg.h" +#include +#include #include #include @@ -67,27 +68,14 @@ static FlopImgType identify_image(std::ifstream& img_file) return FlopImgType::UNKNOWN; } -static int64_t get_hfs_vol_size(const uint8_t *mdb_data) -{ - uint16_t drNmAlBlks = READ_WORD_BE_A(&mdb_data[18]); - uint32_t drAlBlkSiz = READ_DWORD_BE_A(&mdb_data[20]); - - // calculate size of the volume bitmap - uint32_t vol_bmp_size = (((drNmAlBlks + 8) >> 3) + 512) & 0xFFFFFE00UL; - - return (drNmAlBlks * drAlBlkSiz + vol_bmp_size + 3*BLOCK_SIZE); -} - //======================= RAW IMAGE CONVERTER ============================ RawFloppyImg::RawFloppyImg(std::string& file_path) : FloppyImgConverter() { this->img_path = file_path; } -/** For raw images, we're going to ensure that the data fits into - one of the supported floppy disk sizes as well as image size - matches the size of the embedded HFS/MFS volume. - Then we'll attempt to guess disk format based on image size. +/** + For raw images, we'll attempt to guess disk format based on image size. */ int RawFloppyImg::calc_phys_params() { @@ -118,34 +106,25 @@ int RawFloppyImg::calc_phys_params() return -1; } - // read Master Directory Block from logical block 2 - uint8_t buf[512] = { 0 }; - - img_file.seekg(2*BLOCK_SIZE, img_file.beg); - img_file.read((char *)buf, sizeof(buf)); - img_file.close(); - - uint64_t vol_size = 0; - - if (buf[0] == 0x42 && buf[1] == 0x44) { - // check HFS volume size - vol_size = get_hfs_vol_size(buf); - } else if (buf[0] == 0xD2 && buf[1] == 0xD7) { - // check MFS volume size - } else { - LOG_F(ERROR, "RawFloppyImg: unknown volume type!"); - return -1; - } - - if (vol_size > this->img_size) { - LOG_F(INFO, "RawFloppyImg: volume size > image size!"); - LOG_F(INFO, "Volume size: %llu, Image size: %d", vol_size, this->img_size); - return -1; - } - - // raw images don't include anything than raw disk data + // raw images don't include anything other than raw disk data this->data_size = this->img_size; + // see if user has specified disk format manually + std::string fmt = GET_STR_PROP("fdd_fmt"); + if (!fmt.empty()) { + if (fmt == "GCR_400K") { + this->img_size = 409600; + } else if (fmt == "GCR_800K") { + this->img_size = 819200; + } else if (fmt == "MFM_720K") { + this->img_size = 737280; + } else if (fmt == "MFM_1440K") { + this->img_size = 1474560; + } else { + LOG_F(WARNING, "Invalid floppy disk format %s", fmt.c_str()); + } + } + // guess disk format from image file size static struct { int capacity; diff --git a/devices/floppy/swim3.cpp b/devices/floppy/swim3.cpp index 7c0c565..4cb8bd2 100644 --- a/devices/floppy/swim3.cpp +++ b/devices/floppy/swim3.cpp @@ -33,6 +33,7 @@ along with this program. If not, see . #include #include #include +#include using namespace Swim3; @@ -335,11 +336,19 @@ void Swim3Ctrl::stop_disk_access() this->access_timer_id = 0; } +// floppy disk formats properties for the cases +// where disk format needs to be specified manually +static const std::vector FloppyFormats = { + "", "GCR_400K", "GCR_800K", "MFM_720K", "MFM_1440K" +}; + static const PropMap Swim3_Properties = { {"fdd_img", new StrProperty("")}, {"fdd_wr_prot", new BinProperty(0)}, + {"fdd_fmt", + new StrProperty("", FloppyFormats)}, }; static const DeviceDescription Swim3_Descriptor = { diff --git a/machines/machinefactory.cpp b/machines/machinefactory.cpp index ac2553b..e9971cd 100644 --- a/machines/machinefactory.cpp +++ b/machines/machinefactory.cpp @@ -77,6 +77,7 @@ static const map PropHelp = { {"rambank4_size", "specifies RAM bank 4 size in MB"}, {"gfxmem_size", "specifies video memory size in MB"}, {"fdd_img", "specifies path to floppy disk image"}, + {"fdd_fmt", "specifies floppy disk format"}, {"fdd_wr_prot", "toggles floppy disk's write protection"}, {"mon_id", "specifies which monitor to emulate"}, {"pci_A1", "insert a PCI device into A1 slot"},