/*
   CyberRax Programming (C) 2002 - 2003
   TITLE:   DEVICE.H--
   DESCRIPTION:   Structures and some defitions for using with device drivers.
		  Basically an alternative to the definitions in DRIVER.H--
   LAST MODIFIED:   13 Aug 2003
   PROCEDURES DEFINED IN THIS FILE:
       <none>
   STRUCTURES DEFINIED IN THIS FILE:
       struct DEVREQUESTHEADER
       struct DEVINIT
       struct DEVMEDIACHECK
       struct DEVBUILDBPB
       struct DEVIOCTLINPUT
       struct DEVINPUT
       struct DEVNONDESTRUCTIVEINPUT
       struct DEVINPUTSTATUS
       struct DEVINPUTFLUSH
       struct DEVOUTPUT
       struct DEVOUTPUTVERIFY
       struct DEVOUTPUTSTATUS
       struct DEVOUTPUTFLUSH
       struct DEVIOCTLOUTPUT
       struct DEVOPENDEVICE
       struct DEVCLOSEDEVICE
       struct DEVREMOVABLEMEDIA
       struct DEVOUTPUTTILLBUSY
       struct DEVSTOPOUTPUT
       struct DEVRESUMEOUTPUT
       struct DEVGENERETICIOCTL
       struct DEVRESTOREDEVICE
       struct DEVRESETMEDIAFLAG
       struct DEVGETLOGICALDEVICE
       struct DEVSETLOGICALDEVICE
       struct DEVCHECKGENERETICIOCTL
       struct DEVREADLONG
       struct DEVREADLONGPREFETCH
       struct DEVSEEK
       struct DEVPLAYAUDIO
       struct DEVSTOPAUDIO
       struct DEVWRITELONG
       struct DEVWRITELONGVERIFY
       struct DEVRESUMEAUDIO

   NOTE:   this header file uses features of SPHINX/Sheker C-- and needs
	   quite some modifications to work under original SPHINX C-- 0.203
*/


? ifndef _DEVICE_
? define _DEVICE_	TRUE


? ifndef _NUMBERS_
  ? include "NUMBERS.H--"
? endif

? ifndef _JSTUFF_
  ? include "JSTUFF.H--"
? endif



// Bits of device driver header
? define BlockDevAttrBit		0b0000000000000000
? define NonIbmFormatAttrBit		0b0010000000000000
? define NetworkDevAttrBit		0b0001000000000000
? define Adr32AttrBit			0b0000000000000010
? define StdinDevAttrBit		0b0000000000000001
? define StdoutDevAttrBit		0b0000000000000010
? define NulDevAttrBit			0b0000000000000100
? define ClockDevAttrBit		0b0000000000001000
? define SpecialDevBitAttrBit		0b0000000000010000
? define RemovableMediaAttrBit		0b0000000001000000
? define GenereticIoctlBitAttrBit	0b0000000010000000
? define OpenCloseAttrBit		0b0000100000000000
? define OutputTillBusyAttrBit		0b0010000000000000
? define IoctlAttrBit			0b0100000000000000
? define CharDevAttrBit			0b1000000000000000


// Status bit returned by device
? define DevDoneBit			0b0000000100000000
? define DevBusyBit			0b0000001000000000
? define DevErrorBit			0b1000000000000000



// Device errors (returned in bits 00h - 0Fh of status word if
// DevErrorBit is set)
enum { WRITE_PROTECTED, UNK_UNIT, DRIVE_NOT_READY, UNK_COMMAND, CRC_ERR,
       BAD_REQ_LENGTH, SEEK_ERR, UNK_MEDIA, SECTOR_NOT_FOUND, NO_PAPER,
       WRITE_ERR, READ_ERR, GENERAL_ERR,
       CD_UNAVAILABLE = 0xE, INV_DISK_CHANGE };


// Device request codes
enum { DEV_INIT, DEV_MEDIA_CHECK, DEV_BUILD_BPB, DEV_IOCTL_INPUT, DEV_INPUT,
       DEV_NONDESTRUCTIVE_INPUT, DEV_INPUT_STATUS, DEV_INPUT_FLUSH,
       DEV_OUTPUT, DEV_OUTPUT_VERIFY, DEV_OUTPUT_STATUS, DEV_OUTPUT_FLUSH,
       DEV_IOCTL_OUTPUT,
       DEV_OPEN_DEVICE, DEV_CLOSE_DEVICE, DEV_REMOVABLE_MEDIA,
       DEV_OUTPUT_TILL_BUSY, DEV_STOP_OUTPUT, DEV_RESTART_OUTPUT,
       DEV_GENERIC_IOCTL,
       DEV_RESTORE_DEVICE, DEV_RESET_MEDIA_FLAG,
       DEV_GET_LOGICAL_DEVICE, DEV_SET_LOGICAL_DEVICE, DEV_CHECK_GEN_IOCTL,
       DEV_READ_LONG,
       DEV_READ_LONG_PREFETCH, DEV_SEEK, DEV_PLAY_AUDIO, DEV_STOP_AUDIO,
       DEV_WRITE_LONG, DEV_WRITE_LONG_VERIFY, DEV_RESUME_AUDIO };



