Added the FDC SCAN EQUAL, SCAN LOW OR EQUAL, and SCAN HIGH OR EQUAL commands.
This commit is contained in:
11
src/disc.c
11
src/disc.c
@@ -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;
|
||||
|
@@ -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);
|
||||
|
101
src/disc_86f.c
101
src/disc_86f.c
@@ -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);
|
||||
|
@@ -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);
|
||||
|
||||
|
156
src/disc_fdi.c
156
src/disc_fdi.c
@@ -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);
|
||||
|
@@ -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
121
src/fdc.c
@@ -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;
|
||||
|
@@ -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();
|
||||
|
Reference in New Issue
Block a user