summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/hpi_dsk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats/hpi_dsk.cpp')
-rw-r--r--src/lib/formats/hpi_dsk.cpp96
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)