debrix/hw/xorg/int10 LICENSE, NONE, 1.1 Makefile.am, 1.1, 1.2 debug.c, NONE, 1.1 debug.h, NONE, 1.1 decode.c, NONE, 1.1 decode.h, NONE, 1.1 fpu.c, NONE, 1.1 fpu.h, NONE, 1.1 fpu_regs.h, NONE, 1.1 helper_exec.c, 1.3, 1.4 ops.c, NONE, 1.1 ops.h, NONE, 1.1 ops2.c, NONE, 1.1 prim_asm.h, NONE, 1.1 prim_ops.c, NONE, 1.1 prim_ops.h, NONE, 1.1 regs.h, NONE, 1.1 sys.c, NONE, 1.1 types.h, NONE, 1.1 validate.c, NONE, 1.1 x86emu.h, NONE, 1.1 x86emui.h, NONE, 1.1 xf86int10.c, 1.3, 1.4

Adam Jackson xserver-commit at pdx.freedesktop.org
Tue Jun 15 17:25:32 PDT 2004


Committed by: ajax

Update of /cvs/xserver/debrix/hw/xorg/int10
In directory pdx:/home/ajax/debrix/hw/xorg/int10

Modified Files:
	Makefile.am helper_exec.c xf86int10.c 
Added Files:
	LICENSE debug.c debug.h decode.c decode.h fpu.c fpu.h 
	fpu_regs.h ops.c ops.h ops2.c prim_asm.h prim_ops.c prim_ops.h 
	regs.h sys.c types.h validate.c x86emu.h x86emui.h 
Log Message:
Massive build fixes:

- Properly set some defines for Xtrans
- Sanitize included file paths
- Unbreak extmod
- Import of x86emu so int10 will work
- Fix int10 to include x86emu headers


--- NEW FILE: LICENSE ---
                         License information
                         -------------------

The x86emu library is under a BSD style license, comaptible
with the XFree86 1.0 and X licenses used by XFree86. The
original x86emu libraries were under the GNU General Public
License. Due to license incompatibilities between the GPL
and the XFree86 1.0 license, the original authors of the code
decided to allow a license change. If you have submitted
code to the original x86emu project, and you don't agree
with the license change, please contact us and let you
know. Your code will be removed to comply with your wishes.

If you have any questions about this, please send email to
x86emu at linuxlabs.com or KendallB at scitechsoft.com for
clarification.


Index: Makefile.am
===================================================================
RCS file: /cvs/xserver/debrix/hw/xorg/int10/Makefile.am,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Makefile.am	10 Jun 2004 19:14:51 -0000	1.1
+++ Makefile.am	16 Jun 2004 00:25:30 -0000	1.2
@@ -9,4 +9,6 @@
 
 driver_LTLIBRARIES = libint10.la
 
-libint10_la_SOURCES = stub.c xf86int10module.c
+libint10_la_SOURCES = pci.c xf86int10module.c helper_exec.c helper_mem.c \
+		      xf86int10.c xf86x86emu.c generic.c debug.c decode.c \
+		      fpu.c ops.c ops2.c prim_ops.c sys.c

--- NEW FILE: debug.c ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  This file contains the code to handle debugging of the
*				emulator.
*
****************************************************************************/

#include "x86emui.h"
#ifndef NO_SYS_HEADERS
#include <stdarg.h>
#include <stdlib.h>
#endif

/*----------------------------- Implementation ----------------------------*/

#ifdef DEBUG

static void     print_encoded_bytes (u16 s, u16 o);
static void     print_decoded_instruction (void);
static int      parse_line (char *s, int *ps, int *n);
  
/* should look something like debug's output. */
void X86EMU_trace_regs (void)
{
	if (DEBUG_TRACE()) {
		x86emu_dump_regs();
    }
	if (DEBUG_DECODE() && ! DEBUG_DECODE_NOPRINT()) {
		printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
		print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
		print_decoded_instruction();
    }
}

void X86EMU_trace_xregs (void)
{
	if (DEBUG_TRACE()) {
		x86emu_dump_xregs();
    }
}

void x86emu_just_disassemble (void)
{
    /*
     * This routine called if the flag DEBUG_DISASSEMBLE is set kind
     * of a hack!
     */
	printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
	print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
	print_decoded_instruction();
}

static void disassemble_forward (u16 seg, u16 off, int n)
{
	X86EMU_sysEnv tregs;
	int i;
	u8 op1;
    /*
     * hack, hack, hack.  What we do is use the exact machinery set up
     * for execution, except that now there is an additional state
     * flag associated with the "execution", and we are using a copy
     * of the register struct.  All the major opcodes, once fully
     * decoded, have the following two steps: TRACE_REGS(r,m);
     * SINGLE_STEP(r,m); which disappear if DEBUG is not defined to
     * the preprocessor.  The TRACE_REGS macro expands to:
     *
     * if (debug&DEBUG_DISASSEMBLE) 
     *     {just_disassemble(); goto EndOfInstruction;}
     *     if (debug&DEBUG_TRACE) trace_regs(r,m);
     *
     * ......  and at the last line of the routine. 
     *
     * EndOfInstruction: end_instr();
     *
     * Up to the point where TRACE_REG is expanded, NO modifications
     * are done to any register EXCEPT the IP register, for fetch and
     * decoding purposes.
     *
     * This was done for an entirely different reason, but makes a
     * nice way to get the system to help debug codes.
     */
	tregs = M;
    tregs.x86.R_IP = off;
    tregs.x86.R_CS = seg;
    
    /* reset the decoding buffers */
    tregs.x86.enc_str_pos = 0;
    tregs.x86.enc_pos = 0;
    
    /* turn on the "disassemble only, no execute" flag */
    tregs.x86.debug |= DEBUG_DISASSEMBLE_F;
 
    /* DUMP NEXT n instructions to screen in straight_line fashion */
    /*
     * This looks like the regular instruction fetch stream, except
     * that when this occurs, each fetched opcode, upon seeing the
     * DEBUG_DISASSEMBLE flag set, exits immediately after decoding
     * the instruction.  XXX --- CHECK THAT MEM IS NOT AFFECTED!!!
     * Note the use of a copy of the register structure...
     */
    for (i=0; i<n; i++) {
		op1 = (*sys_rdb)(((u32)M.x86.R_CS<<4) + (M.x86.R_IP++));
		(x86emu_optab[op1])(op1);
    }
    /* end major hack mode. */
}

void x86emu_check_ip_access (void)
{
    /* NULL as of now */
}

void x86emu_check_sp_access (void)
{
}

void x86emu_check_mem_access (u32 dummy)
{
	/*  check bounds, etc */
}

void x86emu_check_data_access (uint dummy1, uint dummy2)
{
	/*  check bounds, etc */
}

void x86emu_inc_decoded_inst_len (int x)
{
	M.x86.enc_pos += x;
}

void x86emu_decode_printf (char *x)
{
	sprintf(M.x86.decoded_buf+M.x86.enc_str_pos,"%s",x);
	M.x86.enc_str_pos += strlen(x);
}

void x86emu_decode_printf2 (char *x, int y)
{
	char temp[100];
	sprintf(temp,x,y);
	sprintf(M.x86.decoded_buf+M.x86.enc_str_pos,"%s",temp);
	M.x86.enc_str_pos += strlen(temp);
}

void x86emu_end_instr (void)
{
	M.x86.enc_str_pos = 0;
	M.x86.enc_pos = 0;
}

static void print_encoded_bytes (u16 s, u16 o)
{
    int i;
    char buf1[64];
	for (i=0; i< M.x86.enc_pos; i++) {
		sprintf(buf1+2*i,"%02x", fetch_data_byte_abs(s,o+i));
    }
	printk("%-20s",buf1);
}

static void print_decoded_instruction (void)
{
	printk("%s", M.x86.decoded_buf);
}

void x86emu_print_int_vect (u16 iv)
{
	u16 seg,off;

	if (iv > 256) return;
	seg   = fetch_data_word_abs(0,iv*4);
	off   = fetch_data_word_abs(0,iv*4+2);
	printk("%04x:%04x ", seg, off);
}

void X86EMU_dump_memory (u16 seg, u16 off, u32 amt)
{
	u32 start = off & 0xfffffff0;
	u32 end  = (off+16) & 0xfffffff0;
	u32 i;
	u32 current;

	current = start;
	while (end <= off + amt) {
		printk("%04x:%04x ", seg, start);
		for (i=start; i< off; i++)
		  printk("   ");
		for (       ; i< end; i++)
		  printk("%02x ", fetch_data_byte_abs(seg,i));
		printk("\n");
		start = end;
		end = start + 16;
	}
}

void x86emu_single_step (void)
{
    char s[1024];
    int ps[10];
    int ntok;
    int cmd;
    int done;
		int segment;
    int offset;
    static int breakpoint;
    static int noDecode = 1;
    
    char *p;

		if (DEBUG_BREAK()) {
				if (M.x86.saved_ip != breakpoint) {
						return;
				} else {
 	          M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
						M.x86.debug |= DEBUG_TRACE_F;
						M.x86.debug &= ~DEBUG_BREAK_F;
						print_decoded_instruction ();
						X86EMU_trace_regs();
				}
		}
    done=0;
	offset = M.x86.saved_ip;
    while (!done) {
        printk("-");
        p = fgets(s, 1023, stdin);
        cmd = parse_line(s, ps, &ntok);
        switch(cmd) {
          case 'u':
			disassemble_forward(M.x86.saved_cs,(u16)offset,10);
            break;
          case 'd':  
							if (ntok == 2) {
									segment = M.x86.saved_cs;
									offset = ps[1];
									X86EMU_dump_memory(segment,(u16)offset,16);
									offset += 16;
							} else if (ntok == 3) {
									segment = ps[1];
									offset = ps[2];
									X86EMU_dump_memory(segment,(u16)offset,16);
									offset += 16;
							} else {
									segment = M.x86.saved_cs;
									X86EMU_dump_memory(segment,(u16)offset,16);
									offset += 16;
							}
            break;
          case 'c':
			M.x86.debug ^= DEBUG_TRACECALL_F;
            break;
          case 's':
			M.x86.debug ^= DEBUG_SVC_F | DEBUG_SYS_F | DEBUG_SYSINT_F;
            break;
          case 'r':
			X86EMU_trace_regs();
            break;
          case 'x':
			X86EMU_trace_xregs();
            break;
          case 'g':
            if (ntok == 2) {
                breakpoint = ps[1];
		if (noDecode) {
		                M.x86.debug |= DEBUG_DECODE_NOPRINT_F;
		} else {
		                M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
		}
		M.x86.debug &= ~DEBUG_TRACE_F;
		M.x86.debug |= DEBUG_BREAK_F;
		done = 1;
            }
            break;
          case 'q':
          M.x86.debug |= DEBUG_EXIT;
          return;
	  case 'P':
	      noDecode = (noDecode)?0:1;
	      printk("Toggled decoding to %s\n",(noDecode)?"FALSE":"TRUE");
	      break;
          case 't':
	  case 0:
            done = 1;
            break;
        }   
    }
}

int X86EMU_trace_on(void)
{
	return M.x86.debug |= DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F;
}

int X86EMU_trace_off(void)
{
	return M.x86.debug &= ~(DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F);
}

static int parse_line (char *s, int *ps, int *n)
{
    int cmd;

    *n = 0;
    while(*s == ' ' || *s == '\t') s++;
    ps[*n] = *s;
    switch (*s) {
      case '\n':
        *n += 1;
        return 0;
      default:
        cmd = *s;
        *n += 1;
    }

	while (1) {
		while (*s != ' ' && *s != '\t' && *s != '\n')  s++;
		
		if (*s == '\n')
			return cmd;
		
		while(*s == ' ' || *s == '\t') s++;
		
		sscanf(s,"%x",&ps[*n]);
		*n += 1;
	}
}

#endif /* DEBUG */

void x86emu_dump_regs (void)
{
	printk("\tAX=%04x  ", M.x86.R_AX );
	printk("BX=%04x  ", M.x86.R_BX );
	printk("CX=%04x  ", M.x86.R_CX );
	printk("DX=%04x  ", M.x86.R_DX );
	printk("SP=%04x  ", M.x86.R_SP );
	printk("BP=%04x  ", M.x86.R_BP );
	printk("SI=%04x  ", M.x86.R_SI );
	printk("DI=%04x\n", M.x86.R_DI );
	printk("\tDS=%04x  ", M.x86.R_DS );
	printk("ES=%04x  ", M.x86.R_ES );
	printk("SS=%04x  ", M.x86.R_SS );
	printk("CS=%04x  ", M.x86.R_CS );
	printk("IP=%04x   ", M.x86.R_IP );
	if (ACCESS_FLAG(F_OF))    printk("OV ");     /* CHECKED... */
	else                        printk("NV ");
	if (ACCESS_FLAG(F_DF))    printk("DN ");
	else                        printk("UP ");
	if (ACCESS_FLAG(F_IF))    printk("EI ");
	else                        printk("DI ");
	if (ACCESS_FLAG(F_SF))    printk("NG ");
	else                        printk("PL ");
	if (ACCESS_FLAG(F_ZF))    printk("ZR ");
	else                        printk("NZ ");
	if (ACCESS_FLAG(F_AF))    printk("AC ");
	else                        printk("NA ");
	if (ACCESS_FLAG(F_PF))    printk("PE ");
	else                        printk("PO ");
	if (ACCESS_FLAG(F_CF))    printk("CY ");
	else                        printk("NC ");
	printk("\n");
}

void x86emu_dump_xregs (void)
{
	printk("\tEAX=%08x  ", M.x86.R_EAX );
	printk("EBX=%08x  ", M.x86.R_EBX );
	printk("ECX=%08x  ", M.x86.R_ECX );
	printk("EDX=%08x  \n", M.x86.R_EDX );
	printk("\tESP=%08x  ", M.x86.R_ESP );
	printk("EBP=%08x  ", M.x86.R_EBP );
	printk("ESI=%08x  ", M.x86.R_ESI );
	printk("EDI=%08x\n", M.x86.R_EDI );
	printk("\tDS=%04x  ", M.x86.R_DS );
	printk("ES=%04x  ", M.x86.R_ES );
	printk("SS=%04x  ", M.x86.R_SS );
	printk("CS=%04x  ", M.x86.R_CS );
	printk("EIP=%08x\n\t", M.x86.R_EIP );
	if (ACCESS_FLAG(F_OF))    printk("OV ");     /* CHECKED... */
	else                        printk("NV ");
	if (ACCESS_FLAG(F_DF))    printk("DN ");
	else                        printk("UP ");
	if (ACCESS_FLAG(F_IF))    printk("EI ");
	else                        printk("DI ");
	if (ACCESS_FLAG(F_SF))    printk("NG ");
	else                        printk("PL ");
	if (ACCESS_FLAG(F_ZF))    printk("ZR ");
	else                        printk("NZ ");
	if (ACCESS_FLAG(F_AF))    printk("AC ");
	else                        printk("NA ");
	if (ACCESS_FLAG(F_PF))    printk("PE ");
	else                        printk("PO ");
	if (ACCESS_FLAG(F_CF))    printk("CY ");
	else                        printk("NC ");
	printk("\n");
}

--- NEW FILE: debug.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Header file for debug definitions.
*
****************************************************************************/

#ifndef __X86EMU_DEBUG_H
#define __X86EMU_DEBUG_H

/*---------------------- Macros and type definitions ----------------------*/

/* checks to be enabled for "runtime" */

#define CHECK_IP_FETCH_F                0x1
#define CHECK_SP_ACCESS_F               0x2
#define CHECK_MEM_ACCESS_F              0x4 /*using regular linear pointer */
#define CHECK_DATA_ACCESS_F             0x8 /*using segment:offset*/

#ifdef DEBUG
# define CHECK_IP_FETCH()              	(M.x86.check & CHECK_IP_FETCH_F)
# define CHECK_SP_ACCESS()             	(M.x86.check & CHECK_SP_ACCESS_F)
# define CHECK_MEM_ACCESS()            	(M.x86.check & CHECK_MEM_ACCESS_F)
# define CHECK_DATA_ACCESS()           	(M.x86.check & CHECK_DATA_ACCESS_F)
#else
# define CHECK_IP_FETCH()
# define CHECK_SP_ACCESS()
# define CHECK_MEM_ACCESS()
# define CHECK_DATA_ACCESS()
#endif

#ifdef DEBUG
# define DEBUG_INSTRUMENT()    	(M.x86.debug & DEBUG_INSTRUMENT_F)
# define DEBUG_DECODE()        	(M.x86.debug & DEBUG_DECODE_F)
# define DEBUG_TRACE()         	(M.x86.debug & DEBUG_TRACE_F)
# define DEBUG_STEP()          	(M.x86.debug & DEBUG_STEP_F)
# define DEBUG_DISASSEMBLE()   	(M.x86.debug & DEBUG_DISASSEMBLE_F)
# define DEBUG_BREAK()         	(M.x86.debug & DEBUG_BREAK_F)
# define DEBUG_SVC()           	(M.x86.debug & DEBUG_SVC_F)
# define DEBUG_SAVE_IP_CS()     (M.x86.debug & DEBUG_SAVE_IP_CS_F)

