Added the FDC SCAN EQUAL, SCAN LOW OR EQUAL, and SCAN HIGH OR EQUAL commands.

This commit is contained in:
OBattler
2016-10-05 05:37:07 +02:00
parent 8c439a1bec
commit e1da051f44
8 changed files with 378 additions and 18 deletions

View File

@@ -137,6 +137,7 @@ void disc_close(int drive)
drives[drive].seek = NULL;
drives[drive].readsector = NULL;
drives[drive].writesector = NULL;
drives[drive].comparesector = NULL;
drives[drive].readaddress = NULL;
drives[drive].format = NULL;
drives[drive].realtrack = NULL;
@@ -309,6 +310,16 @@ void disc_writesector(int drive, int sector, int track, int side, int density, i
disc_notfound = 1000;
}
void disc_comparesector(int drive, int sector, int track, int side, int density, int sector_size)
{
drive ^= fdd_swap;
if (drives[drive].comparesector)
drives[drive].comparesector(drive, sector, track, side, density, sector_size);
else
disc_notfound = 1000;
}
void disc_readaddress(int drive, int track, int side, int density)
{
drive ^= fdd_swap;

View File

@@ -6,6 +6,7 @@ typedef struct
void (*seek)(int drive, int track);
void (*readsector)(int drive, int sector, int track, int side, int density, int sector_size);
void (*writesector)(int drive, int sector, int track, int side, int density, int sector_size);
void (*comparesector)(int drive, int sector, int track, int side, int density, int sector_size);
void (*readaddress)(int drive, int track, int side, int density);
void (*format)(int drive, int track, int side, int density, uint8_t fill);
int (*hole)(int drive);
@@ -28,6 +29,7 @@ void disc_poll();
void disc_seek(int drive, int track);
void disc_readsector(int drive, int sector, int track, int side, int density, int sector_size);
void disc_writesector(int drive, int sector, int track, int side, int density, int sector_size);
void disc_comparesector(int drive, int sector, int track, int side, int density, int sector_size);
void disc_readaddress(int drive, int track, int side, int density);
void disc_format(int drive, int track, int side, int density, uint8_t fill);
int disc_realtrack(int drive, int track);

View File

@@ -29,6 +29,10 @@ enum
STATE_WRITE_SECTOR,
STATE_WRITE_SECTOR_CRC,
STATE_WRITE_SECTOR_GAP3,
STATE_COMPARE_FIND_SECTOR,
STATE_COMPARE_SECTOR,
STATE_COMPARE_SECTOR_CRC,
STATE_COMPARE_SECTOR_GAP3,
STATE_READ_FIND_ADDRESS,
STATE_READ_ADDRESS,
STATE_FORMAT_FIND,
@@ -129,6 +133,7 @@ static struct
uint8_t id_read_state;
uint8_t sector_count;
uint8_t format_state;
uint16_t satisfying_bytes;
} d86f[2];
uint8_t encoded_fm[64] = { 0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF,
@@ -535,6 +540,7 @@ void d86f_common_handlers(int drive)
{
drives[drive].readsector = d86f_readsector;
drives[drive].writesector = d86f_writesector;
drives[drive].comparesector=d86f_comparesector;
drives[drive].readaddress = d86f_readaddress;
drives[drive].hole = d86f_hole;
drives[drive].byteperiod = d86f_byteperiod;
@@ -1084,7 +1090,7 @@ void d86f_readsector(int drive, int sector, int track, int side, int rate, int s
d86f[drive].rw_sector_id.dword = 0xFFFFFFFF;
d86f[drive].last_sector.dword = 0xFFFFFFFF;
d86f[drive].req_sector.id.n = sector_size;
d86f[drive].index_count = 0;
d86f[drive].index_count = d86f[drive].satisfying_bytes = 0;
d86f[drive].wait_state = 1;
d86f_new_style_reset(drive);
d86f[drive].state = STATE_READ_FIND_SECTOR;
@@ -1118,12 +1124,46 @@ void d86f_writesector(int drive, int sector, int track, int side, int rate, int
d86f[drive].rw_sector_id.dword = 0xFFFFFFFF;
d86f[drive].last_sector.dword = 0xFFFFFFFF;
d86f_drive = drive;
d86f[drive].index_count = 0;
d86f[drive].index_count = d86f[drive].satisfying_bytes = 0;
d86f[drive].wait_state = 1;
d86f_new_style_reset(drive);
d86f[drive].state = STATE_WRITE_FIND_SECTOR;
}
void d86f_comparesector(int drive, int sector, int track, int side, int rate, int sector_size)
{
d86f[drive].req_sector.id.c = track;
d86f[drive].req_sector.id.h = side;
d86f[drive].req_sector.id.r = sector;
d86f[drive].req_sector.id.n = sector_size;
// pclog("d86f_comparesector: drive=%c: fdc_period=%i img_period=%i rate=%i chrn=%08X\n", drive + 0x41, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, d86f[drive].req_sector.dword);
if (writeprot[drive] || swwp)
{
// pclog("Write protected\n");
fdc_writeprotect();
return;
}
if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1))
{
// pclog("Wrong side\n");
fdc_notfound();
d86f[drive].state = STATE_IDLE;
d86f[drive].index_count = 0;
return;
}
d86f[drive].rw_sector_id.dword = 0xFFFFFFFF;
d86f[drive].last_sector.dword = 0xFFFFFFFF;
d86f_drive = drive;
d86f[drive].index_count = d86f[drive].satisfying_bytes = 0;
d86f[drive].wait_state = 1;
d86f_new_style_reset(drive);
d86f[drive].state = STATE_COMPARE_FIND_SECTOR;
}
void d86f_readaddress(int drive, int track, int side, int rate)
{
// pclog("d86f_readaddress: fdc_period=%i img_period=%i rate=%i track=%i side=%i\n", fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, track, side);
@@ -1142,7 +1182,7 @@ void d86f_readaddress(int drive, int track, int side, int rate)
d86f[drive].rw_sector_id.dword = 0xFFFFFFFF;
d86f[drive].last_sector.dword = 0xFFFFFFFF;
d86f_drive = drive;
d86f[drive].index_count = 0;
d86f[drive].index_count = d86f[drive].satisfying_bytes = 0;
d86f[drive].wait_state = 1;
d86f_new_style_reset(drive);
d86f[drive].state = STATE_READ_FIND_ADDRESS;
@@ -1583,6 +1623,7 @@ int d86f_find_state_nf(int drive)
int temp;
temp = (d86f[drive].state == STATE_READ_FIND_SECTOR);
temp = temp || d86f_find_state_nf_ignore_id(drive);
temp = (d86f[drive].state == STATE_COMPARE_FIND_SECTOR);
temp = temp || (d86f[drive].state == STATE_WRITE_FIND_SECTOR);
temp = temp || (d86f[drive].state == STATE_READ_FIND_ADDRESS);
return temp;
@@ -1611,6 +1652,7 @@ int d86f_read_state_crc(int drive)
temp = (d86f[drive].state == STATE_READ_SECTOR_CRC);
temp = temp || (d86f[drive].state == STATE_READ_FIRST_SECTOR_CRC);
temp = temp || (d86f[drive].state == STATE_READ_NEXT_SECTOR_CRC);
temp = temp || (d86f[drive].state == STATE_COMPARE_SECTOR_CRC);
return temp;
}
@@ -1620,6 +1662,7 @@ int d86f_read_state_gap3(int drive)
temp = (d86f[drive].state == STATE_READ_SECTOR_GAP3);
temp = temp || (d86f[drive].state == STATE_READ_FIRST_SECTOR_GAP3);
temp = temp || (d86f[drive].state == STATE_READ_NEXT_SECTOR_GAP3);
temp = temp || (d86f[drive].state == STATE_COMPARE_SECTOR_GAP3);
return temp;
}
@@ -1987,6 +2030,46 @@ void d86f_poll_readwrite(int drive, int side)
}
d86f_calccrc(drive, data & 0xff);
}
else if (d86f[drive].state == STATE_COMPARE_SECTOR)
{
max_len = d86f_data_size(drive);
if (d86f[drive].datac < d86f_get_data_len(drive))
{
data = fdc_getdata(d86f[drive].datac == ((128 << ((uint32_t) d86f[drive].last_sector.id.n)) - 1));
if (data == -1)
{
data = 0;
}
}
else
{
data = 0;
}
switch(fdc_get_compare_condition())
{
case 0: /* SCAN EQUAL */
if ((data == d86f[drive].track_data_byte) || (data == 0xFF))
{
d86f[drive].satisfying_bytes++;
}
break;
case 1: /* SCAN LOW OR EQUAL */
if ((data <= d86f[drive].track_data_byte) || (data == 0xFF))
{
d86f[drive].satisfying_bytes++;
}
break;
case 2: /* SCAN HIGH OR EQUAL */
if ((data >= d86f[drive].track_data_byte) || (data == 0xFF))
{
d86f[drive].satisfying_bytes++;
}
break;
}
d86f_calccrc(drive, data & 0xff);
}
else if (d86f_read_state_crc(drive))
{
max_len = 2;
@@ -2022,7 +2105,14 @@ void d86f_poll_readwrite(int drive, int side)
else
{
// pclog("Read finished (%i %i %i %i)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n);
fdc_sector_finishread();
if (d86f[drive].state == STATE_COMPARE_SECTOR_GAP3)
{
fdc_sector_finishcompare((d86f[drive].satisfying_bytes == ((128 << ((uint32_t) d86f[drive].last_sector.id.n)) - 1)) ? 1 : 0);
}
else
{
fdc_sector_finishread();
}
}
return;
}
@@ -2266,6 +2356,7 @@ void d86f_poll_find_nf(int drive, int side)
case STATE_WRITE_FIND_SECTOR:
case STATE_READ_FIND_FIRST_SECTOR:
case STATE_READ_FIND_NEXT_SECTOR:
case STATE_COMPARE_FIND_SECTOR:
/* If the data address mark counter is anything other than 0, then either the ID matches or the FDC is in the ignore sector ID mode (ie. the READ TRACK command).
Also, the bitcell period, etc. are already checked during the wait state which is designed to never end in case of a mismatch.
Therefore, ensuring the data address mark acounter is at a correct length is all we need to do. */
@@ -2574,6 +2665,7 @@ void d86f_poll_find_am_fm(int drive, int side)
case STATE_WRITE_FIND_SECTOR:
case STATE_READ_FIND_FIRST_SECTOR:
case STATE_READ_FIND_NEXT_SECTOR:
case STATE_COMPARE_FIND_SECTOR:
d86f[drive].state++;
d86f_poll_advancebyte(drive, side);
d86f[drive].id_was_read = 0; /* Invalidate ID was read flag to avoid false positives after read. */
@@ -2644,6 +2736,7 @@ void d86f_poll_find_am_mfm(int drive, int side)
case STATE_WRITE_FIND_SECTOR:
case STATE_READ_FIND_FIRST_SECTOR:
case STATE_READ_FIND_NEXT_SECTOR:
case STATE_COMPARE_FIND_SECTOR:
// pclog("Advancing state (%04X)...\n", d86f[drive].calc_crc);
d86f[drive].state++;
d86f_poll_advancebyte(drive, side);

