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

/*
 * Copyright University of Southern California, 1988
 */

#include <doscalls.h>
#include <dos.h>
#include <subcalls.h>
#include "pctype.h"
#include "pcparam.h"
#include "rb.h"
#include "os2ioctl.h"
#include "os2data.h"
#include "vga.h"
#include "sem.h"

/* This file contains all global data structures required by the
 * unix process.
 * Some of these structures are shared with UNIX across the pcif.
 */


u_short	pcif_handle;	/* handle to the device driver */
char	*unix_name;	/* points to the process file name */
u_long	pcif_data_handle;	/* handle used to unlock the data segment */

u_short		r_base=0x1e0;		/* base of PCIF registers */
u_long          physmem_bytes = 0,	/* Size of ROMP memory in bytes  */
                pc_base = 0x200000;	/* Starting address of PCIF      */
char far	*pc_wind1 = 0,		/* Starting address of windows   */
                far *pc_wind2 = 0, far *pc_wind3 = 0, far *pc_wind4 = 0;

u_short		physmem_reg,physmem;

char	far	*buff_dio = 0;		/* pointer to a data segment */
char	far	*fdbuf = 0;		/* pointer to a data segment for fd */
char	far	*opbuf = 0;		/* pointer to a data segment for fd */

/***************************************************************************
 * The following structures are shared with UNIX.
 ***************************************************************************
 * NOTE: Some have to be aligned on addresses that are multiples of 4.
 * 	 i.e. they end in 0,4,8,c. These I have marked with an `A'.
 *	 This alignment has to be done at RUN TIME!
 *
 *	 Every 4 byte word has to be aligned. This is because the RISC Memory
 *	 Unit silently truncates 4 byte accesses (int on the RISC side -
 *	 long on the PS/2) to have the last two bits set to zero.
 * 	 On the PS/2 side, the compiler aligns all structures on even
 *	 addresses and cannot align as above, so this has to be done at
 *	 run time.
 */

char	cbcbbuf[16+sizeof(struct cbcb)] = { 0 };
struct	cbcb	*cbcbptr = 0;
		/* (A)
		 * This buffer will contain the aligned CBCB.
		 * cbcbptr will be a pointer to the aligned structure.
		 */

static char     hdr_buff[64];
struct dio_rtn_codes *hd_return_code = (struct dio_rtn_codes *) hdr_buff;
		/* (A)
		 * This points  to the hard disk parameters
		 * This is put in the HDENT pc_cb.
		 */

static char     fdr_buff[64];
struct dio_rtn_codes *fd_return_code = (struct dio_rtn_codes *) fdr_buff;
		/* (A)
		 * This points  to the floppy disk parameters
		 * This is put in the FDENT pc_cb.
		 */

struct kbdata   kbdata = {0};
		/* This is used to pass keyboard commands to OS/2, and to
		 * send keystrokes to UNIX.
		 * This is put in the KBENT pc_cb.
		 */

char            vec_map[16] = {0};
		/* This contains the interrupt vector map. This is used to
		 * enable and disable interrupts to UNIX.
		 * This is put in the SVENT pc_cb.
		 */

struct XCLOCK   xclock = { 0 };
		/* This structure is used to pass the time of day to
		 * UNIX. The RISC card does not maintain a real time 
		 * clock.
		 * This is put in the CLENT pc_cb.
		 */

char vga_buf[16 + sizeof (struct vga_params)] = { 0 } ;
struct vga_params *vga = (struct vga_params *) vga_buf;
		/* (A)
		 * This buffer will contain the aligned structure used by the
		 * vga driver to receive commands from UNIX, and to send hot
		 * key info, screen addresses and other such stuff.
		 * Desired declaration: struct vga_params vga = { 0 };
		 * Instead, vga is a pointer to the structure.
		 */

char ubp[100];	/* unix buffer pool.
		 * This is put in the AFIENT pc_cb.
		 * We do not use it for OS/2.
		 */

struct msdata   msdata = {0};
		/* This is used to send mouse data back to UNIX, and to 
		 * reply to commands.
		 * This is put in the MSENT pc_cb.
		 */

struct spkdata  spkdata = {0};
		/* This structure is used to send speaker replies back to 
		 * UNIX.
		 * This is put in the SPKENT pc_cb.
		 */

struct mask_int old_mask = {0};
		/* This is used to save the old interrupt masks.
		 * This is put in the MASKENT pc_cb.
		 */

/**************************************************************************
 * The following functions are responsible for initializing data and
 * aligning structures.
 **************************************************************************
 */


/* This function allocates memory for the disk buffers. An entire 64K
 * segment is requested for each buffer.
 * It returns -1 on error. No error is signaled if a buffer could not
 * be obtained for the floppy disk. However, a message is printed.
 */

static int
buf_init()

{	int rc;
	u_int	sel;
	u_int	i;
	char far *p;

	if ( rc = DOSALLOCSEG(0,(unsigned far *)&sel,0) ) {
		printf("DOSALLOCSEG returned %d\n",rc);
		return -1;
	}
	buff_dio = GETSEGPTR(sel,0);
	/* clear the buffer */
	for (i=0, p = buff_dio; i < 0xffff ; i++,p++)
		*p = 0;

	/* now get a segment for floppy disk io */

	if ( rc = DOSALLOCSEG(0,(unsigned far *)&sel,0) ) {
		printf(
		"floppy disk buffer unavailable: DOSALLOCSEG returned %d\n",rc);
	} else
		fdbuf = GETSEGPTR(sel,0);

#ifdef notdef
	/* now get a segment for optical disk io */

	if ( rc = DOSALLOCSEG(0,(unsigned far *)&sel,0) ) {
		printf(
		"optical disk buffer unavailable: DOSALLOCSEG returned %d\n",rc);
	} else
		opbuf = GETSEGPTR(sel,0);
#endif
	return 0;
}


/* This function aligns the data buffers that need to be aligned.
 */

static int
align_data()

{
	/* align cbcb structure */
	cbcbptr = (struct cbcb *) align(cbcbbuf, 4, int);

	/* align the vga_params structure */
	vga = (struct vga_params *) align(vga_buf, 4, int);

	/* align the hd params structure */
	hd_return_code = (struct dio_rtn_codes *) align(hd_return_code, 4, int);

	/* align the fd params structure */
	fd_return_code = (struct dio_rtn_codes *) align(fd_return_code, 4, int);

	/* align ub pc data structure */
	ub_pc = (struct ubpc *) align(ub_pc, 4, int);

	return 0;
}

/* This function initializes and aligns all data
 */

int
init_data()
{
	extern long debug;
	if ( align_data() )
		return -1;
	if ( buf_init() )
		return -1;
	cbcbptr->debug = debug;
	return 0;
}