# define DEBUG_FS()            	(M.x86.debug & DEBUG_FS_F)
# define DEBUG_PROC()          	(M.x86.debug & DEBUG_PROC_F)
# define DEBUG_SYSINT()        	(M.x86.debug & DEBUG_SYSINT_F)
# define DEBUG_TRACECALL()     	(M.x86.debug & DEBUG_TRACECALL_F)
# define DEBUG_TRACECALLREGS() 	(M.x86.debug & DEBUG_TRACECALL_REGS_F)
# define DEBUG_SYS()           	(M.x86.debug & DEBUG_SYS_F)
# define DEBUG_MEM_TRACE()     	(M.x86.debug & DEBUG_MEM_TRACE_F)
# define DEBUG_IO_TRACE()      	(M.x86.debug & DEBUG_IO_TRACE_F)
# define DEBUG_DECODE_NOPRINT() (M.x86.debug & DEBUG_DECODE_NOPRINT_F)
#else
# define DEBUG_INSTRUMENT()    	0
# define DEBUG_DECODE()        	0
# define DEBUG_TRACE()         	0
# define DEBUG_STEP()          	0
# define DEBUG_DISASSEMBLE()   	0
# define DEBUG_BREAK()         	0
# define DEBUG_SVC()           	0
# define DEBUG_SAVE_IP_CS()     0
# define DEBUG_FS()            	0
# define DEBUG_PROC()          	0
# define DEBUG_SYSINT()        	0
# define DEBUG_TRACECALL()     	0
# define DEBUG_TRACECALLREGS() 	0
# define DEBUG_SYS()           	0
# define DEBUG_MEM_TRACE()     	0
# define DEBUG_IO_TRACE()      	0
# define DEBUG_DECODE_NOPRINT() 0
#endif

#ifdef DEBUG

# define DECODE_PRINTF(x)     	if (DEBUG_DECODE()) \
									x86emu_decode_printf(x)
# define DECODE_PRINTF2(x,y)  	if (DEBUG_DECODE()) \
									x86emu_decode_printf2(x,y)

/*
 * The following allow us to look at the bytes of an instruction.  The
 * first INCR_INSTRN_LEN, is called everytime bytes are consumed in
 * the decoding process.  The SAVE_IP_CS is called initially when the
 * major opcode of the instruction is accessed.
 */
#define INC_DECODED_INST_LEN(x)                    	\
	if (DEBUG_DECODE())  	                       	\
		x86emu_inc_decoded_inst_len(x)

#define SAVE_IP_CS(x,y)                               			\
	if (DEBUG_DECODE() | DEBUG_TRACECALL() | DEBUG_BREAK() \
              | DEBUG_IO_TRACE() | DEBUG_SAVE_IP_CS()) { \
		M.x86.saved_cs = x;                          			\
		M.x86.saved_ip = y;                          			\
	}
#else
# define INC_DECODED_INST_LEN(x)
# define DECODE_PRINTF(x)
# define DECODE_PRINTF2(x,y)
# define SAVE_IP_CS(x,y)
#endif

#ifdef DEBUG
#define TRACE_REGS()                                   		\
	if (DEBUG_DISASSEMBLE()) {                         		\
		x86emu_just_disassemble();                        	\
		goto EndOfTheInstructionProcedure;             		\
	}                                                   	\
	if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs()
#else
# define TRACE_REGS()
#endif

#ifdef DEBUG
# define SINGLE_STEP()		if (DEBUG_STEP()) x86emu_single_step()
#else
# define SINGLE_STEP()
#endif

#define TRACE_AND_STEP()	\
	TRACE_REGS();			\
	SINGLE_STEP()

#ifdef DEBUG
# define START_OF_INSTR()
# define END_OF_INSTR()		EndOfTheInstructionProcedure: x86emu_end_instr();
# define END_OF_INSTR_NO_TRACE()	x86emu_end_instr();
#else
# define START_OF_INSTR()
# define END_OF_INSTR()
# define END_OF_INSTR_NO_TRACE()
#endif

#ifdef DEBUG
# define  CALL_TRACE(u,v,w,x,s)                                 \
	if (DEBUG_TRACECALLREGS())									\
		x86emu_dump_regs();                                     \
	if (DEBUG_TRACECALL())                                     	\
		printk("%04x:%04x: CALL %s%04x:%04x\n", u , v, s, w, x);
# define RETURN_TRACE(n,u,v)                                    \
	if (DEBUG_TRACECALLREGS())									\
		x86emu_dump_regs();                                     \
	if (DEBUG_TRACECALL())                                     	\
		printk("%04x:%04x: %s\n",u,v,n);
#else
# define CALL_TRACE(u,v,w,x,s)
# define RETURN_TRACE(n,u,v)
#endif

#ifdef DEBUG
#define	DB(x)	x
#else
#define	DB(x)
#endif

/*-------------------------- Function Prototypes --------------------------*/

#ifdef  __cplusplus
extern "C" {            			/* Use "C" linkage when in C++ mode */
#endif

extern void x86emu_inc_decoded_inst_len (int x);
extern void x86emu_decode_printf (char *x);
extern void x86emu_decode_printf2 (char *x, int y);
extern void x86emu_just_disassemble (void);
extern void x86emu_single_step (void);
extern void x86emu_end_instr (void);
extern void x86emu_dump_regs (void);
extern void x86emu_dump_xregs (void);
extern void x86emu_print_int_vect (u16 iv);
extern void x86emu_instrument_instruction (void);
extern void x86emu_check_ip_access (void);
extern void x86emu_check_sp_access (void);
extern void x86emu_check_mem_access (u32 p);
extern void x86emu_check_data_access (uint s, uint o);

#ifdef  __cplusplus
}                       			/* End of "C" linkage for C++   	*/
#endif

#endif /* __X86EMU_DEBUG_H */

--- NEW FILE: decode.c ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
[...1053 lines suppressed...]
            return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
	  case 4:
            DECODE_PRINTF2("%04x[SI]", displacement);
            return (M.x86.R_SI + displacement) & 0xffff;
	  case 5:
            DECODE_PRINTF2("%04x[DI]", displacement);
            return (M.x86.R_DI + displacement) & 0xffff;
	  case 6:
		DECODE_PRINTF2("%04x[BP]", displacement);
		M.x86.mode |= SYSMODE_SEG_DS_SS;
            return (M.x86.R_BP + displacement) & 0xffff;
	  case 7:
            DECODE_PRINTF2("%04x[BX]", displacement);
            return (M.x86.R_BX + displacement) & 0xffff;
	}
	HALT_SYS();
    }
    return 0;
    /*NOTREACHED */
}

--- NEW FILE: decode.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Header file for instruction decoding logic.
*
****************************************************************************/

#ifndef __X86EMU_DECODE_H
#define __X86EMU_DECODE_H

/*---------------------- Macros and type definitions ----------------------*/

/* Instruction Decoding Stuff */

#define FETCH_DECODE_MODRM(mod,rh,rl) 	fetch_decode_modrm(&mod,&rh,&rl)
#define DECODE_RM_BYTE_REGISTER(r)    	decode_rm_byte_register(r)
#define DECODE_RM_WORD_REGISTER(r)    	decode_rm_word_register(r)
#define DECODE_RM_LONG_REGISTER(r)    	decode_rm_long_register(r)
#define DECODE_CLEAR_SEGOVR()         	M.x86.mode &= ~SYSMODE_CLRMASK

/*-------------------------- Function Prototypes --------------------------*/

#ifdef  __cplusplus
extern "C" {            			/* Use "C" linkage when in C++ mode */
#endif

void 	x86emu_intr_raise (u8 type);
void    fetch_decode_modrm (int *mod,int *regh,int *regl);
u8      fetch_byte_imm (void);
u16     fetch_word_imm (void);
u32     fetch_long_imm (void);
u8      fetch_data_byte (uint offset);
u8      fetch_data_byte_abs (uint segment, uint offset);
u16     fetch_data_word (uint offset);
u16     fetch_data_word_abs (uint segment, uint offset);
u32     fetch_data_long (uint offset);
u32     fetch_data_long_abs (uint segment, uint offset);
void    store_data_byte (uint offset, u8 val);
void    store_data_byte_abs (uint segment, uint offset, u8 val);
void    store_data_word (uint offset, u16 val);
void    store_data_word_abs (uint segment, uint offset, u16 val);
void    store_data_long (uint offset, u32 val);
void    store_data_long_abs (uint segment, uint offset, u32 val);
u8* 	decode_rm_byte_register(int reg);
u16* 	decode_rm_word_register(int reg);
u32* 	decode_rm_long_register(int reg);
u16* 	decode_rm_seg_register(int reg);
u32	decode_rm00_address(int rm);
u32	decode_rm01_address(int rm);
u32	decode_rm10_address(int rm);
u32	decode_sib_address(int sib, int mod);

#ifdef  __cplusplus
}                       			/* End of "C" linkage for C++   	*/
#endif

#endif /* __X86EMU_DECODE_H */

--- NEW FILE: fpu.c ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  This file contains the code to implement the decoding and
*               emulation of the FPU instructions.
*
****************************************************************************/

#include "x86emui.h"

/*----------------------------- Implementation ----------------------------*/

/* opcode=0xd8 */
void x86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1))
{
    START_OF_INSTR();
    DECODE_PRINTF("ESC D8\n");
    DECODE_CLEAR_SEGOVR();
    END_OF_INSTR_NO_TRACE();
}

#ifdef DEBUG

static char *x86emu_fpu_op_d9_tab[] = {
    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",

    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",

    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
};

static char *x86emu_fpu_op_d9_tab1[] = {
    "FLD\t", "FLD\t", "FLD\t", "FLD\t",
    "FLD\t", "FLD\t", "FLD\t", "FLD\t",

    "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
    "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",

    "FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
    "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",

    "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
    "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",

    "FCHS", "FABS", "ESC_D9", "ESC_D9",
    "FTST", "FXAM", "ESC_D9", "ESC_D9",

    "FLD1", "FLDL2T", "FLDL2E", "FLDPI",
    "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",

    "F2XM1", "FYL2X", "FPTAN", "FPATAN",
    "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",

    "FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
    "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
};

#endif /* DEBUG */

/* opcode=0xd9 */
void x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1))
{
    int mod, rl, rh;
    uint destoffset = 0;
    u8 stkelem = 0;

    START_OF_INSTR();
    FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
    if (mod != 3) {
        DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl);
    } else {
        DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]);
    }
#endif
    switch (mod) {
      case 0:
        destoffset = decode_rm00_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 1:
        destoffset = decode_rm01_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 2:
        destoffset = decode_rm10_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 3:                   /* register to register */
		stkelem = (u8)rl;
		if (rh < 4) {
				DECODE_PRINTF2("ST(%d)\n", stkelem);
		} else {
				DECODE_PRINTF("\n");
		}
        break;
    }
#ifdef X86EMU_FPU_PRESENT
    /* execute */
    switch (mod) {
      case 3:
        switch (rh) {
          case 0:
            x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem);
            break;
          case 1:
            x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem);
            break;
          case 2:
            switch (rl) {
              case 0:
                x86emu_fpu_R_nop();
                break;
              default:
                x86emu_fpu_illegal();
                break;
            }
          case 3:
            x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem);
            break;
          case 4:
            switch (rl) {
            case 0:
                x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP);
                break;
            case 1:
                x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP);
                break;
            case 4:
                x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP);
                break;
            case 5:
                x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP);
                break;
            default:
                /* 2,3,6,7 */
                x86emu_fpu_illegal();
                break;
            }
            break;

          case 5:
            switch (rl) {
              case 0:
                x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP);
                break;
              case 1:
                x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP);
                break;
              case 2:
                x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP);
                break;
              case 3:
                x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP);
                break;
              case 4:
                x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP);
                break;
              case 5:
                x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP);
                break;
              case 6:
                x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP);
                break;
              default:
                /* 7 */
                x86emu_fpu_illegal();
                break;
            }
            break;

          case 6:
            switch (rl) {
              case 0:
                x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP);
                break;
              case 1:
                x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP);
                break;
              case 2:
                x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP);
                break;
              case 3:
                x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP);
                break;
              case 4:
                x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP);
                break;
              case 5:
                x86emu_fpu_illegal();
                break;
              case 6:
                x86emu_fpu_R_decstp();
                break;
              case 7:
                x86emu_fpu_R_incstp();
                break;
            }
            break;

          case 7:
            switch (rl) {
              case 0:
                x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP);
                break;
              case 1:
                x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP);
                break;
              case 2:
                x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP);
                break;
              case 3:
                x86emu_fpu_illegal();
                break;
              case 4:
                x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP);
                break;
              case 5:
                x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP);
                break;
              case 6:
              case 7:
              default:
                x86emu_fpu_illegal();
                break;
            }
            break;

          default:
            switch (rh) {
              case 0:
                x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset);
                break;
              case 1:
                x86emu_fpu_illegal();
                break;
              case 2:
                x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset);
                break;
              case 3:
                x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset);
                break;
              case 4:
                x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset);
                break;
              case 5:
                x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset);
                break;
              case 6:
                x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset);
                break;
              case 7:
                x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset);
                break;
            }
        }
    }
#else
    (void)destoffset;
    (void)stkelem;
#endif /* X86EMU_FPU_PRESENT */
    DECODE_CLEAR_SEGOVR();
    END_OF_INSTR_NO_TRACE();
}

#ifdef DEBUG

char *x86emu_fpu_op_da_tab[] = {
    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
    "FICOMP\tDWORD PTR ",
    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
    "FIDIVR\tDWORD PTR ",

    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
    "FICOMP\tDWORD PTR ",
    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
    "FIDIVR\tDWORD PTR ",
    
    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
    "FICOMP\tDWORD PTR ",
    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
    "FIDIVR\tDWORD PTR ",

    "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
    "ESC_DA     ", "ESC_DA ", "ESC_DA   ", "ESC_DA ",
};

#endif /* DEBUG */

/* opcode=0xda */
void x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1))
{
    int mod, rl, rh;
    uint destoffset = 0;
    u8 stkelem = 0;

    START_OF_INSTR();
    FETCH_DECODE_MODRM(mod, rh, rl);
    DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
    switch (mod) {
      case 0:
        destoffset = decode_rm00_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 1:
        destoffset = decode_rm01_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 2:
        destoffset = decode_rm10_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 3:           /* register to register */
		stkelem = (u8)rl;
        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
        break;
    }
#ifdef X86EMU_FPU_PRESENT
    switch (mod) {
      case 3:
        x86emu_fpu_illegal();
        break;
      default:
        switch (rh) {
          case 0:
            x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset);
            break;
          case 1:
            x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset);
            break;
          case 2:
            x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset);
            break;
          case 3:
            x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset);
            break;
          case 4:
            x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset);
            break;
          case 5:
            x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset);
            break;
          case 6:
            x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset);
            break;
          case 7:
            x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset);
            break;
        }
    }
#else
    (void)destoffset;
    (void)stkelem;
#endif
    DECODE_CLEAR_SEGOVR();
    END_OF_INSTR_NO_TRACE();
}

#ifdef DEBUG

char *x86emu_fpu_op_db_tab[] = {
    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",

    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",

    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
};

#endif /* DEBUG */

/* opcode=0xdb */
void x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1))
{
    int mod, rl, rh;
    uint destoffset = 0;

    START_OF_INSTR();
    FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
    if (mod != 3) {
        DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl);
    } else if (rh == 4) {       /* === 11 10 0 nnn */
        switch (rl) {
          case 0:
            DECODE_PRINTF("FENI\n");
            break;
          case 1:
            DECODE_PRINTF("FDISI\n");
            break;
          case 2:
            DECODE_PRINTF("FCLEX\n");
            break;
          case 3:
            DECODE_PRINTF("FINIT\n");
            break;
        }
    } else {
        DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl));
    }
#endif /* DEBUG */
    switch (mod) {
      case 0:
        destoffset = decode_rm00_address(rl);
        break;
      case 1:
        destoffset = decode_rm01_address(rl);
        break;
      case 2:
        destoffset = decode_rm10_address(rl);
        break;
      case 3:                   /* register to register */
        break;
    }
#ifdef X86EMU_FPU_PRESENT
    /* execute */
    switch (mod) {
      case 3:
        switch (rh) {
          case 4:
            switch (rl) {
              case 0:
                x86emu_fpu_R_feni();
                break;
              case 1:
                x86emu_fpu_R_fdisi();
                break;
              case 2:
                x86emu_fpu_R_fclex();
                break;
              case 3:
                x86emu_fpu_R_finit();
                break;
              default:
                x86emu_fpu_illegal();
                break;
            }
            break;
          default:
            x86emu_fpu_illegal();
            break;
        }
        break;
      default:
        switch (rh) {
          case 0:
            x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset);
            break;
          case 1:
            x86emu_fpu_illegal();
            break;
          case 2:
            x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset);
            break;
          case 3:
            x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset);
            break;
          case 4:
            x86emu_fpu_illegal();
            break;
          case 5:
            x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset);
            break;
                      case 6:
            x86emu_fpu_illegal();
            break;
          case 7:
            x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset);
            break;
        }
    }
