/*- * $Id: han.h,v 1.4 90/01/27 20:33:22 Rhialto Exp $ * * The header file for the MESSYDOS: file system handler * -*/ #include "dev.h" #define MODE_READWRITE 1004L #define MODE_CREATEFILE (1L<<31) #define FILE_DIR 1 #define FILE_FILE -1 /* #define MS_BPS 512 /* Bytes per sector */ #define MS_SPC 2 /* Sectors per cluster */ #define MS_RES 1 /* Reserved sectors (boot block) */ #define MS_NFATS 2 /* Number of FATs */ #define MS_NDIRS 112 /* Number of directory entries */ #define MS_NSECTS 1440 /* total number of sectors */ #define MS_SPF 3 /* Sectors per FAT */ /* #define MS_SPT 9 /* Sectors per track */ /* #define MS_SPT_MAX 9 /* Max sectors per track */ /* #define MS_NSIDES 2 /* Tracks per cylinder */ #define MS_ROOTDIR (MS_RES + MS_SPF * MS_NFATS) #define MS_DIRENTSIZE sizeof(struct MsDirEntry) /* size of a directory entry */ #define MS_FIRSTCLUST 2 /* Very strange convention... */ #define FAT_EOF 0xFFFF /* end of file FAT entry */ #define FAT_UNUSED 0 /* unused block */ #define SEC_EOF -1 /* end of FAT chain */ #define DIR_DELETED 0xE5 #define DIR_DELETED_MASK 0x80 /* * This structure has its byte order wrong, when it is on the disk. */ struct MsDirEntry { byte msd_Name[8]; byte msd_Ext[3]; byte msd_Attributes; byte msd_Pad1[10]; word msd_Time; /* in 2s of seconds since begin of the day */ word msd_Date; word msd_Cluster; ulong msd_Filesize; }; #define ATTR_READONLY 0x01 #define ATTR_HIDDEN 0x02 #define ATTR_SYSTEM 0x04 #define ATTR_VOLUMELABEL 0x08 #define ATTR_DIRECTORY 0x10 #define ATTR_ARCHIVED 0x20 #define ATTR_DIR (ATTR_DIRECTORY | ATTR_VOLUMELABEL) #define DATE_MIN 0x21 struct DirEntry { struct MsDirEntry de_Msd; word de_Sector; word de_Offset; }; struct DiskParam { word bps; /* bytes per sector. max MS_BPS supported */ byte spc; /* sectors per cluster */ word res; /* reserved sectors (boot block) */ byte nfats; /* number of fats */ word ndirs; /* number of directory entries */ word nsects; /* total number of sectors on disk */ byte media; /* media byte */ word spf; /* sectors per fat */ word spt; /* sectors per track. Only MS_SPT * supported */ word nsides; /* # sides. Max MS_NSIDES supported */ word nhid; /* Number of hidden sectors */ /* derived parameters */ word start; /* sector of cluster 0 */ word maxclst; /* highest cluster number */ word rootdir; /* first sector of root dir */ word ndirsects; /* # of root directory sectors */ word datablock; /* first block available for files &c */ word bpc; /* bytes per cluster */ word nsectsfree; /* amount of free space */ long lowcyl; /* offset to lowcyl */ struct DirEntry vollabel; /* copy of volume label */ word fat16bits; /* Is the FAT 16 bits/entry? */ }; /* * A pointer to an MSFileLock is put into the fl_Key field of a DOS * FileLock structure. We share the MSFileLock with all FileLocks on the * same file. This way, you can compare FileLocks based on their fl_Key * and fl_Task fields, as seems to be done sometimes. Also, a pointer to * an MSFileLock is put in MSFileHandles. * * For ease, we keep a copy of the directory entry in core, WITH THE BYTE * ORDER CORRECTED FOR THIS PROCESSOR. */ struct MSFileLock { struct MinNode msfl_Node; short msfl_Refcount; /* -1: exclusive, >0: # of shared * locks */ struct MSFileLock *msfl_Parent; /* Pointer to parent directory */ struct MsDirEntry msfl_Msd; /* Copy of directory entry */ word msfl_DirSector; /* Location of directory entry */ word msfl_DirOffset; }; /* * A pointer to an MSFileHandle is put into the fh_Arg1 field of a DOS * FileHandle. We get that value with many DOS packets that manipulate the * contents of a file. */ struct MSFileHandle { struct MSFileLock *msfh_FileLock; long msfh_SeekPos; word msfh_Cluster; }; /* * Return values of CompareNames. */ #define CMP_NOT_EQUAL 0 /* Names do not match at all */ #define CMP_OK_DIR 1 /* Name matches with a subdir entry */ #define CMP_OK_FILE 2 /* Name matches with a file entry */ #define CMP_INVALID 3 /* First part of name matches with a file * entry, or other invalid component name */ #define CMP_FREE_SLOT 5 #define CMP_END_OF_DIR 6 struct LockList { struct MinList ll_List; void *ll_Cookie; /* we don't want to know what this is! */ }; struct CacheSec { struct MinNode sec_Node; word sec_Number; word sec_Refcount; byte sec_Data[2];/* Really Disk.bps */ }; #define SEC_DIRTY 0x8000 /* Bit in sec_Refcount */ #define OFFSETOF(tag, member) ((long)(&((struct tag *)0)->member)) #define DELAY_OFF 0 /* Motor is off */ #define DELAY_RUNNING1 1 /* Motor may be on */ #define DELAY_RUNNING2 2 /* Motor may be on */ #define DELAY_RUNNING 3 /* Running1 | 2 */ #define DELAY_DIRTY 4 /* We have dirty buffers to flush */ extern long Wait(); extern struct MsgPort *CreatePort(); extern struct IOExtTD *CreateExtIO(); extern void *AllocMem(), FreeMem(); extern byte *index(), *rindex(); extern void *CheckIO(); /* * PACK.C */ extern char *DevName; extern long UnitNr; extern ulong DevFlags; /* * HANMAIN.C */ extern byte ToUpper(); extern long lmin(); extern byte *ZapSpaces(); extern byte *ToMSName(); extern long MSDiskInfo(); extern void MSDiskInserted(); extern int MSDiskRemoved(); extern void HanCloseDown(); extern int HanOpenUp(); /* * HANSEC.C */ extern struct MsgPort *DiskReplyPort; extern struct IOExtTD *DiskIOReq; extern struct IOStdReq *DiskChangeReq; extern struct DiskParam Disk; extern byte *Fat; extern short FatDirty; /* Fat must be written to disk */ extern short error; /* To put the error value; for Result2 */ extern long IDDiskState; /* InfoData.id_DiskState */ extern long IDDiskType; /* InfoData.id_DiskType */ extern struct timerequest *TimeIOReq; /* For motor-off delay */ extern struct MinList CacheList;/* Sector cache */ extern int CurrentCache; /* How many cached buffers do we have */ extern int MaxCache; /* Maximum amount of cached buffers */ extern ulong BufMemType; extern long CacheBlockSize; /* Size of disk block + overhead */ extern int DelayState; extern byte *Word8086; extern word Get8086Word(); extern word OtherEndianWord(); extern ulong OtherEndianLong(); extern void OtherEndianMsd(); extern word ClusterToSector(); extern word ClusterOffsetToSector(); extern word DirClusterToSector(); extern word SectorToCluster(); extern word NextCluster(); extern word NextClusteredSector(); extern word FindFreeSector(); extern struct CacheSec *FindSecByNumber(); extern struct CacheSec *FindSecByBuffer(); extern struct CacheSec *NewCacheSector(); extern void FreeCacheSector(); extern void InitCacheList(); extern void FreeCacheList(); extern void MSUpdate(); extern void StartTimer(); extern byte *GetSec(); extern byte *EmptySec(); extern void PutSec(); extern void FreeSec(); extern void MarkSecDirty(); extern void WriteFat(); extern int ReadBootBlock(); extern int IdentifyDisk(); extern int TDMotorOff(); extern int TDGetNumCyls(); /* * HANLOCK.C */ extern struct LockList *LockList; /* List of all locked files we * have. Note this is not the same * as all locks we have */ extern struct MSFileLock *RootLock; /* Lock on root directory */ extern struct MSFileLock *EmptyFileLock; /* 2nd result of MSLock() */ extern struct DirEntry FakeRootDirEntry; extern int CompareNames(); extern void NextDirEntry(); extern struct DirEntry *FindNext(); extern struct MSFileLock *MakeLock(); extern void WriteLock(); extern void PrintDirEntry(); extern struct MSFileLock *MSLock(); extern struct MSFileLock *MSDupLock(); extern struct MSFileLock *MSParentDir(); extern int MSUnLock(); extern void ExamineDirEntry(); extern int MSExamine(); extern int MSExNext(); extern long MSSetProtect(); extern void WriteFileLock(); extern void UpdateFileLock(); extern struct LockList *NewLockList(); extern void FreeLockList(); /* * HANFILE.C */ extern int GetFat(); extern void FreeFat(); extern word GetFatEntry(); extern void SetFatEntry(); extern word FindFreeCluster(); extern word ExtendClusterChain(); extern void FreeClusterChain(); extern struct MSFileHandle *MSOpen(); extern void MSClose(); extern long MSSeek(); extern long MSRead(); extern long MSWrite(); extern long MSDeleteFile(); extern long MSSetDate(); extern struct MSFileLock *MSCreateDir(); /* * DATE.C */ extern void ToDateStamp(); extern void ToMSDate();