FDC changes :
- Seperated disk and disk drive emulation - Support more drive types - 5.25" dual RPM, 3.5" DD, 3.5" HD, 3.5" HD 3-Mode - Support drive swapping (FDC37c665 only) - Support FDC FIFO - Support other FDC 'enhanced mode' behaviour - Support IBM XDF format images - Formatting now formats both tracks, and uses correct 'fill' byte - Various other improvements Many of these changes provided by Battler
This commit is contained in:
parent
2ca86ba028
commit
eebdc165b2
16 changed files with 1530 additions and 340 deletions
603
src/disc_img.c
603
src/disc_img.c
|
|
@ -1,6 +1,8 @@
|
|||
#include "ibm.h"
|
||||
#include "fdd.h"
|
||||
#include "disc.h"
|
||||
#include "disc_img.h"
|
||||
#include "disc_sector.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
|
|
@ -9,35 +11,126 @@ static struct
|
|||
int sectors, tracks, sides;
|
||||
int sector_size;
|
||||
int rate;
|
||||
int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */
|
||||
int hole;
|
||||
double bitcell_period_300rpm;
|
||||
} 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 uint8_t xdf_track0[5][3];
|
||||
static uint8_t xdf_spt[5];
|
||||
static uint8_t xdf_map[5][24][3];
|
||||
|
||||
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_sector_next;
|
||||
void img_writeback(int drive, int track);
|
||||
|
||||
static int img_pause = 0;
|
||||
static int img_index = 6250;
|
||||
static int img_sector_size_code(int drive)
|
||||
{
|
||||
switch(img[drive].sector_size)
|
||||
{
|
||||
case 128:
|
||||
return 0;
|
||||
case 256:
|
||||
return 1;
|
||||
default:
|
||||
case 512:
|
||||
return 2;
|
||||
case 1024:
|
||||
return 3;
|
||||
case 2048:
|
||||
return 4;
|
||||
case 4096:
|
||||
return 5;
|
||||
case 8192:
|
||||
return 6;
|
||||
case 16384:
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
|
||||
void img_init()
|
||||
{
|
||||
memset(img, 0, sizeof(img));
|
||||
// adl[0] = adl[1] = 0;
|
||||
img_notfound = 0;
|
||||
}
|
||||
|
||||
static void add_to_map(uint8_t *arr, uint8_t p1, uint8_t p2, uint8_t p3)
|
||||
{
|
||||
arr[0] = p1;
|
||||
arr[1] = p2;
|
||||
arr[2] = p3;
|
||||
}
|
||||
|
||||
static int xdf_maps_initialized = 0;
|
||||
|
||||
static void initialize_xdf_maps()
|
||||
{
|
||||
// XDF 5.25" 2HD
|
||||
/* Adds, in this order: sectors per FAT, sectors per each side of track 0, difference between that and virtual sector number specified in BPB. */
|
||||
add_to_map(xdf_track0[0], 9, 17, 2);
|
||||
xdf_spt[0] = 3;
|
||||
/* Adds, in this order: side, sequential order (not used in PCem), sector size. */
|
||||
add_to_map(xdf_map[0][0], 0, 0, 3);
|
||||
add_to_map(xdf_map[0][1], 0, 2, 6);
|
||||
add_to_map(xdf_map[0][2], 1, 0, 2);
|
||||
add_to_map(xdf_map[0][3], 0, 1, 2);
|
||||
add_to_map(xdf_map[0][4], 1, 2, 6);
|
||||
add_to_map(xdf_map[0][5], 1, 1, 3);
|
||||
|
||||
// XDF 3.5" 2HD
|
||||
add_to_map(xdf_track0[1], 11, 19, 4);
|
||||
xdf_spt[1] = 4;
|
||||
add_to_map(xdf_map[1][0], 0, 0, 3);
|
||||
add_to_map(xdf_map[1][1], 0, 2, 4);
|
||||
add_to_map(xdf_map[1][2], 1, 3, 6);
|
||||
add_to_map(xdf_map[1][3], 0, 1, 2);
|
||||
add_to_map(xdf_map[1][4], 1, 1, 2);
|
||||
add_to_map(xdf_map[1][5], 0, 3, 6);
|
||||
add_to_map(xdf_map[1][6], 1, 0, 4);
|
||||
add_to_map(xdf_map[1][7], 1, 2, 3);
|
||||
|
||||
// XDF 3.5" 2ED
|
||||
add_to_map(xdf_track0[2], 22, 37, 9);
|
||||
xdf_spt[2] = 4;
|
||||
add_to_map(xdf_map[2][0], 0, 0, 3);
|
||||
add_to_map(xdf_map[2][1], 0, 1, 4);
|
||||
add_to_map(xdf_map[2][2], 0, 2, 5);
|
||||
add_to_map(xdf_map[2][3], 0, 3, 7);
|
||||
add_to_map(xdf_map[2][4], 1, 0, 3);
|
||||
add_to_map(xdf_map[2][5], 1, 1, 4);
|
||||
add_to_map(xdf_map[2][6], 1, 2, 5);
|
||||
add_to_map(xdf_map[2][7], 1, 3, 7);
|
||||
|
||||
// XXDF 3.5" 2HD
|
||||
add_to_map(xdf_track0[3], 12, 20, 4);
|
||||
xdf_spt[3] = 2;
|
||||
add_to_map(xdf_map[3][0], 0, 0, 5);
|
||||
add_to_map(xdf_map[3][1], 1, 1, 6);
|
||||
add_to_map(xdf_map[3][2], 0, 1, 6);
|
||||
add_to_map(xdf_map[3][3], 1, 0, 5);
|
||||
|
||||
// XXDF 3.5" 2ED
|
||||
add_to_map(xdf_track0[4], 21, 39, 9);
|
||||
xdf_spt[4] = 2;
|
||||
add_to_map(xdf_map[4][0], 0, 0, 6);
|
||||
add_to_map(xdf_map[4][1], 1, 1, 7);
|
||||
add_to_map(xdf_map[4][2], 0, 1, 7);
|
||||
add_to_map(xdf_map[4][3], 1, 0, 6);
|
||||
|
||||
xdf_maps_initialized = 1;
|
||||
}
|
||||
|
||||
void img_load(int drive, char *fn)
|
||||
{
|
||||
int size;
|
||||
double bit_rate_300;
|
||||
uint16_t bpb_bps;
|
||||
uint16_t bpb_total;
|
||||
uint8_t bpb_mid; /* Media type ID. */
|
||||
uint8_t bpb_sectors;
|
||||
uint8_t bpb_sides;
|
||||
uint32_t bpt;
|
||||
uint8_t max_spt; /* Used for XDF detection. */
|
||||
|
||||
if (!xdf_maps_initialized) initialize_xdf_maps(); /* Initialize XDF maps, will need them to properly register sectors in tracks. */
|
||||
|
||||
writeprot[drive] = 0;
|
||||
img[drive].f = fopen(fn, "rb+");
|
||||
|
|
@ -49,32 +142,167 @@ void img_load(int drive, char *fn)
|
|||
writeprot[drive] = 1;
|
||||
}
|
||||
fwriteprot[drive] = writeprot[drive];
|
||||
|
||||
/* Read the BPB */
|
||||
fseek(img[drive].f, 0x0B, SEEK_SET);
|
||||
fread(&bpb_bps, 1, 2, img[drive].f);
|
||||
fseek(img[drive].f, 0x13, SEEK_SET);
|
||||
fread(&bpb_total, 1, 2, img[drive].f);
|
||||
fseek(img[drive].f, 0x15, SEEK_SET);
|
||||
bpb_mid = fgetc(img[drive].f);
|
||||
fseek(img[drive].f, 0x18, SEEK_SET);
|
||||
bpb_sectors = fgetc(img[drive].f);
|
||||
fseek(img[drive].f, 0x1A, SEEK_SET);
|
||||
bpb_sides = fgetc(img[drive].f);
|
||||
|
||||
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*/
|
||||
|
||||
pclog("BPB reports %i sides and %i bytes per sector\n", bpb_sides, bpb_bps);
|
||||
|
||||
if ((bpb_sides < 1) || (bpb_sides > 2) || (bpb_bps < 128) || (bpb_bps > 2048))
|
||||
{
|
||||
/* The BPB is giving us a wacky number of sides and/or bytes per sector, therefore it is most probably
|
||||
not a BPB at all, so we have to guess the parameters from file size. */
|
||||
|
||||
if (size <= (160*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; img[drive].sides = 1; bit_rate_300 = 250; }
|
||||
else if (size <= (180*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; img[drive].sides = 1; bit_rate_300 = 250; }
|
||||
else if (size <= (320*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; bit_rate_300 = 250; }
|
||||
else if (size <= (360*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; bit_rate_300 = 250; } /*Double density*/
|
||||
else if (size < (1024*1024)) { img[drive].sectors = 9; img[drive].tracks = 80; bit_rate_300 = 250; } /*Double density*/
|
||||
else if (size <= 1228800) { img[drive].sectors = 15; img[drive].tracks = 80; bit_rate_300 = (500.0 * 300.0) / 360.0; } /*High density 1.2MB*/
|
||||
else if (size <= (0x1A4000-1)) { img[drive].sectors = 18; img[drive].tracks = 80; bit_rate_300 = 500; } /*High density (not supported by Tandy 1000)*/
|
||||
// else if (size == 1884160) { img[drive].sectors = 23; img[drive].tracks = 80; bit_rate_300 = 500; } /*XDF format - used by OS/2 Warp*/
|
||||
// else if (size == 1763328) { img[drive].sectors = 21; img[drive].tracks = 82; bit_rate_300 = 500; } /*XDF format - used by OS/2 Warp*/
|
||||
else if (size <= 2000000) { img[drive].sectors = 21; img[drive].tracks = 80; bit_rate_300 = 500; } /*DMF format - used by Windows 95 - changed by OBattler to 2000000, ie. the real unformatted capacity @ 500 kbps and 300 rpm */
|
||||
else { img[drive].sectors = 36; img[drive].tracks = 80; bit_rate_300 = 1000; } /*E density*/
|
||||
|
||||
img[drive].xdf_type = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The BPB readings appear to be valid, so let's set the values. */
|
||||
/* Number of tracks = number of total sectors divided by sides times sectors per track. */
|
||||
img[drive].tracks = ((uint32_t) bpb_total) / (((uint32_t) bpb_sides) * ((uint32_t) bpb_sectors));
|
||||
/* The rest we just set directly from the BPB. */
|
||||
img[drive].sectors = bpb_sectors;
|
||||
img[drive].sides = bpb_sides;
|
||||
/* Now we calculate bytes per track, which is bpb_sectors * bpb_bps. */
|
||||
bpt = (uint32_t) bpb_sectors * (uint32_t) bpb_bps;
|
||||
/* Now we should be able to calculate the bit rate. */
|
||||
pclog("The image has %i bytes per track\n", bpt);
|
||||
if (bpt <= 6250)
|
||||
bit_rate_300 = 250; /* Double-density */
|
||||
else if (bpt <= 7500)
|
||||
bit_rate_300 = 300; /* Double-density, 300 kbps @ 300 rpm */
|
||||
else if (bpt <= 10416)
|
||||
{
|
||||
bit_rate_300 = (bpb_mid == 0xF0) ? 500 : ((500.0 * 300.0) / 360.0); /* High-density @ 300 or 360 rpm, depending on media type ID */
|
||||
max_spt = (bpb_mid == 0xF0) ? 22 : 18;
|
||||
}
|
||||
else if (bpt <= 12500) /* High-density @ 300 rpm */
|
||||
{
|
||||
bit_rate_300 = 500;
|
||||
max_spt = 22;
|
||||
}
|
||||
else if (bpt <= 25000) /* Extended density @ 300 rpm */
|
||||
{
|
||||
bit_rate_300 = 1000;
|
||||
max_spt = 45;
|
||||
}
|
||||
else /* Image too big, eject */
|
||||
{
|
||||
pclog("Image has more than 25000 bytes per track, ejecting...\n");
|
||||
fclose(img[drive].f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bpb_bps == 512) /* BPB reports 512 bytes per sector, let's see if it's XDF or not */
|
||||
{
|
||||
if (bit_rate_300 <= 300) /* Double-density disk, not XDF */
|
||||
{
|
||||
img[drive].xdf_type = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bpb_sectors > max_spt)
|
||||
{
|
||||
switch(bpb_sectors)
|
||||
{
|
||||
case 19: /* High density XDF @ 360 rpm */
|
||||
img[drive].xdf_type = 1;
|
||||
break;
|
||||
case 23: /* High density XDF @ 300 rpm */
|
||||
img[drive].xdf_type = 2;
|
||||
break;
|
||||
case 24: /* High density XXDF @ 300 rpm */
|
||||
img[drive].xdf_type = 4;
|
||||
break;
|
||||
case 46: /* Extended density XDF */
|
||||
img[drive].xdf_type = 3;
|
||||
break;
|
||||
case 48: /* Extended density XXDF */
|
||||
img[drive].xdf_type = 5;
|
||||
break;
|
||||
default: /* Unknown, as we're beyond maximum sectors, get out */
|
||||
fclose(img[drive].f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else /* Amount of sectors per track that fits into a track, therefore not XDF */
|
||||
{
|
||||
img[drive].xdf_type = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* BPB reports sector size other than 512, can't possibly be XDF */
|
||||
{
|
||||
img[drive].xdf_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((bit_rate_300 == 250) || (bit_rate_300 == 300))
|
||||
{
|
||||
img[drive].hole = 0;
|
||||
}
|
||||
else if (bit_rate_300 == 1000)
|
||||
{
|
||||
img[drive].hole = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
img[drive].hole = 1;
|
||||
}
|
||||
|
||||
if (img[drive].xdf_type) /* In case of XDF-formatted image, write-protect */
|
||||
{
|
||||
writeprot[drive] = 1;
|
||||
fwriteprot[drive] = writeprot[drive];
|
||||
}
|
||||
|
||||
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);
|
||||
drives[drive].readsector = disc_sector_readsector;
|
||||
drives[drive].writesector = disc_sector_writesector;
|
||||
drives[drive].readaddress = disc_sector_readaddress;
|
||||
drives[drive].hole = img_hole;
|
||||
drives[drive].poll = disc_sector_poll;
|
||||
drives[drive].format = disc_sector_format;
|
||||
disc_sector_writeback[drive] = img_writeback;
|
||||
|
||||
img[drive].bitcell_period_300rpm = 1000000.0 / bit_rate_300*2.0;
|
||||
pclog("bit_rate_300=%g\n", bit_rate_300);
|
||||
pclog("bitcell_period_300=%g\n", img[drive].bitcell_period_300rpm);
|
||||
// img[drive].bitcell_period_300rpm = disc_get_bitcell_period(img[drive].rate);
|
||||
pclog("img_load %d %p sectors=%i tracks=%i sides=%i sector_size=%i hole=%i\n", drive, drives, img[drive].sectors, img[drive].tracks, img[drive].sides, img[drive].sector_size, img[drive].hole);
|
||||
}
|
||||
|
||||
int img_hole(int drive)
|
||||
{
|
||||
return img[drive].hole;
|
||||
}
|
||||
|
||||
void img_close(int drive)
|
||||
{
|
||||
|
|
@ -85,13 +313,19 @@ void img_close(int drive)
|
|||
|
||||
void img_seek(int drive, int track)
|
||||
{
|
||||
int side;
|
||||
int current_xdft = img[drive].xdf_type - 1;
|
||||
|
||||
uint8_t sectors_fat, effective_sectors, sector_gap; /* Needed for XDF */
|
||||
|
||||
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);
|
||||
|
||||
if (drive_type[drive] && img[drive].tracks == 40)
|
||||
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);
|
||||
// pclog(" %i %i\n", drive_type[drive], img[drive].tracks);
|
||||
if (img[drive].tracks <= 41 && fdd_doublestep_40(drive))
|
||||
track /= 2;
|
||||
|
||||
pclog("Disk seeked to track %i\n", track);
|
||||
disc_track[drive] = track;
|
||||
|
||||
if (img[drive].sides == 2)
|
||||
|
|
@ -105,11 +339,98 @@ void img_seek(int drive, int track)
|
|||
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);
|
||||
}
|
||||
|
||||
disc_sector_reset(drive, 0);
|
||||
disc_sector_reset(drive, 1);
|
||||
|
||||
int sector, current_pos;
|
||||
|
||||
if (img[drive].xdf_type)
|
||||
{
|
||||
sectors_fat = xdf_track0[current_xdft][0];
|
||||
effective_sectors = xdf_track0[current_xdft][1];
|
||||
sector_gap = xdf_track0[current_xdft][2];
|
||||
|
||||
if (!track)
|
||||
{
|
||||
/* Track 0, register sectors according to track 0 map. */
|
||||
/* First, the "Side 0" buffer, will also contain one sector from side 1. */
|
||||
current_pos = 0;
|
||||
for (sector = 0; sector < sectors_fat; sector++)
|
||||
{
|
||||
disc_sector_add(drive, 0, track, 0, sector+0x81, 2,
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[0][current_pos]);
|
||||
current_pos += 512;
|
||||
}
|
||||
disc_sector_add(drive, 1, track, 1, 0x81, 2,
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[0][current_pos]);
|
||||
current_pos += 512;
|
||||
for (sector = 0; sector < 7; sector++)
|
||||
{
|
||||
disc_sector_add(drive, 0, track, 0, sector+1, 2,
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[0][current_pos]);
|
||||
current_pos += 512;
|
||||
}
|
||||
/* Now the "Side 1" buffer, will also contain one sector from side 0. */
|
||||
current_pos = 0;
|
||||
for (sector = 0; (sector < effective_sectors - 1); sector++)
|
||||
{
|
||||
disc_sector_add(drive, 1, track, 1, sector+0x82, 2,
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[1][current_pos]);
|
||||
current_pos += 512;
|
||||
}
|
||||
disc_sector_add(drive, 0, track, 0, 8, 2,
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[1][current_pos]);
|
||||
current_pos += 512;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Non-zero track, this will have sectors of various sizes. */
|
||||
/* First, the "Side 0" buffer. */
|
||||
current_pos = 0;
|
||||
for (sector = 0; sector < xdf_spt[current_xdft]; sector++)
|
||||
{
|
||||
disc_sector_add(drive, xdf_map[current_xdft][sector][0], track, xdf_map[current_xdft][sector][0],
|
||||
xdf_map[current_xdft][sector][2] + 0x80, xdf_map[current_xdft][sector][2],
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[0][current_pos]);
|
||||
current_pos += (128 << xdf_map[current_xdft][sector][2]);
|
||||
}
|
||||
/* Then, the "Side 1" buffer. */
|
||||
current_pos = 0;
|
||||
for (sector = xdf_spt[current_xdft]; sector < (xdf_spt[current_xdft] << 1); sector++)
|
||||
{
|
||||
disc_sector_add(drive, xdf_map[current_xdft][sector][0], track, xdf_map[current_xdft][sector][0],
|
||||
xdf_map[current_xdft][sector][2] + 0x80, xdf_map[current_xdft][sector][2],
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[1][current_pos]);
|
||||
current_pos += (128 << xdf_map[current_xdft][sector][2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (side = 0; side < img[drive].sides; side++)
|
||||
{
|
||||
for (sector = 0; sector < img[drive].sectors; sector++)
|
||||
disc_sector_add(drive, side, track, side, sector+1, img_sector_size_code(drive),
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[side][sector * img->sector_size]);
|
||||
}
|
||||
}
|
||||
}
|
||||
void img_writeback(int drive, int track)
|
||||
{
|
||||
if (!img[drive].f)
|
||||
return;
|
||||
|
||||
if (img[drive].xdf_type)
|
||||
return; /*Should never happen*/
|
||||
|
||||
if (img[drive].sides == 2)
|
||||
{
|
||||
|
|
@ -124,215 +445,3 @@ void img_writeback(int drive, int track)
|
|||
}
|
||||
}
|
||||
|
||||
void img_readsector(int drive, int sector, int track, int side, int rate)
|
||||
{
|
||||
if (drive_type[drive] && rate == 1)
|
||||
rate = 2;
|
||||
|
||||
if (sector == SECTOR_FIRST)
|
||||
{
|
||||
img_sector = 1 - 1;
|
||||
img_sector_next = 2;
|
||||
}
|
||||
else if (sector == SECTOR_NEXT)
|
||||
{
|
||||
img_sector = img_sector_next - 1;
|
||||
img_sector_next++;
|
||||
}
|
||||
else
|
||||
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]) ||
|
||||
img_sector > img[drive].sectors)
|
||||
{
|
||||
// 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 (drive_type[drive] && rate == 1)
|
||||
rate = 2;
|
||||
|
||||
// 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]) ||
|
||||
sector > img[drive].sectors)
|
||||
{
|
||||
img_notfound = 500;
|
||||
return;
|
||||
}
|
||||
img_inwrite = 1;
|
||||
img_readpos = 0;
|
||||
img_pause = 32;
|
||||
}
|
||||
|
||||
void img_readaddress(int drive, int track, int side, int rate)
|
||||
{
|
||||
if (drive_type[drive] && rate == 1)
|
||||
rate = 2;
|
||||
|
||||
img_drive = drive;
|
||||
img_track = disc_track[drive];
|
||||
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))
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
if (drive_type[drive] && rate == 1)
|
||||
rate = 2;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue