307 lines
12 KiB
C
307 lines
12 KiB
C
#include "ibm.h"
|
|
#include "disc.h"
|
|
#include "disc_img.h"
|
|
|
|
static struct
|
|
{
|
|
FILE *f;
|
|
uint8_t track_data[2][20*1024];
|
|
int sectors, tracks, sides;
|
|
int sector_size;
|
|
int rate;
|
|
} img[2];
|
|
|
|
//static FILE *img_f[2];
|
|
//static uint8_t trackinfoa[2][2][20*1024];
|
|
//static int img_dblside[2];
|
|
//static int img_sectors[2], img_size[2], img_trackc[2];
|
|
//static int img_dblstep[2];
|
|
//static int img_density[2];
|
|
|
|
static int img_sector, img_track, img_side, img_drive;
|
|
static int img_inread, img_readpos, img_inwrite, img_inreadaddr;
|
|
static int img_notfound;
|
|
static int img_rsector=0;
|
|
static int img_informat=0;
|
|
|
|
static int img_pause = 0;
|
|
static int img_index = 6250;
|
|
|
|
void img_init()
|
|
{
|
|
memset(img, 0, sizeof(img));
|
|
// adl[0] = adl[1] = 0;
|
|
img_notfound = 0;
|
|
}
|
|
|
|
void img_load(int drive, char *fn)
|
|
{
|
|
int size;
|
|
|
|
writeprot[drive] = 0;
|
|
img[drive].f = fopen(fn, "rb+");
|
|
if (!img[drive].f)
|
|
{
|
|
img[drive].f = fopen(fn, "rb");
|
|
if (!img[drive].f)
|
|
return;
|
|
writeprot[drive] = 1;
|
|
}
|
|
fwriteprot[drive] = writeprot[drive];
|
|
fseek(img[drive].f, -1, SEEK_END);
|
|
size = ftell(img[drive].f) + 1;
|
|
|
|
img[drive].sides = 2;
|
|
img[drive].sector_size = 512;
|
|
if (size <= (160*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; img[drive].sides = 1; img[drive].rate = 2; }
|
|
else if (size <= (180*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; img[drive].sides = 1; img[drive].rate = 2; }
|
|
else if (size <= (320*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; img[drive].rate = 2; }
|
|
else if (size <= (360*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; img[drive].rate = 2; } /*Double density*/
|
|
else if (size < (1024*1024)) { img[drive].sectors = 9; img[drive].tracks = 80; img[drive].rate = 2; } /*Double density*/
|
|
else if (size <= 1228800) { img[drive].sectors = 15; img[drive].tracks = 80; img[drive].rate = 0; } /*High density 1.2MB*/
|
|
else if (size <= (0x1A4000-1)) { img[drive].sectors = 18; img[drive].tracks = 80; img[drive].rate = 0; } /*High density (not supported by Tandy 1000)*/
|
|
else if (size == 1884160) { img[drive].sectors = 23; img[drive].tracks = 80; img[drive].rate = 0; } /*XDF format - used by OS/2 Warp*/
|
|
else if (size == 1763328) { img[drive].sectors = 21; img[drive].tracks = 82; img[drive].rate = 0; } /*XDF format - used by OS/2 Warp*/
|
|
else if (size < (2048*1024)) { img[drive].sectors = 21; img[drive].tracks = 80; img[drive].rate = 0; } /*DMF format - used by Windows 95*/
|
|
else { img[drive].sectors = 36; img[drive].tracks = 80; img[drive].rate = 3; } /*E density*/
|
|
|
|
drives[drive].seek = img_seek;
|
|
drives[drive].readsector = img_readsector;
|
|
drives[drive].writesector = img_writesector;
|
|
drives[drive].readaddress = img_readaddress;
|
|
drives[drive].poll = img_poll;
|
|
drives[drive].format = img_format;
|
|
// pclog("img_load %d %p sectors=%i tracks=%i sides=%i sector_size=%i\n", drive, drives, img[drive].sectors, img[drive].tracks, img[drive].sides, img[drive].sector_size);
|
|
}
|
|
|
|
|
|
void img_close(int drive)
|
|
{
|
|
if (img[drive].f)
|
|
fclose(img[drive].f);
|
|
img[drive].f = NULL;
|
|
}
|
|
|
|
void img_seek(int drive, int track)
|
|
{
|
|
if (!img[drive].f)
|
|
return;
|
|
// pclog("Seek drive=%i track=%i sectors=%i sector_size=%i sides=%i\n", drive, track, img[drive].sectors,img[drive].sector_size, img[drive].sides);
|
|
disc_track[drive] = track;
|
|
if (img[drive].sides == 2)
|
|
{
|
|
fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size * 2, SEEK_SET);
|
|
fread(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
|
fread(img[drive].track_data[1], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
|
}
|
|
else
|
|
{
|
|
fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size, SEEK_SET);
|
|
fread(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
|
}
|
|
}
|
|
void img_writeback(int drive, int track)
|
|
{
|
|
if (!img[drive].f)
|
|
return;
|
|
|
|
if (img[drive].sides == 2)
|
|
{
|
|
fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size * 2, SEEK_SET);
|
|
fwrite(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
|
fwrite(img[drive].track_data[1], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
|
}
|
|
else
|
|
{
|
|
fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size, SEEK_SET);
|
|
fwrite(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
|
}
|
|
}
|
|
|
|
void img_readsector(int drive, int sector, int track, int side, int rate)
|
|
{
|
|
img_sector = sector - 1;
|
|
img_track = track;
|
|
img_side = side;
|
|
img_drive = drive;
|
|
// pclog("imgS Read sector drive=%i side=%i track=%i sector=%i rate=%i\n",drive,side,track,sector, rate);
|
|
|
|
if (!img[drive].f || (side && img[drive].sides == 1) ||
|
|
(rate != img[drive].rate) || (track != disc_track[drive]))
|
|
{
|
|
// pclog("Sector not found rate %i,%i track %i,%i\n", rate, img[drive].rate, track, disc_track[drive]);
|
|
img_notfound=500;
|
|
return;
|
|
}
|
|
// printf("Found\n");
|
|
img_inread = 1;
|
|
img_readpos = 0;
|
|
img_pause = 32;
|
|
}
|
|
|
|
void img_writesector(int drive, int sector, int track, int side, int rate)
|
|
{
|
|
// if (imgdblstep[drive]) track/=2;
|
|
img_sector = sector - 1;
|
|
img_track = track;
|
|
img_side = side;
|
|
img_drive = drive;
|
|
// printf("imgS Write sector %i %i %i %i\n",drive,side,track,sector);
|
|
|
|
if (!img[drive].f || (side && img[drive].sides == 1) ||
|
|
(rate != img[drive].rate) || (track != disc_track[drive]))
|
|
{
|
|
img_notfound = 500;
|
|
return;
|
|
}
|
|
img_inwrite = 1;
|
|
img_readpos = 0;
|
|
img_pause = 32;
|
|
}
|
|
|
|
void img_readaddress(int drive, int track, int side, int rate)
|
|
{
|
|
img_drive = drive;
|
|
img_track = track;
|
|
img_side = side;
|
|
// pclog("Read address %i %i %i %i\n",drive,side,track, rate);
|
|
|
|
if (!img[drive].f || (side && img[drive].sides == 1) ||
|
|
(rate != img[drive].rate) || (track != disc_track[drive]))
|
|
{
|
|
// pclog("Address not found rate %i,%i track %i,%i\n", rate, img[drive].rate, track, disc_track[drive]);
|
|
img_notfound=500;
|
|
return;
|
|
}
|
|
img_inreadaddr = 1;
|
|
img_readpos = 0;
|
|
img_pause = 100;//500;
|
|
img_pause = 32;
|
|
}
|
|
|
|
void img_format(int drive, int track, int side, int rate)
|
|
{
|
|
img_drive = drive;
|
|
img_track = track;
|
|
img_side = side;
|
|
|
|
if (!img[drive].f || (side && img[drive].sides == 1) ||
|
|
(rate != img[drive].rate) || (track != disc_track[drive]))
|
|
{
|
|
img_notfound = 500;
|
|
return;
|
|
}
|
|
img_sector = 0;
|
|
img_readpos = 0;
|
|
img_informat = 1;
|
|
img_pause = 32;
|
|
}
|
|
|
|
void img_stop()
|
|
{
|
|
img_pause = img_notfound = img_inread = img_inwrite = img_inreadaddr = img_informat = 0;
|
|
}
|
|
|
|
void img_poll()
|
|
{
|
|
// pclog("img_poll %i %i %p\n", img_inread, img_readpos, img[img_drive].f);
|
|
img_index--;
|
|
if (!img_index)
|
|
{
|
|
img_index = 6250;
|
|
fdc_indexpulse();
|
|
}
|
|
|
|
if (img_pause)
|
|
{
|
|
img_pause--;
|
|
if (img_pause)
|
|
return;
|
|
}
|
|
|
|
if (img_notfound)
|
|
{
|
|
img_notfound--;
|
|
if (!img_notfound)
|
|
{
|
|
// pclog("Not found!\n");
|
|
fdc_notfound();
|
|
}
|
|
}
|
|
if (img_inread && img[img_drive].f)
|
|
{
|
|
// pclog("Read pos %i\n", img_readpos);
|
|
// if (!imgreadpos) pclog("%i\n",imgsector*imgsize[imgdrive]);
|
|
if (fdc_data(img[img_drive].track_data[img_side][(img_sector * img[img_drive].sector_size) + img_readpos]))
|
|
return;
|
|
|
|
img_readpos++;
|
|
if (img_readpos == img[img_drive].sector_size)
|
|
{
|
|
// pclog("Read %i bytes\n",img_readpos);
|
|
img_inread = 0;
|
|
fdc_finishread();
|
|
}
|
|
}
|
|
if (img_inwrite && img[img_drive].f)
|
|
{
|
|
int data;
|
|
|
|
if (writeprot[img_drive])
|
|
{
|
|
// pclog("writeprotect\n");
|
|
fdc_writeprotect();
|
|
img_inwrite = 0;
|
|
return;
|
|
}
|
|
// pclog("Write data %i\n",img_readpos);
|
|
data = fdc_getdata(img_readpos == (img[img_drive].sector_size - 1));
|
|
if (data == -1)
|
|
return;
|
|
|
|
img[img_drive].track_data[img_side][(img_sector * img[img_drive].sector_size) + img_readpos] = data;
|
|
img_readpos++;
|
|
if (img_readpos == img[img_drive].sector_size)
|
|
{
|
|
// pclog("write over\n");
|
|
img_inwrite = 0;
|
|
fdc_finishread();
|
|
img_writeback(img_drive, img_track);
|
|
}
|
|
}
|
|
if (img_inreadaddr && img[img_drive].f)
|
|
{
|
|
// pclog("img_inreadaddr %08X\n", fdc_sectorid);
|
|
fdc_sectorid(img_track, img_side,
|
|
img_rsector + ((img[img_drive].sector_size == 512) ? 1 : 0), (img[img_drive].sector_size == 256) ? 1 : ((img[img_drive].sector_size == 512) ? 2 : 3), 0, 0);
|
|
img_inreadaddr = 0;
|
|
img_rsector++;
|
|
if (img_rsector == img[img_drive].sectors)
|
|
{
|
|
img_rsector=0;
|
|
// pclog("img_rsector reset\n");
|
|
}
|
|
}
|
|
if (img_informat && img[img_drive].f)
|
|
{
|
|
if (writeprot[img_drive])
|
|
{
|
|
fdc_writeprotect();
|
|
img_informat = 0;
|
|
return;
|
|
}
|
|
img[img_drive].track_data[img_side][(img_sector * img[img_drive].sector_size) + img_readpos] = 0;
|
|
img_readpos++;
|
|
if (img_readpos == img[img_drive].sector_size)
|
|
{
|
|
img_readpos = 0;
|
|
img_sector++;
|
|
if (img_sector == img[img_drive].sectors)
|
|
{
|
|
img_informat = 0;
|
|
fdc_finishread();
|
|
img_writeback(img_drive, img_track);
|
|
}
|
|
}
|
|
}
|
|
}
|