View File

@@ -13,6 +13,7 @@ int d86f_realtrack(int track, int drive);
void d86f_reset(int drive, int side);
void d86f_readsector(int drive, int sector, int track, int side, int density, int sector_size);
void d86f_writesector(int drive, int sector, int track, int side, int density, int sector_size);
void d86f_comparesector(int drive, int sector, int track, int side, int rate, int sector_size);
void d86f_readaddress(int drive, int sector, int side, int density);
void d86f_format(int drive, int sector, int side, int density, uint8_t fill);

View File

@@ -7,6 +7,7 @@
#include "disc.h"
#include "disc_img.h"
#include "disc_fdi.h"
#include "fdc.h"
#include "fdi2raw.h"
static struct
@@ -27,11 +28,12 @@ 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_readpos, fdi_inreadaddr;
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;
static int pollbytesleft=0,pollbitsleft=0,polltotalbytes=0;
int fdi_realtrack(int drive, int track)
{
@@ -129,6 +131,7 @@ void fdi_load(int drive, char *fn)
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;
@@ -215,8 +218,10 @@ void fdi_readsector(int drive, int sector, int track, int side, int rate, int se
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)
@@ -237,8 +242,37 @@ void fdi_writesector(int drive, int sector, int track, int side, int rate, int s
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)
@@ -257,8 +291,10 @@ void fdi_readaddress(int drive, int track, int side, int rate)
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)
@@ -277,12 +313,14 @@ void fdi_format(int drive, int track, int side, int rate, uint8_t fill)
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,fdi_nextsector=0,inreadop=0;
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;
@@ -322,6 +360,7 @@ void fdi_poll()
{
int tempi, c;
int bitcount;
int indata, readdata;
int side = fdd_get_head(fdi_drive);
for (bitcount = 0; bitcount < 16; bitcount++)
@@ -351,7 +390,7 @@ void fdi_poll()
fdc_writeprotect();
return;
}
if (!fdi_inread && !fdi_inreadaddr)
if (!fdi_inread && !fdi_inreadaddr && !fdi_incompare)
return;
if (fdi_pos == fdi[fdi_drive].trackindex[side][fdi_density])
{
@@ -463,6 +502,95 @@ void fdi_poll()
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)
@@ -483,7 +611,15 @@ void fdi_poll()
{
pollbytesleft = sectorsize;
pollbitsleft = 16;
readdatapoll = 1;
if (fdi_inread)
{
readdatapoll = 1;
}
else
{
polltotalbytes = sectorsize;
comparedatapoll = 1;
}
fdi_nextsector = 0;
crc = 0xffff;
if (fdi_buffer == 0xF56A) calccrc(0xF8);
@@ -511,7 +647,15 @@ void fdi_poll()
{
pollbytesleft = sectorsize;
pollbitsleft = 16;
readdatapoll = 1;
if (fdi_inread)
{
readdatapoll = 1;
}
else
{
polltotalbytes = sectorsize;
comparedatapoll = 1;
}
fdi_nextsector = 0;
crc = 0xcdb4;
if (fdi_buffer == 0xF56A) calccrc(0xF8);

View File

@@ -7,6 +7,7 @@ void fdi_close(int drive);
void fdi_seek(int drive, int track);
void fdi_readsector(int drive, int sector, int track, int side, int density, int sector_size);
void fdi_writesector(int drive, int sector, int track, int side, int density, int sector_size);
void fdi_comparesector(int drive, int sector, int track, int side, int density, int sector_size);
void fdi_readaddress(int drive, int sector, int side, int density);
void fdi_format(int drive, int sector, int side, int density, uint8_t fill);
int fdi_hole(int drive);

121
src/fdc.c
View File

@@ -78,6 +78,7 @@ typedef struct FDC
int wrong_am;
int sc;
int satisfying_sectors;
} FDC;
static FDC fdc;
@@ -108,6 +109,20 @@ void fdc_reset()
// pclog("Reset FDC\n");
}
int fdc_get_compare_condition()
{
switch (discint)
{
case 0x11:
default:
return 0;
case 0x19:
return 1;
case 0x1D:
return 2;
}
}
int fdc_is_deleted()
{
return fdc.deleted & 1;
@@ -641,6 +656,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
break;
case 2: /*Read track*/
fdc.satisfying_sectors=0;
fdc.sc=0;
fdc.wrong_am=0;
fdc.pnum=0;
@@ -661,6 +677,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
break;
case 5: /*Write data*/
case 9: /*Write deleted data*/
fdc.satisfying_sectors=0;
fdc.sc=0;
fdc.wrong_am=0;
fdc.deleted = ((fdc.command&0x1F) == 9) ? 1 : 0;
@@ -674,7 +691,11 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
break;
case 6: /*Read data*/
case 0xC: /*Read deleted data*/
case 0x11: /*Scan equal*/
case 0x19: /*Scan low or equal*/
case 0x16: /*Verify*/
case 0x1D: /*Scan high or equal*/
fdc.satisfying_sectors=0;
fdc.sc=0;
fdc.wrong_am=0;
fdc.deleted = ((fdc.command&0x1F) == 0xC) ? 1 : 0;
@@ -882,6 +903,35 @@ bad_command:
// ioc_fiq(IOC_FIQ_DISC_DATA);
break;
case 0x11: /*Scan equal*/
case 0x19: /*Scan low or equal*/
case 0x1D: /*Scan high or equal*/
fdc_rate(fdc.drive);
fdc.head=fdc.params[2];
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
fdc.sector=fdc.params[3];
fdc.eot[fdc.drive] = fdc.params[5];
fdc.gap = fdc.params[6];
fdc.dtl = fdc.params[7];
if (fdc.config & 0x40)
{
if (fdc.params[1] != fdc.track[fdc.drive])
{
fdc_seek(fdc.drive, ((int) fdc.params[1]) - ((int) fdc.track[fdc.drive]));
fdc.track[fdc.drive] = fdc.params[1];
}
}
fdc.rw_track = fdc.params[1];
disc_comparesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0;
fdc.written = 0;
readflash = 1;
fdc.pos = 0;
if (fdc.pcjr)
fdc.stat = 0xb0;
// ioc_fiq(IOC_FIQ_DISC_DATA);
break;
case 0x16: /*Verify*/
if (fdc.params[0] & 0x80) fdc.sc = fdc.params[7];
case 6: /*Read data*/
@@ -1113,7 +1163,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
return temp;
}
void fdc_poll_readwrite_finish()
void fdc_poll_readwrite_finish(int compare)
{
fdc.inread = 0;
discint=-2;
@@ -1126,6 +1176,17 @@ void fdc_poll_readwrite_finish()
fdc.res[6] |= 0x40;
fdc.wrong_am = 0;
}
if (compare)
{
if (!fdc.satisfying_sectors)
{
fdc.res[6] |= 4;
}
else if (fdc.satisfying_sectors == (fdc.params[5] << ((fdc.command & 80) ? 1 : 0)))
{
fdc.res[6] |= 8;
}
}
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
@@ -1133,7 +1194,7 @@ void fdc_poll_readwrite_finish()
paramstogo=7;
}
void fdc_no_dma_end()
void fdc_no_dma_end(int compare)
{
disctime = 0;
@@ -1147,6 +1208,17 @@ void fdc_no_dma_end()
fdc.res[6] |= 0x40;
fdc.wrong_am = 0;
}
if (compare)
{
if (!fdc.satisfying_sectors)
{
fdc.res[6] |= 4;
}
else if (fdc.satisfying_sectors == (fdc.params[5] << ((fdc.command & 80) ? 1 : 0)))
{
fdc.res[6] |= 8;
}
}
fdc.res[7]=fdc.rw_track;
fdc.res[8]=fdc.head;
fdc.res[9]=fdc.sector;
@@ -1157,6 +1229,7 @@ void fdc_no_dma_end()
void fdc_callback()
{
int temp;
int compare = 0;
disctime = 0;
// pclog("fdc_callback %i %i\n", discint, disctime);
// if (fdc.inread)
@@ -1186,7 +1259,7 @@ void fdc_callback()
// pclog("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]);
if (!fdc.eot[fdc.drive] || fdc.tc)
{
fdc_poll_readwrite_finish();
fdc_poll_readwrite_finish(0);
return;
}
else
@@ -1212,8 +1285,19 @@ void fdc_callback()
case 9: /*Write deleted data*/
case 6: /*Read data*/
case 0xC: /*Read deleted data*/
case 0x11: /*Scan equal*/
case 0x19: /*Scan low or equal*/
case 0x1C: /*Verify*/
case 0x1D: /*Scan high or equal*/
// rpclog("Read data %i\n", fdc.tc);
if ((discint == 0x11) || (discint == 0x19) || (discint == 0x1D))
{
compare = 1;
}
else
{
compare = 0;
}
if ((discint == 6) || (discint == 0xC))
{
if (fdc.wrong_am && !(fdc.deleted & 0x20))
@@ -1224,7 +1308,7 @@ void fdc_callback()
}
if (fdc.tc)
{
fdc_poll_readwrite_finish();
fdc_poll_readwrite_finish(compare);
return;
}
readflash = 1;
@@ -1234,7 +1318,7 @@ void fdc_callback()
fdc.sc--;
if (!fdc.sc)
{
fdc_poll_readwrite_finish();
fdc_poll_readwrite_finish(0);
return;
}
/* The rest is processed normally per MT flag and EOT. */
@@ -1244,7 +1328,7 @@ void fdc_callback()
/* VERIFY command, EC clear */
if ((fdc.sector == fdc.params[5]) && (fdc.head == (fdc.command & 0x80) ? 1 : 0))
{
fdc_poll_readwrite_finish();
fdc_poll_readwrite_finish(0);
return;
}
}
@@ -1255,7 +1339,7 @@ void fdc_callback()
{
fdc.rw_track++;
fdc.sector = 1;
fdc_no_dma_end();
fdc_no_dma_end(compare);
return;
}
/* Reached end of track, MT bit is set, head is 1 */
@@ -1265,7 +1349,7 @@ void fdc_callback()
fdc.sector = 1;
fdc.head &= 0xFE;
fdd_set_head(fdc.drive, 0);
fdc_no_dma_end();
fdc_no_dma_end(compare);
return;
}
if ((fdc.command & 0x80) && (fdd_get_head(fdc.drive ^ fdd_swap) == 0))
@@ -1290,6 +1374,11 @@ void fdc_callback()
case 0x16:
disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
break;
case 0x11:
case 0x19:
case 0x1D:
disc_comparesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
break;
}
fdc.inread = 1;
return;
@@ -1552,6 +1641,14 @@ int fdc_data(uint8_t data)
return 0;
}
void fdc_finishcompare(int satisfying)
{
fdc.satisfying_sectors++;
fdc.inread = 0;
disctime = 200 * TIMER_USEC;
// rpclog("fdc_finishread\n");
}
void fdc_finishread()
{
fdc.inread = 0;
@@ -1559,6 +1656,14 @@ void fdc_finishread()
// rpclog("fdc_finishread\n");
}
void fdc_sector_finishcompare(int satisfying)
{
fdc.satisfying_sectors++;
fdc.inread = 0;
fdc_callback();
// rpclog("fdc_finishread\n");
}
void fdc_sector_finishread()
{
fdc.inread = 0;

View File

@@ -31,6 +31,7 @@ void fdc_update_densel_force(int densel_force);
void fdc_update_drvrate(int drive, int drvrate);
void fdc_update_drv2en(int drv2en);
int fdc_get_compare_condition();
int fdc_is_deleted();
int fdc_is_sk();
void fdc_set_wrong_am();
@@ -47,5 +48,7 @@ int fdc_get_gap2(int drive);
int fdc_get_dtl();
int fdc_get_format_sectors();
void fdc_finishcompare(int satisfying);
void fdc_finishread();
void fdc_sector_finishcompare(int satisfying);
void fdc_sector_finishread();