#define		ENOPORT		1	/* Unable to open port 		*/
#define		ENOIOBLK	2	/* Unable to create I/O block	*/
#define		ENOOPEN		3	/* Unable to open device	*/
#define		ENOARGS		4	/* Not enough arguments to prog */
#define		EBADDEV		5	/* Bad device name		*/
#define		EBTOV		6	/* Bad block table overflow	*/
#define		ENOMEM		7	/* No dynamic memory available	*/
#define		EBADBB		8	/* Bad boot block on disk	*/
#define		EBADRB		9	/* Bad root block on disk	*/
#define		ENOBLKS		10	/* Out of room in used blk list	*/
#define		EBMAPWR		11	/* Error writing the bitmap	*/
#define		EBADOPT		12	/* Bad option on cmd line	*/
#define		ENOINH		13	/* Cannot inhibit device	*/
#define		ENOHDR		14	/* Cannot write file hdr block	*/
#define		ENEXTB		15	/* Cannot write extension blks	*/
#define		EBADBLK		16	/* Block number out of range	*/
#define 	ENHDR		17	/* Cannot write bad block hdr	*/
#define		DEFBLKSIZE	512L	/* default block size 		*/
#define		BADTRKSIZE	500	/* size of bad track table 	*/

#define		ROMFS		0	/* Constant for ROM filing sys	*/
#define		FFS		1	/* Constant for Fast filing sys */

#define		BAD		1	/* Indicates bad block		*/
#define		ROOT		2	/* Indicates root block		*/
#define		EXT		3	/* Indicates bmap extension blk	*/
#define		BMAP		4	/* Indicate bitmap block	*/


/* 
  This is the structure that contains all we need to know about a 
  drive to mess with it. (and then some!)
*/
struct	disk_parm
	{
	UWORD	unit;		/* unit number of drive: 0,1,2 etc 	*/
	UWORD	block_size;	/* bytes in a block 			*/
	UWORD	disk_type;	/* used to determine filing system	*/
	UWORD	surfaces;	/* number of surfaces (heads)		*/
	UWORD 	sec_block;	/* number of sectors in a block		*/
	UWORD	blocks_track;	/* number of blocks per track		*/
	UWORD	reserved;	/* sectors reserved at start of disk 	*/
	UWORD	pre_alloc;	/* pre-allocated sectors at end of disk */
	ULONG	low_cyl;	/* lowest cylinder number		*/
	ULONG	high_cyl;	/* highest cylinder number		*/
	ULONG	track_size;	/* bytes in a track: blk_size*blks_trk	*/
	ULONG	lower_key;	/* block number of lowest block		*/
	ULONG	upper_key;	/* block number of highest block	*/
	ULONG	root_key;	/* block number of root block		*/
	ULONG	boot_key;	/* block number of boot block		*/
	char	driver[30];	/* name of device driver		*/
	};



struct	OldBitmap
	{
	ULONG	BitmapExtend;	/* Bit map extension block		*/
	ULONG	BitmapKeys[25]; /* Bit map block numbers		*/
	} obm;

struct	FastBitmap
	{
	ULONG	BitmapKeys[25]; /* Bit map block numbers		*/
	ULONG	BitmapExtend;	/* Bit map extension block		*/
	} fbm;


struct RootBlock
	{
	LONG	Type;		/* This is used to mark the type of this
				   block and is set to TYPE_SHORT (2)	*/
	ULONG	OwnKey;		/* Not used by root, must be set to 0	*/
	ULONG	SeqNum;		/* Not used by root, must be set to 0	*/
	ULONG	HTSize;		/* Size of the hash table in longwords,	
				   must be set to 72			*/
	ULONG	Nothing1;	/* Reserved for future use, must be 0	*/
	LONG	Checksum;	/* Balance to 0 checksum. When all longs
				   in the block are added (ignoring 
				   carry), the sum must be 0.		*/
	ULONG	HashTable[72];	/* Hash table containing block numbers 
				   of files and directories in the root	*/
	LONG	BitmapFlag;	/* Flag to say whether the bitmap is
				   valid or not. -1=valid, 0=invalid. 
				   If a partition is mounted (or 
				   uninhibited) with BitmapFlag = 0, 
	    			   then the validator will kick in to
	    			   rebuild the bitmap			*/
	
	/* 
	  The next two fields are a union because the old filing system
	  has the BitmapExtend field first, and uses the BitmapKeys 
	  array from high to low, while the Fast filing system puts the
	  BitmapKeys field first, and uses them from low to high.
	*/

	union
		{
		struct 	OldBitmap	obm;
		struct	FastBitmap	fbm;
		} bm;

	ULONG	DirAltered[3];	/* A DOS DateStamp indicating the date
		    		   when the root block or a file in the	
				   root block was last modified		*/
	char	Name[40];	/* Name of this volume as a BCPL string
				   with the number of bytes as the first
				   character. Only 30 chars are used	*/
	ULONG	DiskAltered[3];	/* A DOS DateStamp indicating the date
				   when any file or section of the par-
				   tition was modified.			*/
	ULONG	DiskMade[3];	/* A DOS DateStamp indicating when this
				   partition was created (formatted)	*/
	ULONG	Nothing2;	/* Reserved for future use, must be 0	*/
	ULONG	Nothing3;	/* Reserved for future use, must be 0	*/
	ULONG	Nothing4;	/* Reserved for future use, must be 0	*/
	LONG	SecondaryType;	/* Qualifier to Type. Will be set to
				   ST_ROOT (1)				*/
	};


