86F format handler updated to 86F version 2.0 and bit by bit handling;

FDI stream images are now also handled by the 86F handler;
Both floppy drives' motors now spin separately;
Added Plantronics ColorPlus emulation per patch from PCem forum;
Applied all mainline PCem commits;
Fixed several bugs.
This commit is contained in:
OBattler
2016-11-02 22:39:07 +01:00
parent 9a4e044d91
commit e280faa2d6
87 changed files with 16087 additions and 5675 deletions

View File

@@ -8,6 +8,7 @@
#include "disc_img.h"
#include "disc_fdi.h"
#include "fdc.h"
#include "fdd.h"
#include "fdi2raw.h"
static struct
@@ -15,79 +16,101 @@ static struct
FILE *f;
FDI *h;
uint8_t track_data[2][4][256*1024];
uint8_t track_timing[2][4][256*1024];
int sides;
int track;
int tracklen[2][4];
int trackindex[2][4];
int lasttrack;
} fdi[2];
static uint8_t fdi_timing[256*1024];
static int fdi_pos;
static int fdi_revs;
static int fdi_sector, fdi_track, fdi_side, fdi_drive, fdi_density, fdi_n;
static int fdi_inread, fdi_inwrite, fdi_incompare,fdi_readpos, fdi_inreadaddr;
static int fdi_satisfying_bytes;
static uint16_t CRCTable[256];
static int pollbytesleft=0,pollbitsleft=0,polltotalbytes=0;
int fdi_realtrack(int drive, int track)
uint16_t fdi_disk_flags(int drive)
{
return track;
}
uint16_t temp_disk_flags = 0x80; /* We ALWAYS claim to have extra bit cells, even if the actual amount is 0. */
static void fdi_setupcrc(uint16_t poly, uint16_t rvalue)
{
int c = 256, bc;
uint16_t crctemp;
while(c--)
{
crctemp = c << 8;
bc = 8;
while(bc--)
{
if(crctemp & 0x8000)
{
crctemp = (crctemp << 1) ^ poly;
}
else
{
crctemp <<= 1;
}
}
CRCTable[c] = crctemp;
}
}
void fdi_init()
{
// printf("FDI reset\n");
memset(&fdi, 0, sizeof(fdi));
fdi_setupcrc(0x1021, 0xcdb4);
}
double fdi_byteperiod(int drive)
{
switch (fdi2raw_get_bit_rate(fdi[drive].h))
{
case 1000:
return 8.0;
case 500:
return 16.0;
temp_disk_flags |= 2;
case 300:
return 160.0 / 6.0;
case 250:
return 32.0;
temp_disk_flags |= 0;
case 1000:
temp_disk_flags |= 4;
default:
return 32.0;
temp_disk_flags |= 0;
}
if (fdi[drive].sides == 2)
{
temp_disk_flags |= 8;
}
/* Tell the 86F handler that will handle our data to handle it in reverse byte endianness. */
temp_disk_flags |= 0x800;
return temp_disk_flags;
}
uint16_t fdi_side_flags(int drive)
{
uint16_t temp_side_flags = 0;
switch (fdi2raw_get_bit_rate(fdi[drive].h))
{
case 500:
temp_side_flags = 0;
case 300:
temp_side_flags = 1;
case 250:
temp_side_flags = 2;
case 1000:
temp_side_flags = 3;
default:
temp_side_flags = 2;
}
if (fdi2raw_get_rotation(fdi[drive].h) == 360)
{
temp_side_flags |= 0x20;
}
/* Set the encoding value to match that provided by the FDC. Then if it's wrong, it will sector not found anyway. */
temp_side_flags |= 0x08;
return temp_side_flags;
}
int32_t fdi_extra_bit_cells(int drive)
{
int side = 0;
int density = 0;
int raw_size = 0;
side = fdd_get_head(drive);
switch (fdc_get_bit_rate())
{
case 0:
raw_size = (fdd_getrpm(drive ^ fdd_swap) == 300) ? 200000 : 166666;
density = 2;
case 1:
raw_size = (fdd_getrpm(drive ^ fdd_swap) == 300) ? 120000 : 100000;
density = 1;
case 2:
raw_size = (fdd_getrpm(drive ^ fdd_swap) == 300) ? 100000 : 83333;
density = 1;
case 3:
case 5:
raw_size = (fdd_getrpm(drive ^ fdd_swap) == 300) ? 400000 : 333333;
density = 3;
default:
raw_size = (fdd_getrpm(drive ^ fdd_swap) == 300) ? 100000 : 83333;
density = 1;
}
return (fdi[drive].tracklen[side][density] - raw_size);
}
int fdi_hole(int drive)
@@ -103,6 +126,129 @@ int fdi_hole(int drive)
}
}
void fdi_read_revolution(int drive)
{
int density;
int track = fdi[drive].track;
int side = 0;
if (track > fdi[drive].lasttrack)
{
for (density = 0; density < 4; density++)
{
memset(fdi[drive].track_data[0][density], 0, 106096);
memset(fdi[drive].track_data[1][density], 0, 106096);
fdi[drive].tracklen[0][density] = fdi[drive].tracklen[1][density] = 100000;
}
// pclog("Track is bigger than last track\n");
return;
}
for (density = 0; density < 4; density++)
{
for (side = 0; side < fdi[drive].sides; side++)
{
int c = fdi2raw_loadtrack(fdi[drive].h, (uint16_t *)fdi[drive].track_data[side][density],
(uint16_t *)fdi[drive].track_timing[side][density],
track * fdi[drive].sides,
&fdi[drive].tracklen[side][density],
&fdi[drive].trackindex[side][density], NULL, density);
// pclog("Side 0 [%i]: len %i, index %i\n", density, fdi[drive].tracklen[side][density], fdi[drive].trackindex[side][density]);
if (!c)
memset(fdi[drive].track_data[side][density], 0, fdi[drive].tracklen[side][density]);
}
}
if (fdi[drive].sides == 1)
{
memset(fdi[drive].track_data[1][density], 0, 106096);
fdi[drive].tracklen[1][density] = 100000;
}
}
uint32_t fdi_index_hole_pos(int drive, int side)
{
int density;
switch (fdc_get_bit_rate())
{
case 0:
density = 2;
case 1:
density = 1;
case 2:
density = 1;
case 3:
case 5:
density = 3;
default:
density = 1;
}
return fdi[drive].trackindex[side][density];
}
uint32_t fdi_get_raw_size(int drive)
{
int side = 0;
int density;
side = fdd_get_head(drive);
switch (fdc_get_bit_rate())
{
case 0:
density = 2;
case 1:
density = 1;
case 2:
density = 1;
case 3:
case 5:
density = 3;
default:
density = 1;
}
return fdi[drive].tracklen[side][density];
}
uint16_t* fdi_encoded_data(int drive, int side)
{
int density = 0;
if (fdc_get_bit_rate() == 2)
density = 1;
if (fdc_get_bit_rate() == 0)
density = 2;
if (fdc_get_bit_rate() == 3)
density = 3;
if (!fdc_is_mfm())
{
density = 0;
}
return (uint16_t *)fdi[drive].track_data[side][density];
}
void d86f_register_fdi(int drive)
{
d86f_handler[drive].disk_flags = fdi_disk_flags;
d86f_handler[drive].side_flags = fdi_side_flags;
d86f_handler[drive].writeback = null_writeback;
d86f_handler[drive].set_sector = null_set_sector;
d86f_handler[drive].write_data = null_write_data;
d86f_handler[drive].format_conditions = null_format_conditions;
d86f_handler[drive].extra_bit_cells = fdi_extra_bit_cells;
d86f_handler[drive].encoded_data = fdi_encoded_data;
d86f_handler[drive].read_revolution = fdi_read_revolution;
d86f_handler[drive].index_hole_pos = fdi_index_hole_pos;
d86f_handler[drive].get_raw_size = fdi_get_raw_size;
d86f_handler[drive].check_crc = 1;
}
void fdi_load(int drive, char *fn)
{
char header[26];
@@ -111,6 +257,8 @@ void fdi_load(int drive, char *fn)
fdi[drive].f = fopen(fn, "rb");
if (!fdi[drive].f) return;
d86f_unregister(drive);
fread(header, 1, 25, fdi[drive].f);
fseek(fdi[drive].f, 0, SEEK_SET);
header[25] = 0;
@@ -128,22 +276,19 @@ void fdi_load(int drive, char *fn)
fdi[drive].lasttrack = fdi2raw_get_last_track(fdi[drive].h);
fdi[drive].sides = fdi2raw_get_last_head(fdi[drive].h) + 1;
// printf("Last track %i\n",fdilasttrack[drive]);
d86f_register_fdi(drive);
drives[drive].seek = fdi_seek;
drives[drive].readsector = fdi_readsector;
drives[drive].writesector = fdi_writesector;
drives[drive].comparesector=fdi_comparesector;
drives[drive].readaddress = fdi_readaddress;
drives[drive].hole = fdi_hole;
drives[drive].byteperiod = fdi_byteperiod;
drives[drive].poll = fdi_poll;
drives[drive].format = fdi_format;
drives[drive].stop = fdi_stop;
drives[drive].realtrack = fdi_realtrack;
// pclog("Loaded as FDI\n");
d86f_common_handlers(drive);
pclog("Loaded as FDI\n");
}
void fdi_close(int drive)
{
d86f_unregister(drive);
drives[drive].seek = NULL;
if (fdi[drive].h)
fdi2raw_header_free(fdi[drive].h);
if (fdi[drive].f)
@@ -153,8 +298,14 @@ void fdi_close(int drive)
void fdi_seek(int drive, int track)
{
int c;
int density;
if (fdd_doublestep_40(drive))
{
if (fdi[drive].lasttrack < 43)
{
track /= 2;
}
// pclog("fdi_seek(): %i %i\n", fdi[drive].lasttrack, track);
}
if (!fdi[drive].f)
return;
@@ -163,507 +314,13 @@ void fdi_seek(int drive, int track)
track = 0;
if (track > fdi[drive].lasttrack)
track = fdi[drive].lasttrack - 1;
for (density = 0; density < 4; density++)
{
int c = fdi2raw_loadtrack(fdi[drive].h, (uint16_t *)fdi[drive].track_data[0][density],
(uint16_t *)fdi_timing,
track * fdi[drive].sides,
&fdi[drive].tracklen[0][density],
&fdi[drive].trackindex[0][density], NULL, density);
if (!c)
memset(fdi[drive].track_data[0][density], 0, fdi[drive].tracklen[0][density]);
if (fdi[drive].sides == 2)
{
c = fdi2raw_loadtrack(fdi[drive].h, (uint16_t *)fdi[drive].track_data[1][density],
(uint16_t *)fdi_timing,
(track * fdi[drive].sides) + 1,
&fdi[drive].tracklen[1][density],
&fdi[drive].trackindex[1][density], NULL, density);
if (!c)
memset(fdi[drive].track_data[1][density], 0, fdi[drive].tracklen[1][density]);
}
else
{
memset(fdi[drive].track_data[1][density], 0, 65536);
fdi[drive].tracklen[1][density] = fdi[drive].tracklen[1][density] = 10000;
}
}
fdi[drive].track = track;
fdi_read_revolution(drive);
}
void fdi_writeback(int drive, int track)
void fdi_init()
{
return;
}
void fdi_readsector(int drive, int sector, int track, int side, int rate, int sector_size)
{
fdi_revs = 0;
fdi_sector = sector;
fdi_track = track;
fdi_side = side;
fdi_n = sector_size;
fdi_drive = drive;
if (rate == 2)
fdi_density = 1;
if (rate == 0)
fdi_density = 2;
if (rate == 3)
fdi_density = 3;
// pclog("FDI Read sector %i %i %i %i %i\n",drive,side,track,sector, fdi_density);
// if (pollbytesleft)
// pclog("In the middle of a sector!\n");
fdi_inread = 1;
fdi_inwrite = 0;
fdi_incompare = 0;
fdi_inreadaddr = 0;
fdi_readpos = 0;
fdi_satisfying_bytes = 0;
}
void fdi_writesector(int drive, int sector, int track, int side, int rate, int sector_size)
{
fdi_revs = 0;
fdi_sector = sector;
fdi_track = track;
fdi_side = side;
fdi_n = sector_size;
fdi_drive = drive;
if (rate == 2)
fdi_density = 1;
if (rate == 0)
fdi_density = 2;
if (rate == 3)
fdi_density = 3;
// pclog("Write sector %i %i %i %i\n",drive,side,track,sector);
fdi_inread = 0;
fdi_inwrite = 1;
fdi_incompare = 0;
fdi_inreadaddr = 0;
fdi_readpos = 0;
fdi_satisfying_bytes = 0;
}
void fdi_comparesector(int drive, int sector, int track, int side, int rate, int sector_size)
{
fdi_revs = 0;
fdi_sector = sector;
fdi_track = track;
fdi_side = side;
fdi_n = sector_size;
fdi_drive = drive;
if (rate == 2)
fdi_density = 1;
if (rate == 0)
fdi_density = 2;
if (rate == 3)
fdi_density = 3;
// pclog("FDI Read sector %i %i %i %i %i\n",drive,side,track,sector, fdi_density);
// if (pollbytesleft)
// pclog("In the middle of a sector!\n");
fdi_inread = 0;
fdi_inwrite = 0;
fdi_incompare = 1;
fdi_inreadaddr = 0;
fdi_readpos = 0;
fdi_satisfying_bytes = 0;
}
void fdi_readaddress(int drive, int track, int side, int rate)
{
fdi_revs = 0;
fdi_track = track;
fdi_side = side;
fdi_drive = drive;
if (rate == 2)
fdi_density = 1;
if (rate == 0)
fdi_density = 2;
if (rate == 3)
fdi_density = 3;
// pclog("Read address %i %i %i %i %i %p\n",drive,side,track, rate, fdi_density, &fdi_inreadaddr);
fdi_inread = 0;
fdi_inwrite = 0;
fdi_incompare = 0;
fdi_inreadaddr = 1;
fdi_readpos = 0;
fdi_satisfying_bytes = 0;
}
void fdi_format(int drive, int track, int side, int rate, uint8_t fill)
{
fdi_revs = 0;
fdi_track = track;
fdi_side = side;
fdi_drive = drive;
if (rate == 2)
fdi_density = 1;
if (rate == 0)
fdi_density = 2;
if (rate == 3)
fdi_density = 3;
// pclog("Format %i %i %i\n",drive,side,track);
fdi_inread = 0;
fdi_inwrite = 1;
fdi_incompare = 0;
fdi_inreadaddr = 0;
fdi_readpos = 0;
fdi_satisfying_bytes = 0;
}
static uint16_t fdi_buffer;
static int readidpoll=0,readdatapoll=0,comparedatapoll=0,fdi_nextsector=0,inreadop=0;
static uint8_t fdi_sectordat[1026];
static int lastfdidat[2],sectorcrc[2];
static int sectorsize,fdc_sectorsize;
static int ddidbitsleft=0;
static uint8_t decodefm(uint16_t dat)
{
uint8_t temp;
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 fdi_stop(int drive)
{
// pclog("fdi_stop\n");
fdi_inread = fdi_inwrite = fdi_inreadaddr = 0;
fdi_nextsector = ddidbitsleft = pollbitsleft = 0;
}
static uint16_t crc;
static void calccrc(uint8_t byte)
{
crc = (crc << 8) ^ CRCTable[(crc >> 8)^byte];
}
static int fdi_indextime_blank = 6250 * 8;
void fdi_poll()
{
int tempi, c;
int bitcount;
int indata, readdata;
int side = fdd_get_head(fdi_drive);
for (bitcount = 0; bitcount < 16; bitcount++)
{
if (fdi_pos >= fdi[fdi_drive].tracklen[side][fdi_density])
{
fdi_pos = 0;
if (fdi[fdi_drive].tracklen[side][fdi_density])
fdc_indexpulse();
else
{
fdi_indextime_blank--;
if (!fdi_indextime_blank)
{
fdi_indextime_blank = 6250 * 8;
fdc_indexpulse();
}
}
}
tempi = fdi[fdi_drive].track_data[side][fdi_density][((fdi_pos >> 3) & 0xFFFF) ^ 1] & (1 << (7 - (fdi_pos & 7)));
fdi_pos++;
fdi_buffer <<= 1;
fdi_buffer |= (tempi ? 1 : 0);
if (fdi_inwrite)
{
fdi_inwrite = 0;
fdc_writeprotect();
return;
}
if (!fdi_inread && !fdi_inreadaddr && !fdi_incompare)
return;
if (fdi_pos == fdi[fdi_drive].trackindex[side][fdi_density])
{
fdi_revs++;
if (fdi_revs == 3)
{
// pclog("Not found!\n");
fdc_notfound();
fdi_inread = fdi_inreadaddr = 0;
return;
}
if (fdi_sector == SECTOR_FIRST)
fdi_sector = SECTOR_NEXT;
}
if (pollbitsleft)
{
pollbitsleft--;
if (!pollbitsleft)
{
pollbytesleft--;
if (pollbytesleft) pollbitsleft = 16; /*Set up another word if we need it*/
if (readidpoll)
{
fdi_sectordat[5 - pollbytesleft] = decodefm(fdi_buffer);
if (fdi_inreadaddr && !fdc_sectorid)// && pollbytesleft > 1)
{
// rpclog("inreadaddr - %02X\n", fdi_sectordat[5 - pollbytesleft]);
fdc_data(fdi_sectordat[5 - pollbytesleft]);
}
if (!pollbytesleft)
{
// pclog("Header over %i,%i %i,%i\n", fdi_sectordat[0], fdi_sectordat[2], fdi_track, fdi_sector);
if ((fdi_sectordat[0] == fdi_track && (fdi_sectordat[3] == fdi_n) && (fdi_sectordat[2] == fdi_sector || fdi_sector == SECTOR_NEXT)) || fdi_inreadaddr)
{
crc = (fdi_density) ? 0xcdb4 : 0xffff;
calccrc(0xFE);
for (c = 0; c < 4; c++)
calccrc(fdi_sectordat[c]);
if ((crc >> 8) != fdi_sectordat[4] || (crc & 0xFF) != fdi_sectordat[5])
{
// pclog("Header CRC error : %02X %02X %02X %02X\n",crc>>8,crc&0xFF,fdi_sectordat[4],fdi_sectordat[5]);
// dumpregs();
// exit(-1);
inreadop = 0;
if (fdi_inreadaddr)
{
// rpclog("inreadaddr - %02X\n", fdi_sector);
// fdc_data(fdi_sector);
if (fdc_sectorid)
fdc_sectorid(fdi_sectordat[0], fdi_sectordat[1], fdi_sectordat[2], fdi_sectordat[3], fdi_sectordat[4], fdi_sectordat[5]);
else
fdc_finishread();
}
else fdc_headercrcerror();
return;
}
// pclog("Sector %i,%i %i,%i\n", fdi_sectordat[0], fdi_sectordat[2], fdi_track, fdi_sector);
if (fdi_sectordat[0] == fdi_track && (fdi_sectordat[2] == fdi_sector || fdi_sector == SECTOR_NEXT) && fdi_inread && !fdi_inreadaddr)
{
fdi_nextsector = 1;
readidpoll = 0;
sectorsize = (1 << (fdi_sectordat[3] + 7)) + 2;
fdc_sectorsize = fdi_sectordat[3];
}
if (fdi_inreadaddr)
{
if (fdc_sectorid)
fdc_sectorid(fdi_sectordat[0], fdi_sectordat[1], fdi_sectordat[2], fdi_sectordat[3], fdi_sectordat[4], fdi_sectordat[5]);
else
fdc_finishread();
fdi_inreadaddr = 0;
}
}
}
}
if (readdatapoll)
{
// pclog("readdatapoll %i %02x\n", pollbytesleft, decodefm(fdi_buffer));
if (pollbytesleft > 1)
{
calccrc(decodefm(fdi_buffer));
}
else
sectorcrc[1 - pollbytesleft] = decodefm(fdi_buffer);
if (!pollbytesleft)
{
fdi_inread = 0;
//#if 0
if ((crc >> 8) != sectorcrc[0] || (crc & 0xFF) != sectorcrc[1])// || (fditrack==79 && fdisect==4 && fdc_side&1))
{
// pclog("Data CRC error : %02X %02X %02X %02X %i %04X %02X%02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1],fdi_pos,crc,sectorcrc[0],sectorcrc[1]);
inreadop = 0;
fdc_data(decodefm(lastfdidat[1]));
fdc_finishread();
fdc_datacrcerror();
readdatapoll = 0;
return;
}
//#endif
// pclog("End of FDI read %02X %02X %02X %02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1]);
fdc_data(decodefm(lastfdidat[1]));
fdc_finishread();
}
else if (lastfdidat[1] != 0)
fdc_data(decodefm(lastfdidat[1]));
lastfdidat[1] = lastfdidat[0];
lastfdidat[0] = fdi_buffer;
if (!pollbytesleft)
readdatapoll = 0;
}
if (comparedatapoll)
{
// pclog("readdatapoll %i %02x\n", pollbytesleft, decodefm(fdi_buffer));
if (pollbytesleft > 1)
{
calccrc(decodefm(fdi_buffer));
}
else
sectorcrc[1 - pollbytesleft] = decodefm(fdi_buffer);
if (!pollbytesleft)
{
fdi_inread = 0;
//#if 0
if ((crc >> 8) != sectorcrc[0] || (crc & 0xFF) != sectorcrc[1])// || (fditrack==79 && fdisect==4 && fdc_side&1))
{
// pclog("Data CRC error : %02X %02X %02X %02X %i %04X %02X%02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1],fdi_pos,crc,sectorcrc[0],sectorcrc[1]);
inreadop = 0;
fdc_data(decodefm(lastfdidat[1]));
fdc_finishcompare(fdi_satisfying_bytes == polltotalbytes);
fdc_datacrcerror();
comparedatapoll = 0;
return;
}
//#endif
// pclog("End of FDI read %02X %02X %02X %02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1]);
indata = fdc_getdata(!pollbytesleft);
readdata = decodefm(lastfdidat[1]);
if (indata == -1)
{
indata = 0;
}
switch(fdc_get_compare_condition())
{
case 0: /* SCAN EQUAL */
if ((indata == readdata) || (indata == 0xFF))
{
fdi_satisfying_bytes++;
}
break;
case 1: /* SCAN LOW OR EQUAL */
if ((indata <= readdata) || (indata == 0xFF))
{
fdi_satisfying_bytes++;
}
break;
case 2: /* SCAN HIGH OR EQUAL */
if ((indata >= readdata) || (indata == 0xFF))
{
fdi_satisfying_bytes++;
}
break;
}
fdc_finishcompare(fdi_satisfying_bytes == polltotalbytes);
}
else if (lastfdidat[1] != 0)
{
indata = fdc_getdata(!pollbytesleft);
readdata = decodefm(lastfdidat[1]);
if (indata == -1)
{
indata = 0;
}
switch(fdc_get_compare_condition())
{
case 0: /* SCAN EQUAL */
if ((indata == readdata) || (indata == 0xFF))
{
fdi_satisfying_bytes++;
}
break;
case 1: /* SCAN LOW OR EQUAL */
if ((indata <= readdata) || (indata == 0xFF))
{
fdi_satisfying_bytes++;
}
break;
case 2: /* SCAN HIGH OR EQUAL */
if ((indata >= readdata) || (indata == 0xFF))
{
fdi_satisfying_bytes++;
}
break;
}
}
lastfdidat[1] = lastfdidat[0];
lastfdidat[0] = fdi_buffer;
if (!pollbytesleft)
readdatapoll = 0;
}
}
}
if (fdi_buffer == 0x4489 && fdi_density)
{
// rpclog("Found sync\n");
ddidbitsleft = 17;
}
if (fdi_buffer == 0xF57E && !fdi_density)
{
pollbytesleft = 6;
pollbitsleft = 16;
readidpoll = 1;
}
if ((fdi_buffer == 0xF56F || fdi_buffer == 0xF56A) && !fdi_density)
{
if (fdi_nextsector)
{
pollbytesleft = sectorsize;
pollbitsleft = 16;
if (fdi_inread)
{
readdatapoll = 1;
}
else
{
polltotalbytes = sectorsize;
comparedatapoll = 1;
}
fdi_nextsector = 0;
crc = 0xffff;
if (fdi_buffer == 0xF56A) calccrc(0xF8);
else calccrc(0xFB);
lastfdidat[0] = lastfdidat[1] = 0;
}
}
if (ddidbitsleft)
{
ddidbitsleft--;
if (!ddidbitsleft && !readdatapoll)
{
// printf("ID bits over %04X %02X %i\n",fdibuffer,decodefm(fdibuffer),fdipos);
if (decodefm(fdi_buffer) == 0xFE)
{
// printf("Sector header %i %i\n", fdi_inread, fdi_inreadaddr);
pollbytesleft = 6;
pollbitsleft = 16;
readidpoll = 1;
}
else if (decodefm(fdi_buffer) == 0xFB)
{
// printf("Data header %i %i\n", fdi_inread, fdi_inreadaddr);
if (fdi_nextsector)
{
pollbytesleft = sectorsize;
pollbitsleft = 16;
if (fdi_inread)
{
readdatapoll = 1;
}
else
{
polltotalbytes = sectorsize;
comparedatapoll = 1;
}
fdi_nextsector = 0;
crc = 0xcdb4;
if (fdi_buffer == 0xF56A) calccrc(0xF8);
else calccrc(0xFB);
lastfdidat[0] = lastfdidat[1] = 0;
}
}
}
}
}
// printf("FDI reset\n");
}