diff options
Diffstat (limited to 'src/lib/formats/hpi_dsk.cpp')
-rw-r--r-- | src/lib/formats/hpi_dsk.cpp | 96 |
1 files changed, 18 insertions, 78 deletions
diff --git a/src/lib/formats/hpi_dsk.cpp b/src/lib/formats/hpi_dsk.cpp index 50d2653280d..8d23f151862 100644 --- a/src/lib/formats/hpi_dsk.cpp +++ b/src/lib/formats/hpi_dsk.cpp @@ -4,10 +4,9 @@ hpi_dsk.cpp - HP9885/HP9895A "HPI" disk images + HP9895A "HPI" disk images - CHS = 67/1/30 (SSDD) - CHS = 77/2/30 (DSDD) + CHS = 77/2/30 Sector size 256 bytes Cell size 2 µs Gap1 = 16 x 0x00 @@ -41,7 +40,7 @@ 256 bytes per sector). There's also a "reduced" version holding just 75 cylinders. When loading, the disk image is translated to MMFM encoding so - that it can be loaded into HP9885/HP9895 emulator. + that it can be loaded into HP9895 emulator. *********************************************************************/ @@ -66,14 +65,11 @@ constexpr int ID_DATA_OFFSET = 30 * 16; // Nominal distance (in cells) between I // Size of image file (holding 77 cylinders) constexpr unsigned HPI_IMAGE_SIZE = HPI_TRACKS * HPI_HEADS * HPI_SECTORS * HPI_SECTOR_SIZE; constexpr unsigned HPI_RED_TRACKS = 75; // Reduced number of tracks -constexpr unsigned HPI_9885_TRACKS = 67; // Tracks visible to HP9885 drives // Size of reduced image file (holding 75 cylinders) constexpr unsigned HPI_RED_IMAGE_SIZE = HPI_RED_TRACKS * HPI_HEADS * HPI_SECTORS * HPI_SECTOR_SIZE; hpi_format::hpi_format() { - (void)HPI_IMAGE_SIZE; - (void)HPI_RED_IMAGE_SIZE; } int hpi_format::identify(io_generic *io, uint32_t form_factor) @@ -83,79 +79,27 @@ int hpi_format::identify(io_generic *io, uint32_t form_factor) // we try to stay back and give only 50 points, since another image // format may also have images of the same size (there is no header and no // magic number for HPI format... - unsigned dummy_heads; - unsigned dummy_tracks; if (((form_factor == floppy_image::FF_8) || (form_factor == floppy_image::FF_UNKNOWN)) && - geometry_from_size(size , dummy_heads , dummy_tracks)) { + ((size == HPI_RED_IMAGE_SIZE) || (size == HPI_IMAGE_SIZE))) { return 50; } else { return 0; } } -bool hpi_format::geometry_from_size(uint64_t image_size , unsigned& heads , unsigned& tracks) -{ - if ((image_size % HPI_SECTOR_SIZE) != 0) { - // Not a whole number of sectors - return false; - } - unsigned sectors = unsigned(image_size / HPI_SECTOR_SIZE); - if ((sectors % HPI_SECTORS) != 0) { - // Not a whole number of tracks - return false; - } - unsigned tot_tracks = sectors / HPI_SECTORS; - // Possible combinations - // - // | Tot tracks | Heads | Tracks | Format | - // |------------+-------+--------+--------| - // | 67 | 1 | 67 | SSDD | - // | 77 | 1 | 77 | SSDD | - // | 150 | 2 | 75 | DSDD | - // | 154 | 2 | 77 | DSDD | - // - switch (tot_tracks) { - case HPI_9885_TRACKS: - heads = 1; - tracks = HPI_9885_TRACKS; - return true; - - case HPI_TRACKS: - heads = 1; - tracks = HPI_TRACKS; - return true; - - case HPI_RED_TRACKS * 2: - heads = 2; - tracks = HPI_RED_TRACKS; - return true; - - case HPI_TRACKS * 2: - heads = 2; - tracks = HPI_TRACKS; - return true; - - default: - return false; - } -} - bool hpi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) { - unsigned heads; - unsigned cylinders; + image->set_variant(floppy_image::DSDD); // We actually need to derive the variant from the image size depending on the form factor uint64_t size = io_generic_size(io); - if (!geometry_from_size(size, heads, cylinders)) { - return false; - } - int max_tracks; - int max_heads; - image->get_maximal_geometry(max_tracks , max_heads); - if (cylinders > max_tracks || heads > max_heads) { + unsigned cylinders; + if (size == HPI_RED_IMAGE_SIZE) { + cylinders = HPI_RED_TRACKS; + } else if (size == HPI_IMAGE_SIZE) { + cylinders = HPI_TRACKS; + } else { return false; } - image->set_variant(heads == 2 ? floppy_image::DSDD : floppy_image::SSDD); // Suck in the whole image std::vector<uint8_t> image_data(size); @@ -174,11 +118,11 @@ bool hpi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) unsigned list_offset = 0; for (unsigned cyl = 0; cyl < cylinders; cyl++) { - for (unsigned head = 0; head < heads; head++) { + for (unsigned head = 0; head < HPI_HEADS; head++) { std::vector<uint32_t> track_data; for (unsigned sector = 0; sector < HPI_SECTORS; sector++) { unsigned real_sector = sector_list[ (sector + list_offset) % HPI_SECTORS ]; - unsigned offset_in_image = chs_to_lba(cyl, head, real_sector, heads) * HPI_SECTOR_SIZE; + unsigned offset_in_image = chs_to_lba(cyl, head, real_sector) * HPI_SECTOR_SIZE; write_sector(track_data , cyl , real_sector + (head << 7) , &image_data[ offset_in_image ]); } fill_with_gap3(track_data); @@ -191,12 +135,8 @@ bool hpi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) bool hpi_format::save(io_generic *io, floppy_image *image) { - int tracks; - int heads; - image->get_actual_geometry(tracks, heads); - - for (int cyl = 0; cyl < tracks; cyl++) { - for (int head = 0; head < heads; head++) { + for (unsigned cyl = 0; cyl < HPI_TRACKS; cyl++) { + for (unsigned head = 0; head < HPI_HEADS; head++) { uint8_t bitstream[ 21000 ]; int bitstream_size; generate_bitstream_from_track(cyl , head , CELL_SIZE , bitstream , bitstream_size , image , 0); @@ -205,7 +145,7 @@ bool hpi_format::save(io_generic *io, floppy_image *image) uint8_t sector_data[ HPI_SECTOR_SIZE ]; while (get_next_sector(bitstream , bitstream_size , pos , track_no , head_no , sector_no , sector_data)) { if (track_no == cyl && head_no == head && sector_no < HPI_SECTORS) { - unsigned offset_in_image = chs_to_lba(cyl, head, sector_no, heads) * HPI_SECTOR_SIZE; + unsigned offset_in_image = chs_to_lba(cyl, head, sector_no) * HPI_SECTOR_SIZE; io_generic_write(io, sector_data, offset_in_image, HPI_SECTOR_SIZE); } } @@ -360,9 +300,9 @@ void hpi_format::fill_with_gap3(std::vector<uint32_t> &buffer) } } -unsigned hpi_format::chs_to_lba(unsigned cylinder , unsigned head , unsigned sector , unsigned heads) +unsigned hpi_format::chs_to_lba(unsigned cylinder , unsigned head , unsigned sector) { - return sector + (head + cylinder * heads) * HPI_SECTORS; + return sector + (head + cylinder * HPI_HEADS) * HPI_SECTORS; } std::vector<uint8_t> hpi_format::get_next_id_n_block(const uint8_t *bitstream , int bitstream_size , int& pos , int& start_pos) |