Various changes to FDC emulation.
Support for multiple disc image formats. Added preliminary FDI support.
This commit is contained in:
parent
37fe4a56be
commit
a8159f8c09
20 changed files with 3797 additions and 393 deletions
203
src/disc.c
Normal file
203
src/disc.c
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
#include "ibm.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "disc.h"
|
||||
#include "disc_fdi.h"
|
||||
#include "disc_img.h"
|
||||
#include "fdc.h"
|
||||
#include "timer.h"
|
||||
|
||||
int disc_drivesel = 0;
|
||||
int disc_poll_time = 16;
|
||||
|
||||
int disc_track[2];
|
||||
int writeprot[2], fwriteprot[2];
|
||||
|
||||
DRIVE drives[2];
|
||||
|
||||
int curdrive = 0;
|
||||
|
||||
//char discfns[2][260] = {"", ""};
|
||||
int defaultwriteprot = 0;
|
||||
|
||||
int fdc_time;
|
||||
int disc_time;
|
||||
|
||||
int fdc_ready;
|
||||
|
||||
int drive_empty[2] = {1, 1};
|
||||
int disc_changed[2];
|
||||
|
||||
int motorspin;
|
||||
int motoron;
|
||||
|
||||
int fdc_indexcount = 52;
|
||||
|
||||
/*void (*fdc_callback)();
|
||||
void (*fdc_data)(uint8_t dat);
|
||||
void (*fdc_spindown)();
|
||||
void (*fdc_finishread)();
|
||||
void (*fdc_notfound)();
|
||||
void (*fdc_datacrcerror)();
|
||||
void (*fdc_headercrcerror)();
|
||||
void (*fdc_writeprotect)();
|
||||
int (*fdc_getdata)(int last);
|
||||
void (*fdc_sectorid)(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2);
|
||||
void (*fdc_indexpulse)();*/
|
||||
|
||||
static struct
|
||||
{
|
||||
char *ext;
|
||||
void (*load)(int drive, char *fn);
|
||||
void (*close)(int drive);
|
||||
int size;
|
||||
}
|
||||
loaders[]=
|
||||
{
|
||||
{"IMG", img_load, img_close, -1},
|
||||
{"IMA", img_load, img_close, -1},
|
||||
{"FDI", fdi_load, fdi_close, -1},
|
||||
{0,0,0}
|
||||
};
|
||||
|
||||
static int driveloaders[4];
|
||||
|
||||
void disc_load(int drive, char *fn)
|
||||
{
|
||||
int c = 0, size;
|
||||
char *p;
|
||||
FILE *f;
|
||||
// pclog("disc_load %i %s\n", drive, fn);
|
||||
// setejecttext(drive, "");
|
||||
if (!fn) return;
|
||||
p = get_extension(fn);
|
||||
if (!p) return;
|
||||
// setejecttext(drive, fn);
|
||||
pclog("Loading :%i %s %s\n", drive, fn,p);
|
||||
f = fopen(fn, "rb");
|
||||
if (!f) return;
|
||||
fseek(f, -1, SEEK_END);
|
||||
size = ftell(f) + 1;
|
||||
fclose(f);
|
||||
while (loaders[c].ext)
|
||||
{
|
||||
if (!strcasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1))
|
||||
{
|
||||
pclog("Loading as %s\n", p);
|
||||
driveloaders[drive] = c;
|
||||
loaders[c].load(drive, fn);
|
||||
drive_empty[drive] = 0;
|
||||
disc_changed[drive] = 1;
|
||||
strcpy(discfns[drive], fn);
|
||||
return;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
pclog("Couldn't load %s %s\n",fn,p);
|
||||
drive_empty[drive] = 1;
|
||||
discfns[drive][0] = 0;
|
||||
}
|
||||
|
||||
void disc_close(int drive)
|
||||
{
|
||||
// pclog("disc_close %i\n", drive);
|
||||
if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive);
|
||||
drive_empty[drive] = 1;
|
||||
discfns[drive][0] = 0;
|
||||
}
|
||||
|
||||
int disc_notfound=0;
|
||||
static int disc_period = 32;
|
||||
|
||||
void disc_poll()
|
||||
{
|
||||
disc_poll_time += disc_period * TIMER_USEC;
|
||||
|
||||
if (drives[disc_drivesel].poll)
|
||||
drives[disc_drivesel].poll();
|
||||
|
||||
if (disc_notfound)
|
||||
{
|
||||
disc_notfound--;
|
||||
if (!disc_notfound)
|
||||
fdc_notfound();
|
||||
}
|
||||
}
|
||||
|
||||
void disc_set_rate(int rate)
|
||||
{
|
||||
switch (rate)
|
||||
{
|
||||
case 0: /*High density*/
|
||||
case 1: /*High density (360 rpm)*/
|
||||
disc_period = 16;
|
||||
break;
|
||||
case 2: /*Double density*/
|
||||
disc_period = 32;
|
||||
break;
|
||||
case 3: /*Extended density*/
|
||||
disc_period = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void disc_init()
|
||||
{
|
||||
// pclog("disc_init %p\n", drives);
|
||||
drives[0].poll = drives[1].poll = 0;
|
||||
drives[0].seek = drives[1].seek = 0;
|
||||
drives[0].readsector = drives[1].readsector = 0;
|
||||
curdrive = 0;
|
||||
disc_period = 32;
|
||||
timer_add(disc_poll, &disc_poll_time, &motoron, NULL);
|
||||
}
|
||||
|
||||
int oldtrack[2] = {0, 0};
|
||||
void disc_seek(int drive, int track)
|
||||
{
|
||||
if (drives[drive].seek)
|
||||
drives[drive].seek(drive, track);
|
||||
// if (track != oldtrack[drive])
|
||||
fdc_discchange_clear(drive);
|
||||
// ddnoise_seek(track - oldtrack[drive]);
|
||||
oldtrack[drive] = track;
|
||||
disctime = 5000;
|
||||
}
|
||||
|
||||
void disc_readsector(int drive, int sector, int track, int side, int density)
|
||||
{
|
||||
if (drives[drive].readsector)
|
||||
drives[drive].readsector(drive, sector, track, side, density);
|
||||
else
|
||||
disc_notfound = 1000;
|
||||
}
|
||||
|
||||
void disc_writesector(int drive, int sector, int track, int side, int density)
|
||||
{
|
||||
if (drives[drive].writesector)
|
||||
drives[drive].writesector(drive, sector, track, side, density);
|
||||
else
|
||||
disc_notfound = 1000;
|
||||
}
|
||||
|
||||
void disc_readaddress(int drive, int track, int side, int density)
|
||||
{
|
||||
if (drives[drive].readaddress)
|
||||
drives[drive].readaddress(drive, track, side, density);
|
||||
else
|
||||
disc_notfound = 1000;
|
||||
}
|
||||
|
||||
void disc_format(int drive, int track, int side, int density)
|
||||
{
|
||||
if (drives[drive].format)
|
||||
drives[drive].format(drive, track, side, density);
|
||||
else
|
||||
disc_notfound = 1000;
|
||||
}
|
||||
|
||||
void disc_stop(int drive)
|
||||
{
|
||||
if (drives[drive].stop)
|
||||
drives[drive].stop(drive);
|
||||
}
|
||||
Loading…
Reference in a new issue