]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
ADF with appended sector headers format.
authorToni Wilen <twilen@winuae.net>
Sat, 16 Nov 2019 17:46:54 +0000 (19:46 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 16 Nov 2019 17:46:54 +0000 (19:46 +0200)
disk.cpp

index a8fd0ac1450b4637e01f2aa57099c4a4602735b5..6c11dea564c934103a3cdbb530dcc660cfd970da 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -97,6 +97,7 @@ static int side, direction, reserved_side;
 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
@@ -133,7 +134,7 @@ static bool amax_enabled;
 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;
@@ -157,7 +158,7 @@ typedef struct {
 #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;
@@ -1406,7 +1407,7 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
                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++) {
@@ -1430,6 +1431,16 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
                                        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));
@@ -1448,6 +1459,11 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
                        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);
@@ -1625,32 +1641,38 @@ static void drive_motor (drive * drv, bool off)
 #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... */
@@ -1740,7 +1762,7 @@ static void decode_pcdos (drive *drv)
                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;
@@ -1782,6 +1804,7 @@ static void decode_amigados (drive *drv)
        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;
@@ -1797,7 +1820,7 @@ static void decode_amigados (drive *drv)
                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;
@@ -1814,23 +1837,20 @@ static void decode_amigados (drive *drv)
                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;
@@ -1838,9 +1858,20 @@ static void decode_amigados (drive *drv)
                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;
@@ -1903,7 +1934,7 @@ static void decode_diskspare (drive *drv)
                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;
@@ -1986,7 +2017,7 @@ static void drive_fill_bigbuf (drive * drv, int force)
                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;
@@ -2045,7 +2076,7 @@ static void drive_fill_bigbuf (drive * drv, int force)
                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;
@@ -2129,7 +2160,7 @@ static int decode_buffer (uae_u16 *mbuf, int cyl, int drvsec, int ddhd, int file
        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;
@@ -2187,10 +2218,12 @@ static int decode_buffer (uae_u16 *mbuf, int cyl, int drvsec, int ddhd, int file
                        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);
@@ -2235,6 +2268,13 @@ static int decode_buffer (uae_u16 *mbuf, int cyl, int drvsec, int ddhd, int file
                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;
@@ -2378,13 +2418,16 @@ static int drive_write_adf_amigados (drive *drv)
        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;
 }
 
@@ -2482,6 +2525,7 @@ static void drive_write_data (drive * drv)
        }
        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;
@@ -2577,12 +2621,12 @@ static void floppy_get_rootblock (uae_u8 *dst, int block, const TCHAR *disk_name
        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;
@@ -2592,7 +2636,10 @@ bool disk_creatediskfile (struct uae_prefs *p, const TCHAR *name, int type, driv
                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;
@@ -2624,16 +2671,21 @@ bool disk_creatediskfile (struct uae_prefs *p, const TCHAR *name, int type, driv
        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);
@@ -4082,7 +4134,7 @@ void DSKLEN (uae_u16 v, int hpos)
                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 */