struct DEVREQUESTHEADER			// Device request header
{
   byte Len;
   byte SubUnit;
   byte Cmd;
   word Status;
   byte Reserved[EIGHT];
};



struct DEVINIT				// Func. 00, for block & char. devices
{
   DEVREQUESTHEADER Header;
   byte Units;				// Output
   union
      {
      INTBUF HelperFunction;		// Input (for European DOS 4.x only)
      INTBUF EndOfMem;			// Output
      };
   union
      {
      INTBUF Params;			// Input
      INTBUF BPB;			// Output for block, 0 for char. devs
      };
   byte Drive;				// Output (under DOS 3+)
   word ErrMsgFlag;			// Output (under DOS 5+: show 'error on
};					//   CONFIG line xx' if non-zero)



struct DEVMEDIACHECK			// Func. 01, for block devices
{
   DEVREQUESTHEADER Header;
   byte MDescriptor;			// Input for block devs
   byte Status;				// Output: 00 - don't know
					//	   01 - media has not changed
					//	   FF - media has changed
   INTBUF PrevVolID;			// Output (DOS 3+)
};



struct DEVBUILDBPB			// Func. 02, for block devs
{
   DEVREQUESTHEADER Header;
   byte MDescriptor;			// Input for block devs
   INTBUF Buffer;			// Input: first FAT sector or garbage
					//   if NonIbmFormatAttrBit set)
   INTBUF BPB;				// Output
};



struct DEVIOCTLINPUT			// Func. 03, for block & char devs
{
   DEVREQUESTHEADER Header;
   byte MDescriptor;			// Input for block devs
   INTBUF Buffer;			// Input (where to read to)
   word Bytes;				// Input: how much to read
					// Output: how much actually read
};



struct DEVIOCTLOUTPUT			// Func. 0C, for block & char devs
{
   DEVREQUESTHEADER Header;
   byte MDescriptor;			// Input for block devs
   INTBUF Buffer;			// Input: where to write from
   word Bytes;				// Input: how much to write
					// Output: how much actually written
};



struct DEVINPUT				// Func. 04, for block and char devs
{
   DEVREQUESTHEADER Header;
   byte MDescriptor;			// Input (for block devs)
   INTBUF Buffer;			// Input (where to read to)
   union				// Input: how much to read
      {
      word Bytes;			// For char devs
      word Sectors;			// For block devs)
      };
   word StartSector;			// Input for block devs
   INTBUF VolId;			// Output by error 0Fh (DOS 3.0+)
 ? ifdef cpu > 2			// Input for block devs if
   dword StartSector32;			//   Adr32AttrBit set and
 ? else					//   StartSector FFFFh
   word StartSectorLow;
   word StartSectorHigh;
? endif
};



struct DEVOUTPUT			// Func. 08, for block and char devs
{
   DEVREQUESTHEADER Header;
   byte MDescriptor;			// Input (for block devs)
   INTBUF Buffer;			// Input (where to read to)
   union				// Input: how much to read
      {
      word Bytes;			// For char devs
      word Sectors;			// For block devs)
      };
   word StartSector;			// Input for block devs
   INTBUF VolId;			// Output by error 0Fh (DOS 3.0+)
 ? ifdef cpu > 2			// Input for block devs if
   dword StartSector32;			//   Adr32AttrBit set and
 ? else					//   StartSector FFFFh
   word StartSectorLow;
   word StartSectorHigh;
? endif
};



struct DEVOUTPUTVERIFY			// Func. 09, for block and char devs
{
   DEVREQUESTHEADER Header;
   byte MDescriptor;			// Input (for block devs)
   INTBUF Buffer;			// Input (where to read to)
   union				// Input: how much to read
      {
      word Bytes;			// For char devs
      word Sectors;			// For block devs)
      };
   word StartSector;			// Input for block devs
   INTBUF VolId;			// Output by error 0Fh (DOS 3.0+)
 ? ifdef cpu > 2			// Input for block devs if
   dword StartSector32;			//   Adr32AttrBit set and
 ? else					//   StartSector FFFFh
   word StartSectorLow;
   word StartSectorHigh;
? endif
};



struct DEVNONDESTRUCTIVEINPUT		// Func. 05, for char devs
{
   DEVREQUESTHEADER Header;
   byte NextByte;			// Output: next byte read from dev if
};					//   DevBusyBit unset



