static uae_u8 selected = 15, disabled, reserved;
static uae_u8 writebuffer[544 * MAX_SECTORS];
+static uae_u8 writesecheadbuffer[16 * MAX_SECTORS];
#define DISK_INDEXSYNC 1
#define DISK_WORDSYNC 2
typedef enum { TRACK_AMIGADOS, TRACK_RAW, TRACK_RAW1, TRACK_PCDOS, TRACK_DISKSPARE, TRACK_NONE } image_tracktype;
typedef struct {
uae_u16 len;
- uae_u32 offs;
+ int offs, extraoffs;
int bitlen, track;
uae_u16 sync;
image_tracktype type;
#define DRIVE_ID_35HD 0xAAAAAAAA
#define DRIVE_ID_525SD 0x55555555 /* 40 track 5.25 drive , kickstart does not recognize this */
-typedef enum { ADF_NONE = -1, ADF_NORMAL, ADF_EXT1, ADF_EXT2, ADF_FDI, ADF_IPF, ADF_SCP, ADF_CATWEASEL, ADF_PCDOS, ADF_KICK, ADF_SKICK } drive_filetype;
+typedef enum { ADF_NONE = -1, ADF_NORMAL, ADF_EXT1, ADF_EXT2, ADF_FDI, ADF_IPF, ADF_SCP, ADF_CATWEASEL, ADF_PCDOS, ADF_KICK, ADF_SKICK, ADF_NORMAL_HEADER } drive_filetype;
typedef struct {
struct zfile *diskfile;
struct zfile *writediskfile;
ds = 0;
drv->filetype = ADF_NORMAL;
- /* High-density or diskspare disk? */
+ /* High-density, diskspare disk or sector headers included? */
drv->num_tracks = 0;
if (size > 160 * 11 * 512 + 511) { // larger than standard adf?
for (int i = 80; i <= 83; i++) {
ds = 1;
break;
}
+ if (size == i * 11 * (512 + 16) * 2) { // 80+ cyl DD + headers
+ drv->num_tracks = size / ((512 + 16) * (drv->num_secs = 11));
+ drv->filetype = ADF_NORMAL_HEADER;
+ break;
+ }
+ if (size == i * 22 * (512 + 16) * 2) { // 80+ cyl HD + headers
+ drv->num_tracks = size / ((512 + 16) * (drv->num_secs = 22));
+ drv->filetype = ADF_NORMAL_HEADER;
+ break;
+ }
}
if (drv->num_tracks == 0) {
drv->num_tracks = size / (512 * (drv->num_secs = 22));
tid->bitlen = 0;
tid->offs = i * 512 * drv->num_secs;
tid->revolutions = 1;
+ if (drv->filetype == ADF_NORMAL_HEADER) {
+ tid->extraoffs = drv->num_tracks * 512 * drv->num_secs + i * 16 * drv->num_secs;
+ } else {
+ tid->extraoffs = -1;
+ }
}
}
openwritefile (p, drv, 0);
#endif
}
-static void read_floppy_data (struct zfile *diskfile, int type, trackid *tid, int offset, uae_u8 *dst, int len)
+static void read_floppy_data(struct zfile *diskfile, int type, trackid *tid, int sector, uae_u8 *dst, uae_u8 *secheaddst, int len)
{
- if (len == 0)
+ if (len <= 0)
return;
+ if (secheaddst) {
+ memset(secheaddst, 0, 16);
+ }
if (tid->track == 0) {
if (type == ADF_KICK) {
memset (dst, 0, len > 512 ? 512 : len);
- if (offset == 0) {
+ if (sector == 0) {
memcpy (dst, "KICK", 4);
len -= 512;
}
} else if (type == ADF_SKICK) {
memset (dst, 0, len > 512 ? 512 : len);
- if (offset == 0) {
+ if (sector == 0) {
memcpy (dst, "KICKSUP0", 8);
len -= 1024;
- } else if (offset == 512) {
+ } else if (sector == 1) {
len -= 512;
}
}
}
- int off = tid->offs + offset;
- if (off >= 0 && len > 0) {
- zfile_fseek (diskfile, off, SEEK_SET);
- zfile_fread (dst, 1, len, diskfile);
+ if (tid->offs < 0 || sector < 0)
+ return;
+ if (type == ADF_NORMAL_HEADER && tid->extraoffs > 0) {
+ zfile_fseek(diskfile, tid->extraoffs + sector * 16, SEEK_SET);
+ zfile_fread(secheaddst, 1, 16, diskfile);
}
+ zfile_fseek(diskfile, tid->offs + sector * 512, SEEK_SET);
+ zfile_fread(dst, 1, len, diskfile);
}
/* Megalomania does not like zero MFM words... */
secbuf[57] = 0xa1;
secbuf[58] = 0xa1;
secbuf[59] = 0xfb;
- read_floppy_data (drv->diskfile, drv->filetype, ti, i * 512, &secbuf[60], 512);
+ read_floppy_data (drv->diskfile, drv->filetype, ti, i, &secbuf[60], NULL, 512);
crc16 = get_crc16 (secbuf + 56, 3 + 1 + 512);
secbuf[60 + 512] = crc16 >> 8;
secbuf[61 + 512] = crc16 & 0xff;
prevbit = 0;
for (sec = 0; sec < drv->num_secs; sec++) {
uae_u8 secbuf[544];
+ uae_u8 secheadbuf[16];
uae_u16 mfmbuf[544 + 1];
int i;
uae_u32 deven, dodd;
for (i = 8; i < 24; i++)
secbuf[i] = 0;
- read_floppy_data (drv->diskfile, drv->filetype, ti, sec * 512, &secbuf[32], 512);
+ read_floppy_data (drv->diskfile, drv->filetype, ti, sec, &secbuf[32], secheadbuf, 512);
mfmbuf[0] = prevbit ? 0x2aaa : 0xaaaa;
mfmbuf[1] = 0xaaaa;
mfmbuf[6] = deven >> 16;
mfmbuf[7] = deven;
- for (i = 8; i < 48; i++)
- mfmbuf[i] = 0xaaaa;
- for (i = 0; i < 512; i += 4) {
- deven = ((secbuf[i + 32] << 24) | (secbuf[i + 33] << 16)
- | (secbuf[i + 34] << 8) | (secbuf[i + 35]));
+ for (i = 0; i < 16; i += 4) {
+ deven = ((secheadbuf[i] << 24) | (secheadbuf[i + 1] << 16)
+ | (secheadbuf[i + 2] << 8) | (secheadbuf[i + 3]));
dodd = deven >> 1;
deven &= 0x55555555;
dodd &= 0x55555555;
- mfmbuf[(i >> 1) + 32] = dodd >> 16;
- mfmbuf[(i >> 1) + 33] = dodd;
- mfmbuf[(i >> 1) + 256 + 32] = deven >> 16;
- mfmbuf[(i >> 1) + 256 + 33] = deven;
+ mfmbuf[(i >> 1) + 8] = dodd >> 16;
+ mfmbuf[(i >> 1) + 9] = dodd;
+ mfmbuf[(i >> 1) + 8 + 8] = deven >> 16;
+ mfmbuf[(i >> 1) + 8 + 9] = deven;
}
-
- for (i = 4; i < 24; i += 2)
+ for (i = 4; i < 24; i += 2) {
hck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
-
+ }
deven = dodd = hck;
dodd >>= 1;
mfmbuf[24] = dodd >> 16;
mfmbuf[26] = deven >> 16;
mfmbuf[27] = deven;
- for (i = 32; i < 544; i += 2)
+ for (i = 0; i < 512; i += 4) {
+ deven = ((secbuf[i + 32] << 24) | (secbuf[i + 33] << 16)
+ | (secbuf[i + 34] << 8) | (secbuf[i + 35]));
+ dodd = deven >> 1;
+ deven &= 0x55555555;
+ dodd &= 0x55555555;
+ mfmbuf[(i >> 1) + 32] = dodd >> 16;
+ mfmbuf[(i >> 1) + 33] = dodd;
+ mfmbuf[(i >> 1) + 256 + 32] = deven >> 16;
+ mfmbuf[(i >> 1) + 256 + 33] = deven;
+ }
+ for (i = 32; i < 544; i += 2) {
dck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
-
+ }
deven = dodd = dck;
dodd >>= 1;
mfmbuf[28] = dodd >> 16;
secbuf[2] = 0;
secbuf[3] = 0;
- read_floppy_data (drv->diskfile, drv->filetype, ti, sec * 512, &secbuf[4], 512);
+ read_floppy_data (drv->diskfile, drv->filetype, ti, sec, &secbuf[4], NULL, 512);
mfmbuf[0] = 0xaaaa;
mfmbuf[1] = 0x4489;
trackid *wti = &drv->writetrackdata[tr];
drv->tracklen = wti->bitlen;
drv->revolutions = wti->revolutions;
- read_floppy_data (drv->writediskfile, drv->filetype, wti, 0, (uae_u8*)drv->bigmfmbuf, (wti->bitlen + 7) / 8);
+ read_floppy_data (drv->writediskfile, drv->filetype, wti, 0, (uae_u8*)drv->bigmfmbuf, NULL, (wti->bitlen + 7) / 8);
for (i = 0; i < (drv->tracklen + 15) / 16; i++) {
uae_u16 *mfm = drv->bigmfmbuf + i;
uae_u8 *data = (uae_u8 *) mfm;
int base_offset = ti->type == TRACK_RAW ? 0 : 1;
drv->tracklen = ti->bitlen + 16 * base_offset;
drv->bigmfmbuf[0] = ti->sync;
- read_floppy_data (drv->diskfile, drv->filetype, ti, 0, (uae_u8*)(drv->bigmfmbuf + base_offset), (ti->bitlen + 7) / 8);
+ read_floppy_data (drv->diskfile, drv->filetype, ti, 0, (uae_u8*)(drv->bigmfmbuf + base_offset), NULL, (ti->bitlen + 7) / 8);
for (i = base_offset; i < (drv->tracklen + 15) / 16; i++) {
uae_u16 *mfm = drv->bigmfmbuf + i;
uae_u8 *data = (uae_u8 *) mfm;
int length = 2 * fwlen;
uae_u32 odd, even, chksum, id, dlong;
uae_u8 *secdata;
- uae_u8 secbuf[544];
+ uae_u8 secbuf[544], secheadbuf[16];
uae_u16 *mend = mbuf + length, *mstart;
uae_u32 sechead[4];
int shift = 0;
chksum ^= odd ^ even;
}
if (issechead) {
- write_log (_T("Disk decode: sector %d header: %08X %08X %08X %08X\n"),
- trackoffs, sechead[0], sechead[1], sechead[2], sechead[3]);
- if (filetype == ADF_EXT2)
- return 6;
+ if (filetype != ADF_NORMAL_HEADER) {
+ write_log(_T("Disk decode: sector %d header: %08X %08X %08X %08X\n"),
+ trackoffs, sechead[0], sechead[1], sechead[2], sechead[3]);
+ if (filetype == ADF_EXT2)
+ return 6;
+ }
}
mbuf += 8;
odd = getmfmlong (mbuf, shift);
sectable[trackoffs] = 1;
secwritten++;
memcpy (writebuffer + trackoffs * 512, secbuf + 32, 512);
+ uae_u8 *secheadbuf = writesecheadbuffer + trackoffs * 16;
+ for (i = 0; i < 4; i++) {
+ *secheadbuf++ = sechead[i] >> 24;
+ *secheadbuf++ = sechead[i] >> 16;
+ *secheadbuf++ = sechead[i] >> 8;
+ *secheadbuf++ = sechead[i] >> 0;
+ }
}
if (filetype == ADF_EXT2 && (secwritten == 0 || secwritten < 0))
return 5;
if (!drvsec)
return 2;
- if (drv->filetype == ADF_EXT2)
- diskfile_update (drv->diskfile, &drv->trackdata[drv->cyl * 2 + side], drvsec * 512 * 8, TRACK_AMIGADOS);
- for (i = 0; i < drvsec; i++) {
- zfile_fseek (drv->diskfile, drv->trackdata[drv->cyl * 2 + side].offs + i * 512, SEEK_SET);
- zfile_fwrite (writebuffer + i * 512, sizeof (uae_u8), 512, drv->diskfile);
+ if (drv->filetype == ADF_EXT2) {
+ diskfile_update(drv->diskfile, &drv->trackdata[drv->cyl * 2 + side], drvsec * 512 * 8, TRACK_AMIGADOS);
}
-
+ trackid *tid = &drv->trackdata[drv->cyl * 2 + side];
+ if (drv->filetype == ADF_NORMAL_HEADER && tid->extraoffs > 0) {
+ zfile_fseek(drv->diskfile, tid->extraoffs, SEEK_SET);
+ zfile_fwrite(writesecheadbuffer, sizeof(uae_u8), drvsec * 16, drv->diskfile);
+ }
+ zfile_fseek (drv->diskfile, tid->offs, SEEK_SET);
+ zfile_fwrite (writebuffer, sizeof (uae_u8), drvsec * 512, drv->diskfile);
return 0;
}
}
switch (drv->filetype) {
case ADF_NORMAL:
+ case ADF_NORMAL_HEADER:
if (drv->ddhd > 1 && currprefs.floppyslots[drv - &floppy[0]].dfxtype != DRV_35_HD) {
// HD image in DD drive: ignore writing.
drv->buffered_side = 2;
disk_checksum (dst + 512, dst + 512);
}
-/* type: 0=regular, 1=ext2adf */
+/* type: 0=regular, 1=ext2adf, 2=regular+headers */
bool disk_creatediskfile (struct uae_prefs *p, const TCHAR *name, int type, drive_type adftype, int hd, const TCHAR *disk_name, bool ffs, bool bootable, struct zfile *copyfrom)
{
int size = 32768;
struct zfile *f;
- int i, l, file_size, tracks, track_len, sectors;
+ int i, l, file_size, data_size, tracks, track_len, sectors;
uae_u8 *chunk = NULL;
int ddhd = 1;
bool ok = false;
tracks = 2 * 83;
else
tracks = 2 * 80;
- file_size = 880 * 1024;
+ file_size = 880 * 2 * 512;
+ data_size = file_size;
+ if (type == 2)
+ file_size = 880 * 2 * (512 + 16);
sectors = 11;
if (adftype == DRV_PC_525_ONLY_40 || adftype == DRV_PC_35_ONLY_80 || adftype == DRV_PC_525_40_80) {
file_size = 720 * 1024;
if (f && chunk) {
int cylsize = sectors * 2 * 512;
memset (chunk, 0, size);
- if (type == 0) {
+ if (type == 0 || type == 2) {
+ int dataoffset = 0;
+ if (type == 2) {
+ cylsize = sectors * 2 * (512 + 16);
+ dataoffset += 16;
+ }
for (i = 0; i < file_size; i += cylsize) {
memset(chunk, 0, cylsize);
if (adftype == DRV_35_DD || adftype == DRV_35_HD) {
if (i == 0) {
/* boot block */
- floppy_get_bootblock (chunk, ffs, bootable);
+ floppy_get_bootblock (chunk + dataoffset, ffs, bootable);
} else if (i == file_size / 2) {
/* root block */
- floppy_get_rootblock (chunk, file_size / 1024, disk_name, ddhd > 1);
+ floppy_get_rootblock (chunk + dataoffset, data_size / 1024, disk_name, ddhd > 1);
}
}
zfile_fwrite (chunk, cylsize, 1, f);
drive *drv = &floppy[dr];
if (selected & (1 << dr))
continue;
- if (drv->filetype != ADF_NORMAL && drv->filetype != ADF_KICK && drv->filetype != ADF_SKICK)
+ if (drv->filetype != ADF_NORMAL && drv->filetype != ADF_KICK && drv->filetype != ADF_SKICK && drv->filetype != ADF_NORMAL_HEADER)
break;
}
if (dr < MAX_FLOPPY_DRIVES) /* no turbo mode if any selected drive has non-standard ADF */