summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/d64_dsk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats/d64_dsk.c')
-rw-r--r--src/lib/formats/d64_dsk.c849
1 files changed, 0 insertions, 849 deletions
diff --git a/src/lib/formats/d64_dsk.c b/src/lib/formats/d64_dsk.c
index 172918a3051..c36d2dd2050 100644
--- a/src/lib/formats/d64_dsk.c
+++ b/src/lib/formats/d64_dsk.c
@@ -245,852 +245,3 @@ bool d64_format::supports_save() const
}
const floppy_format_type FLOPPY_D64_FORMAT = &floppy_image_format_creator<d64_format>;
-
-
-// ------ LEGACY -----
-
-
-/*********************************************************************
-
- formats/d64_dsk.c
-
- Floppy format code for Commodore 1541/2040/8050 disk images
-
-*********************************************************************/
-
-/*
-
- TODO:
-
- - write to disk
- - disk errors 24, 25, 26, 28, 74
- - variable gaps
-
-*/
-
-#define XTAL_16MHz 16000000
-#define XTAL_12MHz 12000000
-#include "g64_dsk.h"
-#include "flopimg.h"
-#include "d64_dsk.h"
-
-/***************************************************************************
- PARAMETERS
-***************************************************************************/
-
-#define MAX_HEADS 2
-#define MAX_TRACKS 84
-#define MAX_ERROR_SECTORS 4166
-#define SECTOR_SIZE 256
-#define SECTOR_SIZE_GCR 368
-
-#define INVALID_OFFSET 0xbadbad
-
-#define D64_SIZE_35_TRACKS 174848
-#define D64_SIZE_35_TRACKS_WITH_ERRORS 175531
-#define D64_SIZE_40_TRACKS 196608
-#define D64_SIZE_40_TRACKS_WITH_ERRORS 197376
-#define D64_SIZE_42_TRACKS 205312
-#define D64_SIZE_42_TRACKS_WITH_ERRORS 206114
-#define D67_SIZE_35_TRACKS 176640
-#define D71_SIZE_70_TRACKS 349696
-#define D71_SIZE_70_TRACKS_WITH_ERRORS 351062
-#define D80_SIZE_77_TRACKS 533248
-#define D80_SIZE_77_TRACKS_WITH_ERRORS 535331
-#define D82_SIZE_154_TRACKS 1066496
-#define D82_SIZE_154_TRACKS_WITH_ERRORS 1070662
-
-#define G64_SPEED_BLOCK_SIZE 1982
-
-enum
-{
- DOS1,
- DOS2,
- DOS25
-};
-
-static const char *const DOS_VERSION[] = { "1.0", "2.0", "2.5" };
-
-enum
-{
- ERROR_00 = 1,
- ERROR_20, /* header block not found */
- ERROR_21, /* no sync character */
- ERROR_22, /* data block not present */
- ERROR_23, /* checksum error in data block */
- ERROR_24, /* write verify (on format) UNIMPLEMENTED */
- ERROR_25, /* write verify error UNIMPLEMENTED */
- ERROR_26, /* write protect on UNIMPLEMENTED */
- ERROR_27, /* checksum error in header block */
- ERROR_28, /* write error UNIMPLEMENTED */
- ERROR_29, /* disk ID mismatch */
- ERROR_74, /* disk not ready (no device 1) UNIMPLEMENTED */
-};
-
-static const char *const ERROR_CODE[] = { "00", "00", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "74" };
-
-static const UINT8 bin_2_gcr[] =
-{
- 0x0a, 0x0b, 0x12, 0x13, 0x0e, 0x0f, 0x16, 0x17,
- 0x09, 0x19, 0x1a, 0x1b, 0x0d, 0x1d, 0x1e, 0x15
-};
-
-/* This could be of use if we ever implement saving in .d64 format, to convert back GCR -> d64 */
-/*
-static const int gcr_2_bin[] =
-{
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- -1, 0x08, 0x00, 0x01,
- -1, 0x0c, 0x04, 0x05,
- -1, -1, 0x02, 0x03,
- -1, 0x0f, 0x06, 0x07,
- -1, 0x09, 0x0a, 0x0b,
- -1, 0x0d, 0x0e, -1
-};
-*/
-
-static const int DOS1_SECTORS_PER_TRACK[] =
-{
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 20, 20, 20, 20, 20, 20, 20,
- 18, 18, 18, 18, 18, 18,
- 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17,
- 17, 17
-};
-
-static const int DOS1_SPEED_ZONE[] =
-{
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2,
- 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
-};
-
-static const int DOS2_SECTORS_PER_TRACK[] =
-{
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 19, 19, 19, 19, 19, 19, 19,
- 18, 18, 18, 18, 18, 18,
- 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17,
- 17, 17
-};
-
-static const int DOS25_SECTORS_PER_TRACK[] =
-{
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, /* 1-39 */
- 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, /* 40-53 */
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, /* 54-64 */
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, /* 65-77 */
- 23, 23, 23, 23, 23, 23, 23 /* 78-84 */
-};
-
-static const int DOS25_SPEED_ZONE[] =
-{
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 1-39 */
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 40-53 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 54-64 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 65-77 */
- 0, 0, 0, 0, 0, 0, 0 /* 78-84 */
-};
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-struct d64dsk_tag
-{
- int dos; /* CBM DOS version */
- int heads; /* number of physical heads */
- int tracks; /* number of physical tracks */
- int dos_tracks; /* number of logical tracks */
- int track_offset[MAX_HEADS][MAX_TRACKS]; /* offset within image for each physical track */
- UINT32 speed_zone[MAX_TRACKS]; /* speed zone for each physical track */
- bool has_errors; /* flag to check for available error codes */
- UINT8 error[MAX_ERROR_SECTORS]; /* error code for each logical sector */
- int error_offset[MAX_HEADS][MAX_TRACKS]; /* offset within error array for sector 0 of each logical track */
-
- UINT8 id1, id2; /* DOS disk format ID */
-};
-
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
-
-INLINE struct d64dsk_tag *get_tag(floppy_image_legacy *floppy)
-{
- return (d64dsk_tag *)floppy_tag(floppy);
-}
-
-INLINE float get_dos_track(int track)
-{
- return ((float)track / 2) + 1;
-}
-
-/***************************************************************************
- IMPLEMENTATION
-***************************************************************************/
-
-/*-------------------------------------------------
- d64_get_heads_per_disk - returns the number
- of heads in the disk image
--------------------------------------------------*/
-
-static int d64_get_heads_per_disk(floppy_image_legacy *floppy)
-{
- return get_tag(floppy)->heads;
-}
-
-/*-------------------------------------------------
- d64_get_tracks_per_disk - returns the number
- of DOS tracks in the disk image
--------------------------------------------------*/
-
-static int d64_get_tracks_per_disk(floppy_image_legacy *floppy)
-{
- return get_tag(floppy)->tracks;
-}
-
-/*-------------------------------------------------
- d64_get_sectors_per_track - returns the number
- of sectors per given track
--------------------------------------------------*/
-
-static int d64_get_sectors_per_track(floppy_image_legacy *floppy, int head, int track)
-{
- int sectors_per_track = 0;
-
- switch (get_tag(floppy)->dos)
- {
- case DOS1: sectors_per_track = DOS1_SECTORS_PER_TRACK[track / 2]; break;
- case DOS2: sectors_per_track = DOS2_SECTORS_PER_TRACK[track / 2]; break;
- case DOS25: sectors_per_track = DOS25_SECTORS_PER_TRACK[track]; break;
- }
-
- return sectors_per_track;
-}
-
-/*-------------------------------------------------
- get_track_offset - returns the offset within
- the disk image for a given track
--------------------------------------------------*/
-
-static floperr_t get_track_offset(floppy_image_legacy *floppy, int head, int track, UINT64 *offset)
-{
- struct d64dsk_tag *tag = get_tag(floppy);
- UINT64 offs = 0;
-
- if ((track < 0) || (track >= tag->tracks))
- return FLOPPY_ERROR_SEEKERROR;
-
- offs = tag->track_offset[head][track];
-
- if (offset)
- *offset = offs;
-
- return FLOPPY_ERROR_SUCCESS;
-}
-
-/*-------------------------------------------------
- d64_get_track_size - returns the track size
--------------------------------------------------*/
-
-static UINT32 d64_get_track_size(floppy_image_legacy *floppy, int head, int track)
-{
- struct d64dsk_tag *tag = get_tag(floppy);
-
- if (tag->track_offset[head][track] == INVALID_OFFSET)
- return 0;
-
- /* determine number of sectors per track */
- int sectors_per_track = d64_get_sectors_per_track(floppy, head, track);
-
- /* allocate temporary GCR track data buffer */
- UINT32 track_length = sectors_per_track * SECTOR_SIZE_GCR;
-
- return track_length;
-}
-
-/*-------------------------------------------------
- get_sector_error_code - returns the error
- code for the given sector
--------------------------------------------------*/
-
-static int get_sector_error_code(floppy_image_legacy *floppy, int head, int dos_track, int sector)
-{
- struct d64dsk_tag *tag = get_tag(floppy);
-
- if (!tag->has_errors)
- return ERROR_00;
-
- int sector_error = tag->error[tag->error_offset[head][dos_track] + sector]; // TODO index out of bounds!!!
-
- if (sector_error != ERROR_00)
- {
- LOG_FORMATS("D64 error %s head %d track %d sector %d\n", ERROR_CODE[sector_error], head, dos_track, sector);
- }
-
- return sector_error;
-}
-
-/*-------------------------------------------------
- gcr_double_2_gcr - GCR decodes given data
--------------------------------------------------*/
-
-/* gcr_double_2_gcr takes 4 bytes (a, b, c, d) and shuffles their nibbles to obtain 5 bytes in dest */
-/* The result is basically res = (enc(a) << 15) | (enc(b) << 10) | (enc(c) << 5) | enc(d)
- * with res being 5 bytes long and enc(x) being the GCR encode of x.
- * In fact, we store the result as five separate bytes in the dest argument
- */
-
-/*
-
- Commodore GCR format
-
-Original Encoded
-4 bits 5 bits
-
-0000 -> 01010 = 0x0a
-0001 -> 01011 = 0x0b
-0010 -> 10010 = 0x12
-0011 -> 10011 = 0x13
-0100 -> 01110 = 0x0e
-0101 -> 01111 = 0x0f
-0110 -> 10110 = 0x16
-0111 -> 10111 = 0x17
-1000 -> 01001 = 0x09
-1001 -> 11001 = 0x19
-1010 -> 11010 = 0x1a
-1011 -> 11011 = 0x1b
-1100 -> 01101 = 0x0d
-1101 -> 11101 = 0x1d
-1110 -> 11110 = 0x1e
-1111 -> 10101 = 0x15
-
-We use the encoded values in bytes because we use them to encode
-groups of 4 bytes into groups of 5 bytes, below.
-
-*/
-
-static void gcr_double_2_gcr(UINT8 a, UINT8 b, UINT8 c, UINT8 d, UINT8 *dest)
-{
- UINT8 gcr[8];
-
- /* Encode each nibble to 5 bits */
- gcr[0] = bin_2_gcr[a >> 4];
- gcr[1] = bin_2_gcr[a & 0x0f];
- gcr[2] = bin_2_gcr[b >> 4];
- gcr[3] = bin_2_gcr[b & 0x0f];
- gcr[4] = bin_2_gcr[c >> 4];
- gcr[5] = bin_2_gcr[c & 0x0f];
- gcr[6] = bin_2_gcr[d >> 4];
- gcr[7] = bin_2_gcr[d & 0x0f];
-
- /* Re-order the encoded data to only keep the 5 lower bits of each byte */
- dest[0] = (gcr[0] << 3) | (gcr[1] >> 2);
- dest[1] = (gcr[1] << 6) | (gcr[2] << 1) | (gcr[3] >> 4);
- dest[2] = (gcr[3] << 4) | (gcr[4] >> 1);
- dest[3] = (gcr[4] << 7) | (gcr[5] << 2) | (gcr[6] >> 3);
- dest[4] = (gcr[6] << 5) | gcr[7];
-}
-
-/*-------------------------------------------------
- d64_read_track - reads a full track from the
- disk image
--------------------------------------------------*/
-
-/*
-
- Commodore sector format
-
- SYNC FF * 5
- 08
- CHECKSUM sector ^ track ^ id2 ^ id1
- SECTOR 0..20 (2040), 0..28 (8050)
- TRACK 1..35 (2040), 1..77 (8050), 1..70 (1571)
- ID2
- ID1
- GAP 1 55 * 9 (2040), 55 * 8 (1541)
-
- SYNC FF * 5
- 07
- NEXT TRACK
- NEXT SECTOR
- 254 BYTES OF DATA
- CHECKSUM
- GAP 2 55 * 8..19
-
-*/
-
-static floperr_t d64_read_track(floppy_image_legacy *floppy, int head, int track, UINT64 offset, void *buffer, size_t buflen)
-{
- struct d64dsk_tag *tag = get_tag(floppy);
- floperr_t err;
- UINT64 track_offset;
-
- /* get track offset */
- err = get_track_offset(floppy, head, track, &track_offset);
-
- if (err)
- return err;
-
- if (track_offset != INVALID_OFFSET)
- {
- UINT8 id1 = tag->id1;
- UINT8 id2 = tag->id2;
- int sectors_per_track;
- UINT16 d64_track_size;
- UINT8 *d64_track_data;
- UINT16 gcr_track_size;
- UINT8 *gcr_track_data;
- UINT64 gcr_pos = 0;
-
- /* determine logical track number */
- int dos_track = get_dos_track(track);
-
- if (tag->dos == DOS25)
- {
- dos_track = track + 1;
- }
-
- /* logical track numbers continue on the flip side */
- if (head == 1) dos_track += tag->dos_tracks;
-
- /* determine number of sectors per track */
- sectors_per_track = d64_get_sectors_per_track(floppy, head, track);
-
- /* allocate D64 track data buffer */
- d64_track_size = sectors_per_track * SECTOR_SIZE;
- d64_track_data = (UINT8 *)alloca(d64_track_size);
-
- /* allocate temporary GCR track data buffer */
- gcr_track_size = sectors_per_track * SECTOR_SIZE_GCR;
- gcr_track_data = (UINT8 *)alloca(gcr_track_size);
-
- if (buflen < gcr_track_size) { fatalerror("D64 track buffer too small: %u!\n", (UINT32)buflen); }
-
- /* read D64 track data */
- floppy_image_read(floppy, d64_track_data, track_offset, d64_track_size);
-
- /* GCR encode D64 sector data */
- for (int sector = 0; sector < sectors_per_track; sector++)
- {
- // here we convert the sector data to gcr directly!
- // IMPORTANT: errors in reading sectors can modify e.g. header info $01 & $05
- int sector_error = get_sector_error_code(floppy, head, track, sector);
-
- /* first we set the position at which sector data starts in the image */
- UINT64 d64_pos = sector * SECTOR_SIZE;
- int i;
-
- /*
- 1. Header sync FF FF FF FF FF (40 'on' bits, not GCR encoded)
- 2. Header info 52 54 B5 29 4B 7A 5E 95 55 55 (10 GCR bytes)
- 3. Header gap 55 55 55 55 55 55 55 55 55 (9 bytes, never read)
- 4. Data sync FF FF FF FF FF (40 'on' bits, not GCR encoded)
- 5. Data block 55...4A (325 GCR bytes)
- 6. Inter-sector gap 55 55 55 55...55 55 (4 to 19 bytes, never read)
- */
-
- if (sector_error == ERROR_29)
- id1 ^= 0xff;
-
- /* Header sync */
- if (sector_error != ERROR_21)
- {
- for (i = 0; i < 5; i++)
- gcr_track_data[gcr_pos + i] = 0xff;
- gcr_pos += 5;
- }
-
- /* Header info */
- /* These are 8 bytes unencoded, which become 10 bytes encoded */
- // $00 - header block ID ($08) // this byte can be modified by error code 20 -> 0xff
- // $01 - header block checksum (EOR of $02-$05) // this byte can be modified by error code 27 -> ^ 0xff
- // $02 - Sector# of data block
- // $03 - Track# of data block
- UINT8 header_block_id = (sector_error == ERROR_20) ? 0xff : 0x08;
- UINT8 header_block_checksum = sector ^ dos_track ^ id2 ^ id1;
-
- if (sector_error == ERROR_27)
- header_block_checksum ^= 0xff;
-
- gcr_double_2_gcr(header_block_id, header_block_checksum, sector, dos_track, gcr_track_data + gcr_pos);
- gcr_pos += 5;
-
- // $04 - Format ID byte #2
- // $05 - Format ID byte #1
- // $06 - $0F ("off" byte)
- // $07 - $0F ("off" byte)
- gcr_double_2_gcr(id2, id1, 0x0f, 0x0f, gcr_track_data + gcr_pos);
- gcr_pos += 5;
-
- /* Header gap */
- for (i = 0; i < 9; i++)
- gcr_track_data[gcr_pos + i] = 0x55;
- gcr_pos += 9;
-
- /* Data sync */
- for (i = 0; i < 5; i++)
- gcr_track_data[gcr_pos + i] = 0xff;
- gcr_pos += 5;
-
- /* Data block */
- UINT8 data_block_id = (sector_error == ERROR_22) ? 0xff : 0x07;
-
- // we first need to calculate the checksum of the 256 bytes of the sector
- UINT8 sector_checksum = d64_track_data[d64_pos];
- for (i = 1; i < 256; i++)
- sector_checksum ^= d64_track_data[d64_pos + i];
-
- if (sector_error == ERROR_23)
- sector_checksum ^= 0xff;
-
- /*
- $00 - data block ID ($07)
- $01-100 - 256 bytes sector data
- $101 - data block checksum (EOR of $01-100)
- $102-103 - $00 ("off" bytes, to make the sector size a multiple of 5)
- */
- gcr_double_2_gcr(data_block_id, d64_track_data[d64_pos], d64_track_data[d64_pos + 1], d64_track_data[d64_pos + 2], gcr_track_data + gcr_pos);
- gcr_pos += 5;
-
- for (i = 1; i < 64; i++)
- {
- gcr_double_2_gcr(d64_track_data[d64_pos + 4 * i - 1], d64_track_data[d64_pos + 4 * i],
- d64_track_data[d64_pos + 4 * i + 1], d64_track_data[d64_pos + 4 * i + 2], gcr_track_data + gcr_pos);
- gcr_pos += 5;
- }
-
- gcr_double_2_gcr(d64_track_data[d64_pos + 255], sector_checksum, 0x00, 0x00, gcr_track_data + gcr_pos);
- gcr_pos += 5;
-
- /* Inter-sector gap */
- // "In tests that the author conducted on a real 1541 disk, gap sizes of 8 to 19 bytes were seen."
- // Here we put 14 as an average...
- for (i = 0; i < 14; i++)
- gcr_track_data[gcr_pos + i] = 0x55;
- gcr_pos += 14;
- }
-
- /* copy GCR track data to buffer */
- memcpy((UINT8*)buffer, gcr_track_data, gcr_track_size);
-
- // create a speed block with the same speed zone for the whole track
- UINT8 speed = tag->speed_zone[track] & 0x03;
- UINT8 speed_byte = (speed << 6) | (speed << 4) | (speed << 2) | speed;
-
- memset(((UINT8*)buffer) + gcr_track_size, speed_byte, G64_SPEED_BLOCK_SIZE);
-
- LOG_FORMATS("D64 side %u track %.1f length %u\n", head, get_dos_track(track), gcr_track_size);
- }
- else /* half tracks */
- {
- /* set track length to 0 */
- memset(buffer, 0, buflen);
-
- LOG_FORMATS("D64 side %u track %.1f length %u\n", head, get_dos_track(track), 0);
- }
-
- return FLOPPY_ERROR_SUCCESS;
-}
-
-/*-------------------------------------------------
- d64_write_track - writes a full track to the
- disk image
--------------------------------------------------*/
-
-static floperr_t d64_write_track(floppy_image_legacy *floppy, int head, int track, UINT64 offset, const void *buffer, size_t buflen)
-{
- return FLOPPY_ERROR_UNSUPPORTED;
-}
-
-/*-------------------------------------------------
- d64_identify - identifies the disk image
--------------------------------------------------*/
-
-static void d64_identify(floppy_image_legacy *floppy, int *dos, int *heads, int *tracks, bool *has_errors)
-{
- switch (floppy_image_size(floppy))
- {
- /* 2040/3040 */
- case D67_SIZE_35_TRACKS: *dos = DOS1; *heads = 1; *tracks = 35; *has_errors = false; break;
-
- /* 4040/2031/1541/1551 */
- case D64_SIZE_35_TRACKS: *dos = DOS2; *heads = 1; *tracks = 35; *has_errors = false; break;
- case D64_SIZE_35_TRACKS_WITH_ERRORS: *dos = DOS2; *heads = 1; *tracks = 35; *has_errors = true; break;
- case D64_SIZE_40_TRACKS: *dos = DOS2; *heads = 1; *tracks = 40; *has_errors = false; break;
- case D64_SIZE_40_TRACKS_WITH_ERRORS: *dos = DOS2; *heads = 1; *tracks = 40; *has_errors = true; break;
- case D64_SIZE_42_TRACKS: *dos = DOS2; *heads = 1; *tracks = 42; *has_errors = false; break;
- case D64_SIZE_42_TRACKS_WITH_ERRORS: *dos = DOS2; *heads = 1; *tracks = 42; *has_errors = true; break;
-
- /* 1571 */
- case D71_SIZE_70_TRACKS: *dos = DOS2; *heads = 2; *tracks = 35; *has_errors = false; break;
- case D71_SIZE_70_TRACKS_WITH_ERRORS: *dos = DOS2; *heads = 2; *tracks = 35; *has_errors = true; break;
-
- /* 8050 */
- case D80_SIZE_77_TRACKS: *dos = DOS25; *heads = 1; *tracks = 77; *has_errors = false; break;
- case D80_SIZE_77_TRACKS_WITH_ERRORS: *dos = DOS25; *heads = 1; *tracks = 77; *has_errors = true; break;
-
- /* 8250/SFD1001 */
- case D82_SIZE_154_TRACKS: *dos = DOS25; *heads = 2; *tracks = 77; *has_errors = false; break;
- case D82_SIZE_154_TRACKS_WITH_ERRORS: *dos = DOS25; *heads = 2; *tracks = 77; *has_errors = true; break;
- }
-}
-
-/*-------------------------------------------------
- FLOPPY_IDENTIFY( d64_dsk_identify )
--------------------------------------------------*/
-
-FLOPPY_IDENTIFY( d64_dsk_identify )
-{
- int dos = 0, heads, tracks;
- bool has_errors = false;
-
- *vote = 0;
-
- d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
-
- if (dos == DOS2 && heads == 1)
- {
- *vote = 100;
- }
-
- return FLOPPY_ERROR_SUCCESS;
-}
-
-/*-------------------------------------------------
- FLOPPY_IDENTIFY( d67_dsk_identify )
--------------------------------------------------*/
-
-FLOPPY_IDENTIFY( d67_dsk_identify )
-{
- *vote = 0;
-
- if (floppy_image_size(floppy) == D67_SIZE_35_TRACKS)
- {
- *vote = 100;
- }
-
- return FLOPPY_ERROR_SUCCESS;
-}
-
-/*-------------------------------------------------
- FLOPPY_IDENTIFY( d71_dsk_identify )
--------------------------------------------------*/
-
-FLOPPY_IDENTIFY( d71_dsk_identify )
-{
- int heads = 0, tracks = 0, dos = -1;
- bool has_errors = false;
-
- *vote = 0;
-
- d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
-
- if (dos == DOS2 && heads == 2)
- {
- *vote = 100;
- }
-
- return FLOPPY_ERROR_SUCCESS;
-}
-
-/*-------------------------------------------------
- FLOPPY_IDENTIFY( d80_dsk_identify )
--------------------------------------------------*/
-
-FLOPPY_IDENTIFY( d80_dsk_identify )
-{
- int heads = 0, tracks = 0, dos = -1;
- bool has_errors = false;
- *vote = 0;
-
- d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
-
- if (dos == DOS25 && heads == 1)
- {
- *vote = 100;
- }
-
- return FLOPPY_ERROR_SUCCESS;
-}
-
-/*-------------------------------------------------
- FLOPPY_IDENTIFY( d82_dsk_identify )
--------------------------------------------------*/
-
-FLOPPY_IDENTIFY( d82_dsk_identify )
-{
- int heads = 0, tracks = 0, dos = -1;
- bool has_errors = false;
- *vote = 0;
-
- d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
-
- if (dos == DOS25 && heads == 2)
- {
- *vote = 100;
- }
-
- return FLOPPY_ERROR_SUCCESS;
-}
-
-/*-------------------------------------------------
- FLOPPY_CONSTRUCT( d64_dsk_construct )
--------------------------------------------------*/
-
-FLOPPY_CONSTRUCT( d64_dsk_construct )
-{
- struct FloppyCallbacks *callbacks;
- struct d64dsk_tag *tag;
- UINT8 id[2];
-
- int track_offset = 0;
- int head, track;
-
- int heads = 0, dos_tracks = 0, dos = 0;
- bool has_errors = 0;
- int errors_size = 0;
-
- if (params)
- {
- /* create not supported */
- return FLOPPY_ERROR_UNSUPPORTED;
- }
-
- tag = (struct d64dsk_tag *) floppy_create_tag(floppy, sizeof(struct d64dsk_tag));
-
- if (!tag) return FLOPPY_ERROR_OUTOFMEMORY;
-
- /* identify image type */
- d64_identify(floppy, &dos, &heads, &dos_tracks, &has_errors);
-
- tag->dos = dos;
- tag->heads = heads;
- tag->tracks = MAX_TRACKS;
- tag->dos_tracks = dos_tracks;
- tag->has_errors = has_errors;
-
- LOG_FORMATS("D64 size: %04x\n", (UINT32)floppy_image_size(floppy));
- LOG_FORMATS("D64 heads: %d\n", heads);
- LOG_FORMATS("D64 tracks: %d\n", dos_tracks);
- LOG_FORMATS("D64 DOS version: %s\n", DOS_VERSION[dos]);
- LOG_FORMATS("D64 error codes: %s\n", has_errors ? "yes" : "no");
-
- /* clear track data offsets */
- for (head = 0; head < MAX_HEADS; head++)
- {
- for (track = 0; track < MAX_TRACKS; track++)
- {
- tag->track_offset[head][track] = INVALID_OFFSET;
- }
- }
-
- /* determine track data offsets */
- for (head = 0; head < heads; head++)
- {
- for (track = 0; track < tag->tracks; track++)
- {
- if (dos == DOS25)
- {
- if (track >= dos_tracks)
- {
- /* track out of range */
- tag->track_offset[head][track] = INVALID_OFFSET;
- }
- else
- {
- tag->track_offset[head][track] = track_offset;
- tag->error_offset[head][track] = errors_size;
- tag->speed_zone[track] = DOS25_SPEED_ZONE[track];
-
- track_offset += DOS25_SECTORS_PER_TRACK[track] * SECTOR_SIZE;
- /* also store an error entry for each sector */
- errors_size += DOS25_SECTORS_PER_TRACK[track];
-
- LOG_FORMATS("D64 head %d track %d offset %05x", head, track + 1, tag->track_offset[head][track]);
- if (has_errors) LOG_FORMATS(" errors %05x", tag->error_offset[head][track]);
- LOG_FORMATS(" speed %u\n", tag->speed_zone[track]);
- }
- }
- else
- {
- if ((track % 2) || ((track / 2) >= dos_tracks))
- {
- /* half track or out of range */
- tag->track_offset[head][track] = INVALID_OFFSET;
- }
- else
- {
- /* full track */
- tag->track_offset[head][track] = track_offset;
- tag->error_offset[head][track] = errors_size;
- tag->speed_zone[track] = DOS1_SPEED_ZONE[track / 2];
-
- if (dos == DOS1)
- {
- track_offset += DOS1_SECTORS_PER_TRACK[track / 2] * SECTOR_SIZE;
- /* also store an error entry for each sector */
- errors_size += DOS1_SECTORS_PER_TRACK[track / 2];
- }
- else
- {
- track_offset += DOS2_SECTORS_PER_TRACK[track / 2] * SECTOR_SIZE;
- /* also store an error entry for each sector */
- errors_size += DOS2_SECTORS_PER_TRACK[track / 2];
- }
-
- LOG_FORMATS("D64 head %d track %.1f offset %05x", head, get_dos_track(track), tag->track_offset[head][track]);
- if (has_errors) LOG_FORMATS(" errors %05x", tag->error_offset[head][track]);
- LOG_FORMATS(" speed %u\n", tag->speed_zone[track]);
- }
- }
- }
- }
-
- /* read format ID from directory */
- /*
- id1, id2 are the same for extended d64 (i.e. with error tables), for d67 and for d71
-
- for d81 they are at track 40 bytes 0x17 & 0x18
- for d80 & d82 they are at track 39 bytes 0x18 & 0x19
- */
- if (dos == DOS25)
- floppy_image_read(floppy, id, tag->track_offset[0][38] + 0x18, 2);
- else
- floppy_image_read(floppy, id, tag->track_offset[0][34] + 0xa2, 2);
-
- tag->id1 = id[0];
- tag->id2 = id[1];
-
- LOG_FORMATS("D64 format ID: %02x%02x\n", id[0], id[1]);
-
- /* read errors */
- if (tag->has_errors)
- {
- LOG_FORMATS("D64 error blocks: %d %d\n", errors_size, track_offset);
- floppy_image_read(floppy, tag->error, track_offset, errors_size);
- }
- else
- {
- memset(tag->error, ERROR_00, MAX_ERROR_SECTORS);
- }
-
- /* set callbacks */
- callbacks = floppy_callbacks(floppy);
-
- callbacks->read_track = d64_read_track;
- callbacks->write_track = d64_write_track;
- callbacks->get_heads_per_disk = d64_get_heads_per_disk;
- callbacks->get_tracks_per_disk = d64_get_tracks_per_disk;
- callbacks->get_track_size = d64_get_track_size;
-
- return FLOPPY_ERROR_SUCCESS;
-}