/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1987,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */

/* $Header:cbcbbios.h 12.0$ */
/* $ACIS:cbcbbios.h 12.0$ */
/* $Source: /ibm/acis/usr/sys/pc_code/RCS/cbcbbios.h,v $ */

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

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

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

/*---------------------------------------------------------------*
 * IBM PC related definitions, this makes it easy to read common *
 * date structures						 *
 *---------------------------------------------------------------*/
#define BYTE unsigned char
#define WORD unsigned short
#define LONG unsigned long


/* word registers */

struct WORDREGS
{
	WORD            ax, bx, cx, dx, si, di, bp, sp, 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            cs, ds, es, ss;
};


/*
 * BIOS interrupt and all registers in one structure
 *
 * note: PCBIOS_DATA must be < 128 bytes. The current size of PCBIOS_DATA is:
 *    BIOS INT XX, 1 byte =  1
 *    int finished 1 byte =  1	      nonzero indicates INT was completed
 *    REGS  = 9 x 2 bytes = 18
 *    SREGS = 4 x 2 bytes =  8
 *			   ---
 *			    28 bytes
 */

struct PCBIOS_DATA
{
	BYTE            bios_int;
	BYTE            finished;
	union REGS      gen_reg;
	struct SREGS    seg_reg;
};


#ifdef KERNEL
/* direct call to routine in PC BIOS driver */
int             callbios();
int             getbiosmem();
int             freebiosmem();
int             echo_pcbios();

#else
/* PC BIOS Interface Macro's */
static char    *biosf = "/dev/pcbios";
static dev_t    biosdev = 0;
#define bioscmd(command, data) _IOWR(p, command, struct data)
#define openbios()  biosdev = open(biosf, O_RDONLY)
#define closebios() close(biosdev)

#define callbios( pcbios_data)						      \
	   ioctl(biosdev,						      \
		 bioscmd(CALLBIOS, PCBIOS_DATA ), (char *)&pcbios_data)
#define getbiosmem( pcbios_memory )					      \
	   ioctl(biosdev,						      \
		 bioscmd(GETBIOSMEM, PCBIOS_MEMORY), (char *)&pcbios_memory)
#define freebiosmem( pcbios_memory )					      \
	   ioctl(biosdev,						      \
		 bioscmd(FREEBIOSMEM, PCBIOS_MEMORY), (char *)&pcbios_memory)
#define echo_pcbios( pcbios_data)					      \
	   ioctl(biosdev,						      \
		 bioscmd(BIOSTEST, PCBIOS_DATA), (char *)&pcbios_data)

#endif /* KERNEL */


/* PC BIOS IOCTL COMMANDS */

#define CALLBIOS    0x00
#define GETBIOSMEM  0x01
#define FREEBIOSMEM 0x02
#define BIOSTEST    0x03


/* PC BIOS Interrupt Code Values */

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


/* cbcb data structure for BIOS data block */

#define size_dd  256
#define size_ud  16384

struct BIOS_DATA
{
	long            size_disp_data;	/* 4 bytes   */
	long            size_usr_data;	/* 4 bytes   */
	char            display_data[size_dd];	/* 256 bytes */
	char            usr_data[size_ud];	/* 16K bytes */
};


/* structure used for the allocation of usr_data in BIOS_DATA */

struct PCBIOS_MEMORY
{
	long            size;
	char           *ptr;
};


/* macro's to tranformation PC physical address to SEGMENT:OFFSET form */

#define pcsegoff( segment, offset, physaddrs )	 {   \
     segment = (WORD)( (LONG)physaddrs >> 4 );		   \
     offset  = (WORD)( (LONG)physaddrs & 0x0000000F ); };
