Attempted to rework the FDC read/write interrupt issuing a bit.

This commit is contained in:
OBattler
2016-12-25 03:40:58 +01:00
parent 147dcc3222
commit 9eb8868e81

161
src/fdc.c
View File

@@ -923,7 +923,14 @@ bad_command:
fdc.rw_track = fdc.params[1]; fdc.rw_track = fdc.params[1];
// pclog("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.pcn[fdc.params[0] & 3], fdc.head, fdc.sector, fdc.eot[fdc.drive]); // pclog("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.pcn[fdc.params[0] & 3], fdc.head, fdc.sector, fdc.eot[fdc.drive]);
disc_readsector(fdc.drive, SECTOR_FIRST, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); disc_readsector(fdc.drive, SECTOR_FIRST, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
fdc.stat |= 0x40; if (fdc.pcjr || !fdc.dma)
{
fdc.stat = 0x70;
}
else
{
fdc.stat = 0x50;
}
disctime = 0; disctime = 0;
readflash = 1; readflash = 1;
fdc.inread = 1; fdc.inread = 1;
@@ -973,18 +980,13 @@ bad_command:
fdc.written = 0; fdc.written = 0;
readflash = 1; readflash = 1;
fdc.pos = 0; fdc.pos = 0;
if (fdc.pcjr) if (fdc.pcjr || !fdc.dma)
fdc.stat = 0xb0; {
fdc.stat = 0xb0;
}
else else
{ {
if (fdc.dma) fdc.stat = 0x90;
{
fdc.stat = 0x90;
}
else
{
fdc.stat = 0xb0;
}
} }
// ioc_fiq(IOC_FIQ_DISC_DATA); // ioc_fiq(IOC_FIQ_DISC_DATA);
break; break;
@@ -1007,18 +1009,13 @@ bad_command:
fdc.written = 0; fdc.written = 0;
readflash = 1; readflash = 1;
fdc.pos = 0; fdc.pos = 0;
if (fdc.pcjr) if (fdc.pcjr || !fdc.dma)
fdc.stat = 0xb0; {
fdc.stat = 0xb0;
}
else else
{ {
if (fdc.dma) fdc.stat = 0x90;
{
fdc.stat = 0x90;
}
else
{
fdc.stat = 0xb0;
}
} }
// ioc_fiq(IOC_FIQ_DISC_DATA); // ioc_fiq(IOC_FIQ_DISC_DATA);
break; break;
@@ -1047,7 +1044,14 @@ bad_command:
} }
// dma_c2_mode(); // dma_c2_mode();
disc_readsector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); disc_readsector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
fdc.stat |= 0x40; if (fdc.pcjr || !fdc.dma)
{
fdc.stat = 0x70;
}
else
{
fdc.stat = 0x50;
}
disctime = 0; disctime = 0;
readflash = 1; readflash = 1;
fdc.inread = 1; fdc.inread = 1;
@@ -1201,10 +1205,19 @@ bad_command:
if ((real_drive(fdc.drive) != 1) || fdc.drv2en) if ((real_drive(fdc.drive) != 1) || fdc.drv2en)
{ {
disc_readaddress(fdc.drive, fdc.head, fdc.rate); disc_readaddress(fdc.drive, fdc.head, fdc.rate);
fdc.stat |= 0x50; if (fdc.pcjr || !fdc.dma)
{
fdc.stat |= 0x70;
}
else
{
fdc.stat |= 0x50;
}
} }
else else
{
fdc_noidam(); fdc_noidam();
}
break; break;
} }
} }
@@ -1363,7 +1376,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
void fdc_poll_common_finish(int compare, int st5) void fdc_poll_common_finish(int compare, int st5)
{ {
fdc_int(); // fdc_int();
fdc.fintr = 0; fdc.fintr = 0;
fdc.stat=0xD0; fdc.stat=0xD0;
fdc.res[4]=(fdd_get_head(real_drive(fdc.drive))?4:0)|fdc.rw_drive; fdc.res[4]=(fdd_get_head(real_drive(fdc.drive))?4:0)|fdc.rw_drive;
@@ -1474,13 +1487,24 @@ void fdc_callback()
// pclog("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]); // pclog("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]);
if (!fdc.eot[fdc.drive] || fdc.tc) if (!fdc.eot[fdc.drive] || fdc.tc)
{ {
if (!fdc.tc)
{
fdc_int();
}
fdc_poll_readwrite_finish(2); fdc_poll_readwrite_finish(2);
return; return;
} }
else else
{ {
disc_readsector(fdc.drive, SECTOR_NEXT, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); disc_readsector(fdc.drive, SECTOR_NEXT, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
fdc.stat |= 0x40; if (fdc.pcjr || !fdc.dma)
{
fdc.stat = 0x70;
}
else
{
fdc.stat = 0x50;
}
} }
fdc.inread = 1; fdc.inread = 1;
return; return;
@@ -1541,6 +1565,7 @@ void fdc_callback()
if (!fdc.sc) if (!fdc.sc)
{ {
fdc.sector++; fdc.sector++;
fdc_int();
fdc_poll_readwrite_finish(0); fdc_poll_readwrite_finish(0);
return; return;
} }
@@ -1552,18 +1577,27 @@ void fdc_callback()
if ((fdc.sector == old_sector) && (fdc.head == (fdc.command & 0x80) ? 1 : 0)) if ((fdc.sector == old_sector) && (fdc.head == (fdc.command & 0x80) ? 1 : 0))
{ {
fdc.sector++; fdc.sector++;
fdc_int();
fdc_poll_readwrite_finish(0); fdc_poll_readwrite_finish(0);
return; return;
} }
} }
if (fdc.sector == fdc.params[5]) if ((fdc.sector == fdc.params[5]) || (fdc.sector == 255))
{ {
/* Reached end of track, MT bit is clear */ /* Reached end of track, MT bit is clear */
if (!(fdc.command & 0x80)) if (!(fdc.command & 0x80))
{ {
fdc.rw_track++; fdc.rw_track++;
fdc.sector = 1; fdc.sector = 1;
fdc_no_dma_end(compare); fdc_int();
if (old_sector == 255)
{
fdc_no_dma_end(compare);
}
else
{
fdc_poll_readwrite_finish(compare);
}
return; return;
} }
/* Reached end of track, MT bit is set, head is 1 */ /* Reached end of track, MT bit is set, head is 1 */
@@ -1573,7 +1607,15 @@ void fdc_callback()
fdc.sector = 1; fdc.sector = 1;
fdc.head &= 0xFE; fdc.head &= 0xFE;
fdd_set_head(fdc.drive, 0); fdd_set_head(fdc.drive, 0);
fdc_no_dma_end(compare); fdc_int();
if (old_sector == 255)
{
fdc_no_dma_end(compare);
}
else
{
fdc_poll_readwrite_finish(compare);
}
return; return;
} }
if ((fdc.command & 0x80) && (fdd_get_head(real_drive(fdc.drive)) == 0)) if ((fdc.command & 0x80) && (fdd_get_head(real_drive(fdc.drive)) == 0))
@@ -1598,7 +1640,14 @@ void fdc_callback()
case 0xC: case 0xC:
case 0x16: case 0x16:
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.stat |= 0x40; if (fdc.pcjr || !fdc.dma)
{
fdc.stat = 0x70;
}
else
{
fdc.stat = 0x50;
}
break; break;
case 0x11: case 0x11:
case 0x19: case 0x19:
@@ -1684,7 +1733,10 @@ void fdc_callback()
else else
{ {
discint=-2; discint=-2;
fdc_int(); if (!fdc.tc)
{
fdc_int();
}
fdc.fintr = 0; fdc.fintr = 0;
fdc.stat=0xD0; fdc.stat=0xD0;
fdc.res[4] = (fdd_get_head(real_drive(fdc.drive))?4:0)|fdc.drive; fdc.res[4] = (fdd_get_head(real_drive(fdc.drive))?4:0)|fdc.drive;
@@ -1887,15 +1939,24 @@ int fdc_data(uint8_t data)
else else
{ {
result = dma_channel_write(2, data); result = dma_channel_write(2, data);
if (result & DMA_OVER)
{
fdc.tc = 1;
// pclog("DMA overrun!\n");
return -1;
}
if (fdc.tc) if (fdc.tc)
{
/* If we've already TC'd, transfer no further data. */
return -1; return -1;
}
if (result & DMA_OVER)
{
/* If this is the last byte in the DMA, inform the host there's this one last byte to transfer,
then return with error. */
// pclog("DMA overrun!\n");
fdc.tc = 1;
fdc.data_ready = 1;
fdc.stat = 0xd0;
fdc_int();
return -1;
}
if (!fdc.fifo || (fdc.tfifo <= 1)) if (!fdc.fifo || (fdc.tfifo <= 1))
{ {
@@ -2030,14 +2091,26 @@ int fdc_getdata(int last)
data = fdc.dat; data = fdc.dat;
if (!last) if (!last)
{
fdc.stat = 0xb0; fdc.stat = 0xb0;
}
else
{
fdc.stat = 0x30;
}
} }
else else
{ {
data = fdc_fifo_buf_read(); data = fdc_fifo_buf_read();
if (!last && (fdc.fifobufpos == 0)) if (!last && (fdc.fifobufpos == 0))
{
fdc.stat = 0xb0; fdc.stat = 0xb0;
}
else
{
fdc.stat = 0x30;
}
} }
} }
else else
@@ -2047,18 +2120,34 @@ int fdc_getdata(int last)
if (!fdc.fifo) if (!fdc.fifo)
{ {
if (!last) if (!last)
{
fdc.stat = 0x90; fdc.stat = 0x90;
}
else
{
fdc.stat = 0x10;
}
} }
else else
{ {
fdc_fifo_buf_advance(); fdc_fifo_buf_advance();
if (!last && (fdc.fifobufpos == 0)) if (!last && (fdc.fifobufpos == 0))
{
fdc.stat = 0x90; fdc.stat = 0x90;
}
else
{
fdc.stat = 0x10;
}
} }
if (data & DMA_OVER) if (data & DMA_OVER)
{
fdc.tc = 1; fdc.tc = 1;
fdc.stat = 0x10;
fdc_int();
}
} }
fdc.written = 0; fdc.written = 0;