More TD0 bug fixes - fixed handling of sectors without an ID field, and fixed the handling of TD0 images recorded at 300 kbps on a 360 rpm drive (which is equivalent to 250 kbps on a 300 rpm drive), fixes Sid Meier's Pirates!

This commit is contained in:
OBattler
2019-12-06 02:37:52 +01:00
parent b9a35eb418
commit ce9408a817
2 changed files with 25 additions and 14 deletions

View File

@@ -10,7 +10,7 @@
* data in the form of FM/MFM-encoded transitions) which also * data in the form of FM/MFM-encoded transitions) which also
* forms the core of the emulator's floppy disk emulation. * forms the core of the emulator's floppy disk emulation.
* *
* Version: @(#)fdd_86f.c 1.0.19 2019/12/05 * Version: @(#)fdd_86f.c 1.0.20 2019/12/06
* *
* Authors: Miran Grca, <mgrca8@gmail.com> * Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com> * Fred N. van Kempen, <decwiz@yahoo.com>
@@ -1260,18 +1260,19 @@ d86f_word_is_aligned(int drive, int side, uint32_t base_pos)
d86f_t *dev = d86f[drive]; d86f_t *dev = d86f[drive];
uint32_t adjusted_track_pos = dev->track_pos; uint32_t adjusted_track_pos = dev->track_pos;
if (base_pos == 0xFFFFFFFF) return 0; if (base_pos == 0xFFFFFFFF)
return 0;
/* /*
* This is very important, it makes sure alignment is detected * This is very important, it makes sure alignment is detected
* correctly even across the index hole of a track whose length * correctly even across the index hole of a track whose length
* is not divisible by 16. * is not divisible by 16.
*/ */
if (adjusted_track_pos < base_pos) { if (adjusted_track_pos < base_pos)
adjusted_track_pos += d86f_handler[drive].get_raw_size(drive, side); adjusted_track_pos += d86f_handler[drive].get_raw_size(drive, side);
}
if ((adjusted_track_pos & 15) == (base_pos & 15)) return 1; if ((adjusted_track_pos & 15) == (base_pos & 15))
return 1;
return 0; return 0;
} }

View File