#else
    (void)destoffset;
#endif
    DECODE_CLEAR_SEGOVR();
    END_OF_INSTR_NO_TRACE();
}

#ifdef DEBUG
char *x86emu_fpu_op_dc_tab[] = {
    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
    "FCOMP\tQWORD PTR ",
    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
    "FDIVR\tQWORD PTR ",

    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
    "FCOMP\tQWORD PTR ",
    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
    "FDIVR\tQWORD PTR ",

    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
    "FCOMP\tQWORD PTR ",
    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
    "FDIVR\tQWORD PTR ",

    "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
    "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
};
#endif /* DEBUG */

/* opcode=0xdc */
void x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1))
{
    int mod, rl, rh;
    uint destoffset = 0;
    u8 stkelem = 0;

    START_OF_INSTR();
    FETCH_DECODE_MODRM(mod, rh, rl);
    DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
    switch (mod) {
      case 0:
        destoffset = decode_rm00_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 1:
        destoffset = decode_rm01_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 2:
        destoffset = decode_rm10_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 3:                   /* register to register */
		stkelem = (u8)rl;
        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
        break;
    }
#ifdef X86EMU_FPU_PRESENT
    /* execute */
    switch (mod) {
      case 3:
        switch (rh) {
          case 0:
            x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 1:
            x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 2:
            x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 3:
            x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 4:
            x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 5:
            x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 6:
            x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 7:
            x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP);
            break;
        }
        break;
      default:
        switch (rh) {
          case 0:
            x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset);
            break;
          case 1:
            x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset);
            break;
          case 2:
            x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset);
            break;
          case 3:
            x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset);
            break;
          case 4:
            x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset);
            break;
          case 5:
            x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset);
            break;
          case 6:
            x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset);
            break;
          case 7:
            x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset);
            break;
        }
    }
#else
    (void)destoffset;
    (void)stkelem;
#endif
    DECODE_CLEAR_SEGOVR();
    END_OF_INSTR_NO_TRACE();
}

#ifdef DEBUG

static char *x86emu_fpu_op_dd_tab[] = {
    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",

    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",

    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",

    "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
    "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
};

#endif /* DEBUG */

/* opcode=0xdd */
void x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1))
{
    int mod, rl, rh;
    uint destoffset = 0;
    u8 stkelem = 0;

    START_OF_INSTR();
    FETCH_DECODE_MODRM(mod, rh, rl);
    DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
    switch (mod) {
      case 0:
        destoffset = decode_rm00_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 1:
        destoffset = decode_rm01_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 2:
        destoffset = decode_rm10_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 3:                   /* register to register */
		stkelem = (u8)rl;
        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
        break;
    }
#ifdef X86EMU_FPU_PRESENT
    switch (mod) {
      case 3:
        switch (rh) {
          case 0:
            x86emu_fpu_R_ffree(stkelem);
            break;
          case 1:
            x86emu_fpu_R_fxch(stkelem);
            break;
          case 2:
            x86emu_fpu_R_fst(stkelem);  /* register version */
            break;
          case 3:
            x86emu_fpu_R_fstp(stkelem); /* register version */
            break;
          default:
            x86emu_fpu_illegal();
            break;
        }
        break;
      default:
        switch (rh) {
          case 0:
            x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset);
            break;
          case 1:
            x86emu_fpu_illegal();
            break;
          case 2:
            x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset);
            break;
          case 3:
            x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset);
            break;
          case 4:
            x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset);
            break;
          case 5:
            x86emu_fpu_illegal();
            break;
          case 6:
            x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset);
            break;
          case 7:
            x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset);
            break;
        }
    }
#else
    (void)destoffset;
    (void)stkelem;
#endif
    DECODE_CLEAR_SEGOVR();
    END_OF_INSTR_NO_TRACE();
}

#ifdef DEBUG

static char *x86emu_fpu_op_de_tab[] =
{
    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
    "FICOMP\tWORD PTR ",
    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
    "FIDIVR\tWORD PTR ",

    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
    "FICOMP\tWORD PTR ",
    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
    "FIDIVR\tWORD PTR ",

    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
    "FICOMP\tWORD PTR ",
    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
    "FIDIVR\tWORD PTR ",

    "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
    "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
};

#endif /* DEBUG */

/* opcode=0xde */
void x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1))
{
    int mod, rl, rh;
    uint destoffset = 0;
    u8 stkelem = 0;

    START_OF_INSTR();
    FETCH_DECODE_MODRM(mod, rh, rl);
    DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
    switch (mod) {
      case 0:
        destoffset = decode_rm00_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 1:
        destoffset = decode_rm01_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 2:
        destoffset = decode_rm10_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 3:                   /* register to register */
		stkelem = (u8)rl;
        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
        break;
    }
#ifdef X86EMU_FPU_PRESENT
    switch (mod) {
      case 3:
        switch (rh) {
          case 0:
            x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 1:
            x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 2:
            x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 3:
            if (stkelem == 1)
              x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP);
            else
              x86emu_fpu_illegal();
            break;
          case 4:
            x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 5:
            x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 6:
            x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP);
            break;
          case 7:
            x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP);
            break;
        }
        break;
      default:
        switch (rh) {
          case 0:
            x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset);
            break;
          case 1:
            x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset);
            break;
          case 2:
            x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset);
            break;
          case 3:
            x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset);
            break;
          case 4:
            x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset);
            break;
          case 5:
            x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset);
            break;
          case 6:
            x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset);
            break;
          case 7:
            x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset);
            break;
        }
    }
#else
    (void)destoffset;
    (void)stkelem;
#endif
    DECODE_CLEAR_SEGOVR();
    END_OF_INSTR_NO_TRACE();
}

#ifdef DEBUG

static char *x86emu_fpu_op_df_tab[] = {
    /* mod == 00 */
    "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
    "FISTP\tQWORD PTR ",

    /* mod == 01 */
    "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
    "FISTP\tQWORD PTR ",

    /* mod == 10 */
    "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
    "FISTP\tQWORD PTR ",

    /* mod == 11 */
    "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
    "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
};

#endif /* DEBUG */

/* opcode=0xdf */
void x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1))
{
    int mod, rl, rh;
    uint destoffset = 0;
    u8 stkelem = 0;

    START_OF_INSTR();
    FETCH_DECODE_MODRM(mod, rh, rl);
    DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
    switch (mod) {
      case 0:
        destoffset = decode_rm00_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 1:
        destoffset = decode_rm01_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 2:
        destoffset = decode_rm10_address(rl);
        DECODE_PRINTF("\n");
        break;
      case 3:                   /* register to register */
		stkelem = (u8)rl;
        DECODE_PRINTF2("\tST(%d)\n", stkelem);
        break;
    }
#ifdef X86EMU_FPU_PRESENT
    switch (mod) {
      case 3:
        switch (rh) {
          case 0:
            x86emu_fpu_R_ffree(stkelem);
            break;
          case 1:
            x86emu_fpu_R_fxch(stkelem);
            break;
          case 2:
            x86emu_fpu_R_fst(stkelem);  /* register version */
            break;
          case 3:
            x86emu_fpu_R_fstp(stkelem); /* register version */
            break;
          default:
            x86emu_fpu_illegal();
            break;
        }
        break;
      default:
        switch (rh) {
          case 0:
            x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset);
            break;
          case 1:
            x86emu_fpu_illegal();
            break;
          case 2:
            x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset);
            break;
          case 3:
            x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset);
            break;
          case 4:
            x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset);
            break;
          case 5:
            x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset);
            break;
          case 6:
            x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset);
            break;
          case 7:
            x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset);
            break;
        }
    }
#else
    (void)destoffset;
    (void)stkelem;
#endif
    DECODE_CLEAR_SEGOVR();
    END_OF_INSTR_NO_TRACE();
}

--- NEW FILE: fpu.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Header file for FPU instruction decoding.
*
****************************************************************************/

#ifndef __X86EMU_FPU_H
#define __X86EMU_FPU_H

#ifdef  __cplusplus
extern "C" {            			/* Use "C" linkage when in C++ mode */
#endif

/* these have to be defined, whether 8087 support compiled in or not. */

extern void x86emuOp_esc_coprocess_d8 (u8 op1);
extern void x86emuOp_esc_coprocess_d9 (u8 op1);
extern void x86emuOp_esc_coprocess_da (u8 op1);
extern void x86emuOp_esc_coprocess_db (u8 op1);
extern void x86emuOp_esc_coprocess_dc (u8 op1);
extern void x86emuOp_esc_coprocess_dd (u8 op1);
extern void x86emuOp_esc_coprocess_de (u8 op1);
extern void x86emuOp_esc_coprocess_df (u8 op1);

#ifdef  __cplusplus
}                       			/* End of "C" linkage for C++   	*/
#endif

#endif /* __X86EMU_FPU_H */

--- NEW FILE: fpu_regs.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Header file for FPU register definitions.
*
****************************************************************************/

#ifndef __X86EMU_FPU_REGS_H
#define __X86EMU_FPU_REGS_H

#ifdef X86_FPU_SUPPORT

#ifdef PACK
# pragma PACK
#endif

/* Basic 8087 register can hold any of the following values: */

union x86_fpu_reg_u {
    s8                  tenbytes[10];
    double              dval;
    float               fval;
    s16                 sval;
    s32                 lval;
	};

struct x86_fpu_reg {
	union x86_fpu_reg_u reg;
	char                tag;
	};

/*
 * Since we are not going to worry about the problems of aliasing
 * registers, every time a register is modified, its result type is
 * set in the tag fields for that register.  If some operation
 * attempts to access the type in a way inconsistent with its current
 * storage format, then we flag the operation.  If common, we'll
 * attempt the conversion.
 */

#define  X86_FPU_VALID          0x80
#define  X86_FPU_REGTYP(r)      ((r) & 0x7F)

#define  X86_FPU_WORD           0x0
#define  X86_FPU_SHORT          0x1
#define  X86_FPU_LONG           0x2
#define  X86_FPU_FLOAT          0x3
#define  X86_FPU_DOUBLE         0x4
#define  X86_FPU_LDBL           0x5
#define  X86_FPU_BSD            0x6

#define  X86_FPU_STKTOP  0

struct x86_fpu_registers {
    struct x86_fpu_reg  x86_fpu_stack[8];
    int                 x86_fpu_flags;
    int                 x86_fpu_config;         /* rounding modes, etc. */
    short               x86_fpu_tos, x86_fpu_bos;
	};

#ifdef END_PACK
# pragma END_PACK
#endif

/*
 * There are two versions of the following macro.
 *
 * One version is for opcode D9, for which there are more than 32
 * instructions encoded in the second byte of the opcode.
 *
 * The other version, deals with all the other 7 i87 opcodes, for
 * which there are only 32 strings needed to describe the
 * instructions.
 */

#endif /* X86_FPU_SUPPORT */

#ifdef DEBUG
# define DECODE_PRINTINSTR32(t,mod,rh,rl)     	\
	DECODE_PRINTF(t[(mod<<3)+(rh)]);
# define DECODE_PRINTINSTR256(t,mod,rh,rl)    	\
	DECODE_PRINTF(t[(mod<<6)+(rh<<3)+(rl)]);
#else
# define DECODE_PRINTINSTR32(t,mod,rh,rl)
# define DECODE_PRINTINSTR256(t,mod,rh,rl)
#endif

#endif /* __X86EMU_FPU_REGS_H */

Index: helper_exec.c
===================================================================
RCS file: /cvs/xserver/debrix/hw/xorg/int10/helper_exec.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- helper_exec.c	10 Jun 2004 19:40:22 -0000	1.3
+++ helper_exec.c	16 Jun 2004 00:25:30 -0000	1.4
@@ -25,6 +25,7 @@
 #define _INT10_PRIVATE
 #include "int10Defines.h"
 #include "xf86int10.h"
+#include "xf86x86emu.h"
 
 #if !defined (_PC) && !defined (_PC_PCI)
 static int pciCfg1in(CARD16 addr, CARD32 *val);

--- NEW FILE: ops.c ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
[...11658 lines suppressed...]
/*  0xef */ x86emuOp_out_word_DX_AX,

/*  0xf0 */ x86emuOp_lock,
/*  0xf1 */ x86emuOp_illegal_op,
/*  0xf2 */ x86emuOp_repne,
/*  0xf3 */ x86emuOp_repe,
/*  0xf4 */ x86emuOp_halt,
/*  0xf5 */ x86emuOp_cmc,
/*  0xf6 */ x86emuOp_opcF6_byte_RM,
/*  0xf7 */ x86emuOp_opcF7_word_RM,

/*  0xf8 */ x86emuOp_clc,
/*  0xf9 */ x86emuOp_stc,
/*  0xfa */ x86emuOp_cli,
/*  0xfb */ x86emuOp_sti,
/*  0xfc */ x86emuOp_cld,
/*  0xfd */ x86emuOp_std,
/*  0xfe */ x86emuOp_opcFE_byte_RM,
/*  0xff */ x86emuOp_opcFF_word_RM,
};

--- NEW FILE: ops.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Header file for operand decoding functions.
*
****************************************************************************/

#ifndef __X86EMU_OPS_H
#define __X86EMU_OPS_H

extern void (*x86emu_optab[0x100])(u8 op1);
extern void (*x86emu_optab2[0x100])(u8 op2);

#endif /* __X86EMU_OPS_H */

--- NEW FILE: ops2.c ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
[...2765 lines suppressed...]
/*  0xee */ x86emuOp2_illegal_op,
/*  0xef */ x86emuOp2_illegal_op,

/*  0xf0 */ x86emuOp2_illegal_op,
/*  0xf1 */ x86emuOp2_illegal_op,
/*  0xf2 */ x86emuOp2_illegal_op,
/*  0xf3 */ x86emuOp2_illegal_op,
/*  0xf4 */ x86emuOp2_illegal_op,
/*  0xf5 */ x86emuOp2_illegal_op,
/*  0xf6 */ x86emuOp2_illegal_op,
/*  0xf7 */ x86emuOp2_illegal_op,
/*  0xf8 */ x86emuOp2_illegal_op,
/*  0xf9 */ x86emuOp2_illegal_op,
/*  0xfa */ x86emuOp2_illegal_op,
/*  0xfb */ x86emuOp2_illegal_op,
/*  0xfc */ x86emuOp2_illegal_op,
/*  0xfd */ x86emuOp2_illegal_op,
/*  0xfe */ x86emuOp2_illegal_op,
/*  0xff */ x86emuOp2_illegal_op,
};

--- NEW FILE: prim_asm.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		Watcom C++ 10.6 or later
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Inline assembler versions of the primitive operand
*				functions for faster performance. At the moment this is
*				x86 inline assembler, but these functions could be replaced
*				with native inline assembler for each supported processor
*				platform.
*
****************************************************************************/

#ifndef	__X86EMU_PRIM_ASM_H
#define	__X86EMU_PRIM_ASM_H

#ifdef	__WATCOMC__

#ifndef	VALIDATE
#define	__HAVE_INLINE_ASSEMBLER__
#endif

u32		get_flags_asm(void);
#pragma aux get_flags_asm =			\
	"pushf"                         \
	"pop	eax"                  	\
	value [eax]                     \
	modify exact [eax];

u16     aaa_word_asm(u32 *flags,u16 d);
#pragma aux aaa_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"aaa"                  			\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] 				\
	value [ax]                      \
	modify exact [ax];

u16     aas_word_asm(u32 *flags,u16 d);
#pragma aux aas_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"aas"                  			\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] 				\
	value [ax]                      \
	modify exact [ax];

u16     aad_word_asm(u32 *flags,u16 d);
#pragma aux aad_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"aad"                  			\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] 				\
	value [ax]                      \
	modify exact [ax];

u16     aam_word_asm(u32 *flags,u8 d);
#pragma aux aam_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"aam"                  			\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] 				\
	value [ax]                      \
	modify exact [ax];

u8      adc_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux adc_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"adc	al,bl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [bl]            \
	value [al]                      \
	modify exact [al bl];

u16     adc_word_asm(u32 *flags,u16 d, u16 s);
#pragma aux adc_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"adc	ax,bx"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [bx]            \
	value [ax]                      \
	modify exact [ax bx];

u32     adc_long_asm(u32 *flags,u32 d, u32 s);
#pragma aux adc_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"adc	eax,ebx"                \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [ebx]          \
	value [eax]                     \
	modify exact [eax ebx];

u8      add_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux add_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"add	al,bl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [bl]            \
	value [al]                      \
	modify exact [al bl];

u16     add_word_asm(u32 *flags,u16 d, u16 s);
#pragma aux add_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"add	ax,bx"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [bx]            \
	value [ax]                      \
	modify exact [ax bx];

u32     add_long_asm(u32 *flags,u32 d, u32 s);
#pragma aux add_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"add	eax,ebx"                \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [ebx]          \
	value [eax]                     \
	modify exact [eax ebx];

u8      and_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux and_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"and	al,bl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [bl]            \
	value [al]                      \
	modify exact [al bl];

