#include "insignia.h"
#include "host_def.h"
/*
 * SoftPC Revision 3.0
 *
 * Title	: Global variable definitions
 *
 * Description	: Contains definitions for registers and general
 *		  variables required by all modules.
 *
 * Author	: Henry Nash
 *
 * Notes	: None
 *
 */

/*
 * static char SccsID[]="@(#)xt.c	1.11 12/18/92 Copyright Insignia Solutions Ltd.";
 */


/*
 *    O/S include files.
 */
#include <stdio.h>
#include TypesH

/*
 * SoftPC include files
 */
#include "xt.h"
#include "cpu.h"
#include "sas.h"

/*
 * ============================================================================
 * Global data 
 * ============================================================================
 */

/*
   specific CPU variables.
 */
word  cpu_interrupt_map;                /* Bit map of ints outstanding  */

half_word cpu_int_translate[16];        /* this will go very soon!      */
/*
 *
 * The current usage is:
 *
 *              0       - Hardware interrupt
 *              1-7     - Not Used
 *              8       - Software Int - set by cpu_sw_interrupt() - REMOVED!
 *              9       - Trap
 *              10      - Reset IP after a POP/MOV CS.
 *              11      - Trap flag changed - this has delay.
 *              12-15   - Not Used
 */

word cpu_int_delay;                     /* Delay before pending interrupt */

int trap_delay_count;
 
/*
 * The lock flag prevents the Interrupt Controller Adapter from being
 * called from a signal handler while it is already active in the mainline.
 */
 
half_word ica_lock;
 
/*
 * The actual CCPU registers
 */

#if defined(CCPU) && !defined(CPU_30_STYLE)
#ifndef MAC_LIKE
reg A;		/* Accumulator		*/
reg B;		/* Base			*/
reg C;		/* Count		*/
reg D;		/* Data			*/
reg BP;		/* Base pointer		*/
reg SI;		/* Source Index		*/
reg DI;		/* Destination Index	*/
#endif /* MAC_LIKE */
reg SP;		/* Stack Pointer	*/

reg IP;		/* Instruction Pointer	*/

reg CS;		/* Code Segment		*/
reg DS;		/* Data Segment		*/
reg SS;		/* Stack Segment	*/
reg ES;		/* Extra Segment	*/

/* Code Segment Register */
half_word CS_AR;    /* Access Rights Byte */
sys_addr  CS_base;  /* Base Address */
word      CS_limit; /* Segment 'size' */
int       CPL;      /* Current Privilege Level */

/* Data Segment Register */
half_word DS_AR;    /* Access Rights Byte */
sys_addr  DS_base;  /* Base Address */
word      DS_limit; /* Segment 'size' */

/* Stack Segment Register */
half_word SS_AR;    /* Access Rights Byte */
sys_addr  SS_base;  /* Base Address */
word      SS_limit; /* Segment 'size' */

/* Extra Segment Register */
half_word ES_AR;    /* Access Rights Byte */
sys_addr  ES_base;  /* Base Address */
word      ES_limit; /* Segment 'size' */

/* Global Descriptor Table Register */
sys_addr GDTR_base;  /* Base Address */
word     GDTR_limit; /* Segment 'size' */

/* Interrupt Descriptor Table Register */
sys_addr IDTR_base;  /* Base Address */
word     IDTR_limit; /* Segment 'size' */

/* Local Descriptor Table Register */
reg      LDTR;       /* Selector */
sys_addr LDTR_base;  /* Base Address */
word     LDTR_limit; /* Segment 'size' */

/* Task Register */
reg      TR;       /* Selector */
sys_addr TR_base;  /* Base Address */
word     TR_limit; /* Segment 'size' */

mreg MSW;	/* Machine Status Word */