@@ -8,7 +8,7 @@
* *
* Implementation of the Teledisk floppy image format. * Implementation of the Teledisk floppy image format.
* *
* Version: @(#)fdd_td0.c 1.0.9 2019/12/05 * Version: @(#)fdd_td0.c 1.0.10 2019/12/06
* *
* Authors: Milodrag Milanovic, * Authors: Milodrag Milanovic,
* Haruhiko OKUMURA, * Haruhiko OKUMURA,
@@ -808,7 +808,7 @@ td0_initialize(int drive)
track_size += id_field; track_size += id_field;
track_spt_adjusted--; track_spt_adjusted--;
} else if (hs[4] & 0x40) } else if (hs[4] & 0x40)
track_size += (pre_sector - id_field + size + 2); track_size += (pre_sector - id_field + 3);
else { else {
if ((hs[4] & 0x02) || (hs[3] > (dev->max_sector_size - fm))) if ((hs[4] & 0x02) || (hs[3] > (dev->max_sector_size - fm)))
track_size += (pre_sector + 3); track_size += (pre_sector + 3);
@@ -836,9 +836,9 @@ td0_initialize(int drive)
/* Set disk flags so that rotation speed is 2% slower. */ /* Set disk flags so that rotation speed is 2% slower. */
dev->disk_flags |= (3 << 5); dev->disk_flags |= (3 << 5);
size_diff = raw_tsize - track_size; size_diff = raw_tsize - track_size;
if (size_diff < gap_sum) { if ((size_diff < gap_sum) && !fdd_get_turbo(drive)) {
/* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */
td0_log("TD0: Unable to fit the %i sectors in a track\n", track_spt_adjusted); td0_log("TD0: Unable to fit the %i sectors into drive %i, track %i, side %i\n", track_spt_adjusted, drive, track, head);
return 0; return 0;
} }
} }
@@ -1055,7 +1055,7 @@ td0_seek(int drive, int track)
int ordered_pos = 0; int ordered_pos = 0;
int real_sector = 0; int real_sector = 0;
int actual_sector = 0; int actual_sector = 0;
int fm; int fm, sector_adjusted;
if (dev->f == NULL) return; if (dev->f == NULL) return;
@@ -1083,8 +1083,11 @@ td0_seek(int drive, int track)
for (side = 0; side < dev->sides; side++) { for (side = 0; side < dev->sides; side++) {
track_rate = dev->current_side_flags[side] & 7; track_rate = dev->current_side_flags[side] & 7;
/* Make sure 300 kbps @ 360 rpm is treated the same as 250 kbps @ 300 rpm. */
if (!track_rate && (dev->current_side_flags[side] & 0x20)) if (!track_rate && (dev->current_side_flags[side] & 0x20))
track_rate = 4; track_rate = 4;
if ((dev->current_side_flags[side] & 0x27) == 0x21)
track_rate = 2;
track_gap3 = gap3_sizes[track_rate][dev->sects[track][side][0].size][dev->track_spt[track][side]]; track_gap3 = gap3_sizes[track_rate][dev->sects[track][side][0].size][dev->track_spt[track][side]];
if (! track_gap3) if (! track_gap3)
track_gap3 = dev->calculated_gap3_lengths[track][side]; track_gap3 = dev->calculated_gap3_lengths[track][side];
@@ -1096,6 +1099,7 @@ td0_seek(int drive, int track)
interleave_type = track_is_interleave(drive, side, track); interleave_type = track_is_interleave(drive, side, track);
current_pos = d86f_prepare_pretrack(drive, side, 0); current_pos = d86f_prepare_pretrack(drive, side, 0);
sector_adjusted = 0;
if (! xdf_type) { if (! xdf_type) {
for (sector = 0; sector < dev->track_spt[track][side]; sector++) { for (sector = 0; sector < dev->track_spt[track][side]; sector++) {
@@ -1112,14 +1116,17 @@ td0_seek(int drive, int track)
id[2] = real_sector; id[2] = real_sector;
id[3] = dev->sects[track][side][actual_sector].size; id[3] = dev->sects[track][side][actual_sector].size;
fm = dev->sects[track][side][actual_sector].fm; fm = dev->sects[track][side][actual_sector].fm;
if (((dev->sects[track][side][actual_sector].flags & 0x02) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive)) if (((dev->sects[track][side][actual_sector].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive))
ssize = 3; ssize = 3;
else else
ssize = 128 << ((uint32_t) id[3]); ssize = 128 << ((uint32_t) id[3]);
current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, dev->sects[track][side][actual_sector].flags); current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, dev->sects[track][side][actual_sector].flags);
if (sector == 0) if (sector_adjusted == 0)
d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]);
if (!(dev->sects[track][side][actual_sector].flags & 0x40))
sector_adjusted++;
} }
} else { } else {
xdf_type--; xdf_type--;
@@ -1132,7 +1139,7 @@ td0_seek(int drive, int track)
id[3] = is_trackx ? (id[2] & 7) : 2; id[3] = is_trackx ? (id[2] & 7) : 2;
ordered_pos = dev->xdf_ordered_pos[id[2]][side]; ordered_pos = dev->xdf_ordered_pos[id[2]][side];
fm = dev->sects[track][side][ordered_pos].fm; fm = dev->sects[track][side][ordered_pos].fm;
if (((dev->sects[track][side][ordered_pos].flags & 0x02) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive)) if (((dev->sects[track][side][ordered_pos].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive))
ssize = 3; ssize = 3;
else else
ssize = 128 << ((uint32_t) id[3]); ssize = 128 << ((uint32_t) id[3]);
@@ -1141,8 +1148,11 @@ td0_seek(int drive, int track)
else else
current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].flags); current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].flags);
if (sector == 0) if (sector_adjusted == 0)
d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]);
if (!(dev->sects[track][side][ordered_pos].flags & 0x40))
sector_adjusted++;
} }
} }
} }