2016-08-14 22:45:58 -04:00
|
|
|
/* Copyright holders: Sarah Walker, Tenshi
|
2016-08-14 22:07:17 -04:00
|
|
|
see COPYING for more details
|
|
|
|
|
*/
|
2016-06-26 00:34:39 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include "ibm.h"
|
|
|
|
|
#include "disc.h"
|
2016-08-15 03:26:37 +02:00
|
|
|
#include "disc_img.h"
|
2016-06-26 00:34:39 +02:00
|
|
|
#include "disc_fdi.h"
|
|
|
|
|
#include "fdi2raw.h"
|
|
|
|
|
|
|
|
|
|
static struct
|
|
|
|
|
{
|
|
|
|
|
FILE *f;
|
|
|
|
|
FDI *h;
|
|
|
|
|
uint8_t track_data[2][4][256*1024];
|
|
|
|
|
|
|
|
|
|
int sides;
|
|
|
|
|
int tracklen[2][4];
|
|
|
|
|
int trackindex[2][4];
|
|
|
|
|
|
|
|
|
|
int lasttrack;
|
|
|
|
|
} fdi[2];
|
|
|
|
|
|
|
|
|
|
static uint8_t fdi_timing[256*1024];
|
|
|
|
|
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 uint16_t CRCTable[256];
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
static int pollbytesleft=0,pollbitsleft=0;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
|
|
|
|
int fdi_realtrack(int drive, int track)
|
|
|
|
|
{
|
|
|
|
|
return track;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void fdi_setupcrc(uint16_t poly, uint16_t rvalue)
|
|
|
|
|
{
|
|
|
|
|
int c = 256, bc;
|
|
|
|
|
uint16_t crctemp;
|
|
|
|
|
|
|
|
|
|
while(c--)
|
|
|
|
|
{
|
|
|
|
|
crctemp = c << 8;
|
|
|
|
|
bc = 8;
|
|
|
|
|
|
|
|
|
|
while(bc--)
|
|
|
|
|
{
|
|
|
|
|
if(crctemp & 0x8000)
|
|
|
|
|
{
|
|
|
|
|
crctemp = (crctemp << 1) ^ poly;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
crctemp <<= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CRCTable[c] = crctemp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fdi_init()
|
|
|
|
|
{
|
|
|
|
|
// printf("FDI reset\n");
|
|
|
|
|
memset(&fdi, 0, sizeof(fdi));
|
|
|
|
|
fdi_setupcrc(0x1021, 0xcdb4);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
int fdi_byteperiod(int drive)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
|
|
|
|
switch (fdi2raw_get_bit_rate(fdi[drive].h))
|
|
|
|
|
{
|
|
|
|
|
case 1000:
|
2016-07-19 02:44:32 +02:00
|
|
|
return 8;
|
2016-06-26 00:34:39 +02:00
|
|
|
case 500:
|
2016-07-19 02:44:32 +02:00
|
|
|
return 16;
|
|
|
|
|
case 300:
|
|
|
|
|
return 26;
|
|
|
|
|
case 250:
|
|
|
|
|
return 32;
|
2016-06-26 00:34:39 +02:00
|
|
|
default:
|
2016-07-19 02:44:32 +02:00
|
|
|
return 32;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
int fdi_hole(int drive)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
|
|
|
|
switch (fdi2raw_get_bit_rate(fdi[drive].h))
|
|
|
|
|
{
|
|
|
|
|
case 1000:
|
2016-07-19 02:44:32 +02:00
|
|
|
return 2;
|
2016-06-26 00:34:39 +02:00
|
|
|
case 500:
|
2016-07-19 02:44:32 +02:00
|
|
|
return 1;
|
2016-06-26 00:34:39 +02:00
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fdi_load(int drive, char *fn)
|
|
|
|
|
{
|
2016-08-15 03:26:37 +02:00
|
|
|
char header[26];
|
|
|
|
|
|
2016-06-26 00:34:39 +02:00
|
|
|
writeprot[drive] = fwriteprot[drive] = 1;
|
|
|
|
|
fdi[drive].f = fopen(fn, "rb");
|
|
|
|
|
if (!fdi[drive].f) return;
|
2016-08-15 03:26:37 +02:00
|
|
|
|
2016-08-15 03:53:56 +02:00
|
|
|
fread(header, 1, 25, fdi[drive].f);
|
|
|
|
|
fseek(fdi[drive].f, 0, SEEK_SET);
|
2016-08-15 03:40:00 +02:00
|
|
|
header[25] = 0;
|
|
|
|
|
if (strcmp(header, "Formatted Disk Image file") != 0)
|
2016-08-15 03:26:37 +02:00
|
|
|
{
|
|
|
|
|
/* This is a Japanese FDI file. */
|
|
|
|
|
pclog("fdi_load(): Japanese FDI file detected, redirecting to IMG loader\n");
|
2016-08-15 03:53:56 +02:00
|
|
|
fclose(fdi[drive].f);
|
|
|
|
|
img_load(drive, fn);
|
2016-08-15 03:26:37 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-26 00:34:39 +02:00
|
|
|
fdi[drive].h = fdi2raw_header(fdi[drive].f);
|
|
|
|
|
// if (!fdih[drive]) printf("Failed to load!\n");
|
|
|
|
|
fdi[drive].lasttrack = fdi2raw_get_last_track(fdi[drive].h);
|
|
|
|
|
fdi[drive].sides = fdi2raw_get_last_head(fdi[drive].h) + 1;
|
|
|
|
|
// printf("Last track %i\n",fdilasttrack[drive]);
|
|
|
|
|
drives[drive].seek = fdi_seek;
|
|
|
|
|
drives[drive].readsector = fdi_readsector;
|
|
|
|
|
drives[drive].writesector = fdi_writesector;
|
|
|
|
|
drives[drive].readaddress = fdi_readaddress;
|
|
|
|
|
drives[drive].hole = fdi_hole;
|
|
|
|
|
drives[drive].byteperiod = fdi_byteperiod;
|
|
|
|
|
drives[drive].poll = fdi_poll;
|
|
|
|
|
drives[drive].format = fdi_format;
|
|
|
|
|
drives[drive].stop = fdi_stop;
|
|
|
|
|
drives[drive].realtrack = fdi_realtrack;
|
|
|
|
|
// pclog("Loaded as FDI\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fdi_close(int drive)
|
|
|
|
|
{
|
|
|
|
|
if (fdi[drive].h)
|
|
|
|
|
fdi2raw_header_free(fdi[drive].h);
|
|
|
|
|
if (fdi[drive].f)
|
|
|
|
|
fclose(fdi[drive].f);
|
|
|
|
|
fdi[drive].f = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fdi_seek(int drive, int track)
|
|
|
|
|
{
|
|
|
|
|
int c;
|
|
|
|
|
int density;
|
|
|
|
|
|
|
|
|
|
if (!fdi[drive].f)
|
|
|
|
|
return;
|
|
|
|
|
// printf("Track start %i\n",track);
|
|
|
|
|
if (track < 0)
|
|
|
|
|
track = 0;
|
|
|
|
|
if (track > fdi[drive].lasttrack)
|
|
|
|
|
track = fdi[drive].lasttrack - 1;
|
|
|
|
|
|
|
|
|
|
for (density = 0; density < 4; density++)
|
|
|
|
|
{
|
|
|
|
|
int c = fdi2raw_loadtrack(fdi[drive].h, (uint16_t *)fdi[drive].track_data[0][density],
|
|
|
|
|
(uint16_t *)fdi_timing,
|
|
|
|
|
track * fdi[drive].sides,
|
|
|
|
|
&fdi[drive].tracklen[0][density],
|
|
|
|
|
&fdi[drive].trackindex[0][density], NULL, density);
|
|
|
|
|
if (!c)
|
|
|
|
|
memset(fdi[drive].track_data[0][density], 0, fdi[drive].tracklen[0][density]);
|
|
|
|
|
|
|
|
|
|
if (fdi[drive].sides == 2)
|
|
|
|
|
{
|
|
|
|
|
c = fdi2raw_loadtrack(fdi[drive].h, (uint16_t *)fdi[drive].track_data[1][density],
|
|
|
|
|
(uint16_t *)fdi_timing,
|
|
|
|
|
(track * fdi[drive].sides) + 1,
|
|
|
|
|
&fdi[drive].tracklen[1][density],
|
|
|
|
|
&fdi[drive].trackindex[1][density], NULL, density);
|
|
|
|
|
if (!c)
|
|
|
|
|
memset(fdi[drive].track_data[1][density], 0, fdi[drive].tracklen[1][density]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
memset(fdi[drive].track_data[1][density], 0, 65536);
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi[drive].tracklen[1][density] = fdi[drive].tracklen[1][density] = 10000;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fdi_writeback(int drive, int track)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fdi_readsector(int drive, int sector, int track, int side, int rate, int sector_size)
|
|
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_revs = 0;
|
|
|
|
|
fdi_sector = sector;
|
|
|
|
|
fdi_track = track;
|
|
|
|
|
fdi_side = side;
|
|
|
|
|
fdi_n = sector_size;
|
|
|
|
|
fdi_drive = drive;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 2)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 1;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 0)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 2;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 3)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 3;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
|
|
|
|
// 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");
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_inread = 1;
|
|
|
|
|
fdi_inwrite = 0;
|
|
|
|
|
fdi_inreadaddr = 0;
|
|
|
|
|
fdi_readpos = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fdi_writesector(int drive, int sector, int track, int side, int rate, int sector_size)
|
|
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_revs = 0;
|
|
|
|
|
fdi_sector = sector;
|
|
|
|
|
fdi_track = track;
|
|
|
|
|
fdi_side = side;
|
|
|
|
|
fdi_n = sector_size;
|
|
|
|
|
fdi_drive = drive;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 2)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 1;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 0)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 2;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 3)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 3;
|
2016-06-26 00:34:39 +02:00
|
|
|
// pclog("Write sector %i %i %i %i\n",drive,side,track,sector);
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_inread = 0;
|
|
|
|
|
fdi_inwrite = 1;
|
|
|
|
|
fdi_inreadaddr = 0;
|
|
|
|
|
fdi_readpos = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fdi_readaddress(int drive, int track, int side, int rate)
|
|
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_revs = 0;
|
|
|
|
|
fdi_track = track;
|
|
|
|
|
fdi_side = side;
|
|
|
|
|
fdi_drive = drive;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 2)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 1;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 0)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 2;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 3)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 3;
|
2016-06-26 00:34:39 +02:00
|
|
|
// pclog("Read address %i %i %i %i %i %p\n",drive,side,track, rate, fdi_density, &fdi_inreadaddr);
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_inread = 0;
|
|
|
|
|
fdi_inwrite = 0;
|
|
|
|
|
fdi_inreadaddr = 1;
|
|
|
|
|
fdi_readpos = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fdi_format(int drive, int track, int side, int rate, uint8_t fill)
|
|
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_revs = 0;
|
|
|
|
|
fdi_track = track;
|
|
|
|
|
fdi_side = side;
|
|
|
|
|
fdi_drive = drive;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 2)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 1;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 0)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 2;
|
2016-06-26 00:34:39 +02:00
|
|
|
if (rate == 3)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_density = 3;
|
2016-06-26 00:34:39 +02:00
|
|
|
// pclog("Format %i %i %i\n",drive,side,track);
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_inread = 0;
|
|
|
|
|
fdi_inwrite = 1;
|
|
|
|
|
fdi_inreadaddr = 0;
|
|
|
|
|
fdi_readpos = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
static uint16_t fdi_buffer;
|
|
|
|
|
static int readidpoll=0,readdatapoll=0,fdi_nextsector=0,inreadop=0;
|
|
|
|
|
static uint8_t fdi_sectordat[1026];
|
|
|
|
|
static int lastfdidat[2],sectorcrc[2];
|
|
|
|
|
static int sectorsize,fdc_sectorsize;
|
|
|
|
|
static int ddidbitsleft=0;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
|
|
|
|
static uint8_t decodefm(uint16_t dat)
|
|
|
|
|
{
|
|
|
|
|
uint8_t temp;
|
|
|
|
|
temp = 0;
|
|
|
|
|
if (dat & 0x0001) temp |= 1;
|
|
|
|
|
if (dat & 0x0004) temp |= 2;
|
|
|
|
|
if (dat & 0x0010) temp |= 4;
|
|
|
|
|
if (dat & 0x0040) temp |= 8;
|
|
|
|
|
if (dat & 0x0100) temp |= 16;
|
|
|
|
|
if (dat & 0x0400) temp |= 32;
|
|
|
|
|
if (dat & 0x1000) temp |= 64;
|
|
|
|
|
if (dat & 0x4000) temp |= 128;
|
|
|
|
|
return temp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fdi_stop(int drive)
|
|
|
|
|
{
|
|
|
|
|
// pclog("fdi_stop\n");
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_inread = fdi_inwrite = fdi_inreadaddr = 0;
|
|
|
|
|
fdi_nextsector = ddidbitsleft = pollbitsleft = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
static uint16_t crc;
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
static void calccrc(uint8_t byte)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
crc = (crc << 8) ^ CRCTable[(crc >> 8)^byte];
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
static int fdi_indextime_blank = 6250 * 8;
|
|
|
|
|
void fdi_poll()
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
|
|
|
|
int tempi, c;
|
|
|
|
|
int bitcount;
|
|
|
|
|
|
|
|
|
|
for (bitcount = 0; bitcount < 16; bitcount++)
|
|
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
if (fdi_pos >= fdi[fdi_drive].tracklen[fdi_side][fdi_density])
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_pos = 0;
|
|
|
|
|
if (fdi[fdi_drive].tracklen[fdi_side][fdi_density])
|
2016-06-26 00:34:39 +02:00
|
|
|
fdc_indexpulse();
|
|
|
|
|
else
|
|
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_indextime_blank--;
|
|
|
|
|
if (!fdi_indextime_blank)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_indextime_blank = 6250 * 8;
|
2016-06-26 00:34:39 +02:00
|
|
|
fdc_indexpulse();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
tempi = fdi[fdi_drive].track_data[fdi_side][fdi_density][((fdi_pos >> 3) & 0xFFFF) ^ 1] & (1 << (7 - (fdi_pos & 7)));
|
|
|
|
|
fdi_pos++;
|
|
|
|
|
fdi_buffer <<= 1;
|
|
|
|
|
fdi_buffer |= (tempi ? 1 : 0);
|
|
|
|
|
if (fdi_inwrite)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_inwrite = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
fdc_writeprotect();
|
2016-07-19 02:44:32 +02:00
|
|
|
return;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
if (!fdi_inread && !fdi_inreadaddr)
|
|
|
|
|
return;
|
|
|
|
|
if (fdi_pos == fdi[fdi_drive].trackindex[fdi_side][fdi_density])
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_revs++;
|
|
|
|
|
if (fdi_revs == 3)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
|
|
|
|
// pclog("Not found!\n");
|
|
|
|
|
fdc_notfound();
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_inread = fdi_inreadaddr = 0;
|
|
|
|
|
return;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
if (fdi_sector == SECTOR_FIRST)
|
|
|
|
|
fdi_sector = SECTOR_NEXT;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
if (pollbitsleft)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
pollbitsleft--;
|
|
|
|
|
if (!pollbitsleft)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
pollbytesleft--;
|
|
|
|
|
if (pollbytesleft) pollbitsleft = 16; /*Set up another word if we need it*/
|
|
|
|
|
if (readidpoll)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_sectordat[5 - pollbytesleft] = decodefm(fdi_buffer);
|
|
|
|
|
if (fdi_inreadaddr && !fdc_sectorid)// && pollbytesleft > 1)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
// rpclog("inreadaddr - %02X\n", fdi_sectordat[5 - pollbytesleft]);
|
|
|
|
|
fdc_data(fdi_sectordat[5 - pollbytesleft]);
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
if (!pollbytesleft)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
// pclog("Header over %i,%i %i,%i\n", fdi_sectordat[0], fdi_sectordat[2], fdi_track, fdi_sector);
|
|
|
|
|
if ((fdi_sectordat[0] == fdi_track && (fdi_sectordat[3] == fdi_n) && (fdi_sectordat[2] == fdi_sector || fdi_sector == SECTOR_NEXT)) || fdi_inreadaddr)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
crc = (fdi_density) ? 0xcdb4 : 0xffff;
|
|
|
|
|
calccrc(0xFE);
|
2016-06-26 00:34:39 +02:00
|
|
|
for (c = 0; c < 4; c++)
|
2016-07-19 02:44:32 +02:00
|
|
|
calccrc(fdi_sectordat[c]);
|
2016-06-26 00:34:39 +02:00
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
if ((crc >> 8) != fdi_sectordat[4] || (crc & 0xFF) != fdi_sectordat[5])
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
// pclog("Header CRC error : %02X %02X %02X %02X\n",crc>>8,crc&0xFF,fdi_sectordat[4],fdi_sectordat[5]);
|
2016-06-26 00:34:39 +02:00
|
|
|
// dumpregs();
|
|
|
|
|
// exit(-1);
|
2016-07-19 02:44:32 +02:00
|
|
|
inreadop = 0;
|
|
|
|
|
if (fdi_inreadaddr)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
// rpclog("inreadaddr - %02X\n", fdi_sector);
|
|
|
|
|
// fdc_data(fdi_sector);
|
2016-06-26 00:34:39 +02:00
|
|
|
if (fdc_sectorid)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdc_sectorid(fdi_sectordat[0], fdi_sectordat[1], fdi_sectordat[2], fdi_sectordat[3], fdi_sectordat[4], fdi_sectordat[5]);
|
2016-06-26 00:34:39 +02:00
|
|
|
else
|
2016-07-19 02:44:32 +02:00
|
|
|
fdc_finishread();
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
else fdc_headercrcerror();
|
2016-07-19 02:44:32 +02:00
|
|
|
return;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
// pclog("Sector %i,%i %i,%i\n", fdi_sectordat[0], fdi_sectordat[2], fdi_track, fdi_sector);
|
|
|
|
|
if (fdi_sectordat[0] == fdi_track && (fdi_sectordat[2] == fdi_sector || fdi_sector == SECTOR_NEXT) && fdi_inread && !fdi_inreadaddr)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_nextsector = 1;
|
|
|
|
|
readidpoll = 0;
|
|
|
|
|
sectorsize = (1 << (fdi_sectordat[3] + 7)) + 2;
|
|
|
|
|
fdc_sectorsize = fdi_sectordat[3];
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
if (fdi_inreadaddr)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
|
|
|
|
if (fdc_sectorid)
|
2016-07-19 02:44:32 +02:00
|
|
|
fdc_sectorid(fdi_sectordat[0], fdi_sectordat[1], fdi_sectordat[2], fdi_sectordat[3], fdi_sectordat[4], fdi_sectordat[5]);
|
2016-06-26 00:34:39 +02:00
|
|
|
else
|
2016-07-19 02:44:32 +02:00
|
|
|
fdc_finishread();
|
|
|
|
|
fdi_inreadaddr = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
if (readdatapoll)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
// pclog("readdatapoll %i %02x\n", pollbytesleft, decodefm(fdi_buffer));
|
|
|
|
|
if (pollbytesleft > 1)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
calccrc(decodefm(fdi_buffer));
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
else
|
2016-07-19 02:44:32 +02:00
|
|
|
sectorcrc[1 - pollbytesleft] = decodefm(fdi_buffer);
|
|
|
|
|
if (!pollbytesleft)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
fdi_inread = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
//#if 0
|
2016-07-19 02:44:32 +02:00
|
|
|
if ((crc >> 8) != sectorcrc[0] || (crc & 0xFF) != sectorcrc[1])// || (fditrack==79 && fdisect==4 && fdc_side&1))
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
// 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_finishread();
|
2016-06-26 00:34:39 +02:00
|
|
|
fdc_datacrcerror();
|
2016-07-19 02:44:32 +02:00
|
|
|
readdatapoll = 0;
|
|
|
|
|
return;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
//#endif
|
2016-07-19 02:44:32 +02:00
|
|
|
// pclog("End of FDI read %02X %02X %02X %02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1]);
|
|
|
|
|
fdc_data(decodefm(lastfdidat[1]));
|
|
|
|
|
fdc_finishread();
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
else if (lastfdidat[1] != 0)
|
|
|
|
|
fdc_data(decodefm(lastfdidat[1]));
|
|
|
|
|
lastfdidat[1] = lastfdidat[0];
|
|
|
|
|
lastfdidat[0] = fdi_buffer;
|
|
|
|
|
if (!pollbytesleft)
|
|
|
|
|
readdatapoll = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
if (fdi_buffer == 0x4489 && fdi_density)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
|
|
|
|
// rpclog("Found sync\n");
|
2016-07-19 02:44:32 +02:00
|
|
|
ddidbitsleft = 17;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
2016-07-19 02:44:32 +02:00
|
|
|
if (fdi_buffer == 0xF57E && !fdi_density)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
pollbytesleft = 6;
|
|
|
|
|
pollbitsleft = 16;
|
|
|
|
|
readidpoll = 1;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
if ((fdi_buffer == 0xF56F || fdi_buffer == 0xF56A) && !fdi_density)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
if (fdi_nextsector)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
pollbytesleft = sectorsize;
|
|
|
|
|
pollbitsleft = 16;
|
|
|
|
|
readdatapoll = 1;
|
|
|
|
|
fdi_nextsector = 0;
|
|
|
|
|
crc = 0xffff;
|
|
|
|
|
if (fdi_buffer == 0xF56A) calccrc(0xF8);
|
|
|
|
|
else calccrc(0xFB);
|
|
|
|
|
lastfdidat[0] = lastfdidat[1] = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
if (ddidbitsleft)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
ddidbitsleft--;
|
|
|
|
|
if (!ddidbitsleft && !readdatapoll)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
// printf("ID bits over %04X %02X %i\n",fdibuffer,decodefm(fdibuffer),fdipos);
|
|
|
|
|
if (decodefm(fdi_buffer) == 0xFE)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
// printf("Sector header %i %i\n", fdi_inread, fdi_inreadaddr);
|
|
|
|
|
pollbytesleft = 6;
|
|
|
|
|
pollbitsleft = 16;
|
|
|
|
|
readidpoll = 1;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
2016-07-19 02:44:32 +02:00
|
|
|
else if (decodefm(fdi_buffer) == 0xFB)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
// printf("Data header %i %i\n", fdi_inread, fdi_inreadaddr);
|
|
|
|
|
if (fdi_nextsector)
|
2016-06-26 00:34:39 +02:00
|
|
|
{
|
2016-07-19 02:44:32 +02:00
|
|
|
pollbytesleft = sectorsize;
|
|
|
|
|
pollbitsleft = 16;
|
|
|
|
|
readdatapoll = 1;
|
|
|
|
|
fdi_nextsector = 0;
|
|
|
|
|
crc = 0xcdb4;
|
|
|
|
|
if (fdi_buffer == 0xF56A) calccrc(0xF8);
|
|
|
|
|
else calccrc(0xFB);
|
|
|
|
|
lastfdidat[0] = lastfdidat[1] = 0;
|
2016-06-26 00:34:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|