Added support for 86F version 1.32 images;

Forced reseek on disk change is now its own function and is always performed, fixes disk changes on some machines.
This commit is contained in:
OBattler
2016-09-26 20:43:09 +02:00
parent 74aa7e486d
commit 50f65e1ec0
4 changed files with 321 additions and 68 deletions

View File

@@ -107,7 +107,7 @@ void disc_load(int drive, char *fn)
drive_empty[drive] = 0;
strcpy(discfns[drive], fn);
fdd_set_head(drive ^ fdd_swap, 0);
fdd_seek(drive ^ fdd_swap, 0);
fdd_forced_seek(drive ^ fdd_swap, 0);
disc_changed[drive] = 1;
return;
}

View File

@@ -59,11 +59,11 @@ static struct
{
FILE *f;
uint16_t version;
uint8_t disk_flags;
uint16_t disk_flags;
uint8_t track_data[2][50000];
uint8_t track_layout[2][50000];
uint8_t track_flags;
uint8_t side_flags[2];
uint16_t side_flags[2];
uint16_t index_hole_pos[2];
uint8_t track_in_file;
uint32_t track_offset[256];
@@ -83,6 +83,7 @@ static struct
crc_t track_crc;
uint8_t track_byte;
uint8_t track_index;
uint8_t track_is_hole;
uint8_t track_fuzzy;
uint8_t track_data_byte;
uint8_t old_track_byte;
@@ -98,6 +99,67 @@ static struct
uint8_t data_am_counter;
} d86f[2];
uint8_t encoded_fm[64] = { 0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF,
0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF,
0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF,
0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF };
uint8_t encoded_mfm[64] = { 0xAA, 0xA9, 0xA4, 0xA5, 0x92, 0x91, 0x94, 0x95, 0x4A, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55,
0x2A, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15, 0x4A, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55,
0xAA, 0xA9, 0xA4, 0xA5, 0x92, 0x91, 0x94, 0x95, 0x4A, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55,
0x2A, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15, 0x4A, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55 };
typedef union {
uint16_t word;
uint8_t bytes[2];
} encoded_t;
typedef struct {
unsigned nibble0 :4;
unsigned nibble1 :4;
} split_byte_t;
typedef struct {
unsigned area0 :2;
unsigned area1 :6;
} preceding_byte_t;
typedef union {
uint8_t byte;
split_byte_t nibbles;
preceding_byte_t p;
} decoded_t;
static uint16_t d86f_encode_get_data(uint8_t dat)
{
uint16_t temp;
temp = 0;
if (dat & 0x01) temp |= 1;
if (dat & 0x02) temp |= 4;
if (dat & 0x04) temp |= 16;
if (dat & 0x08) temp |= 64;
if (dat & 0x10) temp |= 256;
if (dat & 0x20) temp |= 1024;
if (dat & 0x40) temp |= 4096;
if (dat & 0x80) temp |= 16384;
return temp;
}
static uint16_t d86f_encode_get_clock(uint8_t dat)
{
uint16_t temp;
temp = 0;
if (dat & 0x01) temp |= 2;
if (dat & 0x02) temp |= 8;
if (dat & 0x04) temp |= 32;
if (dat & 0x08) temp |= 128;
if (dat & 0x10) temp |= 512;
if (dat & 0x20) temp |= 2048;
if (dat & 0x40) temp |= 8192;
if (dat & 0x80) temp |= 32768;
return temp;
}
uint8_t* d86f_track_data(int drive, int side)
{
return d86f[drive].track_data[side];
@@ -250,7 +312,7 @@ int d86f_get_sides(int drive)
int d86f_get_rpm_mode(int drive)
{
if (d86f[drive].version != 0x0115) return 0;
if ((d86f[drive].version != 0x0115) && (d86f[drive].version != 0x0132)) return 0;
return (d86f_handler[drive].disk_flags(drive) & 0x60) >> 5;
}
@@ -264,7 +326,7 @@ int d86f_get_array_size(int drive)
case 0:
default:
pos = 7500;
if (d86f[drive].version != 0x0115) return pos;
if ((d86f[drive].version != 0x0115) && (d86f[drive].version != 0x0132)) return pos;
switch (rm)
{
case 1:
@@ -283,7 +345,7 @@ int d86f_get_array_size(int drive)
break;
case 1:
pos = 12500;
if (d86f[drive].version != 0x0115) return pos;
if ((d86f[drive].version != 0x0115) && (d86f[drive].version != 0x0132)) return pos;
switch (rm)
{
case 1:
@@ -302,7 +364,7 @@ int d86f_get_array_size(int drive)
break;
case 2:
pos = 50000;
if (d86f[drive].version != 0x0115) return pos;
if ((d86f[drive].version != 0x0115) && (d86f[drive].version != 0x0132)) return pos;
switch (rm)
{
case 1:
@@ -405,7 +467,7 @@ void d86f_load(int drive, char *fn)
fread(&(d86f[drive].version), 2, 1, d86f[drive].f);
if ((d86f[drive].version != 0x0100) && (d86f[drive].version != 0x010A) && (d86f[drive].version != 0x0114) && (d86f[drive].version != 0x0115))
if ((d86f[drive].version != 0x0100) && (d86f[drive].version != 0x010A) && (d86f[drive].version != 0x0114) && (d86f[drive].version != 0x0115) && (d86f[drive].version != 0x0132))
{
/* File is not of a recognized format version abort. */
pclog("86F: Unrecognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF);
@@ -417,7 +479,15 @@ void d86f_load(int drive, char *fn)
pclog("86F: Recognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF);
}
fread(&(d86f[drive].disk_flags), 1, 1, d86f[drive].f);
if (d86f[drive].version < 0x0132)
{
d86f[drive].disk_flags = 0;
fread(&(d86f[drive].disk_flags), 1, 1, d86f[drive].f);
}
else
{
fread(&(d86f[drive].disk_flags), 2, 1, d86f[drive].f);
}
if (((d86f[drive].disk_flags >> 1) & 3) == 3)
{
@@ -427,6 +497,14 @@ void d86f_load(int drive, char *fn)
return;
}
if (d86f[drive].disk_flags & 0x100)
{
/* Zoned disk. */
pclog("86F: Disk is zoned (Apple or Sony)\n");
fclose(d86f[drive].f);
return;
}
if (!writeprot[drive])
{
writeprot[drive] = (d86f[drive].disk_flags & 0x10) ? 1 : 0;
@@ -445,7 +523,7 @@ void d86f_load(int drive, char *fn)
/* Load track 0 flags as default. */
d86f[drive].side_flag_bytes = d86f_get_sides(drive);
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
if ((d86f[drive].version == 0x010A) && (d86f_get_sides(drive) == 1))
{
@@ -455,10 +533,11 @@ void d86f_load(int drive, char *fn)
if (temp & 0x80) d86f[drive].side_flag_bytes = 2;
}
fseek(d86f[drive].f, d86f[drive].track_offset[0], SEEK_SET);
fread(&(d86f[drive].side_flags[0]), 1, 1, d86f[drive].f);
d86f[drive].side_flags[0] = d86f[drive].side_flags[1] = 0;
fread(&(d86f[drive].side_flags[0]), (d86f[drive].version == 0x0132) ? 2 : 1, 1, d86f[drive].f);
if (d86f_get_sides(drive) == 2)
{
fread(&(d86f[drive].side_flags[1]), 1, 1, d86f[drive].f);
fread(&(d86f[drive].side_flags[1]), (d86f[drive].version == 0x0132) ? 2 : 1, 1, d86f[drive].f);
}
}
else
@@ -483,11 +562,16 @@ int d86f_hole(int drive)
return (d86f_handler[drive].disk_flags(drive) >> 1) & 3;
}
uint8_t d86f_side_flags(int drive)
int d86f_is_encoded(int drive)
{
return (d86f_handler[drive].disk_flags(drive) >> 7) & 1;
}
uint16_t d86f_side_flags(int drive)
{
int side = 0;
side = fdd_get_head(drive);
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
return d86f[drive].side_flags[side];
}
@@ -497,16 +581,16 @@ uint8_t d86f_side_flags(int drive)
}
}
uint8_t d86f_track_flags(int drive)
uint16_t d86f_track_flags(int drive)
{
uint8_t tf = 0;
uint8_t rr = 0;
uint8_t dr = 0;
uint16_t tf = 0;
uint16_t rr = 0;
uint16_t dr = 0;
tf = d86f_handler[drive].side_flags(drive);
rr = tf & 0x27;
rr = tf & 0x67;
dr = fdd_get_flags(drive) & 7;
tf &= ~0x27;
tf &= ~0x67;
switch (rr)
{
@@ -578,10 +662,10 @@ uint16_t d86f_get_raw_size(int drive)
double size = 6250.0;
mfm = d86f_is_mfm(drive);
rpm = (d86f_track_flags(drive) & 0x20) ? 360.0 : 300.0;
rpm = ((d86f_track_flags(drive) & 0xE0) == 0x20) ? 360.0 : 300.0;
rpm_diff = rpm * 0.005;
if (d86f[drive].version == 0x0115)
if ((d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
switch (d86f_get_rpm_mode(drive))
{
@@ -635,12 +719,20 @@ void d86f_seek(int drive, int track)
int store_size = 50000;
int flag_bytes = 2;
sides = d86f_get_sides(drive);
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
full_size = d86f_get_array_size(drive);
store_size = full_size << 1;
if (d86f[drive].side_flag_bytes == 2) flag_bytes++;
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115)) flag_bytes += 4;
if (d86f[drive].version == 0x0132)
{
flag_bytes++;
if (d86f[drive].side_flag_bytes == 2) flag_bytes += 2;
}
else
{
if (d86f[drive].side_flag_bytes == 2) flag_bytes++;
}
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132)) flag_bytes += 4;
}
if (d86f_is_40_track(drive) && fdd_doublestep_40(drive))
@@ -648,7 +740,7 @@ void d86f_seek(int drive, int track)
for (side = 0; side < d86f_get_sides(drive); side++)
{
memset(d86f[drive].track_layout[side], BYTE_GAP4, 50000);
memset(d86f[drive].track_layout[side], (d86f[drive].version == 0x0132) ? BYTE_GAP0 : BYTE_GAP4, 50000);
memset(d86f[drive].track_data[side], 0xFF, 50000);
}
@@ -658,7 +750,7 @@ void d86f_seek(int drive, int track)
{
/* Track does not exist in the image, initialize it as unformatted. */
d86f[drive].track_in_file = 0;
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
for (side = 0; side < d86f_get_sides(drive); side++)
{
@@ -676,14 +768,14 @@ void d86f_seek(int drive, int track)
fseek(d86f[drive].f, d86f[drive].track_offset[track], SEEK_SET);
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
for (side = 0; side < d86f[drive].side_flag_bytes; side++)
{
fread(&(d86f[drive].side_flags[side]), 1, 1, d86f[drive].f);
fread(&(d86f[drive].side_flags[side]), (d86f[drive].version == 0x0132) ? 2 : 1, 1, d86f[drive].f);
}
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
for (side = 0; side < d86f[drive].side_flag_bytes; side++)
{
@@ -713,12 +805,20 @@ void d86f_writeback(int drive)
int full_size = 25000;
int store_size = 50000;
int flag_bytes = 2;
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
full_size = d86f_get_array_size(drive);
store_size = full_size << 1;
if (d86f[drive].side_flag_bytes == 2) flag_bytes++;
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115)) flag_bytes += 4;
if (d86f[drive].version == 0x0132)
{
flag_bytes++;
if (d86f[drive].side_flag_bytes == 2) flag_bytes += 2;
}
else
{
if (d86f[drive].side_flag_bytes == 2) flag_bytes++;
}
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132)) flag_bytes += 4;
}
if (!d86f[drive].f)
@@ -736,14 +836,14 @@ void d86f_writeback(int drive)
fseek(d86f[drive].f, d86f[drive].track_offset[track], SEEK_SET);
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
for (side = 0; side < d86f[drive].side_flag_bytes; side++)
{
fwrite(&(d86f[drive].side_flags[side]), 1, 1, d86f[drive].f);
fwrite(&(d86f[drive].side_flags[side]), (d86f[drive].version == 0x0132) ? 2 : 1, 1, d86f[drive].f);
}
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
for (side = 0; side < d86f[drive].side_flag_bytes; side++)
{
@@ -788,7 +888,7 @@ static int d86f_get_bitcell_period(int drive)
tflags = d86f_track_flags(drive);
mfm = (tflags & 8) ? 1 : 0;
rpm = (tflags & 0x20) ? 360.0 : 300.0;
rpm = ((tflags & 0xE0) == 0x20) ? 360.0 : 300.0;
switch (tflags & 7)
{
@@ -817,7 +917,7 @@ static int d86f_get_bitcell_period(int drive)
void d86f_readsector(int drive, int sector, int track, int side, int rate, int sector_size)
{
// pclog("d86f_readsector: fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, sector, track, side);
pclog("d86f_readsector: fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, sector, track, side);
d86f[drive].req_sector.id.c = track;
d86f[drive].req_sector.id.h = side;
@@ -919,7 +1019,7 @@ uint16_t d86f_prepare_pretrack(int drive, int side, int iso, int write_data)
d86f[drive].index_hole_pos[side] = 0;
memset(d86f[drive].track_layout[side], BYTE_GAP4, d86f_get_raw_size(drive));
memset(d86f[drive].track_layout[side], (d86f[drive].version == 0x0132) ? BYTE_GAP0 : BYTE_GAP4, d86f_get_raw_size(drive));
if (write_data) memset(d86f[drive].track_data[side], mfm ? 0x4E : 0xFF, d86f_get_raw_size(drive));
i = 0;
@@ -1179,12 +1279,20 @@ void d86f_format(int drive, int track, int side, int rate, uint8_t fill)
int full_size = 25000;
int store_size = 50000;
int flag_bytes = 2;
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
full_size = d86f_get_array_size(drive);
store_size = full_size << 1;
if (d86f[drive].side_flag_bytes == 2) flag_bytes++;
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115)) flag_bytes += 4;
if (d86f[drive].version == 0x0132)
{
flag_bytes++;
if (d86f[drive].side_flag_bytes == 2) flag_bytes += 2;
}
else
{
if (d86f[drive].side_flag_bytes == 2) flag_bytes++;
}
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132)) flag_bytes += 4;
}
d86f[drive].req_sector.id.c = d86f[drive].cur_track;
@@ -1226,11 +1334,11 @@ void d86f_format(int drive, int track, int side, int rate, uint8_t fill)
d86f[drive].track_flags |= (fdd_getrpm(drive ^ fdd_swap) == 360) ? 0x20 : 0;
d86f[drive].track_flags |= fdc_get_bit_rate();
d86f[drive].track_flags |= fdc_is_mfm() ? 8 : 0;
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x010A) || (d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
d86f[drive].side_flags[side] = d86f[drive].track_flags;
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
d86f[drive].index_hole_pos[side] = 0;
}
@@ -1295,6 +1403,7 @@ int d86f_can_read_address(int drive)
temp = (fdc_get_bitcell_period() == d86f_get_bitcell_period(drive));
temp = temp && fdd_can_read_medium(drive ^ fdd_swap);
temp = temp && (fdc_is_mfm() == d86f_is_mfm(drive));
temp = temp && (d86f_get_encoding(drive) <= 1);
return temp;
}
@@ -1394,11 +1503,120 @@ uint32_t d86f_get_pos(int drive)
return pos;
}
uint8_t d86f_get_encoding(int drive)
{
return (d86f_track_flags(drive) & 0x18) >> 3;
}
uint16_t d86f_encode_byte(uint8_t encoding, int sync, decoded_t b, decoded_t prev_b)
{
uint8_t val0 = b.nibbles.nibble0;
uint8_t val1 = b.nibbles.nibble1;
uint8_t val2 = prev_b.nibbles.nibble0;
uint16_t encoded_0, encoded_1, result;
if (encoding > 1) return 0xFF;
if (sync)
{
result = d86f_encode_get_data(b);
if (encoding)
{
switch(b)
{
case 0xA1: result | d86f_encode_get_clock(0x0A);
case 0xC2: result | d86f_encode_get_clock(0x14);
case 0xF8: result | d86f_encode_get_clock(0x03);
case 0xFB: case 0xFE: return result | d86f_encode_get_clock(0x00);
case 0xFC: return result | d86f_encode_get_clock(0x01);
}
}
else
{
switch(b)
{
case 0xF8: case 0xFB: case 0xFE: return result | d86f_encode_get_clock(0xC7);
case 0xFC: return result | d86f_encode_get_clock(0xD7);
}
}
}
val0 += ((val1 & 3) << 4);
val1 += ((val2 & 3) << 4);
encoded_0 = (encoding == 1) ? encoded_mfm[val0] ? encoded_fm[val0];
encoded_1 = (encoding == 1) ? encoded_mfm[val1] ? encoded_fm[val1];
result = (encoded_1 << 8) | encoded_0;
}
static uint8_t decodefm(int drive, uint16_t dat)
{
uint8_t temp;
if (d86f_get_encoding(drive) > 1)
{
/* 2 means M2FM encoding, and 3 means GCR encoding, neither of which is supported by this emulator. */
return 0xFF;
}
temp = 0;
if (dat & 0x0001) temp |= 1;
if (dat & 0x0004) temp |= 2;
if (dat & 0x0010) temp |= 4;
if (dat & 0x0040) temp |= 8;
if (dat & 0x0100) temp |= 16;
if (dat & 0x0400) temp |= 32;
if (dat & 0x1000) temp |= 64;
if (dat & 0x4000) temp |= 128;
return temp;
}
void d86f_read_byte(int drive, int side)
{
if (d86f[drive].track_is_hole && (d86f[drive].version == 0x0132))
{
return 0;
}
if ((d86f[drive].version < 0x0132) || !d86f_is_encoded(drive))
{
return d86f[drive].track_data[side][d86f[drive].track_pos];
}
else
{
return decodefm(drive, d86f[drive].track_encoded_data[side][d86f[drive].track_pos]);
}
}
void d86f_write_byte(int drive, int side, uint8_t byte)
{
int sync = 0;
d86f[drive].track_data_byte = byte;
if (d86f[drive].track_is_hole && (d86f[drive].version == 0x0132))
{
return;
}
if ((d86f[drive].version < 0x0132) || !d86f_is_encoded(drive))
{
d86f[drive].track_data[side][d86f[drive].track_pos] = byte;
}
else
{
if (d86f[drive].track_byte == BYTE_IAM_SYNC) ||
d86f[drive].track_byte == BYTE_IAM) ||
d86f[drive].track_byte == BYTE_IDAM_SYNC) ||
d86f[drive].track_byte == BYTE_IDAM) ||
d86f[drive].track_byte == BYTE_DATAAM_SYNC) ||
d86f[drive].track_byte == BYTE_DATAAM))
{
sync = 1;
}
d86f[drive].track_encoded_data[side][d86f[drive].track_pos] = d86f_encode_byte(d86f_get_encoding(drive), sync, byte, d86f[drive].old_track_byte);
}
}
void d86f_poll_write_crc(int drive, int side)
{
if (d86f[drive].state != STATE_FORMAT) return;
d86f[drive].id_pos = d86f_get_pos(drive);
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = d86f[drive].calc_crc.bytes[d86f[drive].id_pos ^ 1];
d86f_write_byte(drive, side, d86f[drive].calc_crc.bytes[d86f[drive].id_pos ^ 1]);
}
void d86f_poll_advancebyte(int drive, int side)
@@ -1411,9 +1629,13 @@ void d86f_poll_advancebyte(int drive, int side)
d86f[drive].old_track_index = d86f[drive].track_index;
d86f[drive].old_track_data_byte = d86f[drive].track_data_byte;
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
d86f[drive].old_track_fuzzy = d86f[drive].track_fuzzy;
if (d86f[drive].version == 0x0132)
{
d86f[drive].old_track_is_hole = d86f[drive].track_is_hole;
}
}
d86f[drive].track_pos++;
@@ -1424,11 +1646,21 @@ void d86f_poll_advancebyte(int drive, int side)
d86f[drive].track_byte = d86f[drive].track_layout[side][d86f[drive].track_pos] & ~BYTE_INDEX_HOLE;
d86f[drive].track_index = d86f[drive].track_layout[side][d86f[drive].track_pos] & BYTE_INDEX_HOLE;
d86f[drive].track_data_byte = d86f[drive].track_data[side][d86f[drive].track_pos];
d86f[drive].track_is_hole = 0;
d86f[drive].track_fuzzy = 0;
}
else if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115))
else if ((d86f[drive].version == 0x0114) || (d86f[drive].version == 0x0115) || (d86f[drive].version == 0x0132))
{
d86f[drive].track_byte = d86f[drive].track_layout[side][d86f[drive].track_pos] & ~BYTE_IS_FUZZY;
if (d86f[drive].version == 0x0132)
{
d86f[drive].track_byte = d86f[drive].track_layout[side][d86f[drive].track_pos] & ~0x20;
d86f[drive].track_is_hole = d86f[drive].track_layout[side][d86f[drive].track_pos] & 0x20;
}
else
{
d86f[drive].track_is_hole = 0;
}
d86f[drive].track_index = (d86f[drive].track_pos == d86f[drive].index_hole_pos[side]);
d86f[drive].track_fuzzy = d86f[drive].track_layout[side][d86f[drive].track_pos] & BYTE_IS_FUZZY;
@@ -1438,7 +1670,7 @@ void d86f_poll_advancebyte(int drive, int side)
}
else
{
d86f[drive].track_data_byte = d86f[drive].track_data[side][d86f[drive].track_pos];
d86f[drive].track_data_byte = d86f_read_byte(drive, side);
}
}
else if (d86f[drive].version == 0x0063)
@@ -1446,6 +1678,7 @@ void d86f_poll_advancebyte(int drive, int side)
d86f[drive].track_byte = d86f[drive].track_layout[side][d86f[drive].track_pos] & ~BYTE_INDEX_HOLE;
d86f[drive].track_index = (d86f[drive].track_pos == 0);
d86f[drive].track_data_byte = d86f[drive].track_data[side][d86f[drive].track_pos];
d86f[drive].track_is_hole = 0;
d86f[drive].track_fuzzy = 0;
}
}
@@ -1487,9 +1720,9 @@ int d86f_mark_index_hole(int drive)
void d86f_poll_write(int drive, int side, uint8_t data, uint8_t type)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = data;
d86f[drive].track_layout[side][d86f[drive].track_pos] = type;
if (!d86f[drive].track_pos && d86f_mark_index_hole(drive)) d86f[drive].track_layout[side][d86f[drive].track_pos] |= BYTE_INDEX_HOLE;
d86f_write_byte(drive, side, data);
}
void d86f_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n)
@@ -1544,7 +1777,6 @@ void d86f_poll_readwrite(int drive, int side)
{
d86f_handler[drive].write_data(drive, side, d86f[drive].datac, data);
}
// d86f_calccrc(drive, d86f[drive].track_data_byte);
d86f_calccrc(drive, data & 0xff);
}
else if (d86f_read_state_crc(drive))
@@ -1562,42 +1794,44 @@ void d86f_poll_readwrite(int drive, int side)
}
else if (d86f_read_state_gap3(drive))
{
max_len = fdc_get_gap();
if (d86f[drive].datac == (fdc_get_gap() - 1))
{
max_len = 1;
// max_len = fdc_get_gap();
// if (d86f[drive].datac == (fdc_get_gap() - 1))
// {
d86f_poll_reset(drive, side);
if ((d86f[drive].track_crc.word != d86f[drive].calc_crc.word) && d86f_handler[drive].check_crc)
{
// pclog("d86f_poll(): Data CRC error (%i %i %i %i) (%04X %04X)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n, d86f[drive].track_crc.word, d86f[drive].calc_crc.word);
pclog("d86f_poll(): Data CRC error (%i %i %i %i) (%04X %04X)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n, d86f[drive].track_crc.word, d86f[drive].calc_crc.word);
fdc_finishread();
fdc_datacrcerror();
}
else
{
// pclog("Read finished (%i %i %i %i)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n);
pclog("Read finished (%i %i %i %i)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n);
fdc_sector_finishread();
}
return;
}
// }
}
else if (d86f[drive].state == STATE_WRITE_SECTOR_GAP3)
{
max_len = fdc_get_gap();
// max_len = fdc_get_gap();
max_len = 1;
if (!disable_write && !d86f[drive].datac)
{
d86f_poll_write(drive, side, fdc_is_mfm() ? 0x4E : 0xFF, BYTE_GAP3);
}
if (d86f[drive].datac == (max_len - 1))
{
// if (d86f[drive].datac == (max_len - 1))
// {
if (!disable_write)
{
d86f_handler[drive].writeback(drive);
}
d86f_poll_reset(drive, side);
// pclog("Write finished (%i %i %i %i)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n);
pclog("Write finished (%i %i %i %i)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n);
fdc_sector_finishread(drive);
return;
}
// }
}
d86f[drive].datac++;
@@ -1838,19 +2072,19 @@ void d86f_poll_format(int drive, int side)
case BYTE_GAP4:
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = fdc_is_mfm() ? 0x4E : 0xFF;
d86f_write_byte(drive, side, fdc_is_mfm() ? 0x4E : 0xFF);
}
break;
case BYTE_IAM_SYNC:
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = 0xC2;
d86f_write_byte(drive, side, 0xC2);
}
break;
case BYTE_IAM:
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = 0xFC;
d86f_write_byte(drive, side, 0xFC);
}
break;
case BYTE_ID_SYNC:
@@ -1883,14 +2117,14 @@ void d86f_poll_format(int drive, int side)
case BYTE_DATA_SYNC:
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = 0;
d86f_write_byte(drive, side, 0);
}
break;
case BYTE_IDAM_SYNC:
case BYTE_DATAAM_SYNC:
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = 0xA1;
d86f_write_byte(drive, side, 0xA1);
}
if (d86f_is_mfm(drive))
{
@@ -1903,7 +2137,7 @@ void d86f_poll_format(int drive, int side)
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = (d86f[drive].track_byte == BYTE_IDAM) ? 0xFE : 0xFB;
d86f_write_byte(drive, side, (d86f[drive].track_byte == BYTE_IDAM) ? 0xFE : 0xFB); d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = (d86f[drive].track_byte == BYTE_IDAM) ? 0xFE : 0xFB;
}
d86f_calccrc(drive, d86f[drive].track_data_byte);
break;
@@ -1913,7 +2147,7 @@ void d86f_poll_format(int drive, int side)
{
if (!disable_write)
{
d86f[drive].track_data[side][d86f[drive].track_pos] = d86f[drive].track_data_byte = d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos];
d86f_write_byte(drive, side, d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos]);
}
}
else

View File

@@ -81,6 +81,24 @@ static struct
int fdd_swap = 0;
void fdd_forced_seek(int drive, int track_diff)
{
drive ^= fdd_swap;
fdd[drive].track += track_diff;
// pclog("Seeking %i tracks...\n", track_diff);
if (fdd[drive].track < 0)
fdd[drive].track = 0;
if (fdd[drive].track > drive_types[fdd[drive].type].max_track)
fdd[drive].track = drive_types[fdd[drive].type].max_track;
disc_seek(drive, fdd[drive].track);
disctime = 5000;
}
void fdd_seek(int drive, int track_diff)
{
drive ^= fdd_swap;

View File

@@ -2,6 +2,7 @@
see COPYING for more details
*/
#define SEEK_RECALIBRATE -999
void fdd_forced_seek(int drive, int track_diff);
void fdd_seek(int drive, int track_diff);
int fdd_track0(int drive);
int fdd_getrpm(int drive);