#ifndef ALFDISK_H
#define ALFDISK_H

/*******************************************************************************
                         _                 ____    ___
                        / \      |        |           |
                       /___\     |        |--      ---
                      /     \ o  |____ o  |  o    |___

                            Amiga Loads Faster 2

                      §name:ALFDisk.h§
                      §author:Andreas Hofbauer§
                      §date:05 Aug 1989§
                      §time:16:23:07§

              copyright 1989 Elaborate Bytes, Oliver Kastl

*******************************************************************************/

#ifndef EXEC_TYPES_H
#include <exec/types.h>
#endif

/*
Based upon the HardBlocks proposal we define here some advanced blocks. These
blocks try to be compatible with the HardBlocks from C= and are, as long as you
set all reserved fields to zero or 0xFFFFFFFF as stated. To distinguish names
defined herein from those from C= we append a 2 to the prefix.

You should be familiar with the devices/hardblocks.(i|h) includes prior to using
this one.
*/

/*
Most hard blocks have a common layout. For some universal functions it is
beneficial to have this frame defined generically.
*/

struct HardBlock
	{
	ULONG hb_ID; /* 4 char identifier of this block. */
	ULONG hb_SummedLongs; /* Number of checksummed long words. This should be
		used as the indicator for the size of this block. Note: all blocks
		have sizes which are multiples of 4. The physical blocksize (which
		is usually 512) is found in the RDSK block. The value stored here is
		the number of longs, i.e. the bytesize divided by 4. */
	LONG hb_CheckSum; /* Checksum of this hardblock. If you sum up all of the
		hb_SummedLongs (including the adb_ChkSum itself and ignoring any
		overflows) you should get zero as the result. */
	/* Here starts the hardblock data. Note: These are hb_SummedLongs-3
	longwords, never use sizeof(...). */
	};

/*
CAVEAT: Current implementation of the ALF software requires that the RDSK block
resides in block 0.
*/

struct RigidDiskBlock2
	{
	ULONG rdb2_ID;
	ULONG rdb2_SummedLongs;
	LONG rdb2_ChkSum;
	ULONG rdb2_HostID; /* The initiator which created this block. */
	ULONG rdb2_BlockBytes; /* CAVEAT: Current implementation of ALF software
		can only handle 512 byte blocks. */
	ULONG rdb2_Flags; /* See below for additional flag(s). */

	/* Block list heads. */

	ULONG rdb2_BadBlockList;
	ULONG rdb2_PartitionList;
	ULONG rdb2_FileSysHeaderList;
	ULONG rdb2_DriveInit;
	ULONG rdb2_Reserved1[6];

	/* Physical drive characteristics. */

	ULONG rdb2_Cylinders;
	ULONG rdb2_Sectors;
	ULONG rdb2_Heads;
	ULONG rdb2_Interleave;
	ULONG rdb2_Park;
	ULONG rdb2_Reserved2[3];
	ULONG rdb2_WritePreComp;
	ULONG rdb2_ReducedWrite;
	ULONG rdb2_StepRate; /* This value may be interpretet quite differently. It
		has no common unit it is just a value which is used with the
		controller. On a different controller you might require a different
		value. */
	UBYTE rdb2_BlockInTransferOptions; /* See below. */
	UBYTE rdb2_BlockOutTransferOptions; /* See below. */
	BYTE rdb2_FlagsReserved[2];
	ULONG rdb2_BadTracks; /* The number of physical tracks reserved at the end of
		the hard disk. */
	ULONG rdb2_Reserved3[3];

	/* Logical drive characteristics. */

	ULONG rdb2_RDBBlocksLo;
	ULONG rdb2_RDBBlocksHi;
	ULONG rdb2_LoCylinder; /* This is the low cylinder value for mount entries.
		It may not correspond with actual physical geometry. */
	ULONG rdb2_HiCylinder;
	ULONG rdb2_CylBlocks; /* Number of blocks within one logical (mount)
		cylinder. This may not correspond to physical geometry. */
	ULONG rdb2_AutoParkSeconds;
	ULONG rdb2_Reserved4[2];

	/* Drive identification. */

	char rdb2_DiskVendor[8];
	char rdb2_DiskProduct[16];
	char rdb2_DiskRevision[4];
	char rdb2_ControllerVendor[8];
	char rdb2_ControllerProduct[16];
	char rdb2_ControllerRevision[4];
	char rdb2_Owner[8]; /* See below. */
	ULONG rdb2_Reserved5[8];
	};

/* The drive has an owner whose ID name is found in the rdb2_Owner field. */
#define RDBFB_OWNER 6L
#define RDBFF_OWNER 0x00000040L

/* The driver should make diskchange (it's a removeable!) */
#define RDBFB_RDB 7L
#define RDBFF_RDB 0x00000080L

/*
The above Block(In|Out)TransferOptions indicate whether the data should be
transfered in Blind and/or Burst mode or none at all. You may also chose to use
the very fast MOVEP method. You may select different modes for reading and
writing. If the NOBLOCK bit is set no block transfer will be done at all,
instead all data is transfered as part of the state machine routines. If the
MOVEP bit is set some special very fast code based upon the MOVEP instruction
will be used. Warning: not all hardware configurations support the possibilty to
use the MOVEP instruction! Other bit patterns lead to a dynamically generated
routine. If the NOBLIND bit is set this routine incorporates status checking
before each byte transfer. If the NOBURST bit is set a loop is created to
transfer 512 bytes instead of repeating the MOVE instruction 512 times.
*/

#define RDBFB_NOBURST 0L
#define RDBFF_NOBURST 0x01L
#define RDBFB_NOBLIND 1L
#define RDBFF_NOBLIND 0x02L
#define RDBFB_MOVEP   2L
#define RDBFF_MOVEP   0x04L
#define RDBFB_NOBLOCK 3L
#define RDBFF_NOBLOCK 0x08L

struct PartitionBlock2
	{
	ULONG pb2_ID;
	ULONG pb2_SummedLongs;
	LONG pb2_ChkSum;
	ULONG pb2_HostID;
	ULONG pb2_Next;
	ULONG pb2_Flags; /* See below for additional flag(s). */
	ULONG pb2_Reserved1[2];
	ULONG pb2_DevFlags; /* These are the PublicDevFlags. */
	UBYTE pb2_DriveName[32];
	char pb2_Owner[8]; /* See below. */
	ULONG pb2_OwnerDevFlags; /* See below. */
	ULONG pb2_Reserved2[12];
	ULONG pb2_Environment[17];
	ULONG pb2_EReserved[15];
	};

/* The partition has an owner whose ID name is found in the rdb2_Owner field. */
#define PBFB_OWNER 2L
#define PBFF_OWNER 0x00000004L
/* The partition is only mounted for the owner. */
#define PBFB_OWNERONLY 3L
#define PBFF_OWNERONLY 0x00000008L

/*
One major extension of this definition from the original HardBlocks is the
introduction of the terms Owner and Public. If the drive has an owner (which is
indicated by the RDBFB_OWNER bit in the rdb_Flags field) the startup software is
expected to inquire his name (or password). Then when ever it is applicable the
owner name is checked against those stored in the blocks. If the names are equal
the OwnerDevFlags of this block are used for the OpenDevice() call. If the names
don't match the PublicDevFlags are used.
*/

#endif
