Added support for version 1.10 of the .86F format;

Floppy drive head now set to 0 on drive eject/load;
FDC result phase now returns head from HDSEL.
This commit is contained in:
OBattler
2016-09-05 21:58:28 +02:00
parent 0b1c2c3a6a
commit 23325e16a1
3 changed files with 174 additions and 53 deletions

View File

@@ -106,6 +106,7 @@ void disc_load(int drive, char *fn)
loaders[c].load(drive, fn);
drive_empty[drive] = 0;
strcpy(discfns[drive], fn);
fdd_set_head(drive ^ fdd_swap, 0);
fdd_seek(drive ^ fdd_swap, 0);
disc_changed[drive] = 1;
return;
@@ -114,6 +115,7 @@ void disc_load(int drive, char *fn)
}
pclog("Couldn't load %s %s\n",fn,p);
drive_empty[drive] = 1;
fdd_set_head(drive ^ fdd_swap, 0);
discfns[drive][0] = 0;
}
@@ -122,6 +124,7 @@ void disc_close(int drive)
// pclog("disc_close %i\n", drive);
if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive);
drive_empty[drive] = 1;
fdd_set_head(drive ^ fdd_swap, 0);
discfns[drive][0] = 0;
drives[drive].hole = NULL;
drives[drive].poll = NULL;

View File

