/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1987
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:pc_bios.h 12.0$ */
/* $ACIS:pc_bios.h 12.0$ */
/* $Source: /ibm/acis/usr/sys/ca_atr/RCS/pc_bios.h,v $ */

#if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
static char    *rcsidpc_bios = "$Header:pc_bios.h 12.0$";
#endif

/*******************************************/
/*					   */
/*     pc_bios.h   1.0	   87/06/15	   */
/*					   */
/*******************************************/

/* Include files that should be included before this one are:
 *
 *    </sys/types.h>
 *    </sys/file.h>
 *    </sys/ioctl.h>
 */


/*---------------------------------------------------------------*
 * IBM PC data types redefined					 *
 *---------------------------------------------------------------*/

#define BYTE unsigned char
#define WORD unsigned short
#define LONG unsigned long


/*---------------------------------------------------------------*
 * IBM PC related register definitions				 *
 *								 *
 * Note: cflag represents the carry flag, nonzero if set	 *
 *---------------------------------------------------------------*/

/* word registers */
struct wordregs {
	WORD            ax, bx, cx, dx, si, di, bp;
	short           cflag;
};

/* byte registers */
struct byteregs {
	BYTE            ah, al, bh, bl, ch, cl, dh, dl;
};

/* general purpose registers union - overlays the corresponding word and
 * byte registers.
 */
union regs {
	struct wordregs x;
	struct byteregs h;
};

/* segment registers */
struct sregs {
	WORD            es, cs, ss, ds;
};


/*---------------------------------------------------------------*
 * BIOS interrupt and all registers in one structure		 *
 *								 *
 * note: bios_int must be < 128 bytes. The current size of	 *
 *    bios_int is:						 *
 *								 *
 *    BIOS INT XX, 2 byte =  2					 *
 *    int finished 2 byte =  2	      <- nonzero indicates	 *
 *    valid regs  2 bytes =  2		 INT was completed	 *
 *    regs  = 8 x 2 bytes = 16					 *
 *    sregs = 4 x 2 bytes =  8					 *
 *			   ---					 *
 *			    30 bytes				 *
 *---------------------------------------------------------------*/

struct bios_int {
	WORD            interrupt;
	WORD            finished;
	WORD            valid_reg;
	union regs      gen_reg;
	struct sregs    seg_reg;
};


/*---------------------------------------------------------------*
 * Valid register flag settings (valid_reg in struct bios_int).  *
 *								 *
 *   12 		    bit setting 		     0	 *
 *  -----------------------------------------------------------  *
 * | AX | BX | CX | DX | DI | SI | BP | CF | ES | CS | DS | SS | *
 *  -----------------------------------------------------------  *
 *								 *
 * Note: This informs the PC BIOS driver which registers are	 *
 *   actually used by the interrupt call on entry. All registers *
 *   supported are available to return information.		 *
 *---------------------------------------------------------------*/

#define AX_VALID     0x0800	/* 0x0800 bit pos; AX, can be an in/out reg  */
#define BX_VALID     0x0400	/* 0x0400 bit pos; BX, can be an in/out reg  */
#define CX_VALID     0x0200	/* 0x0200 bit pos; CX, can be an in/out reg  */
#define DX_VALID     0x0100	/* 0x0100 bit pos; DX, can be an in/out reg  */
#define DI_VALID     0x0080	/* 0x0080 bit pos; DI, can be an in/out reg  */
#define SI_VALID     0x0040	/* 0x0040 bit pos; SI, can be an in/out reg  */
#define BP_VALID     0x0020	/* 0x0020 bit pos; BP, can be an in/out reg  */
#define CF_VALID     0x0000	/* 0x0010 bit pos; cflag never used on entry */
#define ES_VALID     0x0008	/* 0x0008 bit pos; ES, can be an in/out reg  */
#define CS_VALID     0x0000	/* 0x0004 bit pos; CS, not supported	      */
#define SS_VALID     0x0000	/* 0x0002 bit pos; SS, not supported	      */
#define DS_VALID     0x0001	/* 0x0001 bit pos; DS, can be an in/out reg  */