u16     and_word_asm(u32 *flags,u16 d, u16 s);
#pragma aux and_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"and	ax,bx"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [bx]            \
	value [ax]                      \
	modify exact [ax bx];

u32     and_long_asm(u32 *flags,u32 d, u32 s);
#pragma aux and_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"and	eax,ebx"                \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [ebx]          \
	value [eax]                     \
	modify exact [eax ebx];

u8      cmp_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux cmp_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"cmp	al,bl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [bl]            \
	value [al]                      \
	modify exact [al bl];

u16     cmp_word_asm(u32 *flags,u16 d, u16 s);
#pragma aux cmp_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"cmp	ax,bx"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [bx]            \
	value [ax]                      \
	modify exact [ax bx];

u32     cmp_long_asm(u32 *flags,u32 d, u32 s);
#pragma aux cmp_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"cmp	eax,ebx"                \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [ebx]          \
	value [eax]                     \
	modify exact [eax ebx];

u8      daa_byte_asm(u32 *flags,u8 d);
#pragma aux daa_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"daa"                  			\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al]            		\
	value [al]                      \
	modify exact [al];

u8      das_byte_asm(u32 *flags,u8 d);
#pragma aux das_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"das"                  			\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al]            		\
	value [al]                      \
	modify exact [al];

u8      dec_byte_asm(u32 *flags,u8 d);
#pragma aux dec_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"dec	al"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al]            		\
	value [al]                      \
	modify exact [al];

u16     dec_word_asm(u32 *flags,u16 d);
#pragma aux dec_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"dec	ax"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax]            		\
	value [ax]                      \
	modify exact [ax];

u32     dec_long_asm(u32 *flags,u32 d);
#pragma aux dec_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"dec	eax"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax]          		\
	value [eax]                     \
	modify exact [eax];

u8      inc_byte_asm(u32 *flags,u8 d);
#pragma aux inc_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"inc	al"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al]            		\
	value [al]                      \
	modify exact [al];

u16     inc_word_asm(u32 *flags,u16 d);
#pragma aux inc_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"inc	ax"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax]            		\
	value [ax]                      \
	modify exact [ax];

u32     inc_long_asm(u32 *flags,u32 d);
#pragma aux inc_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"inc	eax"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax]          		\
	value [eax]                     \
	modify exact [eax];

u8      or_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux or_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"or	al,bl"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [bl]            \
	value [al]                      \
	modify exact [al bl];

u16     or_word_asm(u32 *flags,u16 d, u16 s);
#pragma aux or_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"or	ax,bx"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [bx]            \
	value [ax]                      \
	modify exact [ax bx];

u32     or_long_asm(u32 *flags,u32 d, u32 s);
#pragma aux or_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"or	eax,ebx"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [ebx]          \
	value [eax]                     \
	modify exact [eax ebx];

u8      neg_byte_asm(u32 *flags,u8 d);
#pragma aux neg_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"neg	al"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al]            		\
	value [al]                      \
	modify exact [al];

u16     neg_word_asm(u32 *flags,u16 d);
#pragma aux neg_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"neg	ax"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax]            		\
	value [ax]                      \
	modify exact [ax];

u32     neg_long_asm(u32 *flags,u32 d);
#pragma aux neg_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"neg	eax"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax]          		\
	value [eax]                     \
	modify exact [eax];

u8      not_byte_asm(u32 *flags,u8 d);
#pragma aux not_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"not	al"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al]            		\
	value [al]                      \
	modify exact [al];

u16     not_word_asm(u32 *flags,u16 d);
#pragma aux not_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"not	ax"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax]            		\
	value [ax]                      \
	modify exact [ax];

u32     not_long_asm(u32 *flags,u32 d);
#pragma aux not_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"not	eax"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax]          		\
	value [eax]                     \
	modify exact [eax];

u8      rcl_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux rcl_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"rcl	al,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [cl]            \
	value [al]                      \
	modify exact [al cl];

u16     rcl_word_asm(u32 *flags,u16 d, u8 s);
#pragma aux rcl_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"rcl	ax,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [cl]            \
	value [ax]                      \
	modify exact [ax cl];

u32     rcl_long_asm(u32 *flags,u32 d, u8 s);
#pragma aux rcl_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"rcl	eax,cl"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [cl]          	\
	value [eax]                     \
	modify exact [eax cl];

u8      rcr_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux rcr_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"rcr	al,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [cl]            \
	value [al]                      \
	modify exact [al cl];

u16     rcr_word_asm(u32 *flags,u16 d, u8 s);
#pragma aux rcr_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"rcr	ax,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [cl]            \
	value [ax]                      \
	modify exact [ax cl];

u32     rcr_long_asm(u32 *flags,u32 d, u8 s);
#pragma aux rcr_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"rcr	eax,cl"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [cl]          	\
	value [eax]                     \
	modify exact [eax cl];

u8      rol_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux rol_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"rol	al,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [cl]            \
	value [al]                      \
	modify exact [al cl];

u16     rol_word_asm(u32 *flags,u16 d, u8 s);
#pragma aux rol_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"rol	ax,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [cl]            \
	value [ax]                      \
	modify exact [ax cl];

u32     rol_long_asm(u32 *flags,u32 d, u8 s);
#pragma aux rol_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"rol	eax,cl"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [cl]          	\
	value [eax]                     \
	modify exact [eax cl];

u8      ror_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux ror_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"ror	al,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [cl]            \
	value [al]                      \
	modify exact [al cl];

u16     ror_word_asm(u32 *flags,u16 d, u8 s);
#pragma aux ror_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"ror	ax,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [cl]            \
	value [ax]                      \
	modify exact [ax cl];

u32     ror_long_asm(u32 *flags,u32 d, u8 s);
#pragma aux ror_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"ror	eax,cl"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [cl]          	\
	value [eax]                     \
	modify exact [eax cl];

u8      shl_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux shl_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"shl	al,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [cl]            \
	value [al]                      \
	modify exact [al cl];

u16     shl_word_asm(u32 *flags,u16 d, u8 s);
#pragma aux shl_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"shl	ax,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [cl]            \
	value [ax]                      \
	modify exact [ax cl];

u32     shl_long_asm(u32 *flags,u32 d, u8 s);
#pragma aux shl_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"shl	eax,cl"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [cl]          	\
	value [eax]                     \
	modify exact [eax cl];

u8      shr_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux shr_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"shr	al,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [cl]            \
	value [al]                      \
	modify exact [al cl];

u16     shr_word_asm(u32 *flags,u16 d, u8 s);
#pragma aux shr_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"shr	ax,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [cl]            \
	value [ax]                      \
	modify exact [ax cl];

u32     shr_long_asm(u32 *flags,u32 d, u8 s);
#pragma aux shr_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"shr	eax,cl"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [cl]          	\
	value [eax]                     \
	modify exact [eax cl];

u8      sar_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux sar_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"sar	al,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [cl]            \
	value [al]                      \
	modify exact [al cl];

u16     sar_word_asm(u32 *flags,u16 d, u8 s);
#pragma aux sar_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"sar	ax,cl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [cl]            \
	value [ax]                      \
	modify exact [ax cl];

u32     sar_long_asm(u32 *flags,u32 d, u8 s);
#pragma aux sar_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"sar	eax,cl"                	\
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [cl]          	\
	value [eax]                     \
	modify exact [eax cl];

u16		shld_word_asm(u32 *flags,u16 d, u16 fill, u8 s);
#pragma aux shld_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"shld	ax,dx,cl"               \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [dx] [cl]       \
	value [ax]                      \
	modify exact [ax dx cl];

u32     shld_long_asm(u32 *flags,u32 d, u32 fill, u8 s);
#pragma aux shld_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"shld	eax,edx,cl"             \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [edx] [cl]     \
	value [eax]                     \
	modify exact [eax edx cl];

u16		shrd_word_asm(u32 *flags,u16 d, u16 fill, u8 s);
#pragma aux shrd_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"shrd	ax,dx,cl"               \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [dx] [cl]       \
	value [ax]                      \
	modify exact [ax dx cl];

u32     shrd_long_asm(u32 *flags,u32 d, u32 fill, u8 s);
#pragma aux shrd_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"shrd	eax,edx,cl"             \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [edx] [cl]     \
	value [eax]                     \
	modify exact [eax edx cl];

u8      sbb_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux sbb_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"sbb	al,bl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [bl]            \
	value [al]                      \
	modify exact [al bl];

u16     sbb_word_asm(u32 *flags,u16 d, u16 s);
#pragma aux sbb_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"sbb	ax,bx"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [bx]            \
	value [ax]                      \
	modify exact [ax bx];

u32     sbb_long_asm(u32 *flags,u32 d, u32 s);
#pragma aux sbb_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"sbb	eax,ebx"                \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [ebx]          \
	value [eax]                     \
	modify exact [eax ebx];

u8      sub_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux sub_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"sub	al,bl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [bl]            \
	value [al]                      \
	modify exact [al bl];

u16     sub_word_asm(u32 *flags,u16 d, u16 s);
#pragma aux sub_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"sub	ax,bx"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [bx]            \
	value [ax]                      \
	modify exact [ax bx];

u32     sub_long_asm(u32 *flags,u32 d, u32 s);
#pragma aux sub_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"sub	eax,ebx"                \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [ebx]          \
	value [eax]                     \
	modify exact [eax ebx];

void	test_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux test_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"test	al,bl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [bl]            \
	modify exact [al bl];

void	test_word_asm(u32 *flags,u16 d, u16 s);
#pragma aux test_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"test	ax,bx"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [bx]            \
	modify exact [ax bx];

void	test_long_asm(u32 *flags,u32 d, u32 s);
#pragma aux test_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"test	eax,ebx"                \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [ebx]          \
	modify exact [eax ebx];

u8      xor_byte_asm(u32 *flags,u8 d, u8 s);
#pragma aux xor_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"xor	al,bl"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [al] [bl]            \
	value [al]                      \
	modify exact [al bl];

u16     xor_word_asm(u32 *flags,u16 d, u16 s);
#pragma aux xor_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"xor	ax,bx"                  \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [ax] [bx]            \
	value [ax]                      \
	modify exact [ax bx];

u32     xor_long_asm(u32 *flags,u32 d, u32 s);
#pragma aux xor_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"xor	eax,ebx"                \
	"pushf"                         \
	"pop	[edi]"            		\
	parm [edi] [eax] [ebx]          \
	value [eax]                     \
	modify exact [eax ebx];

void    imul_byte_asm(u32 *flags,u16 *ax,u8 d,u8 s);
#pragma aux imul_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"imul	bl"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],ax"				\
	parm [edi] [esi] [al] [bl]      \
	modify exact [esi ax bl];

void    imul_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 d,u16 s);
#pragma aux imul_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"imul	bx"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],ax"				\
	"mov	[ecx],dx"				\
	parm [edi] [esi] [ecx] [ax] [bx]\
	modify exact [esi edi ax bx dx];

void    imul_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 d,u32 s);
#pragma aux imul_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"imul	ebx"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],eax"				\
	"mov	[ecx],edx"				\
	parm [edi] [esi] [ecx] [eax] [ebx] \
	modify exact [esi edi eax ebx edx];

void    mul_byte_asm(u32 *flags,u16 *ax,u8 d,u8 s);
#pragma aux mul_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"mul	bl"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],ax"				\
	parm [edi] [esi] [al] [bl]      \
	modify exact [esi ax bl];

void    mul_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 d,u16 s);
#pragma aux mul_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"mul	bx"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],ax"				\
	"mov	[ecx],dx"				\
	parm [edi] [esi] [ecx] [ax] [bx]\
	modify exact [esi edi ax bx dx];

void    mul_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 d,u32 s);
#pragma aux mul_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"mul	ebx"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],eax"				\
	"mov	[ecx],edx"				\
	parm [edi] [esi] [ecx] [eax] [ebx] \
	modify exact [esi edi eax ebx edx];

void	idiv_byte_asm(u32 *flags,u8 *al,u8 *ah,u16 d,u8 s);
#pragma aux idiv_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"idiv	bl"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],al"				\
	"mov	[ecx],ah"				\
	parm [edi] [esi] [ecx] [ax] [bl]\
	modify exact [esi edi ax bl];

void	idiv_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 dlo,u16 dhi,u16 s);
#pragma aux idiv_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"idiv	bx"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],ax"				\
	"mov	[ecx],dx"				\
	parm [edi] [esi] [ecx] [ax] [dx] [bx]\
	modify exact [esi edi ax dx bx];

void	idiv_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 dlo,u32 dhi,u32 s);
#pragma aux idiv_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"idiv	ebx"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],eax"				\
	"mov	[ecx],edx"				\
	parm [edi] [esi] [ecx] [eax] [edx] [ebx]\
	modify exact [esi edi eax edx ebx];

void	div_byte_asm(u32 *flags,u8 *al,u8 *ah,u16 d,u8 s);
#pragma aux div_byte_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"div	bl"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],al"				\
	"mov	[ecx],ah"				\
	parm [edi] [esi] [ecx] [ax] [bl]\
	modify exact [esi edi ax bl];

void	div_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 dlo,u16 dhi,u16 s);
#pragma aux div_word_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"div	bx"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],ax"				\
	"mov	[ecx],dx"				\
	parm [edi] [esi] [ecx] [ax] [dx] [bx]\
	modify exact [esi edi ax dx bx];

void	div_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 dlo,u32 dhi,u32 s);
#pragma aux div_long_asm =			\
	"push	[edi]"            		\
	"popf"                         	\
	"div	ebx"                  	\
	"pushf"                         \
	"pop	[edi]"            		\
	"mov	[esi],eax"				\
	"mov	[ecx],edx"				\
	parm [edi] [esi] [ecx] [eax] [edx] [ebx]\
	modify exact [esi edi eax edx ebx];

#endif

#endif /* __X86EMU_PRIM_ASM_H */

--- NEW FILE: prim_ops.c ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
[...2615 lines suppressed...]
	return res;
}

/****************************************************************************
REMARKS:
Pops a long from the stack.

NOTE: Do not inline this, as (*sys_rdX) is already inline!
****************************************************************************/
u32 pop_long(void)
{
    register u32 res;

DB(	if (CHECK_SP_ACCESS())
	  x86emu_check_sp_access();)
	res = (*sys_rdl)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP);
	M.x86.R_SP += 4;
    return res;
}


--- NEW FILE: prim_ops.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Header file for primitive operation functions.
*
****************************************************************************/

#ifndef __X86EMU_PRIM_OPS_H
#define __X86EMU_PRIM_OPS_H

#ifdef  __cplusplus
extern "C" {            			/* Use "C" linkage when in C++ mode */
#endif

u16     aaa_word (u16 d);
u16     aas_word (u16 d);
u16     aad_word (u16 d);
u16     aam_word (u8 d);
u8      adc_byte (u8 d, u8 s);
u16     adc_word (u16 d, u16 s);
u32     adc_long (u32 d, u32 s);
u8      add_byte (u8 d, u8 s);
u16     add_word (u16 d, u16 s);
u32     add_long (u32 d, u32 s);
u8      and_byte (u8 d, u8 s);
u16     and_word (u16 d, u16 s);
u32     and_long (u32 d, u32 s);
u8      cmp_byte (u8 d, u8 s);
u16     cmp_word (u16 d, u16 s);
u32     cmp_long (u32 d, u32 s);
u8      daa_byte (u8 d);
u8      das_byte (u8 d);
u8      dec_byte (u8 d);
u16     dec_word (u16 d);
u32     dec_long (u32 d);
u8      inc_byte (u8 d);
u16     inc_word (u16 d);
u32     inc_long (u32 d);
u8      or_byte (u8 d, u8 s);
u16     or_word (u16 d, u16 s);
u32     or_long (u32 d, u32 s);
u8      neg_byte (u8 s);
u16     neg_word (u16 s);
u32     neg_long (u32 s);
u8      not_byte (u8 s);
u16     not_word (u16 s);
u32     not_long (u32 s);
u8      rcl_byte (u8 d, u8 s);
u16     rcl_word (u16 d, u8 s);
u32     rcl_long (u32 d, u8 s);
u8      rcr_byte (u8 d, u8 s);
u16     rcr_word (u16 d, u8 s);
u32     rcr_long (u32 d, u8 s);
u8      rol_byte (u8 d, u8 s);
u16     rol_word (u16 d, u8 s);
u32     rol_long (u32 d, u8 s);
u8      ror_byte (u8 d, u8 s);
u16     ror_word (u16 d, u8 s);
u32     ror_long (u32 d, u8 s);
u8      shl_byte (u8 d, u8 s);
u16     shl_word (u16 d, u8 s);
u32     shl_long (u32 d, u8 s);
u8      shr_byte (u8 d, u8 s);
u16     shr_word (u16 d, u8 s);
u32     shr_long (u32 d, u8 s);
u8      sar_byte (u8 d, u8 s);
u16     sar_word (u16 d, u8 s);
u32     sar_long (u32 d, u8 s);
u16     shld_word (u16 d, u16 fill, u8 s);
u32     shld_long (u32 d, u32 fill, u8 s);
u16     shrd_word (u16 d, u16 fill, u8 s);
u32     shrd_long (u32 d, u32 fill, u8 s);
u8      sbb_byte (u8 d, u8 s);
u16     sbb_word (u16 d, u16 s);
u32     sbb_long (u32 d, u32 s);
u8      sub_byte (u8 d, u8 s);
u16     sub_word (u16 d, u16 s);
u32     sub_long (u32 d, u32 s);
void    test_byte (u8 d, u8 s);
void    test_word (u16 d, u16 s);
void    test_long (u32 d, u32 s);
u8      xor_byte (u8 d, u8 s);
u16     xor_word (u16 d, u16 s);
u32     xor_long (u32 d, u32 s);
void    imul_byte (u8 s);
void    imul_word (u16 s);
void    imul_long (u32 s);
void 	imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s);
void    mul_byte (u8 s);
void    mul_word (u16 s);
void    mul_long (u32 s);
void    idiv_byte (u8 s);
void    idiv_word (u16 s);
void    idiv_long (u32 s);
void    div_byte (u8 s);
void    div_word (u16 s);
void    div_long (u32 s);
void    ins (int size);
void    outs (int size);
u16     mem_access_word (int addr);
void    push_word (u16 w);
void    push_long (u32 w);
u16     pop_word (void);
u32		pop_long (void);

