Add support for DiskCopy 4.2 image format.

This commit is contained in:
Stephen Heumann 2018-10-17 20:14:40 -05:00
parent 28367e196e
commit 08fe7fe4b6
10 changed files with 150 additions and 5 deletions

View File

@ -7,7 +7,7 @@ HTTPTEST_PROG = httptest
MOUNTURL_OBJS = mounturl.a netdiskerror.a
MOUNTURL_PROG = mounturl
NETDISKINIT_OBJS = initstart.a netdiskinit.a hostname.a http.a readtcp.a seturl.a strcasecmp.a tcpconnection.a urlparser.a driver.a installdriver.a asmglue.a driverwrapper.a session.a systemservices.a
NETDISKINIT_OBJS = initstart.a netdiskinit.a hostname.a http.a readtcp.a seturl.a strcasecmp.a tcpconnection.a urlparser.a driver.a installdriver.a asmglue.a driverwrapper.a session.a systemservices.a endian.a
# NETDISKINIT_RSRC =
NETDISKINIT_PROG = NetDiskInit

View File

@ -21,7 +21,7 @@ Compatibility
-------------
NetDisk can access disk image files on most servers that allow unencrypted HTTP access. The server must also support HTTP range requests. Most modern servers support these, but some may not, in which case an error message will be shown.
NetDisk supports raw (aka ProDOS-order and various other names), 2MG, and DOS-order disk images. The images may use any filesystem for which you have an FST installed, except that DOS 3.3 filesystems are not supported due to a limitation in that FST. You can use images of any size (subject to the limitations of the relevant FST), from floppy disks to large hard drive partitions or CD-ROMS.
NetDisk supports raw (aka ProDOS-order and various other names), 2MG, DOS-order, and DiskCopy 4.2 disk images. The images may use any filesystem for which you have an FST installed, except that DOS 3.3 filesystems are not supported due to a limitation in that FST. You can use images of any size (subject to the limitations of the relevant FST), from floppy disks to large hard drive partitions or CD-ROMS.
Usage

4
cdev.c
View File

@ -41,6 +41,7 @@
#define format2mgItem 302
#define formatRawItem 303
#define formatDOSOrderItem 304
#define formatDiskCopy42Item 305
#define netDiskMissingError 3000
#define mountURLError 3001
@ -147,6 +148,9 @@ void DoHit(long ctlID, CtlRecHndl ctlHandle)
case formatDOSOrderItem:
format = formatDOSOrder;
break;
case formatDiskCopy42Item:
format = formatDiskCopy42;
break;
}
}

View File

@ -96,6 +96,7 @@ resource rIcon (1) {
#define format2mgItem 302
#define formatRawItem 303
#define formatDOSOrderItem 304
#define formatDiskCopy42Item 305
/*
* Controls in the control panel window (for 640 mode or 320 mode)
@ -202,7 +203,8 @@ resource rMenu (imageFormatMenu) {
formatAutoDetectItem,
format2mgItem,
formatRawItem,
formatDOSOrderItem
formatDOSOrderItem,
formatDiskCopy42Item,
};
};
resource rPString(imageFormatMenu,noCrossBank) { "Format: " };
@ -243,6 +245,15 @@ resource rMenuItem (formatDOSOrderItem) {
};
resource rPString(formatDOSOrderItem,noCrossBank) { "DOS Order" };
resource rMenuItem (formatDiskCopy42Item) {
formatDiskCopy42Item, /* menu item ID */
"","",
0,
refIsResource*itemTitleRefShift,
formatDiskCopy42Item /* menu item title ref */
};
resource rPString(formatDiskCopy42Item,noCrossBank) { "DiskCopy 4.2" };
/*
* Controls in the help window
*/

21
diskcopy42.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef DISKCOPY42_H
#define DISKCOPY42_H
#define DC42_DISK_NAME_LEN 64
#define DC42_DATA_OFFSET 84
/* Expected magic value in "private" header field (taken as little-endian) */
#define DC42_MAGIC 0x0001
struct DiskCopy42Header {
char diskName[DC42_DISK_NAME_LEN]; /* p-string */
LongWord dataSize; /* big-endian */
LongWord tagSize; /* big-endian */
LongWord dataChecksum;
LongWord tagChecksum;
Byte diskFormat;
Byte formatByte;
Word private;
};
#endif

View File