/*---------------------------------------------------------------*
 * cbcb data structure for BIOS data block			 *
 *---------------------------------------------------------------*/

#define SIZE_DD  256
#define SIZE_UD  (16 * 1024)

struct bios_data {
	long            size_disp_data;	/* 4 bytes   */
	long            size_usr_data;	/* 4 bytes   */
	char            display_data[SIZE_DD];
	char            usr_data[SIZE_UD];
};


/*---------------------------------------------------------------*
 * structure used for the allocation of usr_data in bios_data	 *
 *---------------------------------------------------------------*/

struct bios_memory {
	long            size;
	char           *pc_ptr;
	char           *unx_ptr;
};


/*---------------------------------------------------------------*
 * PC BIOS device driver ioctl commands 			 *
 *---------------------------------------------------------------*/

#define CMD_CALLBIOS	 0x00
#define CMD_GETBIOSMEM	 0x01
#define CMD_FREEBIOSMEM  0x02
#define CMD_BIOSTEST	 0x03


/*---------------------------------------------------------------*
 * Macro's that define entry points into PC BIOS device driver   *
 *---------------------------------------------------------------*/

#if ( KERNEL || STANDALONE )
/* direct call to routine in PC BIOS driver */
int             callbios();
int             getbiosmem();
int             freebiosmem();
int             echo_pcbios();
#define CALLBIOS( pcbios_int)		( callbios( &pcbios_int ) )
#define GETBIOSMEM( pcbios_memory )	( getbiosmem( &pcbios_memory ) )
#define FREEBIOSMEM( pcbios_memory )	( freebiosmem( &pcbios_memory ) )
#define ECHO_PCBIOS( pcbios_int)	( echo_pcbios( &pcbios_int ) )

#else
/* user level PC BIOS Interface Macro's */
#ifndef PCBIOS
static char    *biosf = "/dev/pcbios";
static dev_t    biosdev = 0;
#define PCBIOS 1
#endif	PCBIOS

#define BIOSCMD(command, data) ( _IOWR(p, command, struct data) )
#define OPENBIOS()	       ( biosdev = open(biosf, O_RDONLY) )
#define CLOSEBIOS()	       ( close(biosdev) )

#define CALLBIOS( pcbios_int)						      \
	  ioctl(biosdev,						      \
		BIOSCMD(CMD_CALLBIOS, BIOS_INT ), (char *)&pcbios_int)
#define GETBIOSMEM( pcbios_memory )					      \
	  ioctl(biosdev,						      \
		BIOSCMD(CMD_GETBIOSMEM, BIOS_MEMORY), (char *)&pcbios_memory)
#define FREEBIOSMEM( pcbios_memory )					      \
	  ioctl(biosdev,						      \
		BIOSCMD(CMD_FREEBIOSMEM, BIOS_MEMORY), (char *)&pcbios_memory)
#define ECHO_PCBIOS( pcbios_int)					      \
	  ioctl(biosdev,						      \
		bioscmd(CMD_BIOSTEST, BIOS_INT), (char *)&pcbios_int)

#endif KERNEL


/*---------------------------------------------------------------*
 * PC BIOS interrupt code values				 *
 *								 *
 * Note: need to all interrupts available to be complete	 *
 *---------------------------------------------------------------*/

#define   PCINT10   0x10	/* PC BIOS INT 10 - video routines */


/*---------------------------------------------------------------*
 * Macro to convert a linear PC memory address into SEG:OFF form *
 *---------------------------------------------------------------*/

#define   PCSEGOFF( segment, offset, pcaddrs )		\
	     segment = (short)( (long)pcaddrs >> 4 );	\
	     offset  = (short)( (long)pcaddrs & 0x000F );