#ifdef  __cplusplus
}                       			/* End of "C" linkage for C++   	*/
#endif

#endif /* __X86EMU_PRIM_OPS_H */

--- NEW FILE: regs.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Header file for x86 register definitions.
*
****************************************************************************/

#ifndef __X86EMU_REGS_H
#define __X86EMU_REGS_H

/*---------------------- Macros and type definitions ----------------------*/

#ifdef PACK
# pragma PACK
#endif

/*
 * General EAX, EBX, ECX, EDX type registers.  Note that for
 * portability, and speed, the issue of byte swapping is not addressed
 * in the registers.  All registers are stored in the default format
 * available on the host machine.  The only critical issue is that the
 * registers should line up EXACTLY in the same manner as they do in
 * the 386.  That is:
 *
 * EAX & 0xff  === AL
 * EAX & 0xffff == AX
 *
 * etc.  The result is that alot of the calculations can then be
 * done using the native instruction set fully.
 */

#ifdef	__BIG_ENDIAN__

typedef struct {
    u32 e_reg;
	} I32_reg_t;

typedef struct {
	u16 filler0, x_reg;
	} I16_reg_t;

typedef struct {
	u8 filler0, filler1, h_reg, l_reg;
	} I8_reg_t;

#else /* !__BIG_ENDIAN__ */

typedef struct {
    u32 e_reg;
	} I32_reg_t;

typedef struct {
	u16 x_reg;
	} I16_reg_t;

typedef struct {
	u8 l_reg, h_reg;
	} I8_reg_t;

#endif /* BIG_ENDIAN */

typedef union {
	I32_reg_t   I32_reg;
	I16_reg_t   I16_reg;
	I8_reg_t    I8_reg;
	} i386_general_register;

struct i386_general_regs {
	i386_general_register A, B, C, D;
	};

typedef struct i386_general_regs Gen_reg_t;

struct i386_special_regs {
	i386_general_register SP, BP, SI, DI, IP;
	u32 FLAGS;
	};

/*  
 * Segment registers here represent the 16 bit quantities
 * CS, DS, ES, SS.
 */

struct i386_segment_regs {
    u16 CS, DS, SS, ES, FS, GS;
	};

/* 8 bit registers */
#define R_AH  gen.A.I8_reg.h_reg
#define R_AL  gen.A.I8_reg.l_reg
#define R_BH  gen.B.I8_reg.h_reg
#define R_BL  gen.B.I8_reg.l_reg
#define R_CH  gen.C.I8_reg.h_reg
#define R_CL  gen.C.I8_reg.l_reg
#define R_DH  gen.D.I8_reg.h_reg
#define R_DL  gen.D.I8_reg.l_reg

/* 16 bit registers */
#define R_AX  gen.A.I16_reg.x_reg
#define R_BX  gen.B.I16_reg.x_reg
#define R_CX  gen.C.I16_reg.x_reg
#define R_DX  gen.D.I16_reg.x_reg

/* 32 bit extended registers */
#define R_EAX  gen.A.I32_reg.e_reg
#define R_EBX  gen.B.I32_reg.e_reg
#define R_ECX  gen.C.I32_reg.e_reg
#define R_EDX  gen.D.I32_reg.e_reg

/* special registers */
#define R_SP  spc.SP.I16_reg.x_reg
#define R_BP  spc.BP.I16_reg.x_reg
#define R_SI  spc.SI.I16_reg.x_reg
#define R_DI  spc.DI.I16_reg.x_reg
#define R_IP  spc.IP.I16_reg.x_reg
#define R_FLG spc.FLAGS

/* special registers */
#define R_SP  spc.SP.I16_reg.x_reg
#define R_BP  spc.BP.I16_reg.x_reg
#define R_SI  spc.SI.I16_reg.x_reg
#define R_DI  spc.DI.I16_reg.x_reg
#define R_IP  spc.IP.I16_reg.x_reg
#define R_FLG spc.FLAGS

/* special registers */
#define R_ESP  spc.SP.I32_reg.e_reg
#define R_EBP  spc.BP.I32_reg.e_reg
#define R_ESI  spc.SI.I32_reg.e_reg
#define R_EDI  spc.DI.I32_reg.e_reg
#define R_EIP  spc.IP.I32_reg.e_reg
#define R_EFLG spc.FLAGS

/* segment registers */
#define R_CS  seg.CS
#define R_DS  seg.DS
#define R_SS  seg.SS
#define R_ES  seg.ES
#define R_FS  seg.FS
#define R_GS  seg.GS

/* flag conditions   */
#define FB_CF 0x0001            /* CARRY flag  */
#define FB_PF 0x0004            /* PARITY flag */
#define FB_AF 0x0010            /* AUX  flag   */
#define FB_ZF 0x0040            /* ZERO flag   */
#define FB_SF 0x0080            /* SIGN flag   */
#define FB_TF 0x0100            /* TRAP flag   */
#define FB_IF 0x0200            /* INTERRUPT ENABLE flag */
#define FB_DF 0x0400            /* DIR flag    */
#define FB_OF 0x0800            /* OVERFLOW flag */

/* 80286 and above always have bit#1 set */
#define F_ALWAYS_ON  (0x0002)   /* flag bits always on */

/*
 * Define a mask for only those flag bits we will ever pass back 
 * (via PUSHF) 
 */
#define F_MSK (FB_CF|FB_PF|FB_AF|FB_ZF|FB_SF|FB_TF|FB_IF|FB_DF|FB_OF)

/* following bits masked in to a 16bit quantity */

#define F_CF 0x0001             /* CARRY flag  */
#define F_PF 0x0004             /* PARITY flag */
#define F_AF 0x0010             /* AUX  flag   */
#define F_ZF 0x0040             /* ZERO flag   */
#define F_SF 0x0080             /* SIGN flag   */
#define F_TF 0x0100             /* TRAP flag   */
#define F_IF 0x0200             /* INTERRUPT ENABLE flag */
#define F_DF 0x0400             /* DIR flag    */
#define F_OF 0x0800             /* OVERFLOW flag */

#define TOGGLE_FLAG(flag)     	(M.x86.R_FLG ^= (flag))
#define SET_FLAG(flag)        	(M.x86.R_FLG |= (flag))
#define CLEAR_FLAG(flag)      	(M.x86.R_FLG &= ~(flag))
#define ACCESS_FLAG(flag)     	(M.x86.R_FLG & (flag))
#define CLEARALL_FLAG(m)    	(M.x86.R_FLG = 0)

#define CONDITIONAL_SET_FLAG(COND,FLAG) \
  if (COND) SET_FLAG(FLAG); else CLEAR_FLAG(FLAG)

#define F_PF_CALC 0x010000      /* PARITY flag has been calced    */
#define F_ZF_CALC 0x020000      /* ZERO flag has been calced      */
#define F_SF_CALC 0x040000      /* SIGN flag has been calced      */

#define F_ALL_CALC      0xff0000        /* All have been calced   */

/*
 * Emulator machine state.
 * Segment usage control.
 */
#define SYSMODE_SEG_DS_SS       0x00000001
#define SYSMODE_SEGOVR_CS       0x00000002
#define SYSMODE_SEGOVR_DS       0x00000004
#define SYSMODE_SEGOVR_ES       0x00000008
#define SYSMODE_SEGOVR_FS       0x00000010
#define SYSMODE_SEGOVR_GS       0x00000020
#define SYSMODE_SEGOVR_SS       0x00000040
#define SYSMODE_PREFIX_REPE     0x00000080
#define SYSMODE_PREFIX_REPNE    0x00000100
#define SYSMODE_PREFIX_DATA     0x00000200
#define SYSMODE_PREFIX_ADDR     0x00000400
#define SYSMODE_INTR_PENDING    0x10000000
#define SYSMODE_EXTRN_INTR      0x20000000
#define SYSMODE_HALTED          0x40000000

#define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS      | \
						 SYSMODE_SEGOVR_CS      | \
						 SYSMODE_SEGOVR_DS      | \
						 SYSMODE_SEGOVR_ES      | \
						 SYSMODE_SEGOVR_FS      | \
						 SYSMODE_SEGOVR_GS      | \
						 SYSMODE_SEGOVR_SS)
#define SYSMODE_CLRMASK (SYSMODE_SEG_DS_SS      | \
						 SYSMODE_SEGOVR_CS      | \
						 SYSMODE_SEGOVR_DS      | \
						 SYSMODE_SEGOVR_ES      | \
						 SYSMODE_SEGOVR_FS      | \
						 SYSMODE_SEGOVR_GS      | \
						 SYSMODE_SEGOVR_SS      | \
						 SYSMODE_PREFIX_DATA    | \
						 SYSMODE_PREFIX_ADDR)

#define  INTR_SYNCH           0x1
#define  INTR_ASYNCH          0x2
#define  INTR_HALTED          0x4

typedef struct {
    struct i386_general_regs    gen;
    struct i386_special_regs    spc;
    struct i386_segment_regs    seg;
    /*
     * MODE contains information on:
     *  REPE prefix             2 bits  repe,repne
     *  SEGMENT overrides       5 bits  normal,DS,SS,CS,ES
     *  Delayed flag set        3 bits  (zero, signed, parity)
     *  reserved                6 bits
     *  interrupt #             8 bits  instruction raised interrupt
     *  BIOS video segregs      4 bits  
     *  Interrupt Pending       1 bits  
     *  Extern interrupt        1 bits
     *  Halted                  1 bits
     */
    u32                         mode;
    volatile int                intr;   /* mask of pending interrupts */
	int                         debug;
#ifdef DEBUG
	int                         check;
    u16                         saved_ip;
    u16                         saved_cs;
    int                         enc_pos;
    int                         enc_str_pos;
    char                        decode_buf[32]; /* encoded byte stream  */
    char                        decoded_buf[256]; /* disassembled strings */
#endif
    u8                          intno;
    u8                          __pad[3];
	} X86EMU_regs;

/****************************************************************************
REMARKS:
Structure maintaining the emulator machine state.

MEMBERS:
mem_base		- Base real mode memory for the emulator
mem_size		- Size of the real mode memory block for the emulator
private			- private data pointer
x86			- X86 registers
****************************************************************************/
typedef struct {
	unsigned long	mem_base;
	unsigned long	mem_size;
	void*        	private;
	X86EMU_regs		x86;
	} X86EMU_sysEnv;

#ifdef END_PACK
# pragma END_PACK
#endif

/*----------------------------- Global Variables --------------------------*/

#ifdef  __cplusplus
extern "C" {            			/* Use "C" linkage when in C++ mode */
#endif

/* Global emulator machine state.
 *
 * We keep it global to avoid pointer dereferences in the code for speed.
 */

extern    X86EMU_sysEnv	_X86EMU_env;
#define   M             _X86EMU_env

/*-------------------------- Function Prototypes --------------------------*/

/* Function to log information at runtime */

void	printk(const char *fmt, ...);

#ifdef  __cplusplus
}                       			/* End of "C" linkage for C++   	*/
#endif

#endif /* __X86EMU_REGS_H */

--- NEW FILE: sys.c ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  This file includes subroutines which are related to
*				programmed I/O and memory access. Included in this module
*				are default functions with limited usefulness. For real
*				uses these functions will most likely be overriden by the
*				user library.
*
****************************************************************************/

#include "x86emu.h"
#include "x86emui.h"
#include "regs.h"
#include "debug.h"
#include "prim_ops.h"
#ifndef NO_SYS_HEADERS
#include <string.h>
#endif                                                                                           
/*------------------------- Global Variables ------------------------------*/

X86EMU_sysEnv		_X86EMU_env;		/* Global emulator machine state */
X86EMU_intrFuncs	_X86EMU_intrTab[256];

/*----------------------------- Implementation ----------------------------*/
#if defined(__alpha__) || defined(__alpha)
/* to cope with broken egcs-1.1.2 :-(((( */

#define ALPHA_UALOADS
/*
 * inline functions to do unaligned accesses
 * from linux/include/asm-alpha/unaligned.h
 */

/*
 * EGCS 1.1 knows about arbitrary unaligned loads.  Define some
 * packed structures to talk about such things with.
 */

#if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91))
struct __una_u64 { unsigned long  x __attribute__((packed)); };
struct __una_u32 { unsigned int   x __attribute__((packed)); };
struct __una_u16 { unsigned short x __attribute__((packed)); };
#endif

static __inline__ unsigned long ldq_u(unsigned long * r11)
{
#if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91))
	const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
	return ptr->x;
#else
	unsigned long r1,r2;
	__asm__("ldq_u %0,%3\n\t"
		"ldq_u %1,%4\n\t"
		"extql %0,%2,%0\n\t"
		"extqh %1,%2,%1"
		:"=&r" (r1), "=&r" (r2)
		:"r" (r11),
		 "m" (*r11),
		 "m" (*(const unsigned long *)(7+(char *) r11)));
	return r1 | r2;
#endif
}

static __inline__ unsigned long ldl_u(unsigned int * r11)
{
#if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91))
	const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
	return ptr->x;
#else
	unsigned long r1,r2;
	__asm__("ldq_u %0,%3\n\t"
		"ldq_u %1,%4\n\t"
		"extll %0,%2,%0\n\t"
		"extlh %1,%2,%1"
		:"=&r" (r1), "=&r" (r2)
		:"r" (r11),
		 "m" (*r11),
		 "m" (*(const unsigned long *)(3+(char *) r11)));
	return r1 | r2;
#endif
}

static __inline__ unsigned long ldw_u(unsigned short * r11)
{
#if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91))
	const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
	return ptr->x;
#else
	unsigned long r1,r2;
	__asm__("ldq_u %0,%3\n\t"
		"ldq_u %1,%4\n\t"
		"extwl %0,%2,%0\n\t"
		"extwh %1,%2,%1"
		:"=&r" (r1), "=&r" (r2)
		:"r" (r11),
		 "m" (*r11),
		 "m" (*(const unsigned long *)(1+(char *) r11)));
	return r1 | r2;
#endif
}

/*
 * Elemental unaligned stores 
 */

static __inline__ void stq_u(unsigned long r5, unsigned long * r11)
{
#if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91))
	struct __una_u64 *ptr = (struct __una_u64 *) r11;
	ptr->x = r5;
#else
	unsigned long r1,r2,r3,r4;

	__asm__("ldq_u %3,%1\n\t"
		"ldq_u %2,%0\n\t"
		"insqh %6,%7,%5\n\t"
		"insql %6,%7,%4\n\t"
		"mskqh %3,%7,%3\n\t"
		"mskql %2,%7,%2\n\t"
		"bis %3,%5,%3\n\t"
		"bis %2,%4,%2\n\t"
		"stq_u %3,%1\n\t"
		"stq_u %2,%0"
		:"=m" (*r11),
		 "=m" (*(unsigned long *)(7+(char *) r11)),
		 "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4)
		:"r" (r5), "r" (r11));
#endif
}

static __inline__ void stl_u(unsigned long r5, unsigned int * r11)
{
#if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91))
	struct __una_u32 *ptr = (struct __una_u32 *) r11;
	ptr->x = r5;
#else
	unsigned long r1,r2,r3,r4;

	__asm__("ldq_u %3,%1\n\t"
		"ldq_u %2,%0\n\t"
		"inslh %6,%7,%5\n\t"
		"insll %6,%7,%4\n\t"
		"msklh %3,%7,%3\n\t"
		"mskll %2,%7,%2\n\t"
		"bis %3,%5,%3\n\t"
		"bis %2,%4,%2\n\t"
		"stq_u %3,%1\n\t"
		"stq_u %2,%0"
		:"=m" (*r11),
		 "=m" (*(unsigned long *)(3+(char *) r11)),
		 "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4)
		:"r" (r5), "r" (r11));
#endif
}

