diff options
Diffstat (limited to 'src/lib/formats/thom_dsk.cpp')
-rw-r--r-- | src/lib/formats/thom_dsk.cpp | 469 |
1 files changed, 66 insertions, 403 deletions
diff --git a/src/lib/formats/thom_dsk.cpp b/src/lib/formats/thom_dsk.cpp index c8563fc1135..3399a1aa487 100644 --- a/src/lib/formats/thom_dsk.cpp +++ b/src/lib/formats/thom_dsk.cpp @@ -1,444 +1,107 @@ // license:BSD-3-Clause -// copyright-holders:Antoine Mine -/********************************************************************* +// copyright-holders:Olivier Galibert - formats/thom_dsk.c - - Thomson disk images - - Based on work of Antoine Mine' - -*********************************************************************/ - -#include <string.h> -#include <assert.h> #include "thom_dsk.h" -#include "basicdsk.h" - -static const int sap_magic_num = 0xB3; /* simple XOR crypt */ - - -static const char sap_header[] = - "\001SYSTEME D'ARCHIVAGE PUKALL S.A.P. " - "(c) Alexandre PUKALL Avril 1998"; - -static const uint16_t sap_crc[] = +thomson_525_format::thomson_525_format() : wd177x_format(formats) { - 0x0000, 0x1081, 0x2102, 0x3183, 0x4204, 0x5285, 0x6306, 0x7387, - 0x8408, 0x9489, 0xa50a, 0xb58b, 0xc60c, 0xd68d, 0xe70e, 0xf78f, -}; - -struct sap_dsk_tag -{ - int tracks; - int sector_size; - int sector_pos[80][16]; /* remember sector position in file */ -}; - -static uint16_t thom_sap_crc( uint8_t* data, int size ) -{ - int i; - uint16_t crc = 0xffff, crc2; - for ( i = 0; i < size; i++ ) - { - crc2 = ( crc >> 4 ) ^ sap_crc[ ( crc ^ data[i] ) & 15 ]; - crc = ( crc2 >> 4 ) ^ sap_crc[ ( crc2 ^ (data[i] >> 4) ) & 15 ]; - } - return crc; } -static struct sap_dsk_tag *get_tag(floppy_image_legacy *floppy) +const char *thomson_525_format::name() const noexcept { - struct sap_dsk_tag *tag; - tag = (sap_dsk_tag *)floppy_tag(floppy); - return tag; + return "thomson_525"; } - -static FLOPPY_IDENTIFY(sap_dsk_identify) +const char *thomson_525_format::description() const noexcept { - char header[0x100]; - floppy_image_read(floppy, header, 0, sizeof(sap_header)); - if (!memcmp( header, sap_header, sizeof(sap_header) ) ) - { - *vote= 100; - } else { - *vote = 0; - } - return FLOPPY_ERROR_SUCCESS; -} -static int sap_get_heads_per_disk(floppy_image_legacy *floppy) -{ - return 1; + return "Thomson 5.25 disk image"; } -static int sap_get_tracks_per_disk(floppy_image_legacy *floppy) +const char *thomson_525_format::extensions() const noexcept { - return get_tag(floppy)->tracks; + return "fd"; } - -static floperr_t get_offset(floppy_image_legacy *floppy, int head, int track, int sector, bool sector_is_index, uint64_t *offset) -{ - uint64_t offs; - struct sap_dsk_tag *tag = get_tag(floppy); - /* translate the sector to a raw sector */ - if (!sector_is_index) +const thomson_525_format::format thomson_525_format::formats[] = { { - sector -= 1; - } - /* check to see if we are out of range */ - if ((head < 0) || (head >= 1) || (track < 0) || (track >=tag->tracks) - || (sector < 0) || (sector >= 16)) - return FLOPPY_ERROR_SEEKERROR; - - offs = tag->sector_pos[track][sector]; - if (offs <= 0 ) - return FLOPPY_ERROR_SEEKERROR; - - if (offset) - *offset = offs; - return FLOPPY_ERROR_SUCCESS; -} - - - -static floperr_t internal_sap_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, bool sector_is_index, void *buffer, size_t buflen) -{ - uint64_t offset; - floperr_t err; - int i; - uint8_t *buf; - err = get_offset(floppy, head, track, sector, sector_is_index, &offset); - if (err) - return err; - - floppy_image_read(floppy, buffer, offset+4, buflen); - buf = (uint8_t*)buffer; - for (i=0;i<buflen;i++) { - buf[i] ^= sap_magic_num; - } - return FLOPPY_ERROR_SUCCESS; -} - - - -static floperr_t internal_sap_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, bool sector_is_index, const void *buffer, size_t buflen, int ddam) -{ - uint64_t offset; - floperr_t err; - uint8_t buf[256+6]; - uint16_t crc; - int i; - err = get_offset(floppy, head, track, sector, sector_is_index, &offset); - if (err) - return err; - - /* buf = 4-byte header + sector + 2-byte CRC */ - floppy_image_read(floppy, buf, offset, 4); - for (i=0;i<buflen;i++) { - buf[i+4] = ((uint8_t*)buffer)[i]; - } - crc = thom_sap_crc( buf, buflen+4 ); - buf[buflen+4] = crc >> 8; - buf[buflen+5] = crc & 0xff; - for (i=0;i<buflen;i++) { - buf[i+4] ^= sap_magic_num; - } - floppy_image_write(floppy, buf, offset, buflen+6); - - return FLOPPY_ERROR_SUCCESS; -} - - -static floperr_t sap_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen) -{ - return internal_sap_read_sector(floppy, head, track, sector, false, buffer, buflen); -} - -static floperr_t sap_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam) -{ - return internal_sap_write_sector(floppy, head, track, sector, false, buffer, buflen, ddam); -} - -static floperr_t sap_read_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen) -{ - return internal_sap_read_sector(floppy, head, track, sector, true, buffer, buflen); -} - -static floperr_t sap_write_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam) -{ - return internal_sap_write_sector(floppy, head, track, sector, true, buffer, buflen, ddam); -} - -static floperr_t sap_get_sector_length(floppy_image_legacy *floppy, int head, int track, int sector, uint32_t *sector_length) -{ - floperr_t err; - err = get_offset(floppy, head, track, sector, false, nullptr); - if (err) - return err; - - if (sector_length) { - *sector_length = get_tag(floppy)->sector_size; - } - return FLOPPY_ERROR_SUCCESS; -} - - - -static floperr_t sap_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, uint32_t *sector_length, unsigned long *flags) -{ - floperr_t err; - uint8_t header[4]; - uint64_t offset = 0; - sector_index += 1; - err = get_offset(floppy, head, track, sector_index, false, &offset); - - floppy_image_read(floppy, header, offset, 4); - if (cylinder) - *cylinder = header[2]; - if (side) - *side = head; - if (sector) - *sector = header[3]; - if (sector_length) - *sector_length = get_tag(floppy)->sector_size; - if (flags) - /* TODO: read DAM or DDAM and determine flags */ - *flags = 0; - return err; -} - -static floperr_t sap_post_format(floppy_image_legacy *floppy, util::option_resolution *params) -{ - int track,sector; - int pos; - uint8_t buf[256], header[4]; - struct sap_dsk_tag *tag; - tag = (struct sap_dsk_tag *) floppy_create_tag(floppy, sizeof(struct sap_dsk_tag)); - - /* default options */ - if ( !tag->tracks ) - { - tag->tracks = 80; - tag->sector_size = 256; - } - - /* create SAP file header */ - floppy_image_write( floppy, sap_header, 0, 66 ); - - for ( track = 0; track < 80; track++ ) - for ( sector = 0; sector < 16; sector++ ) - tag->sector_pos[track][sector] = 0; - - /* create all sectors with valid header and CRC */ - memset(buf, 0xe5, 256); - pos = 0x42; - header[0] = (tag->sector_size==128) ? 1 : 0; - header[1] = 0; - for ( track = 0, pos = 0x42; track < tag->tracks; track++ ) - for ( sector = 0; sector < 16; sector++, pos += tag->sector_size + 6 ) { - tag->sector_pos[track][sector] = pos; - header[2] = track; - header[3] = sector + 1; - floppy_image_write(floppy, header, pos, 4); - sap_write_indexed_sector( floppy, 0, track, sector, buf, tag->sector_size, 0 ); - } - - return FLOPPY_ERROR_SUCCESS; -} - - -static FLOPPY_CONSTRUCT(sap_dsk_construct) -{ - struct FloppyCallbacks *callbacks; - struct sap_dsk_tag *tag; - int j; - uint8_t fmt; - tag = (struct sap_dsk_tag *) floppy_create_tag(floppy, sizeof(struct sap_dsk_tag)); - if (!tag) - return FLOPPY_ERROR_OUTOFMEMORY; - - /* guess format */ - floppy_image_read(floppy, &fmt, 0x42, 1); - if ( fmt==1 ) tag->sector_size = 128; else tag->sector_size = 256; - - /* start with an empty offset table */ - tag->tracks = 0; - for ( int i = 0; i < 80; i++ ) - for ( j = 0; j < 16; j++ ) - tag->sector_pos[i][j] = 0; - - /* count tracks & fill sector offset table */ - for ( uint64_t i = 0x42; i+4 < floppy_image_size(floppy); i += tag->sector_size + 6 ) // CRC 2 bytes + 4 bytes sector header - { - uint8_t sector, track; - floppy_image_read(floppy, &track, i+2, 1); - floppy_image_read(floppy, §or, i+3, 1); - if ( track >= 80 || sector < 1 || sector > 16 ) continue; - if ( track > tag->tracks ) tag->tracks = track+1; - tag->sector_pos[track][sector-1] = i; - } - callbacks = floppy_callbacks(floppy); - callbacks->read_sector = sap_read_sector; - callbacks->write_sector = sap_write_sector; - callbacks->read_indexed_sector = sap_read_indexed_sector; - callbacks->write_indexed_sector = sap_write_indexed_sector; - callbacks->get_sector_length = sap_get_sector_length; - callbacks->get_heads_per_disk = sap_get_heads_per_disk; - callbacks->get_tracks_per_disk = sap_get_tracks_per_disk; - callbacks->get_indexed_sector_info = sap_get_indexed_sector_info; - callbacks->post_format = sap_post_format; - - return FLOPPY_ERROR_SUCCESS; -} - -static FLOPPY_IDENTIFY(qdd_dsk_identify) -{ - *vote = (floppy_image_size(floppy) == (51200)) ? 100 : 0; - return FLOPPY_ERROR_SUCCESS; -} - -/* fixed interlacing map for QDDs */ -static int thom_qdd_map[400]; - -static int qdd_translate_sector(floppy_image_legacy *floppy, int sector) -{ - return thom_qdd_map[sector-1]; -} - -static void thom_qdd_compute_map ( void ) -{ - /* this map is hardcoded in the QDD BIOS */ - static const int p[6][4] = + floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM, + 4000, + 16, 40, 1, + 128, {}, + 1, {}, + 17, 22, 12 + }, { - { 20, 2, 14, 8 }, { 21, 19, 13, 7 }, - { 22, 18, 12, 6 }, { 23, 17, 11, 5 }, - { 24, 16, 10, 4 }, { 1, 15, 9, 3 } - }; - static const int q[4] = { 0, 8, 4, 12 }; - int t, s; - for ( t = 0; t < 24; t++ ) + floppy_image::FF_525, floppy_image::SSDD, floppy_image::MFM, + 2000, + 16, 40, 1, + 256, {}, + 1, {}, + 31, 22, 44 + }, { - for ( s = 0; s < 16; s++ ) - { - thom_qdd_map[ t*16 + s ] = p[ t/4 ][ s%4 ] * 16 + (s/4) + 4*(t%4); - } - } - for ( s = 0; s < 16; s++ ) - { - thom_qdd_map[ 24*16 + s ] = q[ s%4 ] + (s/4); - } -} - -static FLOPPY_CONSTRUCT(qdd_dsk_construct) -{ - struct basicdsk_geometry geometry; - - thom_qdd_compute_map(); - - memset(&geometry, 0, sizeof(geometry)); - geometry.heads = 1; - geometry.first_sector_id = 1; - geometry.sector_length = 128; - geometry.tracks = 1; - geometry.sectors = 400; - geometry.translate_sector = qdd_translate_sector; - return basicdsk_construct(floppy, &geometry); -} - - -/* ----------------------------------------------------------------------- */ - - -static floperr_t fd_identify(floppy_image_legacy *floppy, int *vote, int tracks, int sector_size) -{ - uint64_t expected_size; - expected_size = sector_size; - expected_size *= tracks; - expected_size *= 16; /* secetors */ - *vote = (floppy_image_size(floppy) == expected_size) ? 100 : 50; - return FLOPPY_ERROR_SUCCESS; -} + floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM, + 2000, + 16, 40, 2, + 256, {}, + 1, {}, + 31, 22, 44 + }, + {} +}; -static floperr_t fd_construct(floppy_image_legacy *floppy, int tracks, int sector_size) +int thomson_525_format::get_image_offset(const format &f, int head, int track) const { - struct basicdsk_geometry geometry; - memset(&geometry, 0, sizeof(geometry)); - geometry.heads = 1; - geometry.first_sector_id = 1; - geometry.sector_length = sector_size; - geometry.tracks = tracks; - geometry.sectors = 16; - return basicdsk_construct(floppy, &geometry); + return (track + (head ? f.track_count : 0)) * compute_track_size(f); } -static FLOPPY_IDENTIFY(fd_80_256_identify) -{ - return fd_identify(floppy, vote, 80, 256); -} -static FLOPPY_CONSTRUCT(fd_80_256_construct) +thomson_35_format::thomson_35_format() : wd177x_format(formats) { - return fd_construct(floppy, 80, 256); } -static FLOPPY_IDENTIFY(fd_40_256_identify) +const char *thomson_35_format::name() const noexcept { - return fd_identify(floppy, vote, 40, 256); + return "thomson_35"; } -static FLOPPY_CONSTRUCT(fd_40_256_construct) +const char *thomson_35_format::description() const noexcept { - return fd_construct(floppy, 40, 256); + return "Thomson 3.5 disk image"; } -static FLOPPY_IDENTIFY(fd_80_128_identify) +const char *thomson_35_format::extensions() const noexcept { - return fd_identify(floppy, vote, 80, 128); + return "fd"; } -static FLOPPY_CONSTRUCT(fd_80_128_construct) -{ - return fd_construct(floppy, 80, 128); -} - -static FLOPPY_IDENTIFY(fd_40_128_identify) -{ - return fd_identify(floppy, vote, 40, 128); -} +// 1280K .fd images exist but are not supported. They represent a notional type +// of 4-sided disk that can be inserted into 2 drives at once. +const thomson_35_format::format thomson_35_format::formats[] = { + { + floppy_image::FF_35, floppy_image::SSDD, floppy_image::MFM, + 2000, + 16, 80, 1, + 256, {}, + 1, {}, + 31, 22, 44 + }, + { + floppy_image::FF_35, floppy_image::DSDD, floppy_image::MFM, + 2000, + 16, 80, 2, + 256, {}, + 1, {}, + 31, 22, 44 + }, + {} +}; -static FLOPPY_CONSTRUCT(fd_40_128_construct) +int thomson_35_format::get_image_offset(const format &f, int head, int track) const { - return fd_construct(floppy, 40, 128); + return (track + (head ? f.track_count : 0)) * compute_track_size(f); } - -/* ----------------------------------------------------------------------- */ - -LEGACY_FLOPPY_OPTIONS_START(thomson) - -LEGACY_FLOPPY_OPTION(fdmfm2, "fd", "Thomson FD (MFM) 80 tracks disk image (3\"1/2 DD)", - fd_80_256_identify, fd_80_256_construct, nullptr, nullptr) - -// Note: no way to distinguish between FD files for 5"1/4 DD and 3"1/2 SD actually, as they have the same size -// however, we expect 3"1/2 SD to be rather rare, so, we simply put it after 5"1/4 DD - -LEGACY_FLOPPY_OPTION(fdmfm, "fd", "Thomson FD (MFM) 40 tracks disk image (5\"1/4 DD)", - fd_40_256_identify, fd_40_256_construct, nullptr, nullptr) - -LEGACY_FLOPPY_OPTION(fd2, "fd", "Thomson FD (FM) 80 tracks disk image (3\"1/2 SD)", - fd_80_128_identify, fd_80_128_construct, nullptr, nullptr) - -LEGACY_FLOPPY_OPTION(fd, "fd", "Thomson FD (FM) 40 tracks disk image (5\"1/4 SD)", - fd_40_128_identify, fd_40_128_construct, nullptr, nullptr) - -LEGACY_FLOPPY_OPTION(sap,"sap", "Thomson SAP floppy disk image", - sap_dsk_identify, sap_dsk_construct, nullptr, nullptr) - -LEGACY_FLOPPY_OPTION(qdd,"qd", "Thomson QDD floppy disk image (2\"8 SD)", - qdd_dsk_identify, qdd_dsk_construct, nullptr, nullptr) - -LEGACY_FLOPPY_OPTIONS_END +const thomson_525_format FLOPPY_THOMSON_525_FORMAT; +const thomson_35_format FLOPPY_THOMSON_35_FORMAT; |