@ -15,6 +15,7 @@
#include "mounturl.h"
#include "systemservices.h"
#include "version.h"
#include "endian.h"
#define BLOCK_SIZE 512
@ -26,6 +27,8 @@
static const int sectorMap[2][8] = {{ 0, 13, 11, 9, 7, 5, 3, 1},
{14, 12, 10, 8, 6, 4, 2, 15}};
#define APPLE_35_DISK_SIZE (800L * 1024)
struct DIB dibs[NDIBS] = {0};
struct DIBList dibList = {NDIBS};
@ -210,6 +213,38 @@ Word DriverDispatch(Word callNum, struct GSOSDP *dp) {
}
#pragma databank 0
/*
* Check for a valid DiskCopy 4.2 header, and process it if found.
* Returns a non-zero error code for an invalid or unsupported DC42 file,
* OPERATION_SUCCESSFUL otherwise (whether it's a DC42 file or not).
*/
static enum NetDiskError CheckDiskCopy42(Session *sess) {
struct DiskCopy42Header *hdr = &sess->fileHeader.diskCopy42Header;
if (sess->totalLength == DISK_II_DISK_SIZE)
return OPERATION_SUCCESSFUL;
if (sess->totalLength == APPLE_35_DISK_SIZE)
return OPERATION_SUCCESSFUL;
if (hdr->private != DC42_MAGIC)
return OPERATION_SUCCESSFUL;
if (hdr->dataSize == 0 || ntohl(hdr->dataSize) % BLOCK_SIZE != 0)
return OPERATION_SUCCESSFUL;
if ((unsigned char)hdr->diskName[0] >= DC42_DISK_NAME_LEN)
return OPERATION_SUCCESSFUL;
if (ntohl(hdr->dataSize) + ntohl(hdr->tagSize) + DC42_DATA_OFFSET
!= sess->totalLength)
return OPERATION_SUCCESSFUL;
sess->dataOffset = DC42_DATA_OFFSET;
sess->dataLength = ntohl(hdr->dataSize);
return OPERATION_SUCCESSFUL;
}
/*
* Check for a 2IMG file, and process its header if one is found.
* Returns a non-zero error code for an invalid or unsupported 2IMG file,
@ -318,6 +353,25 @@ static Word DoMountURL(struct GSOSDP *dp) {
}
}
if (mountURLRec->format == formatAutoDetect
|| mountURLRec->format == formatDiskCopy42)
{
err = CheckDiskCopy42(sess);
if (err != OPERATION_SUCCESSFUL) {
EndNetDiskSession(sess);
dp->transferCount = 0;
mountURLRec->result = err;
return drvrIOError;
}
if (sess->dataOffset == DC42_DATA_OFFSET) {
mountURLRec->format = formatDiskCopy42;
} else if (mountURLRec->format == formatDiskCopy42) {
dp->transferCount = 0;
mountURLRec->result = NOT_SPECIFIED_IMAGE_TYPE;
return drvrIOError;
}
}
if (sess->dataOffset == 0) {
/* No encapsulating disk image - treat this as raw blocks */
sess->dataLength = sess->totalLength;

32
endian.asm Normal file
View File

@ -0,0 +1,32 @@
case on
htons start
ntohs entry
ply
phb
plx
pla
xba
phx
plb
phy
rtl
end
htonl start
ntohl entry
lda 4,s
xba
tax
lda 6,s
xba
tay
phb
pla
sta 3,s
pla
sta 3,s
plb
tya
rtl
end

20
endian.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef ENDIAN_H
#define ENDIAN_H
#include <types.h>
/*
* Undefine these in case they're defined as macros.
* (In particular, GNO has broken macro definitions for these.)
*/
#undef htons
#undef ntohs
#undef htonl
#undef ntohl
Word htons(Word);
Word ntohs(Word);
LongWord htonl(LongWord);
LongWord ntohl(LongWord);
#endif

View File

@ -15,7 +15,8 @@ enum DiskImageFormat {
formatAutoDetect = 0,
format2mg,
formatRaw,
formatDOSOrder
formatDOSOrder,
formatDiskCopy42
};
struct MountURLRec {

View File

@ -3,6 +3,7 @@
#include <types.h>
#include "twoimg.h"
#include "diskcopy42.h"
typedef struct Session {
/* Marinetti TCP connection status */
@ -63,8 +64,9 @@ typedef struct Session {
/* Buffer for initial bytes of file (which may be a disk image header) */
union {
unsigned char buf[32];
unsigned char buf[84];
struct TwoImgHeader twoImgHeader;
struct DiskCopy42Header diskCopy42Header;
} fileHeader;
} Session;