86F format handler updated to 86F version 2.0 and bit by bit handling;
FDI stream images are now also handled by the 86F handler; Both floppy drives' motors now spin separately; Added Plantronics ColorPlus emulation per patch from PCem forum; Applied all mainline PCem commits; Fixed several bugs.
This commit is contained in:
713
src/disc_img.c
713
src/disc_img.c
@@ -2,74 +2,125 @@
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include "ibm.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd.h"
|
||||
#include "disc.h"
|
||||
#include "disc_img.h"
|
||||
#include "disc_sector.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
FILE *f;
|
||||
// uint8_t track_data[2][20*1024];
|
||||
uint8_t track_data[2][50000];
|
||||
int sectors, tracks, sides;
|
||||
int sector_size;
|
||||
int rate;
|
||||
uint8_t sector_size;
|
||||
int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */
|
||||
int dmf;
|
||||
int hole;
|
||||
int byte_period;
|
||||
double bitcell_period_300rpm;
|
||||
int track;
|
||||
int track_width;
|
||||
uint32_t base;
|
||||
uint8_t gap2_size;
|
||||
uint8_t gap3_size;
|
||||
uint16_t disk_flags;
|
||||
uint16_t track_flags;
|
||||
uint8_t sector_pos_side[2][256];
|
||||
uint16_t sector_pos[2][256];
|
||||
uint8_t current_sector_pos_side;
|
||||
uint16_t current_sector_pos;
|
||||
} img[2];
|
||||
|
||||
static uint8_t xdf_track0[3][3];
|
||||
static uint8_t xdf_spt[3] = { 6, 8, 8 };
|
||||
static uint8_t xdf_map[3][24][3];
|
||||
static uint16_t xdf_track0_layout[3][92] = { { 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800,
|
||||
0x8101, 0x8201, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600,
|
||||
0x0700, 0x0800, 0, 0x8301, 0x8401, 0x8501, 0x8601, 0x8701,
|
||||
0x8801, 0x8901, 0x8A01, 0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01,
|
||||
0x9001 }, /* 5.25" 2HD */
|
||||
{ 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800,
|
||||
0x8900, 0x8A00, 0x8B00, 0x8101, 0x0100, 0x0200, 0x0300, 0x0400,
|
||||
0x0500, 0x0600, 0x0700, 0x0800, 0, 0, 0, 0x8201,
|
||||
0x8301, 0x8401, 0x8501, 0x8601, 0x8701, 0x8801, 0x8901, 0x8A01,
|
||||
0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01, 0, 0, 0,
|
||||
0, 0, 0x9001, 0x9101, 0x9201, 0x9301 }, /* 3.5" 2HD */
|
||||
{ 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800,
|
||||
0x8900, 0x8A00, 0x8B00, 0x8C00, 0x8D00, 0x8E00, 0x8F00, 0x9000,
|
||||
0x9100, 0x9200, 0x9300, 0x9400, 0x9500, 0x9600, 0x9700, 0x0100,
|
||||
0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, 0x0800, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0x9800, 0x9900, 0x9A00,
|
||||
0x9B00, 0x9C00, 0x9D00, 0x9E00, 0x8101, 0x8201, 0x8301, 0x8401,
|
||||
0x8501, 0x8601, 0x8701, 0x8801, 0, 0, 0, 0,
|
||||
0x8901, 0x8A01, 0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01, 0x9001,
|
||||
0x9101, 0x9201, 0x9301, 0x9401, 0x9501, 0x9601, 0x9701, 0x9801,
|
||||
0x9901, 0x9A01, 0x9B01, 0x9C01, 0x9D01, 0x9E01, 0x9F01, 0xA001,
|
||||
0xA101, 0xA201, 0xA301, 0xA401 },
|
||||
};
|
||||
static uint16_t xdf_sector_pos[256];
|
||||
uint8_t dmf_r[21] = { 12, 2, 13, 3, 14, 4, 15, 5, 16, 6, 17, 7, 18, 8, 19, 9, 20, 10, 21, 11, 1 };
|
||||
static uint8_t xdf_spt[2] = { 6, 8 };
|
||||
static uint8_t xdf_logical_sectors[2][2] = { { 38, 6 }, { 46, 8 } };
|
||||
uint8_t xdf_physical_sectors[2][2] = { { 16, 3 }, { 19, 4 } };
|
||||
uint8_t xdf_gap3_sizes[2][2] = { { 60, 69 }, { 60, 50 } };
|
||||
uint16_t xdf_trackx_spos[2][8] = { { 0xA7F, 0xF02, 0x11B7, 0xB66, 0xE1B, 0x129E }, { 0x302, 0x7E2, 0xA52, 0x12DA, 0x572, 0xDFA, 0x106A, 0x154A } };
|
||||
|
||||
/* XDF: Layout of the sectors in the image. */
|
||||
xdf_sector_t xdf_img_layout[2][2][46] = { { { 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800,
|
||||
0x8101, 0x8201, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600,
|
||||
0x0700, 0x0800, 0,
|
||||
0x8301, 0x8401, 0x8501, 0x8601, 0x8701, 0x8801, 0x8901, 0x8A01,
|
||||
0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01, 0x9001, 0, 0,
|
||||
0, 0, 0 },
|
||||
{ 0x8300, 0x8600, 0x8201, 0x8200, 0x8601, 0x8301 }
|
||||
}, /* 5.25" 2HD */
|
||||
{ { 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800,
|
||||
0x8900, 0x8A00, 0x8B00, 0x8101, 0x0100, 0x0200, 0x0300, 0x0400,
|
||||
0x0500, 0x0600, 0x0700, 0x0800, 0, 0, 0,
|
||||
0x8201, 0x8301, 0x8401, 0x8501, 0x8601, 0x8701, 0x8801, 0x8901,
|
||||
0x8A01, 0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01, 0, 0,
|
||||
0, 0, 0, 0x9001, 0x9101, 0x9201, 0x9301 },
|
||||
{ 0x8300, 0x8400, 0x8601, 0x8200, 0x8201, 0x8600, 0x8401, 0x8301 }
|
||||
} /* 3.5" 2HD */
|
||||
};
|
||||
|
||||
/* XDF: Layout of the sectors on the disk's track. */
|
||||
xdf_sector_t xdf_disk_layout[2][2][38] = { { { 0x0100, 0x0200, 0x8100, 0x8800, 0x8200, 0x0300, 0x8300, 0x0400,
|
||||
0x8400, 0x0500, 0x8500, 0x0600, 0x8600, 0x0700, 0x8700, 0x0800,
|
||||
0x8D01, 0x8501, 0x8E01, 0x8601, 0x8F01, 0x8701, 0x9001, 0x8801,
|
||||
0x8101, 0x8901, 0x8201, 0x8A01, 0x8301, 0x8B01, 0x8401, 0x8C01 },
|
||||
{ 0x8300, 0x8200, 0x8600, 0x8201, 0x8301, 0x8601 }
|
||||
}, /* 5.25" 2HD */
|
||||
{ { 0x0100, 0x8A00, 0x8100, 0x8B00, 0x8200, 0x0200, 0x8300, 0x0300,
|
||||
0x8400, 0x0400, 0x8500, 0x0500, 0x8600, 0x0600, 0x8700, 0x0700,
|
||||
0x8800, 0x0800, 0x8900,
|
||||
0x9001, 0x8701, 0x9101, 0x8801, 0x9201, 0x8901, 0x9301, 0x8A01,
|
||||
0x8101, 0x8B01, 0x8201, 0x8C01, 0x8301, 0x8D01, 0x8401, 0x8E01,
|
||||
0x8501, 0x8F01, 0x8601 },
|
||||
{ 0x8300, 0x8200, 0x8400, 0x8600, 0x8401, 0x8201, 0x8301, 0x8601 },
|
||||
}, /* 3.5" 2HD */
|
||||
};
|
||||
|
||||
/* First dimension is possible sector sizes (0 = 128, 7 = 16384), second is possible bit rates (250/360, 250, 300, 500/360, 500, 1000). */
|
||||
/* Disks formatted at 250 kbps @ 360 RPM can be read with a 360 RPM single-RPM 5.25" drive by setting the rate to 250 kbps.
|
||||
Disks formatted at 300 kbps @ 300 RPM can be read with any 300 RPM single-RPM drive by setting the rate rate to 300 kbps. */
|
||||
static uint8_t maximum_sectors[8][6] = { { 26, 31, 38, 53, 64, 118 }, /* 128 */
|
||||
{ 15, 19, 23, 32, 38, 73 }, /* 256 */
|
||||
{ 7, 10, 12, 19, 23, 46 }, /* 512 */
|
||||
{ 7, 10, 12, 17, 21, 41 }, /* 512 */
|
||||
{ 3, 5, 6, 9, 11, 22 }, /* 1024 */
|
||||
{ 2, 2, 3, 4, 5, 11 }, /* 2048 */
|
||||
{ 1, 1, 1, 2, 2, 5 }, /* 4096 */
|
||||
{ 0, 0, 0, 1, 1, 3 }, /* 8192 */
|
||||
{ 0, 0, 0, 0, 0, 1 } }; /* 16384 */
|
||||
|
||||
static int gap3_sizes[5][8][256] = { [0][1][16] = 0x54,
|
||||
static uint8_t xdf_sectors[8][6] = { { 0, 0, 0, 0, 0, 0 }, /* 128 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 256 */
|
||||
{ 0, 0, 0, 19, 23, 0 }, /* 512 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 1024 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 2048 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 4096 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 8192 */
|
||||
{ 0, 0, 0, 0, 0, 0 } }; /* 16384 */
|
||||
|
||||
static uint8_t xdf_types[8][6] = { { 0, 0, 0, 0, 0, 0 }, /* 128 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 256 */
|
||||
{ 0, 0, 0, 1, 2, 0 }, /* 512 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 1024 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 2048 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 4096 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 8192 */
|
||||
{ 0, 0, 0, 0, 0, 0 } }; /* 16384 */
|
||||
|
||||
static double bit_rates_300[6] = { (250.0 * 300.0) / 360.0, 250.0, 300.0, (500.0 * 300.0) / 360.0, 500.0, 1000.0 };
|
||||
|
||||
static uint8_t rates[6] = { 2, 2, 1, 4, 0, 3 };
|
||||
|
||||
static uint8_t holes[6] = { 0, 0, 0, 1, 1, 2 };
|
||||
|
||||
int gap3_sizes[5][8][256] = { [0][1][16] = 0x54,
|
||||
[0][2][18] = 0x6C,
|
||||
[0][2][19] = 0x48,
|
||||
[0][2][20] = 0x2A,
|
||||
[0][2][21] = 0x0C,
|
||||
[0][2][21] = 0x08, /* Microsoft DMFWRITE.EXE uses this, 0x0C is used by FDFORMAT. */
|
||||
[0][2][23] = 0x01,
|
||||
[0][3][10] = 0x83,
|
||||
[0][3][11] = 0x26,
|
||||
[1][2][11] = 0x54,
|
||||
[1][2][12] = 0x1C,
|
||||
[1][2][13] = 0x0E,
|
||||
[1][3][6] = 0x79,
|
||||
[1][3][7] = 0x06,
|
||||
[2][1][10] = 0x32,
|
||||
[2][1][11] = 0x0C,
|
||||
[2][1][15] = 0x36,
|
||||
@@ -77,30 +128,32 @@ static int gap3_sizes[5][8][256] = { [0][1][16] = 0x54,
|
||||
[2][2][8] = 0x58,
|
||||
[2][2][9] = 0x50,
|
||||
[2][2][10] = 0x2E,
|
||||
[2][2][11] = 0x02,
|
||||
[2][2][21] = 0x1C,
|
||||
[2][3][4] = 0xF0,
|
||||
[2][3][5] = 0x74,
|
||||
[3][2][36] = 0x53,
|
||||
[3][2][39] = 0x20,
|
||||
[3][2][37] = 0x4E,
|
||||
[3][2][38] = 0x3D,
|
||||
[3][2][39] = 0x2C,
|
||||
[3][2][40] = 0x1C,
|
||||
[3][2][41] = 0x0D,
|
||||
[3][2][42] = 0x02,
|
||||
[3][2][46] = 0x01,
|
||||
[3][3][18] = 0xF7,
|
||||
[3][3][19] = 0xAF,
|
||||
[3][3][20] = 0x6F,
|
||||
[3][3][21] = 0x55,
|
||||
[3][3][22] = 0x1F,
|
||||
[4][1][32] = 0x36,
|
||||
[4][2][14] = 0x92,
|
||||
[4][2][15] = 0x54,
|
||||
[4][2][16] = 0x38,
|
||||
[4][2][17] = 0x23,
|
||||
[4][2][18] = 0x02,
|
||||
[4][2][19] = 0x01,
|
||||
[4][3][8] = 0x74
|
||||
[4][3][8] = 0x74,
|
||||
[4][3][9] = 0x24
|
||||
};
|
||||
|
||||
/* Needed for formatting! */
|
||||
int img_realtrack(int drive, int track)
|
||||
{
|
||||
if ((img[drive].tracks <= 43) && fdd_doublestep_40(drive))
|
||||
track /= 2;
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
void img_writeback(int drive);
|
||||
|
||||
static int sector_size_code(int sector_size)
|
||||
@@ -138,18 +191,7 @@ void img_init()
|
||||
// adl[0] = adl[1] = 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 uint16_t xdf_trackx_layout[3][8] = { { 0x8300, 0x8600, 0x8201, 0x8200, 0x8601, 0x8301},
|
||||
{ 0x8300, 0x8400, 0x8601, 0x8200, 0x8201, 0x8600, 0x8401, 0x8301},
|
||||
{ 0x8300, 0x8400, 0x8500, 0x8700, 0x8301, 0x8401, 0x8501, 0x8701} };
|
||||
void d86f_register_img(int drive);
|
||||
|
||||
void img_load(int drive, char *fn)
|
||||
{
|
||||
@@ -165,12 +207,15 @@ void img_load(int drive, char *fn)
|
||||
int temp_rate;
|
||||
char ext[4];
|
||||
int fdi;
|
||||
int i;
|
||||
|
||||
ext[0] = fn[strlen(fn) - 3] | 0x60;
|
||||
ext[1] = fn[strlen(fn) - 2] | 0x60;
|
||||
ext[2] = fn[strlen(fn) - 1] | 0x60;
|
||||
ext[3] = 0;
|
||||
|
||||
d86f_unregister(drive);
|
||||
|
||||
writeprot[drive] = 0;
|
||||
img[drive].f = fopen(fn, "rb+");
|
||||
if (!img[drive].f)
|
||||
@@ -230,7 +275,7 @@ void img_load(int drive, char *fn)
|
||||
}
|
||||
|
||||
img[drive].sides = 2;
|
||||
img[drive].sector_size = 512;
|
||||
img[drive].sector_size = 2;
|
||||
|
||||
img[drive].hole = 0;
|
||||
|
||||
@@ -241,74 +286,47 @@ void img_load(int drive, char *fn)
|
||||
/* 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; raw_tsize[drive] = 6250; }
|
||||
else if (size <= (180*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; img[drive].sides = 1; bit_rate_300 = 250; raw_tsize[drive] = 6250; }
|
||||
else if (size <= (320*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; bit_rate_300 = 250; raw_tsize[drive] = 6250; }
|
||||
else if (size <= (360*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; bit_rate_300 = 250; raw_tsize[drive] = 6250; } /*Double density*/
|
||||
else if (size <= (640*1024)) { img[drive].sectors = 8; img[drive].tracks = 80; bit_rate_300 = 250; raw_tsize[drive] = 6250; } /*Double density 640k*/
|
||||
else if (size < (1024*1024)) { img[drive].sectors = 9; img[drive].tracks = 80; bit_rate_300 = 250; raw_tsize[drive] = 6250; } /*Double density*/
|
||||
else if (size <= 1228800) { img[drive].sectors = 15; img[drive].tracks = 80; bit_rate_300 = (500.0 * 300.0) / 360.0; raw_tsize[drive] = 10416; } /*High density 1.2MB*/
|
||||
else if (size <= 1261568) { img[drive].sectors = 8; img[drive].tracks = 77; img[drive].sector_size = 1024; bit_rate_300 = (500.0 * 300.0) / 360.0; raw_tsize[drive] = 10416; } /*High density 1.25MB Japanese format*/
|
||||
else if (size <= (0x1A4000-1)) { img[drive].sectors = 18; img[drive].tracks = 80; bit_rate_300 = 500; raw_tsize[drive] = 12500; } /*High density (not supported by Tandy 1000)*/
|
||||
else if (size <= 1556480) { img[drive].sectors = 19; img[drive].tracks = 80; bit_rate_300 = 500; raw_tsize[drive] = 12500; } /*High density (not supported by Tandy 1000)*/
|
||||
else if (size <= 1638400) { img[drive].sectors = 10; img[drive].tracks = 80; img[drive].sector_size = 1024; bit_rate_300 = 500; raw_tsize[drive] = 12500; } /*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; raw_tsize[drive] = 12500; } /*DMF format - used by Windows 95 - changed by OBattler to 2000000, ie. the real unformatted capacity @ 500 kbps and 300 rpm */
|
||||
else if (size <= 2949120) { img[drive].sectors = 36; img[drive].tracks = 80; bit_rate_300 = 1000; raw_tsize[drive] = 25000; } /*E density*/
|
||||
|
||||
temp_rate = 2;
|
||||
bpb_bps = img[drive].sector_size;
|
||||
bpt = bpb_bps * img[drive].sectors;
|
||||
if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][0] * bpb_bps))
|
||||
{
|
||||
temp_rate = 2;
|
||||
raw_tsize[drive] = 5208;
|
||||
}
|
||||
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][1] * bpb_bps))
|
||||
{
|
||||
temp_rate = 2;
|
||||
raw_tsize[drive] = 6250;
|
||||
}
|
||||
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][2] * bpb_bps))
|
||||
{
|
||||
temp_rate = 1;
|
||||
raw_tsize[drive] = 7500;
|
||||
}
|
||||
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][3] * bpb_bps))
|
||||
{
|
||||
if (bpb_bps == 512) max_spt = (bit_rate_300 == 500) ? 21 : 17;
|
||||
temp_rate = (bit_rate_300 == 500) ? 0 : 4;
|
||||
raw_tsize[drive] = (bit_rate_300 == 500) ? 12500 : 10416;
|
||||
}
|
||||
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][4] * bpb_bps))
|
||||
{
|
||||
if (bpb_bps == 512) max_spt = 21;
|
||||
pclog("max_spt is %i\n", max_spt);
|
||||
temp_rate = 0;
|
||||
raw_tsize[drive] = 12500;
|
||||
}
|
||||
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][5] * bpb_bps))
|
||||
{
|
||||
if (bpb_bps == 512) max_spt = 41;
|
||||
temp_rate = 3;
|
||||
raw_tsize[drive] = 25000;
|
||||
}
|
||||
else /* Image too big, eject */
|
||||
if (size <= (160*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; img[drive].sides = 1; }
|
||||
else if (size <= (180*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; img[drive].sides = 1; }
|
||||
else if (size <= (320*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; }
|
||||
else if (size <= (360*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; } /*Double density*/
|
||||
else if (size <= (400*1024)) { img[drive].sectors = 10; img[drive].tracks = 80; img[drive].sides = 1; } /*DEC RX50*/
|
||||
else if (size <= (640*1024)) { img[drive].sectors = 8; img[drive].tracks = 80; } /*Double density 640k*/
|
||||
else if (size <= (720*1024)) { img[drive].sectors = 9; img[drive].tracks = 80; } /*Double density*/
|
||||
else if (size <= (800*1024)) { img[drive].sectors = 10; img[drive].tracks = 80; } /*Double density*/
|
||||
else if (size <= (880*1024)) { img[drive].sectors = 11; img[drive].tracks = 80; } /*Double density*/
|
||||
else if (size <= (960*1024)) { img[drive].sectors = 12; img[drive].tracks = 80; } /*Double density*/
|
||||
else if (size <= (1040*1024)) { img[drive].sectors = 13; img[drive].tracks = 80; } /*Double density*/
|
||||
else if (size <= (1120*1024)) { img[drive].sectors = 14; img[drive].tracks = 80; } /*Double density*/
|
||||
else if (size <= 1228800) { img[drive].sectors = 15; img[drive].tracks = 80; } /*High density 1.2MB*/
|
||||
else if (size <= 1261568) { img[drive].sectors = 8; img[drive].tracks = 77; img[drive].sector_size = 3; } /*High density 1.25MB Japanese format*/
|
||||
else if (size <= (0x1A4000-1)) { img[drive].sectors = 18; img[drive].tracks = 80; } /*High density (not supported by Tandy 1000)*/
|
||||
else if (size <= 1556480) { img[drive].sectors = 19; img[drive].tracks = 80; } /*High density (not supported by Tandy 1000)*/
|
||||
else if (size <= 1638400) { img[drive].sectors = 10; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/
|
||||
else if (size <= 1720320) { img[drive].sectors = 21; img[drive].tracks = 80; } /*DMF format - used by Windows 95 */
|
||||
else if (size <= 1741824) { img[drive].sectors = 21; img[drive].tracks = 81; }
|
||||
else if (size <= 1763328) { img[drive].sectors = 21; img[drive].tracks = 82; }
|
||||
else if (size <= 1802240) { img[drive].sectors = 11; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/
|
||||
else if (size == 1884160) { img[drive].sectors = 23; img[drive].tracks = 80; } /*XDF format - used by OS/2 Warp*/
|
||||
else if (size <= 2949120) { img[drive].sectors = 36; img[drive].tracks = 80; } /*E density*/
|
||||
else if (size <= 3194880) { img[drive].sectors = 39; img[drive].tracks = 80; } /*E density*/
|
||||
else if (size <= 3276800) { img[drive].sectors = 40; img[drive].tracks = 80; } /*E density*/
|
||||
else if (size <= 3358720) { img[drive].sectors = 41; img[drive].tracks = 80; } /*E density, maximum possible size*/
|
||||
else if (size <= 3440640) { img[drive].sectors = 42; img[drive].tracks = 80; } /*E density, maximum possible size*/
|
||||
/* else if (size <= 3440640) { img[drive].sectors = 21; img[drive].tracks = 80; img[drive].sector_size = 3; } */ /*High density (not supported by Tandy 1000)*/
|
||||
else if (size <= 3604480) { img[drive].sectors = 22; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/
|
||||
else if (size <= 3610624) { img[drive].sectors = 41; img[drive].tracks = 86; } /*E density, maximum possible size*/
|
||||
else if (size <= 3698688) { img[drive].sectors = 42; img[drive].tracks = 86; } /*E density, maximum possible size*/
|
||||
else
|
||||
{
|
||||
pclog("Image is bigger than can fit on an ED floppy, ejecting...\n");
|
||||
fclose(img[drive].f);
|
||||
return;
|
||||
}
|
||||
|
||||
pclog("Temporary rate: %i (%i bytes per track)\n", temp_rate, bpt);
|
||||
|
||||
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. */
|
||||
if (fdi)
|
||||
{
|
||||
/* The image is a Japanese FDI, therefore we read the number of tracks from the header. */
|
||||
@@ -317,297 +335,304 @@ void img_load(int drive, char *fn)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
/* The sector size. */
|
||||
img[drive].sector_size = bpb_bps;
|
||||
/* 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);
|
||||
img[drive].sector_size = sector_size_code(bpb_bps);
|
||||
|
||||
temp_rate = 2;
|
||||
if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][0] * bpb_bps))
|
||||
{
|
||||
bit_rate_300 = ((250.0 * 300.0) / 360.0);
|
||||
temp_rate = 2;
|
||||
raw_tsize[drive] = 5208;
|
||||
}
|
||||
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][1] * bpb_bps))
|
||||
{
|
||||
bit_rate_300 = 250;
|
||||
temp_rate = 2;
|
||||
raw_tsize[drive] = 6250;
|
||||
}
|
||||
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][2] * bpb_bps))
|
||||
{
|
||||
bit_rate_300 = 300;
|
||||
temp_rate = 1;
|
||||
raw_tsize[drive] = 7500;
|
||||
}
|
||||
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][3] * bpb_bps))
|
||||
{
|
||||
bit_rate_300 = (bpb_mid == 0xF0) ? 500 : ((500.0 * 300.0) / 360.0);
|
||||
if (bpb_bps == 512) max_spt = (bit_rate_300 == 500) ? 21 : 17;
|
||||
temp_rate = (bit_rate_300 == 500) ? 0 : 4;
|
||||
raw_tsize[drive] = (bit_rate_300 == 500) ? 12500 : 10416;
|
||||
}
|
||||
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][4] * bpb_bps))
|
||||
{
|
||||
bit_rate_300 = 500;
|
||||
if (bpb_bps == 512) max_spt = 21;
|
||||
pclog("max_spt is %i\n", max_spt);
|
||||
temp_rate = 0;
|
||||
raw_tsize[drive] = 12500;
|
||||
}
|
||||
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][5] * bpb_bps))
|
||||
{
|
||||
bit_rate_300 = 1000;
|
||||
if (bpb_bps == 512) max_spt = 41;
|
||||
temp_rate = 3;
|
||||
raw_tsize[drive] = 25000;
|
||||
}
|
||||
else /* Image too big, eject */
|
||||
{
|
||||
pclog("Image is bigger than can fit on an ED floppy, ejecting...\n");
|
||||
fclose(img[drive].f);
|
||||
return;
|
||||
}
|
||||
temp_rate = 0xFF;
|
||||
}
|
||||
|
||||
if (bpb_bps == 512) /* BPB reports 512 bytes per sector, let's see if it's XDF or not */
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if ((img[drive].sectors <= maximum_sectors[img[drive].sector_size][i]) || (img[drive].sectors == xdf_sectors[img[drive].sector_size][i]))
|
||||
{
|
||||
if (bit_rate_300 <= 300) /* Double-density disk, not XDF */
|
||||
bit_rate_300 = bit_rates_300[i];
|
||||
temp_rate = rates[i];
|
||||
img[drive].disk_flags = holes[i] << 1;
|
||||
img[drive].xdf_type = (img[drive].sectors == xdf_sectors[img[drive].sector_size][i]) ? xdf_types[img[drive].sector_size][i] : 0;
|
||||
if ((bit_rate_300 == 500.0) && (img[drive].sectors == 21) && (img[drive].sector_size == 2) && (img[drive].tracks >= 80) && (img[drive].tracks <= 82) && (img[drive].sides == 2))
|
||||
{
|
||||
img[drive].xdf_type = 0;
|
||||
/* This is a DMF floppy, set the flag so we know to interleave the sectors. */
|
||||
img[drive].dmf = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pclog("bpb_sectors is %i\n", bpb_sectors);
|
||||
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;
|
||||
pclog("XDF type is 2 @ %i kbps\n", bit_rate_300);
|
||||
break;
|
||||
case 46: /* Extended density XDF */
|
||||
img[drive].xdf_type = 3;
|
||||
break;
|
||||
default: /* Unknown, as we're beyond maximum sectors, get out */
|
||||
fclose(img[drive].f);
|
||||
return;
|
||||
}
|
||||
pclog("XDF type: %i\n", img[drive].xdf_type);
|
||||
}
|
||||
else /* Amount of sectors per track that fits into a track, therefore not XDF */
|
||||
{
|
||||
img[drive].xdf_type = 0;
|
||||
}
|
||||
img[drive].dmf = 0;
|
||||
}
|
||||
}
|
||||
else /* BPB reports sector size other than 512, can't possibly be XDF */
|
||||
{
|
||||
img[drive].xdf_type = 0;
|
||||
|
||||
pclog("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, DMF: %i, XDF type: %i\n", bit_rate_300, temp_rate, img[drive].disk_flags >> 1, img[drive].dmf, img[drive].xdf_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gap2_size[drive] = (temp_rate == 3) ? 41 : 22;
|
||||
// pclog("GAP2 size: %i bytes\n", gap2_size[drive]);
|
||||
gap3_size[drive] = gap3_sizes[temp_rate][sector_size_code(img[drive].sector_size)][img[drive].sectors];
|
||||
if (!gap3_size[drive])
|
||||
if (temp_rate == 0xFF)
|
||||
{
|
||||
gap3_size[drive] = 40;
|
||||
pclog("WARNING: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41);
|
||||
pclog("Image is bigger than can fit on an ED floppy, ejecting...\n");
|
||||
fclose(img[drive].f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bit_rate_300 == 250)
|
||||
img[drive].gap2_size = (temp_rate == 3) ? 41 : 22;
|
||||
if (img[drive].dmf)
|
||||
{
|
||||
img[drive].hole = 0;
|
||||
/* If drive does not support 300 RPM, the medium is to be read at a period of 26 (300 kbps). */
|
||||
img[drive].byte_period = 29;
|
||||
}
|
||||
else if (bit_rate_300 == 300)
|
||||
{
|
||||
img[drive].hole = 0;
|
||||
img[drive].byte_period = 26;
|
||||
}
|
||||
else if (bit_rate_300 == 1000)
|
||||
{
|
||||
img[drive].hole = 2;
|
||||
img[drive].byte_period = 8;
|
||||
}
|
||||
else if (bit_rate_300 < 250)
|
||||
{
|
||||
img[drive].hole = 0;
|
||||
img[drive].byte_period = 32;
|
||||
img[drive].gap3_size = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
img[drive].hole = 1;
|
||||
img[drive].byte_period = 16;
|
||||
img[drive].gap3_size = gap3_sizes[temp_rate][img[drive].sector_size][img[drive].sectors];
|
||||
}
|
||||
if (!img[drive].gap3_size)
|
||||
{
|
||||
pclog("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41);
|
||||
fclose(img[drive].f);
|
||||
return;
|
||||
}
|
||||
|
||||
img[drive].track_width = 0;
|
||||
if (img[drive].tracks > 43) img[drive].track_width = 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */
|
||||
if (img[drive].sides == 2) img[drive].disk_flags |= 8; /* If the has 2 sides, mark it as such. */
|
||||
|
||||
img[drive].track_flags = 0x08; /* IMG files are always assumed to be MFM-encoded. */
|
||||
img[drive].track_flags |= temp_rate & 3; /* Data rate. */
|
||||
if (temp_rate & 4) img[drive].track_flags |= 0x20; /* RPM. */
|
||||
|
||||
pclog("Disk flags: %i, track flags: %i\n", img[drive].disk_flags, img[drive].track_flags);
|
||||
|
||||
d86f_register_img(drive);
|
||||
|
||||
drives[drive].seek = img_seek;
|
||||
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].byteperiod = img_byteperiod;
|
||||
drives[drive].poll = disc_sector_poll;
|
||||
drives[drive].format = disc_sector_format;
|
||||
drives[drive].realtrack = img_realtrack;
|
||||
drives[drive].stop = disc_sector_stop;
|
||||
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;
|
||||
}
|
||||
|
||||
double img_byteperiod(int drive)
|
||||
{
|
||||
if (img[drive].byte_period == 29)
|
||||
{
|
||||
return (fdd_get_type(drive) & 1) ? 32.0 : (160.0 / 6.0);
|
||||
}
|
||||
return (double) img[drive].byte_period;
|
||||
d86f_common_handlers(drive);
|
||||
}
|
||||
|
||||
void img_close(int drive)
|
||||
{
|
||||
d86f_unregister(drive);
|
||||
if (img[drive].f)
|
||||
fclose(img[drive].f);
|
||||
img[drive].f = NULL;
|
||||
}
|
||||
|
||||
#define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector]
|
||||
#define xdf_disk_sector xdf_disk_layout[current_xdft][!is_t0][array_sector]
|
||||
|
||||
int interleave(int sector, int skew, int track_spt)
|
||||
{
|
||||
uint32_t skewed_i = 0;
|
||||
uint32_t adjusted_r = 0;
|
||||
|
||||
uint32_t add = (track_spt & 1);
|
||||
uint32_t adjust = (track_spt >> 1);
|
||||
|
||||
skewed_i = (sector + skew) % track_spt;
|
||||
adjusted_r = (skewed_i >> 1) + 1;
|
||||
if (skewed_i & 1)
|
||||
{
|
||||
adjusted_r += (adjust + add);
|
||||
}
|
||||
|
||||
return adjusted_r;
|
||||
}
|
||||
|
||||
void img_seek(int drive, int track)
|
||||
{
|
||||
int side;
|
||||
int current_xdft = img[drive].xdf_type - 1;
|
||||
|
||||
int sector, current_pos, sh, sr, sn, sside, total, max_pos;
|
||||
uint8_t id[4] = { 0, 0, 0, 0 };
|
||||
|
||||
int is_t0, sector, current_pos, img_pos, sr, sside, total, array_sector, buf_side, buf_pos;
|
||||
|
||||
int ssize = 128 << ((int) img[drive].sector_size);
|
||||
|
||||
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);
|
||||
// pclog(" %i %i\n", drive_type[drive], img[drive].tracks);
|
||||
if ((img[drive].tracks <= 43) && fdd_doublestep_40(drive))
|
||||
|
||||
if (!img[drive].track_width && fdd_doublestep_40(drive))
|
||||
track /= 2;
|
||||
|
||||
// pclog("Disk seeked to track %i\n", track);
|
||||
disc_track[drive] = track;
|
||||
img[drive].track = track;
|
||||
|
||||
if (img[drive].sides == 2)
|
||||
{
|
||||
fseek(img[drive].f, img[drive].base + (track * img[drive].sectors * img[drive].sector_size * 2), SEEK_SET);
|
||||
// pclog("Seek: Current file position (H0) is: %08X\n", ftell(img[drive].f));
|
||||
fread(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
||||
// pclog("Seek: Current file position (H1) is: %08X\n", ftell(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, img[drive].base + (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);
|
||||
|
||||
if (img[drive].xdf_type)
|
||||
is_t0 = (track == 0) ? 1 : 0;
|
||||
|
||||
fseek(img[drive].f, img[drive].base + (track * img[drive].sectors * ssize * img[drive].sides), SEEK_SET);
|
||||
for (side = 0; side < img[drive].sides; side++)
|
||||
{
|
||||
max_pos = (img[drive].sectors * 512);
|
||||
if (!track)
|
||||
fread(img[drive].track_data[side], img[drive].sectors * ssize, 1, img[drive].f);
|
||||
}
|
||||
|
||||
d86f_reset_index_hole_pos(drive, 0);
|
||||
d86f_reset_index_hole_pos(drive, 1);
|
||||
|
||||
if (!img[drive].xdf_type)
|
||||
{
|
||||
for (side = 0; side < img[drive].sides; side++)
|
||||
{
|
||||
/* Track 0, register sectors according to track 0 layout. */
|
||||
total = img[drive].sectors;
|
||||
current_pos = 0;
|
||||
for (sector = 0; sector < (total << 1); sector++)
|
||||
current_pos = d86f_prepare_pretrack(drive, side, 0);
|
||||
|
||||
for (sector = 0; sector < img[drive].sectors; sector++)
|
||||
{
|
||||
current_pos = (sector % total) << 9;
|
||||
sside = (sector >= total) ? 1 : 0;
|
||||
if (xdf_track0_layout[current_xdft][sector])
|
||||
// sr = img[drive].dmf ? (dmf_r[sector]) : (sector + 1);
|
||||
if (img[drive].gap3_size < 68)
|
||||
{
|
||||
sh = xdf_track0_layout[current_xdft][sector] & 0xFF;
|
||||
sr = xdf_track0_layout[current_xdft][sector] >> 8;
|
||||
xdf_sector_pos[(sh << 8) | sr] = current_pos;
|
||||
disc_sector_add(drive, sh, track, sh, sr, 2,
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[sside][current_pos]);
|
||||
sr = interleave(sector, 1, img[drive].sectors);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Non-zero track, this will have sectors of various sizes. */
|
||||
total = xdf_spt[current_xdft] >> 1;
|
||||
current_pos = 0;
|
||||
for (sector = 0; sector < xdf_spt[current_xdft]; sector++)
|
||||
{
|
||||
sside = (sector >= total) ? 1 : 0;
|
||||
sh = xdf_trackx_layout[current_xdft][sector] & 0xFF;
|
||||
sr = xdf_trackx_layout[current_xdft][sector] >> 8;
|
||||
sn = sr & 7;
|
||||
disc_sector_add(drive, sh, track, sh, sr, sn,
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[sside][current_pos]);
|
||||
current_pos += (128 << sn);
|
||||
current_pos %= max_pos;
|
||||
else
|
||||
{
|
||||
sr = img[drive].dmf ? (dmf_r[sector]) : (sector + 1);
|
||||
}
|
||||
id[0] = track;
|
||||
id[1] = side;
|
||||
id[2] = sr;
|
||||
id[3] = img[drive].sector_size;
|
||||
img[drive].sector_pos_side[side][sr] = side;
|
||||
img[drive].sector_pos[side][sr] = (sr - 1) * ssize;
|
||||
// pclog("Seek: %i %i %i %i | %i %04X\n", id[0], id[1], id[2], id[3], side, (sr - 1) * ssize);
|
||||
current_pos = d86f_prepare_sector(drive, side, current_pos, id, &img[drive].track_data[side][(sr - 1) * ssize], ssize, img[drive].gap2_size, img[drive].gap3_size, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
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[drive].sector_size]);
|
||||
{
|
||||
total = img[drive].sectors;
|
||||
img_pos = 0;
|
||||
sside = 0;
|
||||
|
||||
/* Pass 1, get sector positions in the image. */
|
||||
for (sector = 0; sector < xdf_logical_sectors[current_xdft][!is_t0]; sector++)
|
||||
{
|
||||
if (is_t0)
|
||||
{
|
||||
img_pos = (sector % total) << 9;
|
||||
sside = (sector >= total) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (xdf_img_sector.word)
|
||||
{
|
||||
img[drive].sector_pos_side[xdf_img_sector.id.h][xdf_img_sector.id.r] = sside;
|
||||
img[drive].sector_pos[xdf_img_sector.id.h][xdf_img_sector.id.r] = img_pos;
|
||||
// pclog("Side: %i, Position: %04X\n", sside, img_pos);
|
||||
}
|
||||
|
||||
if (!is_t0)
|
||||
{
|
||||
img_pos += (128 << (xdf_img_sector.id.r & 7));
|
||||
if (img_pos >= (total << 9)) sside = 1;
|
||||
img_pos %= (total << 9);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass 2, prepare the actual track. */
|
||||
for (side = 0; side < img[drive].sides; side++)
|
||||
{
|
||||
current_pos = d86f_prepare_pretrack(drive, side, 0);
|
||||
|
||||
for (sector = 0; sector < xdf_physical_sectors[current_xdft][!is_t0]; sector++)
|
||||
{
|
||||
array_sector = (side * xdf_physical_sectors[current_xdft][!is_t0]) + sector;
|
||||
// pclog("Sector %i, array sector %i\n", sector, array_sector);
|
||||
|
||||
buf_side = img[drive].sector_pos_side[xdf_disk_sector.id.h][xdf_disk_sector.id.r];
|
||||
buf_pos = img[drive].sector_pos[xdf_disk_sector.id.h][xdf_disk_sector.id.r];
|
||||
|
||||
// pclog("Side: %i, Position: %04X\n", buf_side, buf_pos);
|
||||
|
||||
id[0] = track;
|
||||
id[1] = xdf_disk_sector.id.h;
|
||||
id[2] = xdf_disk_sector.id.r;
|
||||
|
||||
if (is_t0)
|
||||
{
|
||||
id[3] = 2;
|
||||
// pclog("XDF Track 0: Registering sector: %i %i %i %i\n", id[0], id[1], id[2], id[3]);
|
||||
current_pos = d86f_prepare_sector(drive, side, current_pos, id, &img[drive].track_data[buf_side][buf_pos], ssize, img[drive].gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
id[3] = id[2] & 7;
|
||||
// pclog("XDF Track X: Registering sector: %i %i %i %i\n", id[0], id[1], id[2], id[3]);
|
||||
ssize = (128 << id[3]);
|
||||
current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &img[drive].track_data[buf_side][buf_pos], ssize, img[drive].gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (side = img[drive].sides - 1; side >= 0; side--)
|
||||
{
|
||||
disc_sector_prepare_track_layout(drive, side, track);
|
||||
}
|
||||
|
||||
// pclog("Seeked to track: %i\n", img[drive].track);
|
||||
}
|
||||
|
||||
void img_writeback(int drive)
|
||||
{
|
||||
int side;
|
||||
int ssize = 128 << ((int) img[drive].sector_size);
|
||||
|
||||
if (!img[drive].f)
|
||||
return;
|
||||
|
||||
// if (img[drive].xdf_type)
|
||||
// return; /*Should never happen*/
|
||||
|
||||
if (img[drive].sides == 2)
|
||||
{
|
||||
fseek(img[drive].f, img[drive].base + (disc_track[drive] * 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, img[drive].base + (disc_track[drive] * 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);
|
||||
}
|
||||
fseek(img[drive].f, img[drive].base + (img[drive].track * img[drive].sectors * ssize * img[drive].sides), SEEK_SET);
|
||||
for (side = 0; side < img[drive].sides; side++)
|
||||
{
|
||||
fwrite(img[drive].track_data[side], img[drive].sectors * ssize, 1, img[drive].f);
|
||||
}
|
||||
}
|
||||
|
||||
int img_xdf_type(int drive)
|
||||
{
|
||||
return img[drive].xdf_type;
|
||||
}
|
||||
|
||||
uint16_t img_disk_flags(int drive)
|
||||
{
|
||||
return img[drive].disk_flags;
|
||||
}
|
||||
|
||||
uint16_t img_side_flags(int drive)
|
||||
{
|
||||
return img[drive].track_flags;
|
||||
}
|
||||
|
||||
void img_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n)
|
||||
{
|
||||
img[drive].current_sector_pos_side = img[drive].sector_pos_side[h][r];
|
||||
img[drive].current_sector_pos = img[drive].sector_pos[h][r];
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t img_poll_read_data(int drive, int side, uint16_t pos)
|
||||
{
|
||||
return img[drive].track_data[img[drive].current_sector_pos_side][img[drive].current_sector_pos + pos];
|
||||
}
|
||||
|
||||
void img_poll_write_data(int drive, int side, uint16_t pos, uint8_t data)
|
||||
{
|
||||
img[drive].track_data[img[drive].current_sector_pos_side][img[drive].current_sector_pos + pos] = data;
|
||||
}
|
||||
|
||||
int img_format_conditions(int drive)
|
||||
{
|
||||
int temp = (fdc_get_format_sectors() == img[drive].sectors);
|
||||
temp = temp && (fdc_get_format_n() == img[drive].sector_size);
|
||||
temp = temp && (img[drive].xdf_type == 0);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void d86f_register_img(int drive)
|
||||
{
|
||||
d86f_handler[drive].disk_flags = img_disk_flags;
|
||||
d86f_handler[drive].side_flags = img_side_flags;
|
||||
d86f_handler[drive].writeback = img_writeback;
|
||||
d86f_handler[drive].set_sector = img_set_sector;
|
||||
d86f_handler[drive].write_data = img_poll_write_data;
|
||||
d86f_handler[drive].format_conditions = img_format_conditions;
|
||||
d86f_handler[drive].extra_bit_cells = null_extra_bit_cells;
|
||||
d86f_handler[drive].encoded_data = common_encoded_data;
|
||||
d86f_handler[drive].read_revolution = common_read_revolution;
|
||||
d86f_handler[drive].index_hole_pos = null_index_hole_pos;
|
||||
d86f_handler[drive].get_raw_size = common_get_raw_size;
|
||||
d86f_handler[drive].check_crc = 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user