static __inline__ void stw_u(unsigned long r5, unsigned short * r11)
{
#if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91))
	struct __una_u16 *ptr = (struct __una_u16 *) r11;
	ptr->x = r5;
#else
	unsigned long r1,r2,r3,r4;

	__asm__("ldq_u %3,%1\n\t"
		"ldq_u %2,%0\n\t"
		"inswh %6,%7,%5\n\t"
		"inswl %6,%7,%4\n\t"
		"mskwh %3,%7,%3\n\t"
		"mskwl %2,%7,%2\n\t"
		"bis %3,%5,%3\n\t"
		"bis %2,%4,%2\n\t"
		"stq_u %3,%1\n\t"
		"stq_u %2,%0"
		:"=m" (*r11),
		 "=m" (*(unsigned long *)(1+(char *) r11)),
		 "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4)
		:"r" (r5), "r" (r11));
#endif
}

#elif defined(__GNUC__) && ((__GNUC__ < 3)) && \
             (defined (__ia64__) || defined (ia64__))
#define IA64_UALOADS
/*
 * EGCS 1.1 knows about arbitrary unaligned loads.  Define some
 * packed structures to talk about such things with.
 */
struct __una_u64 { unsigned long  x __attribute__((packed)); };
struct __una_u32 { unsigned int   x __attribute__((packed)); };
struct __una_u16 { unsigned short x __attribute__((packed)); };

static __inline__ unsigned long
__uldq (const unsigned long * r11)
{
    const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
    return ptr->x;
}

static __inline__ unsigned long
uldl (const unsigned int * r11)
{
    const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
    return ptr->x;
}

static __inline__ unsigned long
uldw (const unsigned short * r11)
{
    const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
    return ptr->x;
}

static __inline__ void
ustq (unsigned long r5, unsigned long * r11)
{
    struct __una_u64 *ptr = (struct __una_u64 *) r11;
    ptr->x = r5;
}

static __inline__ void
ustl (unsigned long r5, unsigned int * r11)
{
    struct __una_u32 *ptr = (struct __una_u32 *) r11;
    ptr->x = r5;
}

static __inline__ void
ustw (unsigned long r5, unsigned short * r11)
{
    struct __una_u16 *ptr = (struct __una_u16 *) r11;
    ptr->x = r5;
}

#endif

/****************************************************************************
PARAMETERS:
addr	- Emulator memory address to read

RETURNS:
Byte value read from emulator memory.

REMARKS:
Reads a byte value from the emulator memory. 
****************************************************************************/
u8 X86API rdb(
    u32 addr)
{
	u8 val;

	if (addr > M.mem_size - 1) {
		DB(printk("mem_read: address %#lx out of range!\n", addr);)
		HALT_SYS();
		}
	val = *(u8*)(M.mem_base + addr);
DB(	if (DEBUG_MEM_TRACE())
		printk("%#08x 1 -> %#x\n", addr, val);)
	return val;
}

/****************************************************************************
PARAMETERS:
addr	- Emulator memory address to read

RETURNS:
Word value read from emulator memory.

REMARKS:
Reads a word value from the emulator memory.
****************************************************************************/
u16 X86API rdw(
	u32 addr)
{
	u16 val = 0;

	if (addr > M.mem_size - 2) {
		DB(printk("mem_read: address %#lx out of range!\n", addr);)
		HALT_SYS();
		}
#ifdef __BIG_ENDIAN__
	if (addr & 0x1) {
		val = (*(u8*)(M.mem_base + addr) |
			  (*(u8*)(M.mem_base + addr + 1) << 8));
		}
	else
#endif
#if defined(ALPHA_UALOADS)
		val = ldw_u((u16*)(M.mem_base + addr));
#elif  defined(IA64_UALOADS)
      val = uldw((u16*)(M.mem_base + addr));
#else
		val = *(u16*)(M.mem_base + addr);
#endif
		DB(	if (DEBUG_MEM_TRACE())
		printk("%#08x 2 -> %#x\n", addr, val);)
    return val;
}

/****************************************************************************
PARAMETERS:
addr	- Emulator memory address to read

RETURNS:
Long value read from emulator memory.
REMARKS:
Reads a long value from the emulator memory. 
****************************************************************************/
u32 X86API rdl(
	u32 addr)
{
	u32 val = 0;

	if (addr > M.mem_size - 4) {
		DB(printk("mem_read: address %#lx out of range!\n", addr);)
		HALT_SYS();
		}
#ifdef __BIG_ENDIAN__
	if (addr & 0x3) {
		val = (*(u8*)(M.mem_base + addr + 0) |
			  (*(u8*)(M.mem_base + addr + 1) << 8) |
			  (*(u8*)(M.mem_base + addr + 2) << 16) |
			  (*(u8*)(M.mem_base + addr + 3) << 24));
		}
	else
#endif
#if defined(ALPHA_UALOADS)
		val = ldl_u((u32*)(M.mem_base + addr));
#elif  defined(IA64_UALOADS)
        val = uldl((u32*)(M.mem_base + addr));
#else
		val = *(u32*)(M.mem_base + addr);
#endif
DB(	if (DEBUG_MEM_TRACE())
		printk("%#08x 4 -> %#x\n", addr, val);)
	return val;
}

/****************************************************************************
PARAMETERS:
addr	- Emulator memory address to read
val		- Value to store

REMARKS:
Writes a byte value to emulator memory.
****************************************************************************/
void X86API wrb(
	u32 addr,
	u8 val)
{
DB(	if (DEBUG_MEM_TRACE())
		printk("%#08x 1 <- %#x\n", addr, val);)
    if (addr > M.mem_size - 1) {
		DB(printk("mem_write: address %#lx out of range!\n", addr);)
		HALT_SYS();
		}
	*(u8*)(M.mem_base + addr) = val;
}

/****************************************************************************
PARAMETERS:
addr	- Emulator memory address to read
val		- Value to store

REMARKS:
Writes a word value to emulator memory.
****************************************************************************/
void X86API wrw(
	u32 addr,
	u16 val)
{
DB(	if (DEBUG_MEM_TRACE())
		printk("%#08x 2 <- %#x\n", addr, val);)
	if (addr > M.mem_size - 2) {
		DB(printk("mem_write: address %#lx out of range!\n", addr);)
		HALT_SYS();
		}
#ifdef __BIG_ENDIAN__
	if (addr & 0x1) {
		*(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
		*(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
		}
	else
#endif
#if defined(ALPHA_UALOADS)
	 stw_u(val,(u16*)(M.mem_base + addr));
#elif defined(IA64_UALOADS)
     ustw(val,(u16*)(M.mem_base + addr));
#else
	 *(u16*)(M.mem_base + addr) = val;
#endif
}

/****************************************************************************
PARAMETERS:
addr	- Emulator memory address to read
val		- Value to store

REMARKS:
Writes a long value to emulator memory. 
****************************************************************************/
void X86API wrl(
	u32 addr,
	u32 val)
{
DB(	if (DEBUG_MEM_TRACE())
		printk("%#08x 4 <- %#x\n", addr, val);)
	if (addr > M.mem_size - 4) {
		DB(printk("mem_write: address %#lx out of range!\n", addr);)
		HALT_SYS();
		}
#ifdef __BIG_ENDIAN__
	if (addr & 0x1) {
		*(u8*)(M.mem_base + addr + 0) = (val >>  0) & 0xff;
		*(u8*)(M.mem_base + addr + 1) = (val >>  8) & 0xff;
		*(u8*)(M.mem_base + addr + 2) = (val >> 16) & 0xff;
		*(u8*)(M.mem_base + addr + 3) = (val >> 24) & 0xff;
		}
	else
#endif
#if defined(ALPHA_UALOADS)
	 stl_u(val,(u32*)(M.mem_base + addr));
#elif defined(IA64_UALOADS)
     ustl(val,(u32*)(M.mem_base + addr));
#else
	 *(u32*)(M.mem_base + addr) = val;
#endif
}

/****************************************************************************
PARAMETERS:
addr	- PIO address to read
RETURN:
0
REMARKS:
Default PIO byte read function. Doesn't perform real inb.
****************************************************************************/
static u8 X86API p_inb(
	X86EMU_pioAddr addr)
{
DB(	if (DEBUG_IO_TRACE())
		printk("inb %#04x \n", addr);)
	return 0;
}

/****************************************************************************
PARAMETERS:
addr	- PIO address to read
RETURN:
0
REMARKS:
Default PIO word read function. Doesn't perform real inw.
****************************************************************************/
static u16 X86API p_inw(
	X86EMU_pioAddr addr)
{
DB(	if (DEBUG_IO_TRACE())
		printk("inw %#04x \n", addr);)
	return 0;
}

/****************************************************************************
PARAMETERS:
addr	- PIO address to read
RETURN:
0
REMARKS:
Default PIO long read function. Doesn't perform real inl.
****************************************************************************/
static u32 X86API p_inl(
	X86EMU_pioAddr addr)
{
DB(	if (DEBUG_IO_TRACE())
		printk("inl %#04x \n", addr);)
	return 0;
}

/****************************************************************************
PARAMETERS:
addr	- PIO address to write
val     - Value to store
REMARKS:
Default PIO byte write function. Doesn't perform real outb.
****************************************************************************/
static void X86API p_outb(
	X86EMU_pioAddr addr,
	u8 val)
{
DB(	if (DEBUG_IO_TRACE())
		printk("outb %#02x -> %#04x \n", val, addr);)
    return;
}

/****************************************************************************
PARAMETERS:
addr	- PIO address to write
val     - Value to store
REMARKS:
Default PIO word write function. Doesn't perform real outw.
****************************************************************************/
static void X86API p_outw(
	X86EMU_pioAddr addr,
	u16 val)
{
DB(	if (DEBUG_IO_TRACE())
		printk("outw %#04x -> %#04x \n", val, addr);)
	return;
}

/****************************************************************************
PARAMETERS:
addr	- PIO address to write
val     - Value to store
REMARKS:
Default PIO ;ong write function. Doesn't perform real outl.
****************************************************************************/
static void X86API p_outl(
	X86EMU_pioAddr addr,
	u32 val)
{
DB(	if (DEBUG_IO_TRACE())
		printk("outl %#08x -> %#04x \n", val, addr);)
    return;
}

/*------------------------- Global Variables ------------------------------*/

u8  	(X86APIP sys_rdb)(u32 addr) 			            = rdb;
u16 	(X86APIP sys_rdw)(u32 addr) 			            = rdw;
u32 	(X86APIP sys_rdl)(u32 addr) 			            = rdl;
void 	(X86APIP sys_wrb)(u32 addr,u8 val) 		            = wrb;
void 	(X86APIP sys_wrw)(u32 addr,u16 val) 	            = wrw;
void 	(X86APIP sys_wrl)(u32 addr,u32 val) 	            = wrl;
u8  	(X86APIP sys_inb)(X86EMU_pioAddr addr)	            = p_inb;
u16 	(X86APIP sys_inw)(X86EMU_pioAddr addr)	            = p_inw;
u32 	(X86APIP sys_inl)(X86EMU_pioAddr addr)              = p_inl;
void 	(X86APIP sys_outb)(X86EMU_pioAddr addr, u8 val) 	= p_outb;
void 	(X86APIP sys_outw)(X86EMU_pioAddr addr, u16 val)	= p_outw;
void 	(X86APIP sys_outl)(X86EMU_pioAddr addr, u32 val)	= p_outl;

/*----------------------------- Setup -------------------------------------*/

/****************************************************************************
PARAMETERS:
funcs	- New memory function pointers to make active

REMARKS:
This function is used to set the pointers to functions which access
memory space, allowing the user application to override these functions
and hook them out as necessary for their application.
****************************************************************************/
void X86EMU_setupMemFuncs(
	X86EMU_memFuncs *funcs)
{
    sys_rdb = funcs->rdb;
    sys_rdw = funcs->rdw;
    sys_rdl = funcs->rdl;
    sys_wrb = funcs->wrb;
    sys_wrw = funcs->wrw;
    sys_wrl = funcs->wrl;
}

/****************************************************************************
PARAMETERS:
funcs	- New programmed I/O function pointers to make active

REMARKS:
This function is used to set the pointers to functions which access
I/O space, allowing the user application to override these functions
and hook them out as necessary for their application.
****************************************************************************/
void X86EMU_setupPioFuncs(
	X86EMU_pioFuncs *funcs)
{
    sys_inb = funcs->inb;
    sys_inw = funcs->inw;
    sys_inl = funcs->inl;
    sys_outb = funcs->outb;
    sys_outw = funcs->outw;
    sys_outl = funcs->outl;
}

/****************************************************************************
PARAMETERS:
funcs	- New interrupt vector table to make active

REMARKS:
This function is used to set the pointers to functions which handle
interrupt processing in the emulator, allowing the user application to
hook interrupts as necessary for their application. Any interrupts that
are not hooked by the user application, and reflected and handled internally
in the emulator via the interrupt vector table. This allows the application
to get control when the code being emulated executes specific software
interrupts.
****************************************************************************/
void X86EMU_setupIntrFuncs(
	X86EMU_intrFuncs funcs[])
{
    int i;
    
	for (i=0; i < 256; i++)
		_X86EMU_intrTab[i] = NULL;
	if (funcs) {
		for (i = 0; i < 256; i++)
			_X86EMU_intrTab[i] = funcs[i];
		}
}

/****************************************************************************
PARAMETERS:
int	- New software interrupt to prepare for

REMARKS:
This function is used to set up the emulator state to exceute a software
interrupt. This can be used by the user application code to allow an
interrupt to be hooked, examined and then reflected back to the emulator
so that the code in the emulator will continue processing the software
interrupt as per normal. This essentially allows system code to actively
hook and handle certain software interrupts as necessary.
****************************************************************************/
void X86EMU_prepareForInt(
	int num)
{
    push_word((u16)M.x86.R_FLG);
    CLEAR_FLAG(F_IF);
    CLEAR_FLAG(F_TF);
    push_word(M.x86.R_CS);
    M.x86.R_CS = mem_access_word(num * 4 + 2);
    push_word(M.x86.R_IP);
    M.x86.R_IP = mem_access_word(num * 4);
	M.x86.intr = 0;
}

--- NEW FILE: types.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Header file for x86 emulator type definitions.
*
****************************************************************************/


#ifndef __X86EMU_TYPES_H
#define __X86EMU_TYPES_H

#ifndef NO_SYS_HEADERS
#include <sys/types.h>
#endif

/*
 * The following kludge is an attempt to work around typedef conflicts with
 * <sys/types.h>.
 */
#define u8   x86emuu8
#define u16  x86emuu16
#define u32  x86emuu32
#define u64  x86emuu64
#define s8   x86emus8
#define s16  x86emus16
#define s32  x86emus32
#define s64  x86emus64
#define uint x86emuuint
#define sint x86emusint

/*---------------------- Macros and type definitions ----------------------*/

/* Currently only for Linux/32bit */
#undef  __HAS_LONG_LONG__
#if defined(__GNUC__) && !defined(NO_LONG_LONG)
#define __HAS_LONG_LONG__
#endif

/* Taken from Xmd.h */
#undef NUM32
#if defined (_LP64) || \
    defined(__alpha) || defined(__alpha__) || \
    defined(__ia64__) || defined(ia64) || \
    defined(__sparc64__) || \
    defined(__s390x__) || \
    (defined(__hppa__) && defined(__LP64)) || \
    defined(__amd64__) || defined(amd64) || \
    (defined(__sgi) && (_MIPS_SZLONG == 64))
#define NUM32 int
#else
#define NUM32 long
#endif

typedef unsigned char 		u8;
typedef unsigned short 		u16;
typedef unsigned NUM32 		u32;
#ifdef __HAS_LONG_LONG__
typedef unsigned long long 	u64;
#endif

typedef char 				s8;
typedef short 				s16;
typedef NUM32 				s32;
#ifdef __HAS_LONG_LONG__
typedef long long 			s64;
#endif

typedef unsigned int			uint;
typedef int 				sint;

typedef u16 X86EMU_pioAddr;

#undef NUM32

#endif	/* __X86EMU_TYPES_H */

--- NEW FILE: validate.c ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:     Watcom C 10.6 or later
* Environment:  32-bit DOS
* Developer:    Kendall Bennett
*
* Description:  Program to validate the x86 emulator library for
*               correctness. We run the emulator primitive operations
*               functions against the real x86 CPU, and compare the result
*               and flags to ensure correctness.
*
*               We use inline assembler to compile and build this program.
*
****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "x86emu.h"
#include "prim_asm.h"

/*-------------------------- Implementation -------------------------------*/

#define true 1
#define false 0

#define ALL_FLAGS   (F_CF | F_PF | F_AF | F_ZF | F_SF | F_OF)

#define VAL_START_BINARY(parm_type,res_type,dmax,smax,dincr,sincr)  \
{                                                                   \
    parm_type   d,s;                                                \
    res_type    r,r_asm;                                            \
	ulong     	flags,inflags;                                      \
	int         f,failed = false;                                   \
    char        buf1[80],buf2[80];                                  \
    for (d = 0; d < dmax; d += dincr) {                             \
        for (s = 0; s < smax; s += sincr) {                         \
            M.x86.R_EFLG = inflags = flags = def_flags;             \
            for (f = 0; f < 2; f++) {

#define VAL_TEST_BINARY(name)                                           \
                r_asm = name##_asm(&flags,d,s);                         \
                r = name(d,s);                                  \
                if (r != r_asm || M.x86.R_EFLG != flags)                \
                    failed = true;                                      \
                if (failed || trace) {

#define VAL_TEST_BINARY_VOID(name)                                      \
                name##_asm(&flags,d,s);                                 \
                name(d,s);                                      \
                r = r_asm = 0;                                          \
                if (M.x86.R_EFLG != flags)                              \
                    failed = true;                                      \
                if (failed || trace) {

#define VAL_FAIL_BYTE_BYTE_BINARY(name)                                                                 \
                    if (failed)                                                                         \
                        printk("fail\n");                                                               \
                    printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
                        r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
                    printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
                        r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));

#define VAL_FAIL_WORD_WORD_BINARY(name)                                                                 \
                    if (failed)                                                                         \
                        printk("fail\n");                                                               \
                    printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                         \
                        r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));   \
                    printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                         \
                        r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));

#define VAL_FAIL_LONG_LONG_BINARY(name)                                                                 \
                    if (failed)                                                                         \
                        printk("fail\n");                                                               \
                    printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                         \
                        r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
                    printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                         \
                        r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));