int STATUS_CF;
int STATUS_SF;
int STATUS_ZF;
int STATUS_AF;
int STATUS_OF;
int STATUS_PF;
int STATUS_TF;
int STATUS_IF;
int STATUS_DF;
int STATUS_NT;
int STATUS_IOPL;
#endif /* defined(CCPU) && !defined(CPU_30_STYLE) */

/*
 * Global Flags and variables
 */

char **pargv;			/* Pointer to argv		*/
int *pargc;			/* Pointer to argc		*/
int verbose;			/* TRUE => trace instructions   */
GLOBAL IU32 io_verbose;		/* TRUE => report io errors	*/

/*
 * Misc. Prot Mode support routines which are independant of CPU type
 *                                  ---------------------------------
 */
#ifdef CPU_30_STYLE

#define GET_SELECTOR_INDEX_TIMES8(x)  ((x) & 0xfff8)
#define GET_SELECTOR_TI(x)            (((x) & 0x0004) >> 2)

#if !defined(NTVDM) || ( defined(NTVDM) && !defined(MONITOR) )  /* MS NT monitor has own effective_addr fn */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Calculate effective address.                                       */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef ANSI
GLOBAL double_word
effective_addr(word seg, word off)
#else
   GLOBAL double_word effective_addr(seg, off) word seg; word off;
#endif
   {
   double_word descr_addr;
   DESCR entry;

   if ( getPE() == 0 )
      {
      return ((double_word)seg << 4) + off;
      }
   else
      {
      if ( selector_outside_table(seg, &descr_addr) == 1 )
	 {
	 /*
	    This is probably not a major disaster, just a result of the
	    fact that after protected mode is invoked it will take say
	    5-10 instructions for an application to update all the
	    segment registers. We just maintain real mode semantics
	    while this error occurs.
	  */
	 return ((double_word)seg << 4) + off;
	 }
      else
	 {
	 read_descriptor(descr_addr, &entry);
	 return entry.base + off;
	 }
      }
   }
#endif	/* !NTVDM | (NTVDM & !MONITOR) */

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Read a decriptor table entry from memory.                          */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef ANSI
GLOBAL VOID
read_descriptor(double_word addr, DESCR *descr)
#else
   GLOBAL VOID read_descriptor(addr, descr) double_word addr; DESCR *descr;
#endif
   {
   double_word first_dword;
   double_word second_dword;

   /*
      The format of a 286 descriptor is:-

	 ===========================
      +1 |        LIMIT 15-0       | +0
	 ===========================
      +3 |        BASE 15-0        | +2
	 ===========================
      +5 |     AR     | BASE 23-16 | +4
	 ===========================
      +7 |         RESERVED        | +6
	 ===========================
   */

   /* read in decriptor with minimum interaction with memory */
   first_dword = sas_dw_at(addr);
   second_dword = sas_dw_at(addr+4);

   second_dword &= 0xffff; /* RESERVED acts like all zero */

   /* load attributes and access rights */
   descr->AR = second_dword >> 8;

   /* unpack the base */
   descr->base = (first_dword >> 16) | 
		 (second_dword << 16 & 0xff0000 );

   /* unpack the limit */
   descr->limit = first_dword & 0xffff;
   }

#if !defined(NTVDM) || ( defined(NTVDM) && !defined(MONITOR) )  /* MS NT monitor has own selector_outside_table fn */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Check if selector outside bounds of GDT or LDT                     */
/* Return 1 for outside table, 0 for inside table.                    */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef ANSI
GLOBAL boolean
selector_outside_table(word selector, double_word *descr_addr)
#else
   GLOBAL boolean selector_outside_table(selector, descr_addr)
   word selector; double_word *descr_addr;
