pcem/src/disc.c
TomW de6369b82f Disc function pointers cleared when disc ejected.
Read address on an ejected disc now times out.
Write protect bit in ST3 now set correctly (Sense Drive Status command).
Fixes discs on Windows 95.
2015-06-21 14:51:58 +01:00

212 lines
5.4 KiB
C

#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;
drives[drive].poll = NULL;
drives[drive].seek = NULL;
drives[drive].readsector = NULL;
drives[drive].writesector = NULL;
drives[drive].readaddress = NULL;
drives[drive].format = NULL;
}
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_reset()
{
curdrive = 0;
disc_period = 32;
timer_add(disc_poll, &disc_poll_time, &motoron, NULL);
}
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;
disc_reset();
}
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);
}
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);
}