FDC errors now report last sector ID
FDC multitrack read/write now works properly Fixes floppy issues in Windows 9x
This commit is contained in:
parent
acb4307954
commit
69edc3fc2d
1 changed files with 97 additions and 79 deletions
176
src/fdc.c
176
src/fdc.c
|
|
@ -17,6 +17,7 @@ typedef struct FDC
|
||||||
{
|
{
|
||||||
uint8_t dor,stat,command,dat,st0;
|
uint8_t dor,stat,command,dat,st0;
|
||||||
int head,track[256],sector,drive,lastdrive;
|
int head,track[256],sector,drive,lastdrive;
|
||||||
|
int sector_size;
|
||||||
int rw_track;
|
int rw_track;
|
||||||
int pos;
|
int pos;
|
||||||
uint8_t params[256];
|
uint8_t params[256];
|
||||||
|
|
@ -33,6 +34,7 @@ typedef struct FDC
|
||||||
int format_state;
|
int format_state;
|
||||||
int tc;
|
int tc;
|
||||||
int written;
|
int written;
|
||||||
|
int in_seek_mt;
|
||||||
|
|
||||||
int pcjr, ps1;
|
int pcjr, ps1;
|
||||||
|
|
||||||
|
|
@ -409,6 +411,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
fdc.tc = 0;
|
fdc.tc = 0;
|
||||||
fdc.data_ready = 0;
|
fdc.data_ready = 0;
|
||||||
|
fdc.in_seek_mt = 0;
|
||||||
|
|
||||||
fdc.command=val;
|
fdc.command=val;
|
||||||
// pclog("Starting FDC command %02X\n",fdc.command);
|
// pclog("Starting FDC command %02X\n",fdc.command);
|
||||||
|
|
@ -562,6 +565,7 @@ bad_command:
|
||||||
fdc_rate(fdc.drive);
|
fdc_rate(fdc.drive);
|
||||||
fdc.head=fdc.params[2];
|
fdc.head=fdc.params[2];
|
||||||
fdc.sector=fdc.params[3];
|
fdc.sector=fdc.params[3];
|
||||||
|
fdc.sector_size = fdc.params[4];
|
||||||
fdc.eot[fdc.drive] = fdc.params[5];
|
fdc.eot[fdc.drive] = fdc.params[5];
|
||||||
if (fdc.config & 0x40)
|
if (fdc.config & 0x40)
|
||||||
fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
|
fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
|
||||||
|
|
@ -585,6 +589,7 @@ bad_command:
|
||||||
fdc_rate(fdc.drive);
|
fdc_rate(fdc.drive);
|
||||||
fdc.head=fdc.params[2];
|
fdc.head=fdc.params[2];
|
||||||
fdc.sector=fdc.params[3];
|
fdc.sector=fdc.params[3];
|
||||||
|
fdc.sector_size = fdc.params[4];
|
||||||
fdc.eot[fdc.drive] = fdc.params[5];
|
fdc.eot[fdc.drive] = fdc.params[5];
|
||||||
if (fdc.config & 0x40)
|
if (fdc.config & 0x40)
|
||||||
fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
|
fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
|
||||||
|
|
@ -605,6 +610,7 @@ bad_command:
|
||||||
fdc_rate(fdc.drive);
|
fdc_rate(fdc.drive);
|
||||||
fdc.head=fdc.params[2];
|
fdc.head=fdc.params[2];
|
||||||
fdc.sector=fdc.params[3];
|
fdc.sector=fdc.params[3];
|
||||||
|
fdc.sector_size = fdc.params[4];
|
||||||
fdc.eot[fdc.drive] = fdc.params[5];
|
fdc.eot[fdc.drive] = fdc.params[5];
|
||||||
if (fdc.config & 0x40)
|
if (fdc.config & 0x40)
|
||||||
fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
|
fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
|
||||||
|
|
@ -774,6 +780,8 @@ uint8_t fdc_read(uint16_t addr, void *priv)
|
||||||
void fdc_callback()
|
void fdc_callback()
|
||||||
{
|
{
|
||||||
int temp;
|
int temp;
|
||||||
|
int doseek = 0;
|
||||||
|
|
||||||
disctime = 0;
|
disctime = 0;
|
||||||
// pclog("fdc_callback %i %i\n", discint, disctime);
|
// pclog("fdc_callback %i %i\n", discint, disctime);
|
||||||
// if (fdc.inread)
|
// if (fdc.inread)
|
||||||
|
|
@ -834,92 +842,102 @@ void fdc_callback()
|
||||||
disctime = 0;
|
disctime = 0;
|
||||||
return;
|
return;
|
||||||
case 5: /*Write data*/
|
case 5: /*Write data*/
|
||||||
readflash = 1;
|
if (!fdc.in_seek_mt)
|
||||||
fdc.sector++;
|
|
||||||
if (fdc.sector > fdc.params[5])
|
|
||||||
{
|
{
|
||||||
fdc.sector = 1;
|
readflash = 1;
|
||||||
if (fdc.command & 0x80)
|
fdc.sector++;
|
||||||
|
if (fdc.sector > fdc.params[5])
|
||||||
{
|
{
|
||||||
fdc.head ^= 1;
|
fdc.sector = 1;
|
||||||
if (!fdc.head)
|
if (fdc.command & 0x80)
|
||||||
|
{
|
||||||
|
fdc.head ^= 1;
|
||||||
|
if (!fdc.head)
|
||||||
|
{
|
||||||
|
fdc.rw_track++;
|
||||||
|
doseek = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
fdc.rw_track++;
|
fdc.rw_track++;
|
||||||
// fdc.track[fdc.drive]++;
|
fdc.tc = 1;
|
||||||
/* if (fdc.track[fdc.drive] >= 79)
|
|
||||||
{
|
|
||||||
fdc.track[fdc.drive] = 79;
|
|
||||||
fdc.tc = 1;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
if (fdc.tc)
|
||||||
{
|
{
|
||||||
fdc.rw_track++;
|
discint=-2;
|
||||||
// fdc.track[fdc.drive]++;
|
fdc_int();
|
||||||
fdc.tc = 1;
|
fdc.stat=0xD0;
|
||||||
|
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
|
||||||
|
fdc.res[5]=fdc.res[6]=0;
|
||||||
|
fdc.res[7]=fdc.rw_track;
|
||||||
|
fdc.res[8]=fdc.head;
|
||||||
|
fdc.res[9]=fdc.sector;
|
||||||
|
fdc.res[10]=fdc.params[4];
|
||||||
|
paramstogo=7;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (doseek)
|
||||||
|
{
|
||||||
|
fdd_seek(fdc.drive, 1);
|
||||||
|
fdc.in_seek_mt = 1;
|
||||||
|
/*Allow seek to complete before starting next sector write*/
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fdc.tc)
|
fdc.in_seek_mt = 0;
|
||||||
{
|
|
||||||
discint=-2;
|
|
||||||
fdc_int();
|
|
||||||
fdc.stat=0xD0;
|
|
||||||
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
|
|
||||||
fdc.res[5]=fdc.res[6]=0;
|
|
||||||
fdc.res[7]=fdc.rw_track;
|
|
||||||
fdc.res[8]=fdc.head;
|
|
||||||
fdc.res[9]=fdc.sector;
|
|
||||||
fdc.res[10]=fdc.params[4];
|
|
||||||
paramstogo=7;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
|
disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
|
||||||
// ioc_fiq(IOC_FIQ_DISC_DATA);
|
// ioc_fiq(IOC_FIQ_DISC_DATA);
|
||||||
return;
|
return;
|
||||||
case 6: /*Read data*/
|
case 6: /*Read data*/
|
||||||
// rpclog("Read data %i\n", fdc.tc);
|
// rpclog("Read data %i\n", fdc.tc);
|
||||||
readflash = 1;
|
if (!fdc.in_seek_mt)
|
||||||
fdc.sector++;
|
|
||||||
if (fdc.sector > fdc.params[5])
|
|
||||||
{
|
{
|
||||||
fdc.sector = 1;
|
readflash = 1;
|
||||||
if (fdc.command & 0x80)
|
fdc.sector++;
|
||||||
|
if (fdc.sector > fdc.params[5])
|
||||||
{
|
{
|
||||||
fdc.head ^= 1;
|
fdc.sector = 1;
|
||||||
if (!fdc.head)
|
if (fdc.command & 0x80)
|
||||||
|
{
|
||||||
|
fdc.head ^= 1;
|
||||||
|
if (!fdc.head)
|
||||||
|
{
|
||||||
|
fdc.rw_track++;
|
||||||
|
doseek = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
fdc.rw_track++;
|
fdc.rw_track++;
|
||||||
// fdc.track[fdc.drive]++;
|
fdc.tc = 1;
|
||||||
/* if (fdc.track[fdc.drive] >= 79)
|
|
||||||
{
|
|
||||||
fdc.track[fdc.drive] = 79;
|
|
||||||
fdc.tc = 1;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
if (fdc.tc)
|
||||||
{
|
{
|
||||||
fdc.rw_track++;
|
fdc.inread = 0;
|
||||||
// fdc.track[fdc.drive]++;
|
discint=-2;
|
||||||
fdc.tc = 1;
|
fdc_int();
|
||||||
|
fdc.stat=0xD0;
|
||||||
|
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
|
||||||
|
fdc.res[5]=fdc.res[6]=0;
|
||||||
|
fdc.res[7]=fdc.rw_track;
|
||||||
|
fdc.res[8]=fdc.head;
|
||||||
|
fdc.res[9]=fdc.sector;
|
||||||
|
fdc.res[10]=fdc.params[4];
|
||||||
|
paramstogo=7;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (doseek)
|
||||||
|
{
|
||||||
|
fdd_seek(fdc.drive, 1);
|
||||||
|
fdc.in_seek_mt = 1;
|
||||||
|
/*Allow seek to complete before starting next sector read*/
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fdc.tc)
|
fdc.in_seek_mt = 0;
|
||||||
{
|
|
||||||
fdc.inread = 0;
|
|
||||||
discint=-2;
|
|
||||||
fdc_int();
|
|
||||||
fdc.stat=0xD0;
|
|
||||||
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
|
|
||||||
fdc.res[5]=fdc.res[6]=0;
|
|
||||||
fdc.res[7]=fdc.rw_track;
|
|
||||||
fdc.res[8]=fdc.head;
|
|
||||||
fdc.res[9]=fdc.sector;
|
|
||||||
fdc.res[10]=fdc.params[4];
|
|
||||||
paramstogo=7;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
|
disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
|
||||||
fdc.inread = 1;
|
fdc.inread = 1;
|
||||||
return;
|
return;
|
||||||
|
|
@ -1194,10 +1212,10 @@ void fdc_notfound()
|
||||||
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
|
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
|
||||||
fdc.res[5]=5;
|
fdc.res[5]=5;
|
||||||
fdc.res[6]=0;
|
fdc.res[6]=0;
|
||||||
fdc.res[7]=0;
|
fdc.res[7] = fdc.rw_track;
|
||||||
fdc.res[8]=0;
|
fdc.res[8] = fdc.head;
|
||||||
fdc.res[9]=0;
|
fdc.res[9] = fdc.sector;
|
||||||
fdc.res[10]=0;
|
fdc.res[10] = fdc.sector_size;
|
||||||
paramstogo=7;
|
paramstogo=7;
|
||||||
// rpclog("c82c711_fdc_notfound\n");
|
// rpclog("c82c711_fdc_notfound\n");
|
||||||
}
|
}
|
||||||
|
|
@ -1211,10 +1229,10 @@ void fdc_datacrcerror()
|
||||||
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
|
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
|
||||||
fdc.res[5]=0x20; /*Data error*/
|
fdc.res[5]=0x20; /*Data error*/
|
||||||
fdc.res[6]=0x20; /*Data error in data field*/
|
fdc.res[6]=0x20; /*Data error in data field*/
|
||||||
fdc.res[7]=0;
|
fdc.res[7] = fdc.rw_track;
|
||||||
fdc.res[8]=0;
|
fdc.res[8] = fdc.head;
|
||||||
fdc.res[9]=0;
|
fdc.res[9] = fdc.sector;
|
||||||
fdc.res[10]=0;
|
fdc.res[10] = fdc.sector_size;
|
||||||
paramstogo=7;
|
paramstogo=7;
|
||||||
// rpclog("c82c711_fdc_datacrcerror\n");
|
// rpclog("c82c711_fdc_datacrcerror\n");
|
||||||
}
|
}
|
||||||
|
|
@ -1228,10 +1246,10 @@ void fdc_headercrcerror()
|
||||||
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
|
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
|
||||||
fdc.res[5]=0x20; /*Data error*/
|
fdc.res[5]=0x20; /*Data error*/
|
||||||
fdc.res[6]=0;
|
fdc.res[6]=0;
|
||||||
fdc.res[7]=0;
|
fdc.res[7] = fdc.rw_track;
|
||||||
fdc.res[8]=0;
|
fdc.res[8] = fdc.head;
|
||||||
fdc.res[9]=0;
|
fdc.res[9] = fdc.sector;
|
||||||
fdc.res[10]=0;
|
fdc.res[10] = fdc.sector_size;
|
||||||
paramstogo=7;
|
paramstogo=7;
|
||||||
// rpclog("c82c711_fdc_headercrcerror\n");
|
// rpclog("c82c711_fdc_headercrcerror\n");
|
||||||
}
|
}
|
||||||
|
|
@ -1245,10 +1263,10 @@ void fdc_writeprotect()
|
||||||
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
|
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
|
||||||
fdc.res[5]=0x02; /*Not writeable*/
|
fdc.res[5]=0x02; /*Not writeable*/
|
||||||
fdc.res[6]=0;
|
fdc.res[6]=0;
|
||||||
fdc.res[7]=0;
|
fdc.res[7] = fdc.rw_track;
|
||||||
fdc.res[8]=0;
|
fdc.res[8] = fdc.head;
|
||||||
fdc.res[9]=0;
|
fdc.res[9] = fdc.sector;
|
||||||
fdc.res[10]=0;
|
fdc.res[10] = fdc.sector_size;
|
||||||
paramstogo=7;
|
paramstogo=7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue