summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/d88_dsk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats/d88_dsk.cpp')
-rw-r--r--src/lib/formats/d88_dsk.cpp127
1 files changed, 65 insertions, 62 deletions
diff --git a/src/lib/formats/d88_dsk.cpp b/src/lib/formats/d88_dsk.cpp
index 30073d1874d..a6b809eb7a1 100644
--- a/src/lib/formats/d88_dsk.cpp
+++ b/src/lib/formats/d88_dsk.cpp
@@ -29,13 +29,19 @@
*
*/
- #include <cassert>
-
-#include "flopimg.h"
+#include "flopimg_legacy.h"
#include "imageutl.h"
+#include "ioprocs.h"
+#include "multibyte.h"
+
+#include <tuple>
+
+
#define D88_HEADER_LEN 0x2b0
+#define SPOT_DUPLICATES 0
+
struct d88_tag
{
uint32_t image_size;
@@ -68,7 +74,7 @@ static int d88_get_sector_id(floppy_image_legacy *floppy, int head, int track, i
x=0;
while(x<sector_index)
{
- offset += ((sector_hdr[15] << 8) | sector_hdr[14]);
+ offset += get_u16le(&sector_hdr[14]);
offset += 16;
floppy_image_read(floppy,sector_hdr,offset,16);
x++;
@@ -120,10 +126,10 @@ static floperr_t d88_get_sector_length(floppy_image_legacy *floppy, int head, in
if(sector == sector_hdr[2])
{
if(sector_length)
- *sector_length = (sector_hdr[15] << 8) | sector_hdr[14];
+ *sector_length = get_u16le(&sector_hdr[14]);
return FLOPPY_ERROR_SUCCESS;
}
- len = (sector_hdr[15] << 8) | sector_hdr[14];
+ len = get_u16le(&sector_hdr[14]);
len += 16;
offset += len;
}
@@ -161,7 +167,7 @@ static uint32_t d88_get_sector_offset(floppy_image_legacy* floppy, int head, int
LOG_FORMATS("d88_get_sector_offset - track %i, side %i, sector %02x, returns %08x\n",track,head,sector,offset+16);
return offset + 16;
}
- len = (sector_hdr[15] << 8) | sector_hdr[14];
+ len = get_u16le(&sector_hdr[14]);
len += 16;
offset += len;
}
@@ -191,7 +197,7 @@ static floperr_t d88_get_indexed_sector_info(floppy_image_legacy *floppy, int he
x=0;
while(x<sector_index)
{
- offset += ((sector_hdr[15] << 8) | sector_hdr[14]);
+ offset += get_u16le(&sector_hdr[14]);
offset += 16;
floppy_image_read(floppy,sector_hdr,offset,16);
x++;
@@ -201,7 +207,7 @@ static floperr_t d88_get_indexed_sector_info(floppy_image_legacy *floppy, int he
return FLOPPY_ERROR_SEEKERROR;
if(sector_length)
- *sector_length = (sector_hdr[15] << 8) | sector_hdr[14];
+ *sector_length = get_u16le(&sector_hdr[14]);
if(cylinder)
*cylinder = sector_hdr[0];
if(side)
@@ -275,43 +281,29 @@ static floperr_t d88_write_indexed_sector(floppy_image_legacy *floppy, int head,
static void d88_get_header(floppy_image_legacy* floppy,uint32_t* size, uint8_t* prot, uint8_t* type, uint32_t* offsets)
{
uint8_t header[D88_HEADER_LEN];
- int x,s;
floppy_image_read(floppy,header,0,D88_HEADER_LEN);
-#ifdef SPOT_DUPLICATES
+ if(SPOT_DUPLICATES)
+ {
// there exist many .d88 files with same data and different headers and
// this allows to spot duplicates, making easier to debug softlists.
uint32_t temp_size = floppy_image_size(floppy);
- uint8_t tmp_copy[temp_size - D88_HEADER_LEN];
- floppy_image_read(floppy,tmp_copy,D88_HEADER_LEN,temp_size - D88_HEADER_LEN);
- printf("CRC16: %d\n", ccitt_crc16(0xffff, tmp_copy, temp_size - D88_HEADER_LEN));
-#endif
+ auto tmp_copy = std::make_unique<uint8_t[]>(temp_size - D88_HEADER_LEN);
+ floppy_image_read(floppy,tmp_copy.get(),D88_HEADER_LEN,temp_size - D88_HEADER_LEN);
+ printf("CRC16: %d\n", ccitt_crc16(0xffff, tmp_copy.get(), temp_size - D88_HEADER_LEN));
+ }
if(prot)
*prot = header[0x1a];
if(type)
*type = header[0x1b];
if(size)
- {
- s = 0;
- s |= header[0x1f] << 24;
- s |= header[0x1e] << 16;
- s |= header[0x1d] << 8;
- s |= header[0x1c];
- *size = s;
- }
+ *size = get_u32le(&header[0x1c]);
if(offsets)
{
- for(x=0;x<164;x++)
- {
- s = 0;
- s |= header[0x23 + (x*4)] << 24;
- s |= header[0x22 + (x*4)] << 16;
- s |= header[0x21 + (x*4)] << 8;
- s |= header[0x20 + (x*4)];
- *(offsets+x) = s;
- }
+ for(int x=0;x<164;x++)
+ *(offsets+x) = get_u32le(&header[0x20 + (x*4)]);
}
}
@@ -387,7 +379,7 @@ FLOPPY_CONSTRUCT(d88_dsk_construct)
// copyright-holders:Olivier Galibert
/*********************************************************************
- formats/d88_dsk.h
+ formats/d88_dsk.cpp
D88 disk images
@@ -399,39 +391,48 @@ d88_format::d88_format()
{
}
-const char *d88_format::name() const
+const char *d88_format::name() const noexcept
{
return "d88";
}
-const char *d88_format::description() const
+const char *d88_format::description() const noexcept
{
return "D88 disk image";
}
-const char *d88_format::extensions() const
+const char *d88_format::extensions() const noexcept
{
return "d77,d88,1dd";
}
-int d88_format::identify(io_generic *io, uint32_t form_factor)
+int d88_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const
{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if(io.length(size))
+ return 0;
+
uint8_t h[32];
+ auto const [err, actual] = read_at(io, 0, h, 32);
+ if(err || (32 != actual))
+ return 0;
- io_generic_read(io, h, 0, 32);
- if((little_endianize_int32(*(uint32_t *)(h+0x1c)) == size) &&
+ if((get_u32le(h+0x1c) == size) &&
(h[0x1b] == 0x00 || h[0x1b] == 0x10 || h[0x1b] == 0x20 || h[0x1b] == 0x30 || h[0x1b] == 0x40))
- return 100;
+ return FIFID_SIZE|FIFID_STRUCT;
return 0;
}
-bool d88_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
+bool d88_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const
{
- uint8_t h[32];
+ std::error_condition err;
+ size_t actual;
- io_generic_read(io, h, 0, 32);
+ uint8_t h[32];
+ std::tie(err, actual) = read_at(io, 0, h, 32);
+ if(err || (32 != actual))
+ return false;
int cell_count = 0;
int track_count = 0;
@@ -441,35 +442,35 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
cell_count = 100000;
track_count = 42;
head_count = 2;
- image->set_variant(floppy_image::DSDD);
+ image.set_variant(floppy_image::DSDD);
break;
case 0x10:
cell_count = 100000;
track_count = 82;
head_count = 2;
- image->set_variant(floppy_image::DSQD);
+ image.set_variant(floppy_image::DSQD);
break;
case 0x20:
cell_count = form_factor == floppy_image::FF_35 ? 200000 : 166666;
track_count = 82;
head_count = 2;
- image->set_variant(floppy_image::DSHD);
+ image.set_variant(floppy_image::DSHD);
break;
case 0x30:
cell_count = 100000;
track_count = 42;
head_count = 1;
- image->set_variant(floppy_image::SSDD);
+ image.set_variant(floppy_image::SSDD);
break;
case 0x40:
cell_count = 100000;
track_count = 82;
head_count = 1;
- image->set_variant(floppy_image::SSQD);
+ image.set_variant(floppy_image::SSQD);
break;
}
@@ -477,9 +478,11 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
return false;
uint32_t track_pos[164];
- io_generic_read(io, track_pos, 32, 164*4);
+ std::tie(err, actual) = read_at(io, 32, track_pos, 164*4); // FIXME: check for errors and premature EOF
- uint64_t file_size = io_generic_size(io);
+ uint64_t file_size;
+ if(io.length(file_size))
+ return false;
for(int track=0; track < track_count; track++)
for(int head=0; head < head_count; head++) {
@@ -490,13 +493,14 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
uint8_t sect_data[65536];
int sdatapos = 0;
int sector_count = 1;
+ uint8_t density = 0;
for(int i=0; i<sector_count; i++) {
if (pos + 16 > file_size)
return true;
uint8_t hs[16];
- io_generic_read(io, hs, pos, 16);
+ std::tie(err, actual) = read_at(io, pos, hs, 16); // FIXME: check for errors and premature EOF
pos += 16;
uint16_t size = little_endianize_int16(*(uint16_t *)(hs+14));
@@ -509,6 +513,8 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
// Support broken vfman converter
if(sector_count == 0x1000)
sector_count = 0x10;
+
+ density = hs[6];
}
sects[i].track = hs[0];
@@ -521,7 +527,7 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
if(size) {
sects[i].data = sect_data + sdatapos;
- io_generic_read(io, sects[i].data, pos, size);
+ std::tie(err, actual) = read_at(io, pos, sects[i].data, size); // FIXME: check for errors and premature EOF
pos += size;
sdatapos += size;
@@ -529,21 +535,18 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
sects[i].data = nullptr;
}
- build_pc_track_mfm(track, head, image, cell_count, sector_count, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size));
+ if(density == 0x40)
+ build_pc_track_fm(track, head, image, cell_count / 2, sector_count, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size));
+ else
+ build_pc_track_mfm(track, head, image, cell_count, sector_count, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size));
}
return true;
}
-
-bool d88_format::save(io_generic *io, floppy_image *image)
-{
- return false;
-}
-
-bool d88_format::supports_save() const
+bool d88_format::supports_save() const noexcept
{
return false;
}
-const floppy_format_type FLOPPY_D88_FORMAT = &floppy_image_format_creator<d88_format>;
+const d88_format FLOPPY_D88_FORMAT;