#define VAL_END_BINARY()                                                    \
                    }                                                       \
                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
                if (failed)                                                 \
                    break;                                                  \
                }                                                           \
            if (failed)                                                     \
                break;                                                      \
            }                                                               \
        if (failed)                                                         \
            break;                                                          \
        }                                                                   \
    if (!failed)                                                            \
        printk("passed\n");                                                 \
}

#define VAL_BYTE_BYTE_BINARY(name)          \
    printk("Validating %s ... ", #name);    \
    VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1)   \
    VAL_TEST_BINARY(name)                   \
    VAL_FAIL_BYTE_BYTE_BINARY(name)         \
    VAL_END_BINARY()

#define VAL_WORD_WORD_BINARY(name)                      \
    printk("Validating %s ... ", #name);                \
    VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \
    VAL_TEST_BINARY(name)                               \
    VAL_FAIL_WORD_WORD_BINARY(name)                     \
    VAL_END_BINARY()

#define VAL_LONG_LONG_BINARY(name)                                      \
    printk("Validating %s ... ", #name);                                \
    VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \
    VAL_TEST_BINARY(name)                                               \
    VAL_FAIL_LONG_LONG_BINARY(name)                                     \
    VAL_END_BINARY()

#define VAL_VOID_BYTE_BINARY(name)          \
    printk("Validating %s ... ", #name);    \
    VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1)   \
    VAL_TEST_BINARY_VOID(name)              \
    VAL_FAIL_BYTE_BYTE_BINARY(name)         \
    VAL_END_BINARY()

#define VAL_VOID_WORD_BINARY(name)                      \
    printk("Validating %s ... ", #name);                \
    VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \
    VAL_TEST_BINARY_VOID(name)                          \
    VAL_FAIL_WORD_WORD_BINARY(name)                     \
    VAL_END_BINARY()

#define VAL_VOID_LONG_BINARY(name)                                      \
    printk("Validating %s ... ", #name);                                \
    VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \
    VAL_TEST_BINARY_VOID(name)                                          \
    VAL_FAIL_LONG_LONG_BINARY(name)                                     \
    VAL_END_BINARY()

#define VAL_BYTE_ROTATE(name)               \
    printk("Validating %s ... ", #name);    \
    VAL_START_BINARY(u8,u8,0xFF,8,1,1)      \
    VAL_TEST_BINARY(name)                   \
    VAL_FAIL_BYTE_BYTE_BINARY(name)         \
    VAL_END_BINARY()

#define VAL_WORD_ROTATE(name)                           \
    printk("Validating %s ... ", #name);                \
    VAL_START_BINARY(u16,u16,0xFF00,16,0x100,1)         \
    VAL_TEST_BINARY(name)                               \
    VAL_FAIL_WORD_WORD_BINARY(name)                     \
    VAL_END_BINARY()

#define VAL_LONG_ROTATE(name)                                           \
    printk("Validating %s ... ", #name);                                \
    VAL_START_BINARY(u32,u32,0xFF000000,32,0x1000000,1)                 \
    VAL_TEST_BINARY(name)                                               \
    VAL_FAIL_LONG_LONG_BINARY(name)                                     \
    VAL_END_BINARY()

#define VAL_START_TERNARY(parm_type,res_type,dmax,smax,dincr,sincr,maxshift)\
{                                                                   \
    parm_type   d,s;                                                \
    res_type    r,r_asm;                                            \
    u8          shift;                                              \
	u32         flags,inflags;                                      \
    int         f,failed = false;                                   \
    char        buf1[80],buf2[80];                                  \
    for (d = 0; d < dmax; d += dincr) {                             \
        for (s = 0; s < smax; s += sincr) {                         \
            for (shift = 0; shift < maxshift; shift += 1) {        \
                M.x86.R_EFLG = inflags = flags = def_flags;         \
                for (f = 0; f < 2; f++) {

#define VAL_TEST_TERNARY(name)                                          \
                    r_asm = name##_asm(&flags,d,s,shift);               \
                    r = name(d,s,shift);                           \
                    if (r != r_asm || M.x86.R_EFLG != flags)            \
                        failed = true;                                  \
                    if (failed || trace) {

#define VAL_FAIL_WORD_WORD_TERNARY(name)                                                                \
                        if (failed)                                                                         \
                            printk("fail\n");                                                               \
                        printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n",                      \
                            r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));   \
                        printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n",                      \
                            r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags));

#define VAL_FAIL_LONG_LONG_TERNARY(name)                                                                \
                        if (failed)                                                                         \
                            printk("fail\n");                                                               \
                        printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n",                      \
                            r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));  \
                        printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n",                      \
                            r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags));

#define VAL_END_TERNARY()                                                   \
                        }                                                       \
                    M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
                    if (failed)                                                 \
                        break;                                                  \
                    }                                                           \
                if (failed)                                                     \
                    break;                                                      \
                }                                                               \
            if (failed)                                                     \
                break;                                                      \
            }                                                               \
        if (failed)                                                         \
            break;                                                          \
        }                                                                   \
    if (!failed)                                                            \
        printk("passed\n");                                                 \
}

#define VAL_WORD_ROTATE_DBL(name)                           \
    printk("Validating %s ... ", #name);                    \
    VAL_START_TERNARY(u16,u16,0xFF00,0xFF00,0x100,0x100,16) \
    VAL_TEST_TERNARY(name)                                  \
    VAL_FAIL_WORD_WORD_TERNARY(name)                        \
    VAL_END_TERNARY()

#define VAL_LONG_ROTATE_DBL(name)                                           \
    printk("Validating %s ... ", #name);                                    \
    VAL_START_TERNARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000,32) \
    VAL_TEST_TERNARY(name)                                                  \
    VAL_FAIL_LONG_LONG_TERNARY(name)                                        \
    VAL_END_TERNARY()

#define VAL_START_UNARY(parm_type,max,incr)                 \
{                                                           \
    parm_type   d,r,r_asm;                                  \
	u32         flags,inflags;                              \
    int         f,failed = false;                           \
    char        buf1[80],buf2[80];                          \
    for (d = 0; d < max; d += incr) {                       \
        M.x86.R_EFLG = inflags = flags = def_flags;         \
        for (f = 0; f < 2; f++) {

#define VAL_TEST_UNARY(name)                                \
            r_asm = name##_asm(&flags,d);                   \
            r = name(d);                                \
            if (r != r_asm || M.x86.R_EFLG != flags) {      \
                failed = true;

#define VAL_FAIL_BYTE_UNARY(name)                                                               \
                printk("fail\n");                                                               \
                printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n",                            \
                    r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));    \
                printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n",                            \
                    r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));

#define VAL_FAIL_WORD_UNARY(name)                                                               \
                printk("fail\n");                                                               \
                printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n",                            \
                    r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));  \
                printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n",                            \
                    r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));

#define VAL_FAIL_LONG_UNARY(name)                                                               \
                printk("fail\n");                                                               \
                printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n",                            \
                    r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));    \
                printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n",                            \
                    r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));

#define VAL_END_UNARY()                                                 \
                }                                                       \
            M.x86.R_EFLG = inflags = flags = def_flags | ALL_FLAGS;     \
            if (failed)                                                 \
                break;                                                  \
            }                                                           \
        if (failed)                                                     \
            break;                                                      \
        }                                                               \
    if (!failed)                                                        \
        printk("passed\n");                                             \
}

