[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: DSK format specification
CPM: i've got all the C++ routines to set/read all these items too,
if you want them, lemme know
// CpmStructs.h
#ifndef _H_CpmStructs
#define _H_CpmStructs
#include "GenStructs.h"
#include "CpmDiskLocSpec.h"
#include "FileSystemTypes.h"
#ifndef ushort
typedef unsigned short ushort;
#endif
#pragma options align = packed
typedef Cpm_BlockSpec Cpm_BlockNum;
typedef ushort Cpm_EntryIndex;
#define Cpm_GetBlock(imageRec, blockNum) \
&(imageRec->image.cpm->userType.block[blockNum])
/*
for access bits, they are stored in the hi-bit of
the corresponding character position.
eg: to see if a file is locked, look in the
Cpm_kAccessChar_READ_ONLY char of the file name,
if it's hi bit is set, it's locked.
the bits are propagated thru all the dir entries for a
single file, not just set on the first entry
*/
enum {
Cpm_kAccessChar_ILLEGAL_0,
Cpm_kAccessChar_PUBLIC,
Cpm_kAccessChar_DATESTAMP,
Cpm_kAccessChar_ILLEGAL_3,
Cpm_kAccessChar_ILLEGAL_4,
Cpm_kAccessChar_ILLEGAL_5,
Cpm_kAccessChar_ILLEGAL_6,
Cpm_kAccessChar_WHEEL_PROTECT, Cpm_kNameLength,
Cpm_kAccessChar_READ_ONLY = Cpm_kNameLength,
Cpm_kAccessChar_SYSTEM,
Cpm_kAccessChar_ARCHIVE, Cpm_kNameAndTypeLength,
Cpm_kTypeLength = Cpm_kNameAndTypeLength - Cpm_kNameLength
};
typedef short Cpm_AccessChar;
#define FOR_EACH_ACCESS_CHAR(_IDX) \
for ( charIndex = Cpm_kAccessChar_ILLEGAL_0; \
charIndex <= Cpm_kAccessChar_ARCHIVE; \
charIndex++)
enum {
Cpm_kAccessBit_ILLEGAL_0 = 1 << Cpm_kAccessChar_ILLEGAL_0,
Cpm_kAccessBit_PUBLIC = 1 << Cpm_kAccessChar_PUBLIC,
Cpm_kAccessBit_DATESTAMP = 1 << Cpm_kAccessChar_DATESTAMP,
Cpm_kAccessBit_ILLEGAL_3 = 1 << Cpm_kAccessChar_ILLEGAL_3,
Cpm_kAccessBit_ILLEGAL_4 = 1 << Cpm_kAccessChar_ILLEGAL_4,
Cpm_kAccessBit_ILLEGAL_5 = 1 << Cpm_kAccessChar_ILLEGAL_5,
Cpm_kAccessBit_ILLEGAL_6 = 1 << Cpm_kAccessChar_ILLEGAL_6,
Cpm_kAccessBit_WHEEL_PROTECT = 1 << Cpm_kAccessChar_WHEEL_PROTECT,
Cpm_kAccessBit_READ_ONLY = 1 << Cpm_kAccessChar_READ_ONLY,
Cpm_kAccessBit_SYSTEM = 1 << Cpm_kAccessChar_SYSTEM,
Cpm_kAccessBit_ARCHIVE = 1 << Cpm_kAccessChar_ARCHIVE
};
typedef short Cpm_AccessBits;
typedef char Cpm_FileName[Cpm_kNameLength];
typedef char Cpm_FileNameStr[Cpm_kNameLength + 1];
typedef char Cpm_FileType[Cpm_kTypeLength];
typedef char Cpm_FileTypeStr[Cpm_kTypeLength + 1];
// room for "dot" and the "\0"
typedef char Cpm_FileNameAndTypeStr[Cpm_kNameAndTypeLength + 2];
#define Cpm_IsAccessCharSet(_foo) \
(((_foo) & 0x80) != 0)
#define Cpm_SetAccessChar(_char, _setB) \
if (_setB) { \
(_char) |= 0x80; \
} else { \
(_char) &= 0x7F; \
}
#define Cpm_SetAccessBit(_bits, _bit, _setB) \
if (_setB) { \
(_bits) |= _bit; \
} else { \
(_bits) &= ~_bit; \
}
#define Cpm_GetAccessBit(_bits, _bit) \
(((_bits) & _bit) != 0)
#define Cpm_kMaxTotalDirEntries 64
#define Cpm_kMaxUseableDirEntries 48
#define Cpm_kUserNumber 0
#define Cpm_kIllegalBlock 0xFF
#define Cpm_kErasedSentinel 0xE5
#define Cpm_kTextFileEnd 0x1A // ctrl-Z
#define Cpm_kBytesPerRecord 128L
#define Cpm_kRecordsPerBlock 8
#define Cpm_kBytesPerBlock /* 1024 */ (Cpm_kBytesPerRecord *
Cpm_kRecordsPerBlock)
#define Cpm_kBlocksPerExtent 16
#define Cpm_kBlocksPerTrack 4
#define Cpm_kSectorsPerBlock 4
#define Cpm_kRecordsPerExtent /* 128 */ (Cpm_kBlocksPerExtent *
Cpm_kRecordsPerBlock)
#define Cpm_kHeaderBlocksPerDisk ((Cpm_BlockNum)12)
#define Cpm_kUserBlocksPerDisk ((Cpm_BlockNum)128)
#define Cpm_kBlocksPerDisk (Cpm_kHeaderBlocksPerDisk +
Cpm_kUserBlocksPerDisk)
typedef struct {
Byte userNumber;
Cpm_FileName name;
Cpm_FileType fileType;
Byte extentNum;
RboShort system;
Byte numRecords;
Cpm_BlockSpec extent[Cpm_kBlocksPerExtent];
} Cpm_DirEntry;
typedef Cpm_DirEntry Cpm_Directory[Cpm_kMaxTotalDirEntries];
typedef struct {
Byte byte[Cpm_kBytesPerRecord];
} Cpm_Record;
typedef union {
Cpm_Record record[Cpm_kRecordsPerBlock];
Byte byte[Cpm_kBytesPerBlock];
Gen_Sector sector[Cpm_kSectorsPerBlock];
} Cpm_Block;
typedef Cpm_Block Cpm_HeaderArea[Cpm_kHeaderBlocksPerDisk];
typedef Cpm_Block Cpm_UserArea[Cpm_kUserBlocksPerDisk];
typedef struct Cpm_Disk {
Cpm_HeaderArea header;
union {
Cpm_UserArea block;
Cpm_Directory directory;
} userType;
} Cpm_Disk;
#define Cpm_kNumBootBlocks ((Cpm_BlockNum)0)
#define Cpm_kDirStartBlock ((Cpm_BlockNum)0)
#define Cpm_kNumDirBlocks /* 2 */
((Cpm_BlockNum)(sizeof(Cpm_Directory) / Cpm_kBytesPerBlock))
#define Cpm_kDirEndBlock /* 1 */ ((Cpm_BlockNum)Cpm_kDirStartBlock +
Cpm_kNumDirBlocks - 1)
#define Cpm_kFreeUserArea /* ????? */ (sizeof(Cpm_Disk) -
sizeof(Cpm_HeaderArea) - sizeof(Cpm_Directory));
#define Cpm_kMaxFileSize /* ????? */ (Cpm_kMaxUseableDirEntries *
Cpm_kBlocksPerExtent * Cpm_kBytesPerBlock)
#define Cpm_kMaxExtentNum (Cpm_kUserBlocksPerDisk /
Cpm_kBlocksPerExtent)
#pragma options align = reset
Boolean Cpm_IsCpm(DiskImageRec *imageRec);
void Cpm_Catalog(DiskImageRec *imageRec);
#endif