@@ -63,8 +63,8 @@ static struct
{
FILE *f;
uint8_t disk_flags;
uint8_t track_data[2][25000];
uint8_t track_layout[2][25000];
uint8_t track_data[2][50000];
uint8_t track_layout[2][50000];
uint8_t track_flags;
uint8_t track_in_file;
uint32_t track_offset[256];
@@ -140,6 +140,63 @@ void d86f_init()
d86f_setupcrc(0x1021, 0xcdb4);
}
int d86f_get_sides(int drive)
{
return (d86f[drive].disk_flags & 8) ? 2 : 1;
}
int d86f_get_side_size(int drive)
{
int pos = 25002;
switch (d86f_hole(drive))
{
case 0:
pos = 15001;
break;
case 1:
pos = 25001;
break;
case 2:
pos = 100001;
break;
}
}
int d86f_get_array_size(int drive)
{
int pos = 25002;
switch (d86f_hole(drive))
{
case 0:
pos = 7500;
break;
case 1:
pos = 12500;
break;
case 2:
pos = 50000;
break;
}
}
int d86f_valid_bit_rate(int drive)
{
int rate = fdc_get_bit_rate();
switch (d86f_hole(drive))
{
case 0: /* DD */
if ((rate < 1) || (rate > 2)) return 0;
return 1;
case 1: /* HD */
if (rate != 0) return 0;
return 1;
case 2: /* ED */
if (rate < 3) return 0;
return 1;
}
return 1;
}
void d86f_load(int drive, char *fn)
{
uint32_t magic = 0;
@@ -183,13 +240,17 @@ void d86f_load(int drive, char *fn)
fread(&version, 2, 1, d86f[drive].f);
if (version != 0x0100)
if ((version != 0x0100) && (version != 0x010A))
{
/* File is not of a recognized format version abort. */
pclog("86F: Unrecognized file version: %04X\n", version);
pclog("86F: Unrecognized file version: %i.%02i\n", version >> 8, version & 0xFF);
fclose(d86f[drive].f);
return;
}
else
{
pclog("86F: Recognized file version: %i.%02i\n", version >> 8, version & 0xFF);
}
fread(&(d86f[drive].disk_flags), 1, 1, d86f[drive].f);
@@ -218,8 +279,17 @@ void d86f_load(int drive, char *fn)
}
/* Load track 0 flags as default. */
if (d86f[drive].version == 0x010A)
{
fseek(d86f[drive].f, d86f[drive].track_offset[0], SEEK_SET);
fread(&(d86f[drive].side_flags[0]), 1, 1, d86f[drive].f);
fread(&(d86f[drive].side_flags[1]), 1, 1, d86f[drive].f);
}
else
{
fseek(d86f[drive].f, d86f[drive].track_offset[0], SEEK_SET);
fread(&(d86f[drive].track_flags), 1, 1, d86f[drive].f);
}
fseek(d86f[drive].f, 0, SEEK_END);
d86f[drive].file_size = ftell(d86f[drive].f);
@@ -243,9 +313,22 @@ int d86f_hole(int drive)
return (d86f[drive].disk_flags >> 1) & 3;
}
uint8_t d86f_flags(int drive)
{
int side = fdd_get_head(drive);
if (d86f[drive].version == 0x010A)
{
return d86f[drive].side_flags[side];
}
else
{
return d86f[drive].track_flags;
}
}
uint8_t d86f_track_flags(int drive)
{
uint8_t tf = d86f[drive].track_flags;
uint8_t tf = d86f_flags(drive);
uint8_t rr = tf & 0x27;
uint8_t dr = fdd_get_flags(drive) & 7;
tf &= ~0x27;
@@ -306,14 +389,9 @@ void d86f_close(int drive)
d86f[drive].f = NULL;
}
int d86f_get_sides(int drive)
{
return (d86f[drive].disk_flags & 8) ? 2 : 1;
}
int d86f_is_mfm(int drive)
{
return (d86f[drive].track_flags & 8) ? 1 : 0;
return (d86f_track_flags(drive) & 8) ? 1 : 0;
}
uint16_t d86f_get_raw_size(int drive)
@@ -350,14 +428,23 @@ void d86f_seek(int drive, int track)
{
int sides = d86f_get_sides(drive);
int side;
int full_size = 25000;
int store_size = 50000;
int flag_bytes = 2;
if (d86f[drive].version == 0x010A)
{
full_size = d86f_get_array_size(drive);
store_size = full_size << 1;
flag_bytes++;
}
if (d86f_is_40_track(drive) && fdd_doublestep_40(drive))
track /= 2;
for (side = 0; side < d86f_get_sides(drive); side++)
{
memset(d86f[drive].track_layout[side], BYTE_GAP4, 25000);
memset(d86f[drive].track_data[side], 0xFF, 25000);
memset(d86f[drive].track_layout[side], BYTE_GAP4, full_size);
memset(d86f[drive].track_data[side], 0xFF, full_size);
}
d86f[drive].cur_track = track;
@@ -366,7 +453,15 @@ 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].side_flags[0] = 0x0A; /* 300 rpm, MFM, 250 kbps */
d86f[drive].side_flags[1] = 0x0A; /* 300 rpm, MFM, 250 kbps */
}
else
{
d86f[drive].track_flags = 0x0A; /* 300 rpm, MFM, 250 kbps */
}
return;
}
@@ -374,13 +469,21 @@ void d86f_seek(int drive, int track)
fseek(d86f[drive].f, d86f[drive].track_offset[track], SEEK_SET);
if (d86f[drive].version == 0x010A)
{
fread(&(d86f[drive].side_flags[0]), 1, 1, d86f[drive].f);
fread(&(d86f[drive].side_flags[1]), 1, 1, d86f[drive].f);
}
else
{
fread(&(d86f[drive].track_flags), 1, 1, d86f[drive].f);
}
for (side = 0; side < d86f_get_sides(drive); side++)
{
fseek(d86f[drive].f, d86f[drive].track_offset[track] + (side * 50000) + 2, SEEK_SET);
fseek(d86f[drive].f, d86f[drive].track_offset[track] + (side * store_size) + flag_bytes, SEEK_SET);
fread(d86f[drive].track_layout[side], 1, d86f_get_raw_size(drive), d86f[drive].f);
fseek(d86f[drive].f, d86f[drive].track_offset[track] + (side * 50000) + 25002, SEEK_SET);
fseek(d86f[drive].f, d86f[drive].track_offset[track] + (side * store_size) + full_size + flag_bytes, SEEK_SET);
fread(d86f[drive].track_data[side], 1, d86f_get_raw_size(drive), d86f[drive].f);
}
}
@@ -389,6 +492,15 @@ void d86f_writeback(int drive)
{
int track = d86f[drive].cur_track;
int side;
int full_size = 25000;
int store_size = 50000;
int flag_bytes = 2;
if (d86f[drive].version == 0x010A)
{
full_size = d86f_get_array_size(drive);
store_size = full_size << 1;
flag_bytes++;
}
if (!d86f[drive].f)
return;
@@ -400,13 +512,21 @@ void d86f_writeback(int drive)
fwrite(d86f[drive].track_offset, 1, 1024, d86f[drive].f);
fseek(d86f[drive].f, d86f[drive].track_offset[track], SEEK_SET);
if (d86f[drive].version == 0x010A)
{
fwrite(&(d86f[drive].side_flags[0]), 1, 1, d86f[drive].f);
fwrite(&(d86f[drive].side_flags[1]), 1, 1, d86f[drive].f);
}
else
{
fwrite(&(d86f[drive].track_flags), 1, 1, d86f[drive].f);
}
for (side = 0; side < d86f_get_sides(drive); side++)
{
fseek(d86f[drive].f, d86f[drive].track_offset[track] + (side * 50000) + 2, SEEK_SET);
fseek(d86f[drive].f, d86f[drive].track_offset[track] + (side * store_size) + flag_bytes, SEEK_SET);
fwrite(d86f[drive].track_layout[side], 1, d86f_get_raw_size(drive), d86f[drive].f);
fseek(d86f[drive].f, d86f[drive].track_offset[track] + (side * 50000) + 25002, SEEK_SET);
fseek(d86f[drive].f, d86f[drive].track_offset[track] + (side * store_size) + full_size + flag_bytes, SEEK_SET);
fwrite(d86f[drive].track_data[side], 1, d86f_get_raw_size(drive), d86f[drive].f);
}
@@ -589,6 +709,16 @@ void d86f_prepare_track_layout(int drive, int side)
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)
{
full_size = d86f_get_array_size(drive);
store_size = full_size << 1;
flag_bytes++;
}
d86f[drive].req_sector.id.c = d86f[drive].cur_track;
d86f[drive].req_sector.id.h = side;
@@ -616,17 +746,21 @@ 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;
memset(d86f[drive].track_data[side], 0xFF, 25000);
if (d86f[drive].version == 0x010A)
{
d86f[drive].side_flags[side] = d86f[drive].track_flags;
}
memset(d86f[drive].track_data[side], 0xFF, full_size);
d86f_prepare_track_layout(drive, side);
if (!d86f[drive].track_in_file)
{
/* Track is absent from the file, let's add it. */
d86f[drive].track_offset[d86f[drive].cur_track] = d86f[drive].file_size;
d86f[drive].file_size += 50002;
d86f[drive].file_size += store_size + flag_bytes;
if (d86f_get_sides(drive) == 2)
{
d86f[drive].file_size += 50000;
d86f[drive].file_size += store_size;
}
d86f[drive].track_in_file = 1;
}
@@ -679,24 +813,6 @@ int d86f_can_read_address(int drive)
return temp;
}
int d86f_valid_bit_rate(int drive)
{
int rate = fdc_get_bit_rate();
switch (d86f_hole(drive))
{
case 0: /* DD */
if ((rate < 1) || (rate > 2)) return 0;
return 1;
case 1: /* HD */
if (rate != 0) return 0;
return 1;
case 2: /* ED */
if (rate < 3) return 0;
return 1;
}
return 1;
}
int d86f_can_format(int drive)
{
int temp;

View File

@@ -978,7 +978,7 @@ void fdc_callback()
discint=-2;
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
@@ -1015,6 +1015,7 @@ void fdc_callback()
if (fdc.command & 0x80)
{
fdc.head ^= 1;
fdd_set_head(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap) ^ 1);
if (!fdc.head)
{
fdc.rw_track++;
@@ -1038,7 +1039,7 @@ void fdc_callback()
discint=-2;
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
@@ -1060,6 +1061,7 @@ void fdc_callback()
if (fdc.command & 0x80)
{
fdc.head ^= 1;
fdd_set_head(fdc.drive, fdd_get_head(fdc.drive ^ fdd_swap) ^ 1);
if (!fdc.head)
{
fdc.rw_track++;
@@ -1084,7 +1086,7 @@ void fdc_callback()
discint=-2;
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
@@ -1152,7 +1154,7 @@ void fdc_callback()
discint=-2;
fdc_int();
fdc.stat=0xD0;
fdc.res[4] = (fdc.head?4:0)|fdc.drive;
fdc.res[4] = (fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5] = fdc.res[6] = 0;
fdc.res[7] = fdc.track[fdc.drive];
fdc.res[8] = fdc.head;
@@ -1267,7 +1269,7 @@ void fdc_overrun()
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
fdc.res[4]=0x40|(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=0x10; /*Overrun*/
fdc.res[6]=0;
fdc.res[7]=0;
@@ -1354,7 +1356,7 @@ void fdc_notfound()
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
fdc.res[4]=0x40|(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=5;
fdc.res[6]=0;
fdc.res[7]=0;
@@ -1371,7 +1373,7 @@ void fdc_datacrcerror()
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
fdc.res[4]=0x40|(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=0x20; /*Data error*/
fdc.res[6]=0x20; /*Data error in data field*/
fdc.res[7]=0;
@@ -1388,7 +1390,7 @@ void fdc_headercrcerror()
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
fdc.res[4]=0x40|(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=0x20; /*Data error*/
fdc.res[6]=0;
fdc.res[7]=0;
@@ -1405,7 +1407,7 @@ void fdc_writeprotect()
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
fdc.res[4]=0x40|(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=0x02; /*Not writeable*/
fdc.res[6]=0;
fdc.res[7]=0;
@@ -1472,7 +1474,7 @@ void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uin
// pclog("SectorID %i %i %i %i\n", track, side, sector, size);
fdc_int();
fdc.stat=0xD0;
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=0;
fdc.res[6]=0;
fdc.res[7]=track;