struct	extension_block
	{
	struct	extension_block	*next;
	ULONG	block[127];
	ULONG	next_ext;
	ULONG	key;
	};


struct	FileHeaderBlock
	{
	LONG	Type;		/* This is used to mark the type of this
				   block and is set to TYPE_SHORT (2)	  */
	ULONG	OwnKey;		/* Set to file headers own block number	  */
	ULONG	HighSeq;	/* Total blocks used in file (not updated
				   by FFS, only the old file system	  */
	ULONG	DataSize;	/* Number of data blocks in file	  */
	ULONG	FirstBlock;	/* Block number of first block in file	  */
	LONG	Checksum;	/* Balance to 0 checksum		  */
	ULONG	DataBlocks[72];	/* Table of block numbers for the first 72
				   blocks of data in this file. Slots are
				   used from DataBlocks[71] to zero, then
				   extension is used.			  */
	ULONG	Spare1[2];	/* Not used, must be 0			  */
	ULONG	Protect;	/* Protection bits bit mask		  */
	ULONG	ByteSize;	/* Size of file in bytes...		  */
	char	Comment[92];	/* Comment attached to file		  */
	ULONG	Date[3];	/* DOS DateStamp indicating creation date */
	char	FileName[64];	/* Filename (only 30 characters used tho) */
	ULONG	HashChain;	/* Next entry with same hash value	  */
	ULONG	Parent;		/* Block number of parent directory	  */
	ULONG	Extension;	/* When all data block slots are used, 
				   this points to an extension block that
				   has the same format as the file header
				   block (but FileName and Date are not
				   maintained and Type is ST_LIST (16) ).
				   A block number of zero terminates the
				   list					  */
	LONG	SecondaryType;	/* Qualifier to type = ST_FILE (-3)	  */
	};


struct	FileDataBlock
	{
	LONG	Type;		/* This is used to mark the type of this
				   block and is set to TYPE_DATA (8). 
				   There is no secondary type on this blk */
	ULONG	OwnKey;		/* Set to data block's own block number	  */
	ULONG	SeqNumber;	/* Sequence # of this block in the file	  */
	ULONG	DataSize;	/* # of bytes of info used in this block  */
	ULONG	NextBlock;	/* Key of next block in file		  */
	LONG	CheckSum;	/* Balance to 0 checksum		  */
	char	Data[488];	/* The actual data			  */
	};


struct	DosEnvironment
	{
	ULONG	de_TableSize;		/* Size of env vector		*/
	ULONG	de_SizeBlock;		/* Block size in longwords	*/
	ULONG	de_SecOrg;		/* Not used; must be 0		*/
	ULONG	de_Surfaces;		/* Number of heads		*/
	ULONG	de_SecPerBlock;		/* Not used; must be 1		*/
	ULONG	de_BlocksPerTrack;	/* Blocks per track		*/
	ULONG	de_Reserved;		/* Reserved blocks at start	*/
	ULONG	de_PreAlloc;		/* Pre_allocated blocks at end	*/
	ULONG	de_Interleave;		/* Usually 0			*/
	ULONG	de_LowCyl;		/* Starting cylinder		*/
	ULONG	de_HighCyl;		/* Max cylinder			*/
	ULONG	de_NumBuffers;		/* Initial # of Dos buffers	*/
	ULONG	de_BufMemType;		/* Type of mem for buffers	*/
	ULONG	de_MaxTransfer;		/* Max # of bytes to transfer	*/
	ULONG	de_Mask;		/* Address mask			*/
	ULONG	de_BootPri;		/* Boot priority		*/
	char	de_DosType[4];		/* Dos type as ascii string	*/
	};
				

struct	file_ext_block
	{
	struct	file_ext_block	*next;
	struct	FileHeaderBlock	fhb;
	ULONG	key;
	};

struct	bitmap_block
	{
	ULONG	check_sum;
	ULONG	block[127];
	ULONG	key;
	};


struct	bad_block
	{
	struct	bad_block	*next;
	int	type;
	ULONG	key;
	};