#endif
   {
   /* selector		(I) selector to be checked */
   /* descr_addr	(O) address of related descriptor */

   FAST word offset;

   offset = GET_SELECTOR_INDEX_TIMES8(selector);

   /* choose a table */
   if ( GET_SELECTOR_TI(selector) == 0 )
      {
      /* GDT - trap NULL selector or outside table */
      if ( offset == 0 || offset + 7 > getGDT_LIMIT() )
	 return 1;
      *descr_addr = getGDT_BASE() + offset;
      }
   else
      {
      /* LDT - trap invalid LDT or outside table */
      if ( getLDT_SELECTOR() == 0 || offset + 7 > getLDT_LIMIT() )
	 return 1;
      *descr_addr = getLDT_BASE() + offset;
      }
   
   return 0;
   }
#endif	/* !NTVDM | (NTVDM & !MONITOR) */

#endif /* CPU_30_STYLE */

/*
 * The following is a table lookup for finding parity of a byte
 */

#if !defined(MAC_LIKE) && !defined(CPU_30_STYLE)

half_word pf_table[] = {
	1,	/* 00 */
	0,	/* 01 */
	0,	/* 02 */
	1,	/* 03 */
	0,	/* 04 */
	1,	/* 05 */
	1,	/* 06 */
	0,	/* 07 */
	0,	/* 08 */
	1,	/* 09 */
	1,	/* 0a */
	0,	/* 0b */
	1,	/* 0c */
	0,	/* 0d */
	0,	/* 0e */
	1,	/* 0f */
	0,	/* 10 */
	1,	/* 11 */
	1,	/* 12 */
	0,	/* 13 */
	1,	/* 14 */
	0,	/* 15 */
	0,	/* 16 */
	1,	/* 17 */
	1,	/* 18 */
	0,	/* 19 */
	0,	/* 1a */
	1,	/* 1b */
	0,	/* 1c */
	1,	/* 1d */
	1,	/* 1e */
	0,	/* 1f */
	0,	/* 20 */
	1,	/* 21 */
	1,	/* 22 */
	0,	/* 23 */
	1,	/* 24 */
	0,	/* 25 */
	0,	/* 26 */
	1,	/* 27 */
	1,	/* 28 */
	0,	/* 29 */
	0,	/* 2a */
	1,	/* 2b */
	0,	/* 2c */
	1,	/* 2d */
	1,	/* 2e */
	0,	/* 2f */
	1,	/* 30 */
	0,	/* 31 */
	0,	/* 32 */
	1,	/* 33 */
	0,	/* 34 */
	1,	/* 35 */
	1,	/* 36 */
	0,	/* 37 */
	0,	/* 38 */
	1,	/* 39 */
	1,	/* 3a */
	0,	/* 3b */
	1,	/* 3c */
	0,	/* 3d */
	0,	/* 3e */
	1,	/* 3f */
	0,	/* 40 */
	1,	/* 41 */
	1,	/* 42 */
	0,	/* 43 */
	1,	/* 44 */
	0,	/* 45 */
	0,	/* 46 */
	1,	/* 47 */
	1,	/* 48 */
	0,	/* 49 */
	0,	/* 4a */
	1,	/* 4b */
	0,	/* 4c */
	1,	/* 4d */
	1,	/* 4e */
	0,	/* 4f */
	1,	/* 50 */
	0,	/* 51 */
	0,	/* 52 */
	1,	/* 53 */
	0,	/* 54 */
	1,	/* 55 */
	1,	/* 56 */
	0,	/* 57 */
	0,	/* 58 */
	1,	/* 59 */
	1,	/* 5a */
	0,	/* 5b */
	1,	/* 5c */
	0,	/* 5d */
	0,	/* 5e */
	1,	/* 5f */
	1,	/* 60 */
	0,	/* 61 */
	0,	/* 62 */
	1,	/* 63 */
	0,	/* 64 */
	1,	/* 65 */
	1,	/* 66 */
	0,	/* 67 */
	0,	/* 68 */
	1,	/* 69 */
	1,	/* 6a */
	0,	/* 6b */
	1,	/* 6c */
	0,	/* 6d */
	0,	/* 6e */
	1,	/* 6f */
	0,	/* 70 */
	1,	/* 71 */
	1,	/* 72 */
	0,	/* 73 */
	1,	/* 74 */
	0,	/* 75 */
	0,	/* 76 */
	1,	/* 77 */
	1,	/* 78 */
	0,	/* 79 */
	0,	/* 7a */
	1,	/* 7b */
	0,	/* 7c */
	1,	/* 7d */
	1,	/* 7e */
	0,	/* 7f */
	0,	/* 80 */
	1,	/* 81 */
	1,	/* 82 */
	0,	/* 83 */
	1,	/* 84 */
	0,	/* 85 */
	0,	/* 86 */
	1,	/* 87 */
	1,	/* 88 */
	0,	/* 89 */
	0,	/* 8a */
	1,	/* 8b */
	0,	/* 8c */
	1,	/* 8d */
	1,	/* 8e */
	0,	/* 8f */
	1,	/* 90 */
	0,	/* 91 */
	0,	/* 92 */
	1,	/* 93 */
	0,	/* 94 */
	1,	/* 95 */
	1,	/* 96 */
	0,	/* 97 */
	0,	/* 98 */
	1,	/* 99 */
	1,	/* 9a */
	0,	/* 9b */
	1,	/* 9c */
	0,	/* 9d */
	0,	/* 9e */
	1,	/* 9f */
	1,	/* a0 */
	0,	/* a1 */
	0,	/* a2 */
	1,	/* a3 */
	0,	/* a4 */
	1,	/* a5 */
	1,	/* a6 */
	0,	/* a7 */
	0,	/* a8 */
	1,	/* a9 */
	1,	/* aa */
	0,	/* ab */
	1,	/* ac */
	0,	/* ad */
	0,	/* ae */
	1,	/* af */
	0,	/* b0 */
	1,	/* b1 */
	1,	/* b2 */
	0,	/* b3 */
	1,	/* b4 */
	0,	/* b5 */
	0,	/* b6 */
	1,	/* b7 */
	1,	/* b8 */
	0,	/* b9 */
	0,	/* ba */
	1,	/* bb */
	0,	/* bc */
	1,	/* bd */
	1,	/* be */
	0,	/* bf */
	1,	/* c0 */
	0,	/* c1 */
	0,	/* c2 */
	1,	/* c3 */
	0,	/* c4 */
	1,	/* c5 */
	1,	/* c6 */
	0,	/* c7 */
	0,	/* c8 */
	1,	/* c9 */
	1,	/* ca */
	0,	/* cb */
	1,	/* cc */
	0,	/* cd */
	0,	/* ce */
	1,	/* cf */
	0,	/* d0 */
	1,	/* d1 */
	1,	/* d2 */
	0,	/* d3 */
	1,	/* d4 */
	0,	/* d5 */
	0,	/* d6 */
	1,	/* d7 */
	1,	/* d8 */
	0,	/* d9 */
	0,	/* da */
	1,	/* db */
	0,	/* dc */
	1,	/* dd */
	1,	/* de */
	0,	/* df */
	0,	/* e0 */
	1,	/* e1 */
	1,	/* e2 */
	0,	/* e3 */
	1,	/* e4 */
	0,	/* e5 */
	0,	/* e6 */
	1,	/* e7 */
	1,	/* e8 */
	0,	/* e9 */
	0,	/* ea */
	1,	/* eb */
	0,	/* ec */
	1,	/* ed */
	1,	/* ee */
	0,	/* ef */
	1,	/* f0 */
	0,	/* f1 */
	0,	/* f2 */
	1,	/* f3 */
	0,	/* f4 */
	1,	/* f5 */
	1,	/* f6 */
	0,	/* f7 */
	0,	/* f8 */
	1,	/* f9 */
	1,	/* fa */
	0,	/* fb */
	1,	/* fc */
	0,	/* fd */
	0,	/* fe */
	1	/* ff */
};
#endif /* !defined(MAC_LIKE) && !defined(CPU_30_STYLE) */
