diff options
Diffstat (limited to 'src/lib/formats/d88_dsk.cpp')
-rw-r--r-- | src/lib/formats/d88_dsk.cpp | 137 |
1 files changed, 75 insertions, 62 deletions
diff --git a/src/lib/formats/d88_dsk.cpp b/src/lib/formats/d88_dsk.cpp index c2bf9772e7d..93a995a47fb 100644 --- a/src/lib/formats/d88_dsk.cpp +++ b/src/lib/formats/d88_dsk.cpp @@ -29,13 +29,19 @@ * */ - #include <assert.h> - -#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(§or_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(§or_hdr[14]); return FLOPPY_ERROR_SUCCESS; } - len = (sector_hdr[15] << 8) | sector_hdr[14]; + len = get_u16le(§or_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(§or_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(§or_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(§or_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) || (get_u32le(h+0x1c) == (size >> 1))) && (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,45 +442,55 @@ 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; } if(!head_count) return false; + int img_tracks, img_heads; + image.get_maximal_geometry(img_tracks, img_heads); + if (track_count > img_tracks) + osd_printf_warning("d88: Floppy disk has too many tracks for this drive (floppy tracks=%d, drive tracks=%d).\n", track_count, img_tracks); + + if (head_count > img_heads) + osd_printf_warning("d88: Floppy disk has excess of heads for this drive that will be discarded (floppy heads=%d, drive heads=%d).\n", head_count, img_heads); + 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 +501,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 +521,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 +535,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 +543,20 @@ 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(head < img_heads) { + 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; |