struct DEVINPUTSTATUS			// Func. 06, for char devs
{
   DEVREQUESTHEADER Header;
};



struct DEVINPUTFLUSH			// Func. 07, for char devs
{
   DEVREQUESTHEADER Header;
};



struct DEVOUTPUTSTATUS			// Func. 0A, for char devs
{
   DEVREQUESTHEADER Header;
};



struct DEVOUTPUTFLUSH			// Func. 0B, for char devs
{
   DEVREQUESTHEADER Header;
};



struct DEVOPENDEVICE			// Func. 0D, for char and  block devs
{
? DOSrequired 0x0300
   DEVREQUESTHEADER Header;
};



struct DEVCLOSEDEVICE			// Func. 0E, for char and block devs
{
? DOSrequired 0x0300
   DEVREQUESTHEADER Header;
};



struct DEVREMOVABLEMEDIA		// Func. 0Fh, for block devs
{
? DOSrequired 0x0300
   DEVREQUESTHEADER Header;
};


struct DEVOUTPUTTILLBUSY		// Func. 10h, for char devs
{
? DOSrequired 0x0300
   byte Reserved;
   INTBUF Buffer;			// Input: where to read from
   word Bytes;				// Input: bytes to read
};					// Output: bytes actually read


struct DEVSTOPOUTPUT			// Func. 11h, for char devs
{
? DOSrequired 0x0400			// European MS-DOS 4.0 only(?)
   DEVREQUESTHEADER Header;
   byte Reserved;
};


struct DEVRESUMEOUTPUT			// Func. 12h, for char devs
{
? DOSrequired 0x0400			// European MS-DOS 4.0 only(?)
   DEVREQUESTHEADER Header;
   byte Reserved;
};



struct DEVRESTOREDEVICE			// Func. 14h, for char devs
{
? DOSrequired 0x0400			// European MS-DOS 4.0 only(?)
   DEVREQUESTHEADER Header;
};



struct DEVRESETMEDIAFLAG		// Func. 15h, for block devs
{
? DOSrequired 0x0400			// European MS-DOS 4.0 only(?)
   DEVREQUESTHEADER Header;
};



struct DEVGENERETICIOCTL		// Func. 13h, for block and char devs
{
? DOSrequired 0x0314
   DEVREQUESTHEADER Header;
   byte Func;				// Input: 00h-7Fh reserved for M$
					//	  00h unknown
					//	  01h COMn: (serial) (DOS 3.3+)
					//	  02h reserved for terminal
					//	  03h CON (DOS 3.3+)
					//	  04h reserved for keyb
					//	  05h LPTn:
					//	  07h mouse (European DOS 4.0)
					//	  08h disk
					//	  48h FAT32 disk (DOS 7.10+)
					//	  80h-FFh reserved for OEM/user-defined
					//	  9Eh STARLITE Media Access
					//	      Control driver
					//	  EDh DR PalmDOS login security
   byte SubFunc;			// Input
   word OriginalSI;			// Input
   word OriginalDI;			// Input
   INTBUF IoctlBlock;			// Input
};


struct DEVCHECKGENERETICIOCTL		// Func. 19h, for block and char devs
{
? DOSrequired 0x0314
   DEVREQUESTHEADER Header;
   byte Func;				// Input (see previous structure)
   byte SubFunc;			// Input
   word OriginalSI;			// Input
   word OriginalDI;			// Input
   INTBUF IoctlBlock;			// Input
};



struct DEVGETLOGICALDEVICE		// Func. 17h, for block & char devs
{
   DEVREQUESTHEADER Header;
   union
      {
      byte Unit;			// Input
      byte LastUnit;			// Output
      };
   byte Cmd;
   byte Reserved[THREE];
};



struct DEVSETLOGICALDEVICE		// Func. 18h, for block & char devs
{
   DEVREQUESTHEADER Header;
   union
      {
      byte Unit;			// Input
      byte LastUnit;			// Output
      };
   byte Cmd;
   byte Reserved[THREE];
};



struct DEVREADLONG			// Func. 80h, for char (CD-ROM and
{					//   DRFAT32) devs
   DEVREQUESTHEADER Header;
   byte AdrMode;			// Input: 00 - HSG
					//	  01 - Philips/Sony Red Book
   INTBUF Buffer;			// Input: where to read to
   word Sectors;			// Input
 ? ifdef cpu > 2			// Input:
   dword StartSector32;			//   logical sector number if HSG
 ? else					//   frame/second/minute/unused if
   word StartSectorLow;			//     Red Book mode (HSG sector =
   word StartSectorHigh;		//     = minute * 4500 + second * 75 +
 ? endif				//     + frame - 150)
   byte ReadMode;			// Input: 00 - cooked (2048 bytes)
					//	  01 - raw (2353 bytes)
   byte InterleaveSize;
   byte InterleaveSkip;
};



