diff options
Diffstat (limited to 'src/lib/formats/dsk_dsk.cpp')
-rw-r--r-- | src/lib/formats/dsk_dsk.cpp | 93 |
1 files changed, 52 insertions, 41 deletions
diff --git a/src/lib/formats/dsk_dsk.cpp b/src/lib/formats/dsk_dsk.cpp index db9d54920e5..e10e94f80be 100644 --- a/src/lib/formats/dsk_dsk.cpp +++ b/src/lib/formats/dsk_dsk.cpp @@ -2,21 +2,28 @@ // copyright-holders:Olivier Galibert /********************************************************************* - formats/dsk_dsk.c + formats/dsk_dsk.cpp DSK disk images *********************************************************************/ -#include <string.h> -#include <assert.h> - +#include "dsk_dsk.h" +#include "flopimg_legacy.h" #include "imageutl.h" -#include "flopimg.h" + +#include "ioprocs.h" +#include "multibyte.h" + +#include "osdcore.h" // osd_printf_* + +#include <cstring> #define MV_CPC "MV - CPC" #define EXTENDED "EXTENDED" +#define SPOT_DUPLICATES 0 + struct dskdsk_tag { int disk_image_type; /* image type: standard or extended */ @@ -97,10 +104,10 @@ static floperr_t get_offset(floppy_image_legacy *floppy, int head, int track, in get_tag(floppy)->sector_size = (1<<(track_info[0x014]+7)); offs = track_offset + 0x100 +sector * get_tag(floppy)->sector_size; } else { - get_tag(floppy)->sector_size = track_info[0x18 + (sector<<3) + 6] + (track_info[0x18+(sector<<3) + 7]<<8); + get_tag(floppy)->sector_size = get_u16le(&track_info[0x18 + (sector<<3) + 6]); offs = track_offset + 0x100; for (i=0;i<sector;i++) { - offs += track_info[0x18 + (i<<3) + 6] + (track_info[0x18+(i<<3) + 7]<<8); + offs += get_u16le(&track_info[0x18 + (i<<3) + 6]); } } @@ -218,13 +225,14 @@ FLOPPY_CONSTRUCT( dsk_dsk_construct ) } floppy_image_read(floppy, header, 0, 0x100); -#ifdef SPOT_DUPLICATES - // this allow to spot .dsk files with same data and different headers, making easier to debug softlists. - uint32_t temp_size = floppy_image_size(floppy); - uint8_t tmp_copy[temp_size - 0x100]; - floppy_image_read(floppy,tmp_copy,0x100,temp_size - 0x100); - printf("CRC16: %d\n", ccitt_crc16(0xffff, tmp_copy, temp_size - 0x100)); -#endif + if(SPOT_DUPLICATES) + { + // this allow to spot .dsk files with same data and different headers, making easier to debug softlists. + uint32_t temp_size = floppy_image_size(floppy); + auto tmp_copy = std::make_unique<uint8_t[]>(temp_size - 0x100); + floppy_image_read(floppy,tmp_copy.get(),0x100,temp_size - 0x100); + printf("CRC16: %d\n", ccitt_crc16(0xffff, tmp_copy.get(), temp_size - 0x100)); + } tag = (struct dskdsk_tag *) floppy_create_tag(floppy, sizeof(struct dskdsk_tag)); if (!tag) @@ -244,7 +252,7 @@ FLOPPY_CONSTRUCT( dsk_dsk_construct ) for (i=0; i<tag->tracks * tag->heads; i++) { tag->track_offsets[cnt] = tmp; - tmp += pick_integer_le(header, 0x32, 2); + tmp += get_u16le(&header[0x32]); cnt += skip; } } else { @@ -270,7 +278,8 @@ FLOPPY_CONSTRUCT( dsk_dsk_construct ) return FLOPPY_ERROR_SUCCESS; } -#include "dsk_dsk.h" + + #define DSK_FORMAT_HEADER "MV - CPC" #define EXT_FORMAT_HEADER "EXTENDED CPC DSK" @@ -279,36 +288,38 @@ dsk_format::dsk_format() : floppy_image_format_t() { } -const char *dsk_format::name() const +const char *dsk_format::name() const noexcept { return "dsk"; } -const char *dsk_format::description() const +const char *dsk_format::description() const noexcept { return "CPC DSK Format"; } -const char *dsk_format::extensions() const +const char *dsk_format::extensions() const noexcept { return "dsk"; } -bool dsk_format::supports_save() const +bool dsk_format::supports_save() const noexcept { return false; } -int dsk_format::identify(io_generic *io, uint32_t form_factor) +int dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t header[16]; - - io_generic_read(io, &header, 0, sizeof(header)); - if ( memcmp( header, DSK_FORMAT_HEADER, 8 ) ==0) { - return 100; + auto const [err, actual] = read_at(io, 0, &header, sizeof(header)); + if (err) { + return 0; } - if ( memcmp( header, EXT_FORMAT_HEADER, 16 ) ==0) { - return 100; + if ((8 <= actual) && !memcmp(header, DSK_FORMAT_HEADER, 8)) { + return FIFID_SIGN; + } + if ((16 <= actual) && !memcmp(header, EXT_FORMAT_HEADER, 16)) { + return FIFID_SIGN; } return 0; } @@ -344,14 +355,16 @@ struct sector_header #pragma pack() -bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) +bool dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { uint8_t header[0x100]; bool extendformat = false; - uint64_t image_size = io_generic_size(io); + uint64_t image_size; + if (io.length(image_size)) + return false; - io_generic_read(io, &header, 0, sizeof(header)); + read_at(io, 0, &header, sizeof(header)); // FIXME: check for errors and premature EOF if ( memcmp( header, EXT_FORMAT_HEADER, 16 ) ==0) { extendformat = true; } @@ -364,7 +377,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) int tracks = header[0x30]; int img_tracks, img_heads; - image->get_maximal_geometry(img_tracks, img_heads); + image.get_maximal_geometry(img_tracks, img_heads); if (tracks > img_tracks) { if (tracks - img_tracks > DUMP_THRESHOLD) @@ -381,7 +394,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) } } if (heads > img_heads) - return false; + osd_printf_warning("dsk: Floppy disk has excess of heads for this drive that will be discarded (floppy heads=%d, drive heads=%d).\n", heads, img_heads); uint64_t track_offsets[84*2]; int cnt =0; @@ -390,7 +403,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) for (int i=0; i<tracks * heads; i++) { track_offsets[cnt] = tmp; - tmp += pick_integer_le(header, 0x32, 2); + tmp += get_u16le(&header[0x32]); cnt += skip; } } else { @@ -412,13 +425,12 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) } } - int counter = 0; for(int track=0; track < tracks; track++) { - for(int side=0; side < heads; side++) { + for(int side=0; side < std::min(heads, img_heads); side++) { if(track_offsets[(track<<1)+side] >= image_size) continue; track_header tr; - io_generic_read(io, &tr,track_offsets[(track<<1)+side],sizeof(tr)); + read_at(io, track_offsets[(track<<1)+side], &tr, sizeof(tr)); // FIXME: check for errors and premature EOF // skip if there are no sectors in this track if (tr.number_of_sector == 0) @@ -428,7 +440,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) int first_sector_code = -1; for(int j=0;j<tr.number_of_sector;j++) { sector_header sector; - io_generic_read(io, §or,track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j),sizeof(sector)); + read_at(io, track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j), §or, sizeof(sector)); // FIXME: check for errors and premature EOF if (j == 0) first_sector_code = sector.sector_size_code; @@ -447,7 +459,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) for(int j=0;j<tr.number_of_sector;j++) { sector_header sector; - io_generic_read(io, §or,track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j),sizeof(sector)); + read_at(io, track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j), §or, sizeof(sector)); // FIXME: check for errors and premature EOF sects[j].track = sector.track; sects[j].head = sector.side; @@ -470,7 +482,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) if(!(sector.fdc_status_reg1 & 0x04)) { sects[j].data = sect_data + sdatapos; - io_generic_read(io, sects[j].data, pos, sects[j].actual_size); + read_at(io, pos, sects[j].data, sects[j].actual_size); // FIXME: check for errors and premature EOF sdatapos += sects[j].actual_size; } else @@ -483,10 +495,9 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) } // larger cell count (was 100000) to allow for slightly out of spec images (theatre europe on einstein) build_pc_track_mfm(track, side, image, 105000, tr.number_of_sector, sects, tr.gap3_length); - counter++; } } return true; } -const floppy_format_type FLOPPY_DSK_FORMAT = &floppy_image_format_creator<dsk_format>; +const dsk_format FLOPPY_DSK_FORMAT; |