#define VAL_BYTE_UNARY(name)                \
    printk("Validating %s ... ", #name);    \
    VAL_START_UNARY(u8,0xFF,0x1)            \
    VAL_TEST_UNARY(name)                    \
    VAL_FAIL_BYTE_UNARY(name)               \
    VAL_END_UNARY()

#define VAL_WORD_UNARY(name)                \
    printk("Validating %s ... ", #name);    \
    VAL_START_UNARY(u16,0xFF00,0x100)       \
    VAL_TEST_UNARY(name)                    \
    VAL_FAIL_WORD_UNARY(name)               \
    VAL_END_UNARY()

#define VAL_WORD_BYTE_UNARY(name)           \
    printk("Validating %s ... ", #name);    \
    VAL_START_UNARY(u16,0xFF,0x1)           \
    VAL_TEST_UNARY(name)                    \
    VAL_FAIL_WORD_UNARY(name)               \
    VAL_END_UNARY()

#define VAL_LONG_UNARY(name)                \
    printk("Validating %s ... ", #name);    \
    VAL_START_UNARY(u32,0xFF000000,0x1000000) \
    VAL_TEST_UNARY(name)                    \
    VAL_FAIL_LONG_UNARY(name)               \
    VAL_END_UNARY()

#define VAL_BYTE_MUL(name)                                              \
    printk("Validating %s ... ", #name);                                \
{                                                                       \
    u8          d,s;                                                    \
    u16         r,r_asm;                                                \
	u32         flags,inflags;                                          \
    int         f,failed = false;                                       \
    char        buf1[80],buf2[80];                                      \
    for (d = 0; d < 0xFF; d += 1) {                                     \
        for (s = 0; s < 0xFF; s += 1) {                                 \
            M.x86.R_EFLG = inflags = flags = def_flags;                 \
            for (f = 0; f < 2; f++) {                                   \
                name##_asm(&flags,&r_asm,d,s);                          \
                M.x86.R_AL = d;                                         \
                name(s);                                            \
                r = M.x86.R_AX;                                         \
                if (r != r_asm || M.x86.R_EFLG != flags)                \
                    failed = true;                                      \
                if (failed || trace) {                                  \
                    if (failed)                                         \
                        printk("fail\n");                               \
                    printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
                        r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
                    printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
                        r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
                    }                                                       \
                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
                if (failed)                                                 \
                    break;                                                  \
                }                                                           \
            if (failed)                                                     \
                break;                                                      \
            }                                                               \
        if (failed)                                                         \
            break;                                                          \
        }                                                                   \
    if (!failed)                                                            \
        printk("passed\n");                                                 \
}

#define VAL_WORD_MUL(name)                                              \
    printk("Validating %s ... ", #name);                                \
{                                                                       \
    u16         d,s;                                                    \
    u16         r_lo,r_asm_lo;                                          \
    u16         r_hi,r_asm_hi;                                          \
	u32         flags,inflags;                                          \
    int         f,failed = false;                                       \
    char        buf1[80],buf2[80];                                      \
    for (d = 0; d < 0xFF00; d += 0x100) {                               \
        for (s = 0; s < 0xFF00; s += 0x100) {                           \
            M.x86.R_EFLG = inflags = flags = def_flags;                 \
            for (f = 0; f < 2; f++) {                                   \
                name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s);             \
                M.x86.R_AX = d;                                         \
                name(s);                                            \
                r_lo = M.x86.R_AX;                                      \
                r_hi = M.x86.R_DX;                                      \
                if (r_lo != r_asm_lo || r_hi != r_asm_hi || M.x86.R_EFLG != flags)\
                    failed = true;                                      \
                if (failed || trace) {                                  \
                    if (failed)                                         \
                        printk("fail\n");                               \
                    printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                              \
                        r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));       \
                    printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                              \
                        r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
                    }                                                                                               \
                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
                if (failed)                                                 \
                    break;                                                  \
                }                                                           \
            if (failed)                                                     \
                break;                                                      \
            }                                                               \
        if (failed)                                                         \
            break;                                                          \
        }                                                                   \
    if (!failed)                                                            \
        printk("passed\n");                                                 \
}

#define VAL_LONG_MUL(name)                                              \
    printk("Validating %s ... ", #name);                                \
{                                                                       \
    u32         d,s;                                                    \
    u32         r_lo,r_asm_lo;                                          \
    u32         r_hi,r_asm_hi;                                          \
	u32         flags,inflags;                                          \
    int         f,failed = false;                                       \
    char        buf1[80],buf2[80];                                      \
    for (d = 0; d < 0xFF000000; d += 0x1000000) {                       \
        for (s = 0; s < 0xFF000000; s += 0x1000000) {                   \
            M.x86.R_EFLG = inflags = flags = def_flags;                 \
            for (f = 0; f < 2; f++) {                                   \
                name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s);             \
                M.x86.R_EAX = d;                                        \
                name(s);                                            \
                r_lo = M.x86.R_EAX;                                     \
                r_hi = M.x86.R_EDX;                                     \
                if (r_lo != r_asm_lo || r_hi != r_asm_hi || M.x86.R_EFLG != flags)\
                    failed = true;                                      \
                if (failed || trace) {                                  \
                    if (failed)                                         \
                        printk("fail\n");                               \
                    printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                              \
                        r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));       \
                    printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                              \
                        r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
                    }                                                                                               \
                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
                if (failed)                                                 \
                    break;                                                  \
                }                                                           \
            if (failed)                                                     \
                break;                                                      \
            }                                                               \
        if (failed)                                                         \
            break;                                                          \
        }                                                                   \
    if (!failed)                                                            \
        printk("passed\n");                                                 \
}

#define VAL_BYTE_DIV(name)                                              \
    printk("Validating %s ... ", #name);                                \
{                                                                       \
    u16         d,s;                                                    \
    u8          r_quot,r_rem,r_asm_quot,r_asm_rem;                      \
	u32         flags,inflags;                                          \
    int         f,failed = false;                                       \
    char        buf1[80],buf2[80];                                      \
    for (d = 0; d < 0xFF00; d += 0x100) {                               \
        for (s = 1; s < 0xFF; s += 1) {                                 \
            M.x86.R_EFLG = inflags = flags = def_flags;                 \
            for (f = 0; f < 2; f++) {                                   \
                M.x86.intr = 0;                                         \
                M.x86.R_AX = d;                                         \
                name(s);                                            \
                r_quot = M.x86.R_AL;                                    \
                r_rem = M.x86.R_AH;                                     \
                if (M.x86.intr & INTR_SYNCH)                            \
                    continue;                                           \
                name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,s);          \
                if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \
                    failed = true;                                      \
                if (failed || trace) {                                  \
                    if (failed)                                         \
                        printk("fail\n");                               \
                    printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n",                      \
                        r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
                    printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n",                      \
                        r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
                    }                                                       \
                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
                if (failed)                                                 \
                    break;                                                  \
                }                                                           \
            if (failed)                                                     \
                break;                                                      \
            }                                                               \
        if (failed)                                                         \
            break;                                                          \
        }                                                                   \
    if (!failed)                                                            \
        printk("passed\n");                                                 \
}

#define VAL_WORD_DIV(name)                                              \
    printk("Validating %s ... ", #name);                                \
{                                                                       \
    u32         d,s;                                                    \
    u16         r_quot,r_rem,r_asm_quot,r_asm_rem;                      \
	u32         flags,inflags;                                          \
    int         f,failed = false;                                       \
    char        buf1[80],buf2[80];                                      \
    for (d = 0; d < 0xFF000000; d += 0x1000000) {                       \
        for (s = 0x100; s < 0xFF00; s += 0x100) {                       \
            M.x86.R_EFLG = inflags = flags = def_flags;                 \
            for (f = 0; f < 2; f++) {                                   \
                M.x86.intr = 0;                                         \
                M.x86.R_AX = d & 0xFFFF;                                \
                M.x86.R_DX = d >> 16;                                   \
                name(s);                                            \
                r_quot = M.x86.R_AX;                                    \
                r_rem = M.x86.R_DX;                                     \
                if (M.x86.intr & INTR_SYNCH)                            \
                    continue;                                           \
                name##_asm(&flags,&r_asm_quot,&r_asm_rem,d & 0xFFFF,d >> 16,s);\
                if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \
                    failed = true;                                      \
                if (failed || trace) {                                  \
                    if (failed)                                         \
                        printk("fail\n");                               \
                    printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n",                      \
                        r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
                    printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n",                      \
                        r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
                    }                                                       \
                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
                if (failed)                                                 \
                    break;                                                  \
                }                                                           \
            if (failed)                                                     \
                break;                                                      \
            }                                                               \
        if (failed)                                                         \
            break;                                                          \
        }                                                                   \
    if (!failed)                                                            \
        printk("passed\n");                                                 \
}

#define VAL_LONG_DIV(name)                                              \
    printk("Validating %s ... ", #name);                                \
{                                                                       \
    u32         d,s;                                                    \
    u32         r_quot,r_rem,r_asm_quot,r_asm_rem;                      \
	u32         flags,inflags;                                          \
    int         f,failed = false;                                       \
    char        buf1[80],buf2[80];                                      \
    for (d = 0; d < 0xFF000000; d += 0x1000000) {                       \
        for (s = 0x100; s < 0xFF00; s += 0x100) {                       \
            M.x86.R_EFLG = inflags = flags = def_flags;                 \
            for (f = 0; f < 2; f++) {                                   \
                M.x86.intr = 0;                                         \
                M.x86.R_EAX = d;                                        \
                M.x86.R_EDX = 0;                                        \
                name(s);                                            \
                r_quot = M.x86.R_EAX;                                   \
                r_rem = M.x86.R_EDX;                                    \
                if (M.x86.intr & INTR_SYNCH)                            \
                    continue;                                           \
                name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,0,s);        \
                if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \
                    failed = true;                                      \
                if (failed || trace) {                                  \
                    if (failed)                                         \
                        printk("fail\n");                               \
                    printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n",                       \
                        r_quot, r_rem, #name, 0, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));  \
                    printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n",                       \
                        r_asm_quot, r_asm_rem, #name"_asm", 0, d, s, print_flags(buf1,inflags), print_flags(buf2,flags));   \
                    }                                                       \
                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
                if (failed)                                                 \
                    break;                                                  \
                }                                                           \
            if (failed)                                                     \
                break;                                                      \
            }                                                               \
        if (failed)                                                         \
            break;                                                          \
        }                                                                   \
    if (!failed)                                                            \
        printk("passed\n");                                                 \
}

void printk(const char *fmt, ...)
{
    va_list argptr;
    va_start(argptr, fmt);
    vfprintf(stdout, fmt, argptr);
    fflush(stdout);
    va_end(argptr);
}

char * print_flags(char *buf,ulong flags)
{
    char *separator = "";

    buf[0] = 0;
    if (flags & F_CF) {
        strcat(buf,separator);
        strcat(buf,"CF");
        separator = ",";
        }
    if (flags & F_PF) {
        strcat(buf,separator);
        strcat(buf,"PF");
        separator = ",";
        }
    if (flags & F_AF) {
        strcat(buf,separator);
        strcat(buf,"AF");
        separator = ",";
        }
    if (flags & F_ZF) {
        strcat(buf,separator);
        strcat(buf,"ZF");
        separator = ",";
        }
    if (flags & F_SF) {
        strcat(buf,separator);
        strcat(buf,"SF");
        separator = ",";
        }
    if (flags & F_OF) {
        strcat(buf,separator);
        strcat(buf,"OF");
        separator = ",";
        }
    if (separator[0] == 0)
        strcpy(buf,"None");
    return buf;
}

int main(int argc)
{
    ulong   def_flags;
    int trace = false;

    if (argc > 1)
        trace = true;
    memset(&M, 0, sizeof(M));
    def_flags = get_flags_asm() & ~ALL_FLAGS;

    VAL_WORD_UNARY(aaa_word);
    VAL_WORD_UNARY(aas_word);

    VAL_WORD_UNARY(aad_word);
    VAL_WORD_UNARY(aam_word);

    VAL_BYTE_BYTE_BINARY(adc_byte);
    VAL_WORD_WORD_BINARY(adc_word);
    VAL_LONG_LONG_BINARY(adc_long);

    VAL_BYTE_BYTE_BINARY(add_byte);
    VAL_WORD_WORD_BINARY(add_word);
    VAL_LONG_LONG_BINARY(add_long);

    VAL_BYTE_BYTE_BINARY(and_byte);
    VAL_WORD_WORD_BINARY(and_word);
    VAL_LONG_LONG_BINARY(and_long);

    VAL_BYTE_BYTE_BINARY(cmp_byte);
    VAL_WORD_WORD_BINARY(cmp_word);
    VAL_LONG_LONG_BINARY(cmp_long);

    VAL_BYTE_UNARY(daa_byte);
    VAL_BYTE_UNARY(das_byte);   // Fails for 0x9A (out of range anyway)

    VAL_BYTE_UNARY(dec_byte);
    VAL_WORD_UNARY(dec_word);
    VAL_LONG_UNARY(dec_long);

    VAL_BYTE_UNARY(inc_byte);
    VAL_WORD_UNARY(inc_word);
    VAL_LONG_UNARY(inc_long);

    VAL_BYTE_BYTE_BINARY(or_byte);
    VAL_WORD_WORD_BINARY(or_word);
    VAL_LONG_LONG_BINARY(or_long);

    VAL_BYTE_UNARY(neg_byte);
    VAL_WORD_UNARY(neg_word);
    VAL_LONG_UNARY(neg_long);

    VAL_BYTE_UNARY(not_byte);
    VAL_WORD_UNARY(not_word);
    VAL_LONG_UNARY(not_long);

    VAL_BYTE_ROTATE(rcl_byte);
    VAL_WORD_ROTATE(rcl_word);
    VAL_LONG_ROTATE(rcl_long);

    VAL_BYTE_ROTATE(rcr_byte);
    VAL_WORD_ROTATE(rcr_word);
    VAL_LONG_ROTATE(rcr_long);

    VAL_BYTE_ROTATE(rol_byte);
    VAL_WORD_ROTATE(rol_word);
    VAL_LONG_ROTATE(rol_long);

    VAL_BYTE_ROTATE(ror_byte);
    VAL_WORD_ROTATE(ror_word);
    VAL_LONG_ROTATE(ror_long);

    VAL_BYTE_ROTATE(shl_byte);
    VAL_WORD_ROTATE(shl_word);
    VAL_LONG_ROTATE(shl_long);

    VAL_BYTE_ROTATE(shr_byte);
    VAL_WORD_ROTATE(shr_word);
    VAL_LONG_ROTATE(shr_long);

    VAL_BYTE_ROTATE(sar_byte);
    VAL_WORD_ROTATE(sar_word);
    VAL_LONG_ROTATE(sar_long);

    VAL_WORD_ROTATE_DBL(shld_word);
    VAL_LONG_ROTATE_DBL(shld_long);

    VAL_WORD_ROTATE_DBL(shrd_word);
    VAL_LONG_ROTATE_DBL(shrd_long);

    VAL_BYTE_BYTE_BINARY(sbb_byte);
    VAL_WORD_WORD_BINARY(sbb_word);
    VAL_LONG_LONG_BINARY(sbb_long);

    VAL_BYTE_BYTE_BINARY(sub_byte);
    VAL_WORD_WORD_BINARY(sub_word);
    VAL_LONG_LONG_BINARY(sub_long);

    VAL_BYTE_BYTE_BINARY(xor_byte);
    VAL_WORD_WORD_BINARY(xor_word);
    VAL_LONG_LONG_BINARY(xor_long);

    VAL_VOID_BYTE_BINARY(test_byte);
    VAL_VOID_WORD_BINARY(test_word);
    VAL_VOID_LONG_BINARY(test_long);

    VAL_BYTE_MUL(imul_byte);
    VAL_WORD_MUL(imul_word);
    VAL_LONG_MUL(imul_long);

    VAL_BYTE_MUL(mul_byte);
    VAL_WORD_MUL(mul_word);
    VAL_LONG_MUL(mul_long);

    VAL_BYTE_DIV(idiv_byte);
    VAL_WORD_DIV(idiv_word);
    VAL_LONG_DIV(idiv_long);

    VAL_BYTE_DIV(div_byte);
    VAL_WORD_DIV(div_word);
    VAL_LONG_DIV(div_long);

    return 0;
}

--- NEW FILE: x86emu.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Header file for public specific functions.
*               Any application linking against us should only
*               include this header
*
****************************************************************************/

#ifndef __X86EMU_X86EMU_H
#define __X86EMU_X86EMU_H

#ifdef SCITECH
#include "scitech.h"
#define	X86API	_ASMAPI
#define	X86APIP	_ASMAPIP
typedef int X86EMU_pioAddr;
#else
#include "types.h"
#define	X86API
#define	X86APIP	*
#endif
#include "regs.h"

/*---------------------- Macros and type definitions ----------------------*/

#ifdef PACK
# pragma	PACK   /* Don't pack structs with function pointers! */
#endif

/****************************************************************************
REMARKS:
Data structure containing ponters to programmed I/O functions used by the
emulator. This is used so that the user program can hook all programmed
I/O for the emulator to handled as necessary by the user program. By
default the emulator contains simple functions that do not do access the
hardware in any way. To allow the emualtor access the hardware, you will
need to override the programmed I/O functions using the X86EMU_setupPioFuncs
function.

HEADER:
x86emu.h

MEMBERS:
inb		- Function to read a byte from an I/O port
inw		- Function to read a word from an I/O port
inl     - Function to read a dword from an I/O port
outb	- Function to write a byte to an I/O port
outw    - Function to write a word to an I/O port
outl    - Function to write a dword to an I/O port
****************************************************************************/
typedef struct {
	u8  	(X86APIP inb)(X86EMU_pioAddr addr);
	u16 	(X86APIP inw)(X86EMU_pioAddr addr);
	u32 	(X86APIP inl)(X86EMU_pioAddr addr);
	void 	(X86APIP outb)(X86EMU_pioAddr addr, u8 val);
	void 	(X86APIP outw)(X86EMU_pioAddr addr, u16 val);
	void 	(X86APIP outl)(X86EMU_pioAddr addr, u32 val);
	} X86EMU_pioFuncs;

/****************************************************************************
REMARKS:
Data structure containing ponters to memory access functions used by the
emulator. This is used so that the user program can hook all memory
access functions as necessary for the emulator. By default the emulator
contains simple functions that only access the internal memory of the
emulator. If you need specialised functions to handle access to different
types of memory (ie: hardware framebuffer accesses and BIOS memory access
etc), you will need to override this using the X86EMU_setupMemFuncs
function.

HEADER:
x86emu.h

MEMBERS:
rdb		- Function to read a byte from an address
rdw		- Function to read a word from an address
rdl     - Function to read a dword from an address
wrb		- Function to write a byte to an address
wrw    	- Function to write a word to an address
wrl    	- Function to write a dword to an address
****************************************************************************/
typedef struct {
	u8  	(X86APIP rdb)(u32 addr);
	u16 	(X86APIP rdw)(u32 addr);
	u32 	(X86APIP rdl)(u32 addr);
	void 	(X86APIP wrb)(u32 addr, u8 val);
	void 	(X86APIP wrw)(u32 addr, u16 val);
	void	(X86APIP wrl)(u32 addr, u32 val);
	} X86EMU_memFuncs;

/****************************************************************************
  Here are the default memory read and write
  function in case they are needed as fallbacks.
***************************************************************************/
extern u8 X86API rdb(u32 addr);
extern u16 X86API rdw(u32 addr);
extern u32 X86API rdl(u32 addr);
extern void X86API wrb(u32 addr, u8 val);
extern void X86API wrw(u32 addr, u16 val);
extern void X86API wrl(u32 addr, u32 val);

#ifdef END_PACK
# pragma	END_PACK
#endif

/*--------------------- type definitions -----------------------------------*/

typedef void (X86APIP X86EMU_intrFuncs)(int num);
extern X86EMU_intrFuncs _X86EMU_intrTab[256];

/*-------------------------- Function Prototypes --------------------------*/

#ifdef  __cplusplus
extern "C" {            			/* Use "C" linkage when in C++ mode */
#endif

void 	X86EMU_setupMemFuncs(X86EMU_memFuncs *funcs);
void 	X86EMU_setupPioFuncs(X86EMU_pioFuncs *funcs);
void 	X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[]);
void 	X86EMU_prepareForInt(int num);

/* decode.c */

void 	X86EMU_exec(void);
void 	X86EMU_halt_sys(void);

#ifdef	DEBUG
#define	HALT_SYS()	\
	printk("halt_sys: file %s, line %d\n", __FILE__, __LINE__), \
	X86EMU_halt_sys()
#else
#define	HALT_SYS()	X86EMU_halt_sys()
#endif

/* Debug options */

#define DEBUG_DECODE_F          0x000001 /* print decoded instruction  */
#define DEBUG_TRACE_F           0x000002 /* dump regs before/after execution */
#define DEBUG_STEP_F            0x000004
#define DEBUG_DISASSEMBLE_F     0x000008
#define DEBUG_BREAK_F           0x000010
#define DEBUG_SVC_F             0x000020
#define DEBUG_SAVE_IP_CS_F      0x000040
#define DEBUG_FS_F              0x000080
#define DEBUG_PROC_F            0x000100
#define DEBUG_SYSINT_F          0x000200 /* bios system interrupts. */
#define DEBUG_TRACECALL_F       0x000400
#define DEBUG_INSTRUMENT_F      0x000800
#define DEBUG_MEM_TRACE_F       0x001000 
#define DEBUG_IO_TRACE_F        0x002000 
#define DEBUG_TRACECALL_REGS_F  0x004000
#define DEBUG_DECODE_NOPRINT_F  0x008000 
#define DEBUG_EXIT              0x010000
#define DEBUG_SYS_F             (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F)

void 	X86EMU_trace_regs(void);
void 	X86EMU_trace_xregs(void);
void 	X86EMU_dump_memory(u16 seg, u16 off, u32 amt);
int 	X86EMU_trace_on(void);
int 	X86EMU_trace_off(void);

#ifdef  __cplusplus
}                       			/* End of "C" linkage for C++   	*/
#endif

#endif /* __X86EMU_X86EMU_H */

--- NEW FILE: x86emui.h ---
/****************************************************************************
*
*						Realmode X86 Emulator Library
*
*            	Copyright (C) 1996-1999 SciTech Software, Inc.
* 				     Copyright (C) David Mosberger-Tang
* 					   Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
*  ========================================================================
*
* Language:		ANSI C
* Environment:	Any
* Developer:    Kendall Bennett
*
* Description:  Header file for system specific functions. These functions
*				are always compiled and linked in the OS depedent libraries,
*				and never in a binary portable driver.
*
****************************************************************************/


#ifndef __X86EMU_X86EMUI_H
#define __X86EMU_X86EMUI_H

/* If we are compiling in C++ mode, we can compile some functions as
 * inline to increase performance (however the code size increases quite
 * dramatically in this case).
 */

#if	defined(__cplusplus) && !defined(_NO_INLINE)
#define	_INLINE	inline
#else
#define	_INLINE static
#endif

/* Get rid of unused parameters in C++ compilation mode */

#ifdef __cplusplus
#define	X86EMU_UNUSED(v)
#else
#define	X86EMU_UNUSED(v)	v
#endif

#include "x86emu.h"
#include "regs.h"
#include "debug.h"
#include "decode.h"
#include "ops.h"
#include "prim_ops.h"
#include "fpu.h"
#include "fpu_regs.h"

#ifndef NO_SYS_HEADERS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif                                                                                           
/*--------------------------- Inline Functions ----------------------------*/

#ifdef  __cplusplus
extern "C" {            			/* Use "C" linkage when in C++ mode */
#endif

extern u8  	(X86APIP sys_rdb)(u32 addr);
extern u16 	(X86APIP sys_rdw)(u32 addr);
extern u32 	(X86APIP sys_rdl)(u32 addr);
extern void (X86APIP sys_wrb)(u32 addr,u8 val);
extern void (X86APIP sys_wrw)(u32 addr,u16 val);
extern void (X86APIP sys_wrl)(u32 addr,u32 val);

extern u8  	(X86APIP sys_inb)(X86EMU_pioAddr addr);
extern u16 	(X86APIP sys_inw)(X86EMU_pioAddr addr);
extern u32 	(X86APIP sys_inl)(X86EMU_pioAddr addr);
extern void (X86APIP sys_outb)(X86EMU_pioAddr addr,u8 val);
extern void (X86APIP sys_outw)(X86EMU_pioAddr addr,u16 val);
extern void	(X86APIP sys_outl)(X86EMU_pioAddr addr,u32 val);

#ifdef  __cplusplus
}                       			/* End of "C" linkage for C++   	*/
#endif

#endif /* __X86EMU_X86EMUI_H */

Index: xf86int10.c
===================================================================
RCS file: /cvs/xserver/debrix/hw/xorg/int10/xf86int10.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- xf86int10.c	10 Jun 2004 19:40:22 -0000	1.3
+++ xf86int10.c	16 Jun 2004 00:25:30 -0000	1.4
@@ -14,6 +14,7 @@
 #define _INT10_PRIVATE
 #include "xf86int10.h"
 #include "int10Defines.h"
+#include "xf86x86emu.h"
 
 #define REG pInt
 




More information about the xserver-commit mailing list