struct DEVREADLONGPREFETCH		// Func. 82h, for char (CD-ROM and
{					//   DRFAT32) devs
   DEVREQUESTHEADER Header;
   byte AdrMode;			// Input: 00 - HSG
					//	  01 - Philips/Sony Red Book
   INTBUF Buffer;			// Input: where to read to
   word Sectors;			// Input
 ? ifdef cpu > 2			// Input:
   dword StartSector32;			//   logical sector number if HSG
 ? else					//   frame/second/minute/unused if
   word StartSectorLow;			//     Red Book mode (HSG sector =
   word StartSectorHigh;		//     = minute * 4500 + second * 75 +
 ? endif				//     + frame - 150)
   byte ReadMode;			// Input: 00 - cooked (2048 bytes)
					//	  01 - raw (2353 bytes)
   byte InterleaveSize;
   byte InterleaveSkip;
};



struct DEVSEEK				// Func. 83h, for char (CD-ROM and
{					//   DRFAT32) devs
   DEVREQUESTHEADER Header;
   byte AdrMode;			// Input: 00 - HSG
					//	  01 - Philips/Sony Red Book
   byte Ignored[SIX];
 ? ifdef cpu > 2			// Input:
   dword StartSector32;			//   logical sector number if HSG
 ? else					//   frame/second/minute/unused if
   word StartSectorLow;			//     Red Book mode (HSG sector =
   word StartSectorHigh;		//     = minute * 4500 + second * 75 +
 ? endif				//     + frame - 150)
};



struct DEVPLAYAUDIO			// Func. 84h, for char (CD-ROM) devs
{
   DEVREQUESTHEADER Header;
   byte AdrMode;			// Input: 00 - HSG
					//	  01 - Philips/Sony Red Book
 ? ifdef cpu > 2			// Input:
   dword StartSector32;			//   logical sector number if HSG
 ? else					//   frame/second/minute/unused if
   word StartSectorLow;			//     Red Book mode (HSG sector =
   word StartSectorHigh;		//     = minute * 4500 + second * 75 +
 ? endif				//     + frame - 150)
 ? ifdef cpu > 2
   dword Sectors32;			// Input: amount of sectors to play
 ? else
   word SectorsLow;
   word SectorsHigh;
 ? endif
};



struct DEVSTOPAUDIO			// Func. 85h, for char (CD-ROM) devs
{
   DEVREQUESTHEADER Header;
};



struct DEVRESUMEAUDIO			// Func. 88h, for char (CD-ROM) devs
{
   DEVREQUESTHEADER Header;
};



struct DEVWRITELONG			// Func. 86h, for char (CD-ROM and
{					//   DRFAT32) devs
   DEVREQUESTHEADER Header;
   byte AdrMode;			// Input: 00 - HSG (default)
					//	  01 - Philips/Sony Red Book
   INTBUF Buffer;			// Input: where to write from
   word Sectors;			// Input
 ? ifdef cpu > 2			// Input:
   dword StartSector32;			//   logical sector number if HSG
 ? else					//   frame/second/minute/unused if
   word StartSectorLow;			//     Red Book mode (HSG sector =
   word StartSectorHigh;		//     = minute * 4500 + second * 75 +
 ? endif				//     + frame - 150)
   byte WriteMode;			// Input: 00 - mode 0 (write all
					//	       zeroes)
					//	  01 - mode 1 (2048 bytes per
					//	       sector)
					//	  02 - mode 2 form 1 (2048
					//	       bytes per sector)
					//	  03 - mode 2 form 2 (2336
					//	       bytes per sector)
   byte InterleaveSize;
   byte InterleaveSkip;
};



struct DEVWRITELONGVERIFY		// Func. 87h, for char (CD-ROM and
{					//   DRFAT32) devs
   DEVREQUESTHEADER Header;
   byte AdrMode;			// Input: 00 - HSG (default)
					//	  01 - Philips/Sony Red Book
   INTBUF Buffer;			// Input: where to write from
   word Sectors;			// Input
 ? ifdef cpu > 2			// Input:
   dword StartSector32;			//   logical sector number if HSG
 ? else					//   frame/second/minute/unused if
   word StartSectorLow;			//     Red Book mode (HSG sector =
   word StartSectorHigh;		//     = minute * 4500 + second * 75 +
 ? endif				//     + frame - 150)
   byte WriteMode;			// Input (see previous structure)
   byte InterleaveSize;
   byte InterleaveSkip;
};


? endif


/* end of DEVICE.H-- */
