TD0 and IMD images of DMF media are now loaded with the correct sector interleave;

Fixed several bugs in TD0 and IMD loading;
Added FDC READ DELETED DATA, WRITE DELETED DATA, and VERIFY commands;
Mismatching data address marks are now handled correctly.
This commit is contained in:
OBattler
2016-10-05 00:47:50 +02:00
parent 8f9bbb3679
commit 64d9cdc665
7 changed files with 298 additions and 26 deletions

View File

@@ -73,6 +73,11 @@ typedef struct FDC
int max_track;
int mfm;
int deleted;
int wrong_am;
int sc;
} FDC;
static FDC fdc;
@@ -103,6 +108,21 @@ void fdc_reset()
// pclog("Reset FDC\n");
}
int fdc_is_deleted()
{
return fdc.deleted & 1;
}
int fdc_is_sk()
{
return (fdc.deleted & 0x20) ? 1 : 0;
}
void fdc_set_wrong_am()
{
fdc.wrong_am = 1;
}
int fdc_get_drive()
{
return fdc.drive;
@@ -621,6 +641,8 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
break;
case 2: /*Read track*/
fdc.sc=0;
fdc.wrong_am=0;
fdc.pnum=0;
fdc.ptot=8;
fdc.stat=0x90;
@@ -638,6 +660,10 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
fdc.stat=0x90;
break;
case 5: /*Write data*/
case 9: /*Write deleted data*/
fdc.sc=0;
fdc.wrong_am=0;
fdc.deleted = ((fdc.command&0x1F) == 9) ? 1 : 0;
// printf("Write data!\n");
fdc.pnum=0;
fdc.ptot=8;
@@ -647,6 +673,13 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
// readflash=1;
break;
case 6: /*Read data*/
case 0xC: /*Read deleted data*/
case 0x16: /*Verify*/
fdc.sc=0;
fdc.wrong_am=0;
fdc.deleted = ((fdc.command&0x1F) == 0xC) ? 1 : 0;
if ((fdc.command&0x1F) == 0x16) fdc.deleted = 2;
fdc.deleted |= (fdc.command & 0x20);
fdc.pnum=0;
fdc.ptot=8;
fdc.stat=0x90;
@@ -822,6 +855,7 @@ bad_command:
break;
case 5: /*Write data*/
case 9: /*Write deleted data*/
fdc_rate(fdc.drive);
fdc.head=fdc.params[2];
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
@@ -848,7 +882,10 @@ bad_command:
// ioc_fiq(IOC_FIQ_DISC_DATA);
break;
case 0x16: /*Verify*/
if (fdc.params[0] & 0x80) fdc.sc = fdc.params[7];
case 6: /*Read data*/
case 0xC: /*Read deleted data*/
fdc_rate(fdc.drive);
fdc.head=fdc.params[2];
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
@@ -1084,6 +1121,11 @@ void fdc_poll_readwrite_finish()
fdc.stat=0xD0;
fdc.res[4]=(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
if (fdc.wrong_am)
{
fdc.res[6] |= 0x40;
fdc.wrong_am = 0;
}
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
@@ -1100,6 +1142,11 @@ void fdc_no_dma_end()
fdc.res[4]=0x40|(fdd_get_head(fdc.drive ^ fdd_swap)?4:0)|fdc.drive;
fdc.res[5]=0x80; /*NDE (No DMA End)*/
fdc.res[6]=0;
if (fdc.wrong_am)
{
fdc.res[6] |= 0x40;
fdc.wrong_am = 0;
}
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
@@ -1162,14 +1209,45 @@ void fdc_callback()
disctime = 0;
return;
case 5: /*Write data*/
case 9: /*Write deleted data*/
case 6: /*Read data*/
case 0xC: /*Read deleted data*/
case 0x1C: /*Verify*/
// rpclog("Read data %i\n", fdc.tc);
if ((discint == 6) || (discint == 0xC))
{
if (fdc.wrong_am && !(fdc.deleted & 0x20))
{
/* Mismatching data address mark and no skip, set TC. */
fdc.tc = 1;
}
}
if (fdc.tc)
{
fdc_poll_readwrite_finish();
return;
}
readflash = 1;
if ((discint == 0x16) && (fdc.params[0] & 0x80))
{
/* VERIFY command, EC set */
fdc.sc--;
if (!fdc.sc)
{
fdc_poll_readwrite_finish();
return;
}
/* The rest is processed normally per MT flag and EOT. */
}
else if ((discint == 0x16) && !(fdc.params[0] & 0x80))
{
/* VERIFY command, EC clear */
if ((fdc.sector == fdc.params[5]) && (fdc.head == (fdc.command & 0x80) ? 1 : 0))
{
fdc_poll_readwrite_finish();
return;
}
}
if (fdc.sector == fdc.params[5])
{
/* Reached end of track, MT bit is clear */
@@ -1410,6 +1488,12 @@ void fdc_overrun()
int fdc_data(uint8_t data)
{
if (fdc.deleted & 2)
{
/* We're in a VERIFY command, so return with 0. */
return 0;
}
if (fdc.tc)
return 0;