replaced Firetos x86 emulator with the optimised NetBSD version

This commit is contained in:
Markus Fröschle
2015-02-16 22:14:44 +00:00
parent 9cb5e7f4fd
commit a907bc61a8
25 changed files with 8429 additions and 15117 deletions

View File

@@ -198,3 +198,6 @@ util/wait.c
bas.lk.in
i2c/i2c.c
Makefile
x86emu/x86biosemu.c
x86emu/x86emu.c
x86emu/x86pcibios.c

View File

@@ -131,15 +131,7 @@ CSRCS= \
radeon_monitor.c \
fnt_st_8x16.c \
\
x86decode.c \
x86sys.c \
x86debug.c \
x86prim_ops.c \
x86ops.c \
x86ops2.c \
x86fpu.c \
x86biosemu.c \
x86pcibios.c \
x86emu.c \
\
basflash.c \
basflash_start.c

View File

@@ -93,15 +93,7 @@ SECTIONS
OBJDIR/fbmodedb.o(.text)
OBJDIR/offscreen.o(.text)
OBJDIR/x86decode.o(.text)
OBJDIR/x86ops.o(.text)
OBJDIR/x86ops2.o(.text)
OBJDIR/x86fpu.o(.text)
OBJDIR/x86sys.o(.text)
OBJDIR/x86biosemu.o(.text)
OBJDIR/x86debug.o(.text)
OBJDIR/x86prim_ops.o(.text)
OBJDIR/x86pcibios.o(.text)
OBJDIR/x86emu.o(.text)
OBJDIR/radeon_base.o(.text)
OBJDIR/radeon_accel.o(.text)

View File

@@ -1,241 +0,0 @@
/****************************************************************************
*
* 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.
*
****************************************************************************/
/* $XFree86: xc/extras/x86emu/src/x86emu/x86emu/debug.h,v 1.4 2000/11/21 23:10:27 tsi Exp $ */
#include <bas_types.h>
#include "bas_printf.h"
/*
* for the X86 emulator, debug cannot be enabled and disabled on a per-file mode
* as with all the other modules. It must be centrally enabled here.
*/
#define DBG_X86EMU
#ifdef DBG_X86EMU
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else
#define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_X86EMU */
#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 DBG_X86EMU
# 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 DBG_X86EMU
# 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 DBG_X86EMU
# 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 DBG_X86EMU
#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 DBG_X86EMU
# define SINGLE_STEP() if (DEBUG_STEP()) x86emu_single_step()
#else
# define SINGLE_STEP()
#endif
#define TRACE_AND_STEP() \
TRACE_REGS(); \
SINGLE_STEP()
#ifdef DBG_X86EMU
# 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 DBG_X86EMU
# define CALL_TRACE(u,v,w,x,s) \
if (DEBUG_TRACECALLREGS()) \
x86emu_dump_regs(); \
if (DEBUG_TRACECALL()) { \
xprintf("%x", u); \
xprintf(":%x", v); \
xprintf(": CALL "); \
xprintf("%x", s); \
xprintf(" %x", w); \
xprintf(":%x", x); \
xprintf("%s", "\r\n"); \
}
# define RETURN_TRACE(n,u,v) \
if (DEBUG_TRACECALLREGS()) \
x86emu_dump_regs(); \
if (DEBUG_TRACECALL()) \
{ \
xprintf("%x", (unsigned long)u); \
xprintf(":%x", (unsigned long)v); \
xprintf(": CALL "); \
xprintf("%x", n); \
xprintf("\r\n"); \
}
#else
# define CALL_TRACE(u,v,w,x,s)
# define RETURN_TRACE(n,u,v)
#endif
#ifdef DBG_X86EMU
#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 (uint16_t 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 (uint32_t p);
extern void x86emu_check_data_access (unsigned int s, unsigned int o);
#ifdef __cplusplus
} /* End of "C" linkage for C++ */
#endif
#endif /* __X86EMU_DEBUG_H */

View File

@@ -1,89 +0,0 @@
/****************************************************************************
*
* 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 --------------------------*/
#include "bas_types.h"
#ifdef __cplusplus
extern "C" { /* Use "C" linkage when in C++ mode */
#endif
void x86emu_intr_raise(uint8_t type);
void fetch_decode_modrm(int *mod, int *regh, int *regl);
uint8_t fetch_byte_imm(void);
uint16_t fetch_word_imm(void);
uint32_t fetch_long_imm(void);
uint8_t fetch_data_byte(unsigned int offset);
uint8_t fetch_data_byte_abs(unsigned int segment, unsigned int offset);
uint16_t fetch_data_word(unsigned int offset);
uint16_t fetch_data_word_abs(unsigned int segment, unsigned int offset);
uint32_t fetch_data_long(unsigned int offset);
uint32_t fetch_data_long_abs(unsigned int segment, unsigned int offset);
void store_data_byte(unsigned int offset, uint8_t val);
void store_data_byte_abs(unsigned int segment, unsigned int offset, uint8_t val);
void store_data_word(unsigned int offset, uint16_t val);
void store_data_word_abs(unsigned int segment, unsigned int offset, uint16_t val);
void store_data_long(unsigned int offset, uint32_t val);
void store_data_long_abs(unsigned int segment, unsigned int offset, uint32_t val);
uint8_t *decode_rm_byte_register(int reg);
uint16_t *decode_rm_word_register(int reg);
uint32_t *decode_rm_long_register(int reg);
uint16_t *decode_rm_seg_register(int reg);
unsigned decode_rm00_address(int rm);
unsigned decode_rm01_address(int rm);
unsigned decode_rm10_address(int rm);
#ifdef __cplusplus
} /* End of "C" linkage for C++ */
#endif
#endif /* __X86EMU_DECODE_H */

View File

@@ -1,192 +1,159 @@
/* $NetBSD: x86emu.h,v 1.1 2007/12/01 20:14:10 joerg Exp $ */
/****************************************************************************
*
* 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
*
****************************************************************************/
/* $XFree86: xc/extras/x86emu/include/x86emu.h,v 1.2 2000/11/21 23:10:25 tsi Exp $ */
*
* Realmode X86 Emulator Library
*
* Copyright (C) 1996-1999 SciTech Software, Inc.
* Copyright (C) David Mosberger-Tang
* Copyright (C) 1999 Egbert Eich
* Copyright (C) 2007 Joerg Sonnenberger
*
* ========================================================================
*
* 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.
*
****************************************************************************/
#ifndef __X86EMU_X86EMU_H
#define __X86EMU_X86EMU_H
#include "bas_types.h"
#define X86API
#define X86APIP *
#include "x86regs.h"
typedef uint16_t X86EMU_pioAddr;
/*---------------------- Macros and type definitions ----------------------*/
/*
* 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.
*/
//#pragma pack(1)
/****************************************************************************
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.
struct X86EMU_register32 {
uint32_t e_reg;
};
HEADER:
x86emu.h
struct X86EMU_register16 {
uint16_t filler0;
uint16_t x_reg;
};
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
{
uint8_t (X86APIP inb)(X86EMU_pioAddr addr);
uint16_t (X86APIP inw)(X86EMU_pioAddr addr);
uint32_t (X86APIP inl)(X86EMU_pioAddr addr);
void (X86APIP outb)(X86EMU_pioAddr addr, uint8_t val);
void (X86APIP outw)(X86EMU_pioAddr addr, uint16_t val);
void (X86APIP outl)(X86EMU_pioAddr addr, uint32_t val);
} X86EMU_pioFuncs;
struct X86EMU_register8 {
uint8_t filler0, filler1;
uint8_t h_reg, l_reg;
};
/****************************************************************************
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
union X86EMU_register {
struct X86EMU_register32 I32_reg;
struct X86EMU_register16 I16_reg;
struct X86EMU_register8 I8_reg;
};
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 {
uint8_t (X86APIP rdb)(uint32_t addr);
uint16_t (X86APIP rdw)(uint32_t addr);
uint32_t (X86APIP rdl)(uint32_t addr);
void (X86APIP wrb)(uint32_t addr, uint8_t val);
void (X86APIP wrw)(uint32_t addr, uint16_t val);
void (X86APIP wrl)(uint32_t addr, uint32_t val);
} X86EMU_memFuncs;
struct X86EMU_regs {
uint16_t register_cs;
uint16_t register_ds;
uint16_t register_es;
uint16_t register_fs;
uint16_t register_gs;
uint16_t register_ss;
uint32_t register_flags;
union X86EMU_register register_a;
union X86EMU_register register_b;
union X86EMU_register register_c;
union X86EMU_register register_d;
/****************************************************************************
Here are the default memory read and write
function in case they are needed as fallbacks.
***************************************************************************/
extern uint8_t X86API rdb(uint32_t addr);
extern uint16_t X86API rdw(uint32_t addr);
extern uint32_t X86API rdl(uint32_t addr);
extern void X86API wrb(uint32_t addr, uint8_t val);
extern void X86API wrw(uint32_t addr, uint16_t val);
extern void X86API wrl(uint32_t addr, uint32_t val);
union X86EMU_register register_sp;
union X86EMU_register register_bp;
union X86EMU_register register_si;
union X86EMU_register register_di;
union X86EMU_register register_ip;
//#pragma pack()
/*
* 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
*/
uint32_t mode;
volatile int intr; /* mask of pending interrupts */
uint8_t intno;
uint8_t __pad[3];
};
/*--------------------- type definitions -----------------------------------*/
typedef uint32_t label_t;
typedef void (X86APIP X86EMU_intrFuncs)(int num);
extern X86EMU_intrFuncs _X86EMU_intrTab[256];
struct X86EMU {
char *mem_base;
size_t mem_size;
void *sys_private;
struct X86EMU_regs x86;
/*-------------------------- Function Prototypes --------------------------*/
label_t exec_state;
#ifdef __cplusplus
extern "C" { /* Use "C" linkage when in C++ mode */
#endif
uint64_t cur_cycles;
void X86EMU_setupMemFuncs(X86EMU_memFuncs *funcs);
void X86EMU_setupPioFuncs(X86EMU_pioFuncs *funcs);
void X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[]);
void X86EMU_prepareForInt(int num);
unsigned int cur_mod:2;
unsigned int cur_rl:3;
unsigned int cur_rh:3;
uint32_t cur_offset;
/* decode.c */
uint8_t (*emu_rdb)(struct X86EMU *, uint32_t addr);
uint16_t (*emu_rdw)(struct X86EMU *, uint32_t addr);
uint32_t (*emu_rdl)(struct X86EMU *, uint32_t addr);
void (*emu_wrb)(struct X86EMU *, uint32_t addr,uint8_t val);
void (*emu_wrw)(struct X86EMU *, uint32_t addr, uint16_t val);
void (*emu_wrl)(struct X86EMU *, uint32_t addr, uint32_t val);
void X86EMU_exec(void);
void X86EMU_halt_sys(void);
uint8_t (*emu_inb)(struct X86EMU *, uint16_t addr);
uint16_t (*emu_inw)(struct X86EMU *, uint16_t addr);
uint32_t (*emu_inl)(struct X86EMU *, uint16_t addr);
void (*emu_outb)(struct X86EMU *, uint16_t addr, uint8_t val);
void (*emu_outw)(struct X86EMU *, uint16_t addr, uint16_t val);
void (*emu_outl)(struct X86EMU *, uint16_t addr, uint32_t val);
#ifdef DBG_X86EMU
#define HALT_SYS() \
dbg("%s: halt_sys: file %s line %d\r\n", __FUNCTION__, __FILE__, __LINE__);\
X86EMU_halt_sys();
#else
#define HALT_SYS() X86EMU_halt_sys()
#endif
void (*_X86EMU_intrTab[256])(struct X86EMU *, int);
};
/* 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_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_SAVE_IP_CS_F 0x010000
#define DEBUG_SYS_F (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F)
void X86EMU_init_default(struct X86EMU *);
void X86EMU_trace_regs(void);
void X86EMU_trace_xregs(void);
void X86EMU_dump_memory(uint16_t seg, uint16_t off, uint32_t amt);
int X86EMU_trace_on(void);
int X86EMU_trace_off(void);
int X86EMU_set_debug(int debug);
void X86EMU_setMemBase(void *base, unsigned long size);
/* decode.c */
void X86EMU_exec(struct X86EMU *);
void X86EMU_exec_call(struct X86EMU *, uint16_t, uint16_t);
void X86EMU_exec_intr(struct X86EMU *, uint8_t);
void X86EMU_halt_sys(struct X86EMU *);
#ifdef __cplusplus
} /* End of "C" linkage for C++ */
#endif
#endif /* __X86EMU_X86EMU_H */

View File

@@ -0,0 +1,169 @@
/* $NetBSD: x86emu_regs.h,v 1.1 2007/12/01 20:14:10 joerg Exp $ */
/****************************************************************************
*
* Realmode X86 Emulator Library
*
* Copyright (C) 1996-1999 SciTech Software, Inc.
* Copyright (C) David Mosberger-Tang
* Copyright (C) 1999 Egbert Eich
* Copyright (C) 2007 Joerg Sonnenberger
*
* ========================================================================
*
* 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.
*
****************************************************************************/
#ifndef __X86EMU_REGS_H
#define __X86EMU_REGS_H
/*---------------------- Macros and type definitions ----------------------*/
/* 8 bit registers */
#define R_AH register_a.I8_reg.h_reg
#define R_AL register_a.I8_reg.l_reg
#define R_BH register_b.I8_reg.h_reg
#define R_BL register_b.I8_reg.l_reg
#define R_CH register_c.I8_reg.h_reg
#define R_CL register_c.I8_reg.l_reg
#define R_DH register_d.I8_reg.h_reg
#define R_DL register_d.I8_reg.l_reg
/* 16 bit registers */
#define R_AX register_a.I16_reg.x_reg
#define R_BX register_b.I16_reg.x_reg
#define R_CX register_c.I16_reg.x_reg
#define R_DX register_d.I16_reg.x_reg
/* 32 bit extended registers */
#define R_EAX register_a.I32_reg.e_reg
#define R_EBX register_b.I32_reg.e_reg
#define R_ECX register_c.I32_reg.e_reg
#define R_EDX register_d.I32_reg.e_reg
/* special registers */
#define R_SP register_sp.I16_reg.x_reg
#define R_BP register_bp.I16_reg.x_reg
#define R_SI register_si.I16_reg.x_reg
#define R_DI register_di.I16_reg.x_reg
#define R_IP register_ip.I16_reg.x_reg
#define R_FLG register_flags
/* special registers */
#define R_ESP register_sp.I32_reg.e_reg
#define R_EBP register_bp.I32_reg.e_reg
#define R_ESI register_si.I32_reg.e_reg
#define R_EDI register_di.I32_reg.e_reg
#define R_EIP register_ip.I32_reg.e_reg
#define R_EFLG register_flags
/* segment registers */
#define R_CS register_cs
#define R_DS register_ds
#define R_SS register_ss
#define R_ES register_es
#define R_FS register_fs
#define R_GS register_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 SET_FLAG(flag) (emu->x86.R_FLG |= (flag))
#define CLEAR_FLAG(flag) (emu->x86.R_FLG &= ~(flag))
#define ACCESS_FLAG(flag) (emu->x86.R_FLG & (flag))
#define CLEARALL_FLAG(m) (emu->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
#endif /* __X86EMU_REGS_H */

View File

@@ -1,99 +0,0 @@
/****************************************************************************
*
* 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.
*
****************************************************************************/
/* $XFree86: xc/extras/x86emu/src/x86emu/x86emu/x86emui.h,v 1.4 2001/04/01 13:59:58 tsi Exp $ */
#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 "radeonfb.h"
#include "x86emu.h"
#include "x86regs.h"
#include "x86decode.h"
#include "x86ops.h"
#include "x86prim_ops.h"
#include "x86fpu.h"
/*--------------------------- Inline Functions ----------------------------*/
#ifdef __cplusplus
extern "C" { /* Use "C" linkage when in C++ mode */
#endif
extern uint8_t (X86APIP sys_rdb)(uint32_t addr);
extern uint16_t (X86APIP sys_rdw)(uint32_t addr);
extern uint32_t (X86APIP sys_rdl)(uint32_t addr);
extern void (X86APIP sys_wrb)(uint32_t addr,uint8_t val);
extern void (X86APIP sys_wrw)(uint32_t addr,uint16_t val);
extern void (X86APIP sys_wrl)(uint32_t addr,uint32_t val);
extern uint8_t (X86APIP sys_inb)(X86EMU_pioAddr addr);
extern uint16_t (X86APIP sys_inw)(X86EMU_pioAddr addr);
extern uint32_t (X86APIP sys_inl)(X86EMU_pioAddr addr);
extern void (X86APIP sys_outb)(X86EMU_pioAddr addr,uint8_t val);
extern void (X86APIP sys_outw)(X86EMU_pioAddr addr,uint16_t val);
extern void (X86APIP sys_outl)(X86EMU_pioAddr addr,uint32_t val);
#ifdef __cplusplus
} /* End of "C" linkage for C++ */
#endif
#endif /* __X86EMU_X86EMUI_H */

View File

@@ -1,61 +0,0 @@
/****************************************************************************
*
* 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 (uint8_t op1);
extern void x86emuOp_esc_coprocess_d9 (uint8_t op1);
extern void x86emuOp_esc_coprocess_da (uint8_t op1);
extern void x86emuOp_esc_coprocess_db (uint8_t op1);
extern void x86emuOp_esc_coprocess_dc (uint8_t op1);
extern void x86emuOp_esc_coprocess_dd (uint8_t op1);
extern void x86emuOp_esc_coprocess_de (uint8_t op1);
extern void x86emuOp_esc_coprocess_df (uint8_t op1);
#ifdef __cplusplus
} /* End of "C" linkage for C++ */
#endif
#endif /* __X86EMU_FPU_H */

View File

@@ -1,116 +0,0 @@
/****************************************************************************
*
* 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
#pragma pack(1)
/* 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;
};
#pragma pack()
/*
* 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 DBG_X86EMU
#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 */

View File

@@ -1,45 +0,0 @@
/****************************************************************************
*
* 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])(uint8_t op1);
extern void (*x86emu_optab2[0x100])(uint8_t op2);
#endif /* __X86EMU_OPS_H */

View File

@@ -1,971 +0,0 @@
/****************************************************************************
*
* 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.
*
****************************************************************************/
/* $XFree86: xc/extras/x86emu/src/x86emu/x86emu/prim_asm.h,v 1.3 2000/04/19 15:48:15 tsi Exp $ */
#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 */

View File

@@ -1,232 +0,0 @@
/****************************************************************************
*
* 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
#include "x86prim_asm.h"
#ifdef __cplusplus
extern "C" { /* Use "C" linkage when in C++ mode */
#endif
uint16_t aaa_word (uint16_t d);
uint16_t aas_word (uint16_t d);
uint16_t aad_word (uint16_t d);
uint16_t aam_word (uint8_t d);
uint8_t adc_byte (uint8_t d, uint8_t s);
uint16_t adc_word (uint16_t d, uint16_t s);
uint32_t adc_long (uint32_t d, uint32_t s);
uint8_t add_byte (uint8_t d, uint8_t s);
uint16_t add_word (uint16_t d, uint16_t s);
uint32_t add_long (uint32_t d, uint32_t s);
uint8_t and_byte (uint8_t d, uint8_t s);
uint16_t and_word (uint16_t d, uint16_t s);
uint32_t and_long (uint32_t d, uint32_t s);
uint8_t cmp_byte (uint8_t d, uint8_t s);
uint16_t cmp_word (uint16_t d, uint16_t s);
uint32_t cmp_long (uint32_t d, uint32_t s);
uint8_t daa_byte (uint8_t d);
uint8_t das_byte (uint8_t d);
uint8_t dec_byte (uint8_t d);
uint16_t dec_word (uint16_t d);
uint32_t dec_long (uint32_t d);
uint8_t inc_byte (uint8_t d);
uint16_t inc_word (uint16_t d);
uint32_t inc_long (uint32_t d);
uint8_t or_byte (uint8_t d, uint8_t s);
uint16_t or_word (uint16_t d, uint16_t s);
uint32_t or_long (uint32_t d, uint32_t s);
uint8_t neg_byte (uint8_t s);
uint16_t neg_word (uint16_t s);
uint32_t neg_long (uint32_t s);
uint8_t not_byte (uint8_t s);
uint16_t not_word (uint16_t s);
uint32_t not_long (uint32_t s);
uint8_t rcl_byte (uint8_t d, uint8_t s);
uint16_t rcl_word (uint16_t d, uint8_t s);
uint32_t rcl_long (uint32_t d, uint8_t s);
uint8_t rcr_byte (uint8_t d, uint8_t s);
uint16_t rcr_word (uint16_t d, uint8_t s);
uint32_t rcr_long (uint32_t d, uint8_t s);
uint8_t rol_byte (uint8_t d, uint8_t s);
uint16_t rol_word (uint16_t d, uint8_t s);
uint32_t rol_long (uint32_t d, uint8_t s);
uint8_t ror_byte (uint8_t d, uint8_t s);
uint16_t ror_word (uint16_t d, uint8_t s);
uint32_t ror_long (uint32_t d, uint8_t s);
uint8_t shl_byte (uint8_t d, uint8_t s);
uint16_t shl_word (uint16_t d, uint8_t s);
uint32_t shl_long (uint32_t d, uint8_t s);
uint8_t shr_byte (uint8_t d, uint8_t s);
uint16_t shr_word (uint16_t d, uint8_t s);
uint32_t shr_long (uint32_t d, uint8_t s);
uint8_t sar_byte (uint8_t d, uint8_t s);
uint16_t sar_word (uint16_t d, uint8_t s);
uint32_t sar_long (uint32_t d, uint8_t s);
uint16_t shld_word (uint16_t d, uint16_t fill, uint8_t s);
uint32_t shld_long (uint32_t d, uint32_t fill, uint8_t s);
uint16_t shrd_word (uint16_t d, uint16_t fill, uint8_t s);
uint32_t shrd_long (uint32_t d, uint32_t fill, uint8_t s);
uint8_t sbb_byte (uint8_t d, uint8_t s);
uint16_t sbb_word (uint16_t d, uint16_t s);
uint32_t sbb_long (uint32_t d, uint32_t s);
uint8_t sub_byte (uint8_t d, uint8_t s);
uint16_t sub_word (uint16_t d, uint16_t s);
uint32_t sub_long (uint32_t d, uint32_t s);
void test_byte (uint8_t d, uint8_t s);
void test_word (uint16_t d, uint16_t s);
void test_long (uint32_t d, uint32_t s);
uint8_t xor_byte (uint8_t d, uint8_t s);
uint16_t xor_word (uint16_t d, uint16_t s);
uint32_t xor_long (uint32_t d, uint32_t s);
void imul_byte (uint8_t s);
void imul_word (uint16_t s);
void imul_long (uint32_t s);
void imul_long_direct(uint32_t *res_lo, uint32_t* res_hi,uint32_t d, uint32_t s);
void mul_byte (uint8_t s);
void mul_word (uint16_t s);
void mul_long (uint32_t s);
void idiv_byte (uint8_t s);
void idiv_word (uint16_t s);
void idiv_long (uint32_t s);
void div_byte (uint8_t s);
void div_word (uint16_t s);
void div_long (uint32_t s);
void ins (int size);
void outs (int size);
uint16_t mem_access_word (int addr);
void push_word (uint16_t w);
void push_long (uint32_t w);
uint16_t pop_word (void);
uint32_t pop_long (void);
#if defined(__HAVE_INLINE_ASSEMBLER__) && !defined(PRIM_OPS_NO_REDEFINE_ASM)
#define aaa_word(d) aaa_word_asm(&M.x86.R_EFLG,d)
#define aas_word(d) aas_word_asm(&M.x86.R_EFLG,d)
#define aad_word(d) aad_word_asm(&M.x86.R_EFLG,d)
#define aam_word(d) aam_word_asm(&M.x86.R_EFLG,d)
#define adc_byte(d,s) adc_byte_asm(&M.x86.R_EFLG,d,s)
#define adc_word(d,s) adc_word_asm(&M.x86.R_EFLG,d,s)
#define adc_long(d,s) adc_long_asm(&M.x86.R_EFLG,d,s)
#define add_byte(d,s) add_byte_asm(&M.x86.R_EFLG,d,s)
#define add_word(d,s) add_word_asm(&M.x86.R_EFLG,d,s)
#define add_long(d,s) add_long_asm(&M.x86.R_EFLG,d,s)
#define and_byte(d,s) and_byte_asm(&M.x86.R_EFLG,d,s)
#define and_word(d,s) and_word_asm(&M.x86.R_EFLG,d,s)
#define and_long(d,s) and_long_asm(&M.x86.R_EFLG,d,s)
#define cmp_byte(d,s) cmp_byte_asm(&M.x86.R_EFLG,d,s)
#define cmp_word(d,s) cmp_word_asm(&M.x86.R_EFLG,d,s)
#define cmp_long(d,s) cmp_long_asm(&M.x86.R_EFLG,d,s)
#define daa_byte(d) daa_byte_asm(&M.x86.R_EFLG,d)
#define das_byte(d) das_byte_asm(&M.x86.R_EFLG,d)
#define dec_byte(d) dec_byte_asm(&M.x86.R_EFLG,d)
#define dec_word(d) dec_word_asm(&M.x86.R_EFLG,d)
#define dec_long(d) dec_long_asm(&M.x86.R_EFLG,d)
#define inc_byte(d) inc_byte_asm(&M.x86.R_EFLG,d)
#define inc_word(d) inc_word_asm(&M.x86.R_EFLG,d)
#define inc_long(d) inc_long_asm(&M.x86.R_EFLG,d)
#define or_byte(d,s) or_byte_asm(&M.x86.R_EFLG,d,s)
#define or_word(d,s) or_word_asm(&M.x86.R_EFLG,d,s)
#define or_long(d,s) or_long_asm(&M.x86.R_EFLG,d,s)
#define neg_byte(s) neg_byte_asm(&M.x86.R_EFLG,s)
#define neg_word(s) neg_word_asm(&M.x86.R_EFLG,s)
#define neg_long(s) neg_long_asm(&M.x86.R_EFLG,s)
#define not_byte(s) not_byte_asm(&M.x86.R_EFLG,s)
#define not_word(s) not_word_asm(&M.x86.R_EFLG,s)
#define not_long(s) not_long_asm(&M.x86.R_EFLG,s)
#define rcl_byte(d,s) rcl_byte_asm(&M.x86.R_EFLG,d,s)
#define rcl_word(d,s) rcl_word_asm(&M.x86.R_EFLG,d,s)
#define rcl_long(d,s) rcl_long_asm(&M.x86.R_EFLG,d,s)
#define rcr_byte(d,s) rcr_byte_asm(&M.x86.R_EFLG,d,s)
#define rcr_word(d,s) rcr_word_asm(&M.x86.R_EFLG,d,s)
#define rcr_long(d,s) rcr_long_asm(&M.x86.R_EFLG,d,s)
#define rol_byte(d,s) rol_byte_asm(&M.x86.R_EFLG,d,s)
#define rol_word(d,s) rol_word_asm(&M.x86.R_EFLG,d,s)
#define rol_long(d,s) rol_long_asm(&M.x86.R_EFLG,d,s)
#define ror_byte(d,s) ror_byte_asm(&M.x86.R_EFLG,d,s)
#define ror_word(d,s) ror_word_asm(&M.x86.R_EFLG,d,s)
#define ror_long(d,s) ror_long_asm(&M.x86.R_EFLG,d,s)
#define shl_byte(d,s) shl_byte_asm(&M.x86.R_EFLG,d,s)
#define shl_word(d,s) shl_word_asm(&M.x86.R_EFLG,d,s)
#define shl_long(d,s) shl_long_asm(&M.x86.R_EFLG,d,s)
#define shr_byte(d,s) shr_byte_asm(&M.x86.R_EFLG,d,s)
#define shr_word(d,s) shr_word_asm(&M.x86.R_EFLG,d,s)
#define shr_long(d,s) shr_long_asm(&M.x86.R_EFLG,d,s)
#define sar_byte(d,s) sar_byte_asm(&M.x86.R_EFLG,d,s)
#define sar_word(d,s) sar_word_asm(&M.x86.R_EFLG,d,s)
#define sar_long(d,s) sar_long_asm(&M.x86.R_EFLG,d,s)
#define shld_word(d,fill,s) shld_word_asm(&M.x86.R_EFLG,d,fill,s)
#define shld_long(d,fill,s) shld_long_asm(&M.x86.R_EFLG,d,fill,s)
#define shrd_word(d,fill,s) shrd_word_asm(&M.x86.R_EFLG,d,fill,s)
#define shrd_long(d,fill,s) shrd_long_asm(&M.x86.R_EFLG,d,fill,s)
#define sbb_byte(d,s) sbb_byte_asm(&M.x86.R_EFLG,d,s)
#define sbb_word(d,s) sbb_word_asm(&M.x86.R_EFLG,d,s)
#define sbb_long(d,s) sbb_long_asm(&M.x86.R_EFLG,d,s)
#define sub_byte(d,s) sub_byte_asm(&M.x86.R_EFLG,d,s)
#define sub_word(d,s) sub_word_asm(&M.x86.R_EFLG,d,s)
#define sub_long(d,s) sub_long_asm(&M.x86.R_EFLG,d,s)
#define test_byte(d,s) test_byte_asm(&M.x86.R_EFLG,d,s)
#define test_word(d,s) test_word_asm(&M.x86.R_EFLG,d,s)
#define test_long(d,s) test_long_asm(&M.x86.R_EFLG,d,s)
#define xor_byte(d,s) xor_byte_asm(&M.x86.R_EFLG,d,s)
#define xor_word(d,s) xor_word_asm(&M.x86.R_EFLG,d,s)
#define xor_long(d,s) xor_long_asm(&M.x86.R_EFLG,d,s)
#define imul_byte(s) imul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s)
#define imul_word(s) imul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s)
#define imul_long(s) imul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s)
#define imul_long_direct(res_lo,res_hi,d,s) imul_long_asm(&M.x86.R_EFLG,res_lo,res_hi,d,s)
#define mul_byte(s) mul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s)
#define mul_word(s) mul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s)
#define mul_long(s) mul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s)
#define idiv_byte(s) idiv_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s)
#define idiv_word(s) idiv_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s)
#define idiv_long(s) idiv_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s)
#define div_byte(s) div_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s)
#define div_word(s) div_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s)
#define div_long(s) div_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s)
#endif
#ifdef __cplusplus
} /* End of "C" linkage for C++ */
#endif
#endif /* __X86EMU_PRIM_OPS_H */

View File

@@ -1,358 +0,0 @@
/****************************************************************************
*
* 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.
*
****************************************************************************/
/* $XFree86: xc/extras/x86emu/include/x86emu/regs.h,v 1.3 2001/10/28 03:32:25 tsi Exp $ */
#ifndef __X86EMU_REGS_H
#define __X86EMU_REGS_H
#include "x86debug.h"
/*---------------------- Macros and type definitions ----------------------*/
//#pragma pack(1)
/*
* 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.
*/
typedef struct {
uint32_t e_reg;
} I32_reg_t;
typedef struct {
uint16_t filler0, x_reg;
} I16_reg_t;
typedef struct {
uint8_t filler0, filler1, h_reg, l_reg;
} I8_reg_t;
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;
uint32_t FLAGS;
};
/*
* Segment registers here represent the 16 bit quantities
* CS, DS, ES, SS.
*/
struct i386_segment_regs {
uint16_t 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
*/
uint32_t mode;
volatile int intr; /* mask of pending interrupts */
int debug;
#ifdef DBG_X86EMU
int check;
uint16_t saved_ip;
uint16_t saved_cs;
int enc_pos;
int enc_str_pos;
// char decode_buf[32]; /* encoded byte stream */
char decoded_buf[256]; /* disassembled strings */
#endif
uint8_t intno;
uint8_t __pad[3];
} X86EMU_regs;
/****************************************************************************
REMARKS:
Structure maintaining the emulator machine state.
MEMBERS:
mem_base - Base real mode memory for the emulator
abseg - Base for the absegment
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;
unsigned long abseg;
void* private;
X86EMU_regs x86;
} X86EMU_sysEnv;
//#pragma pack()
/*----------------------------- 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
#define X86_EAX M.x86.R_EAX
#define X86_EBX M.x86.R_EBX
#define X86_ECX M.x86.R_ECX
#define X86_EDX M.x86.R_EDX
#define X86_ESI M.x86.R_ESI
#define X86_EDI M.x86.R_EDI
#define X86_EBP M.x86.R_EBP
#define X86_EIP M.x86.R_EIP
#define X86_ESP M.x86.R_ESP
#define X86_EFLAGS M.x86.R_EFLG
#define X86_FLAGS M.x86.R_FLG
#define X86_AX M.x86.R_AX
#define X86_BX M.x86.R_BX
#define X86_CX M.x86.R_CX
#define X86_DX M.x86.R_DX
#define X86_SI M.x86.R_SI
#define X86_DI M.x86.R_DI
#define X86_BP M.x86.R_BP
#define X86_IP M.x86.R_IP
#define X86_SP M.x86.R_SP
#define X86_CS M.x86.R_CS
#define X86_DS M.x86.R_DS
#define X86_ES M.x86.R_ES
#define X86_SS M.x86.R_SS
#define X86_FS M.x86.R_FS
#define X86_GS M.x86.R_GS
#define X86_AL M.x86.R_AL
#define X86_BL M.x86.R_BL
#define X86_CL M.x86.R_CL
#define X86_DL M.x86.R_DL
#define X86_AH M.x86.R_AH
#define X86_BH M.x86.R_BH
#define X86_CH M.x86.R_CH
#define X86_DH M.x86.R_DH
/*-------------------------- Function Prototypes --------------------------*/
/* Function to log information at runtime */
#ifdef __cplusplus
} /* End of "C" linkage for C++ */
#endif
#endif /* __X86EMU_REGS_H */

View File

@@ -65,3 +65,18 @@ _rom_entry:
/* initialize any hardware specific issues */
bra _initialize_hardware
#ifdef _NOT_USED_
.globl ___muldi3
.extern __muldi3
___muldi3: jmp __muldi3
.globl ___divdi3
.extern __divdi3
___divdi3: jmp __divdi3
.globl ___moddi3
.extern __moddi3
___moddi3: jmp __moddi3
.globl ___modsi3
.extern __modsi3
___modsi3: jmp __modsi3
#endif /* _NOT_USED_ */

View File

@@ -1,5 +1,4 @@
#define RINFO_ONLY
#include "x86debug.h"
#include "radeonfb.h"
#include "bas_printf.h"
#include "bas_string.h"

View File

@@ -1,451 +0,0 @@
/****************************************************************************
*
* Realmode X86 Emulator Library
*
* Copyright (C) 1991-2004 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 "bas_types.h"
#include "bas_printf.h"
#include "bas_string.h"
#include "x86debug.h"
#include "x86emui.h"
/*----------------------------- Implementation ----------------------------*/
#ifdef DBG_X86EMU
static void print_encoded_bytes (uint16_t s, uint16_t 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())
{
xprintf("%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!
*/
xprintf("%x:%x ", M.x86.saved_cs, M.x86.saved_ip);
print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
print_decoded_instruction();
}
#if 0
static void disassemble_forward (uint16_t seg, uint16_t 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)(((uint32_t)M.x86.R_CS<<4) + (M.x86.R_IP++));
(x86emu_optab[op1])(op1);
}
/* end major hack mode. */
}
#endif
void x86emu_check_ip_access (void)
{
/* NULL as of now */
}
void x86emu_check_sp_access (void)
{
}
void x86emu_check_mem_access(uint32_t dummy)
{
/* check bounds, etc */
}
void x86emu_check_data_access(unsigned int dummy1, unsigned int 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 (uint16_t s, uint16_t 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));
}
xprintf("%-20s", buf1);
}
static void print_decoded_instruction (void)
{
xprintf("%s", M.x86.decoded_buf);
}
void x86emu_print_int_vect(uint16_t iv)
{
uint16_t seg,off;
if (iv > 256)
return;
seg = fetch_data_word_abs(0, iv * 4);
off = fetch_data_word_abs(0, iv *4 + 2);
xprintf("%04x:%04x", seg, off);
}
void X86EMU_dump_memory (uint16_t seg, uint16_t off, uint32_t amt)
{
uint32_t start = off & 0xfffffff0;
uint32_t end = (off + 16) & 0xfffffff0;
uint32_t i;
uint32_t current;
current = start;
while (end <= off + amt) {
xprintf("%04x:%04x ", seg, start);
for (i = start; i < off; i++)
xprintf(" ");
for ( ; i< end; i++)
xprintf("%02x", fetch_data_byte_abs(seg, i));
xprintf("\r\n");
start = end;
end = start + 16;
}
}
void x86emu_single_step (void)
{
#if 0
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) {
DPRINT("-");
p = fgets(s, 1023, stdin);
cmd = parse_line(s, ps, &ntok);
switch(cmd) {
case 'u':
disassemble_forward(M.x86.saved_cs,(uint16_t)offset,10);
break;
case 'd':
if (ntok == 2) {
segment = M.x86.saved_cs;
offset = ps[1];
X86EMU_dump_memory(segment,(uint16_t)offset,16);
offset += 16;
} else if (ntok == 3) {
segment = ps[1];
offset = ps[2];
X86EMU_dump_memory(segment,(uint16_t)offset,16);
offset += 16;
} else {
segment = M.x86.saved_cs;
X86EMU_dump_memory(segment,(uint16_t)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;
DPRINT("Toggled decoding to ");
DPRINT((noDecode)?"FALSE":"TRUE");
DPRINT("\r\n");
break;
case 't':
case 0:
done = 1;
break;
}
}
#endif
}
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);
}
int X86EMU_set_debug(int debug)
{
return M.x86.debug = debug;
}
#if 0
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
#endif /* DBG_X86EMU */
void x86emu_dump_regs (void)
{
xprintf("\tAX=%04x", M.x86.R_AX);
xprintf(" BX=%04x", M.x86.R_BX);
xprintf(" CX=%04x", M.x86.R_CX);
xprintf(" DX=%04x", M.x86.R_DX);
xprintf(" SP=%04x", M.x86.R_SP);
xprintf(" BP=%04x", M.x86.R_BP);
xprintf(" SI=%04x", M.x86.R_SI);
xprintf(" DI=%04x", M.x86.R_DI);
xprintf("\r\n");
xprintf("\tDS=%04x", M.x86.R_DS);
xprintf(" ES=%04x", M.x86.R_ES);
xprintf(" SS=%04x", M.x86.R_SS);
xprintf(" CS=%04x", M.x86.R_CS);
xprintf(" IP=%04x", M.x86.R_IP);
if (ACCESS_FLAG(F_OF)) xprintf("OV "); /* CHECKED... */
else xprintf("NV ");
if (ACCESS_FLAG(F_DF)) xprintf("DN ");
else xprintf("UP ");
if (ACCESS_FLAG(F_IF)) xprintf("EI ");
else xprintf("DI ");
if (ACCESS_FLAG(F_SF)) xprintf("NG ");
else xprintf("PL ");
if (ACCESS_FLAG(F_ZF)) xprintf("ZR ");
else xprintf("NZ ");
if (ACCESS_FLAG(F_AF)) xprintf("AC ");
else xprintf("NA ");
if (ACCESS_FLAG(F_PF)) xprintf("PE ");
else xprintf("PO ");
if (ACCESS_FLAG(F_CF)) xprintf("CY ");
else xprintf("NC ");
xprintf("\r\n");
}
void x86emu_dump_xregs (void)
{
xprintf(" EAX=%08x", M.x86.R_EAX );
xprintf(" EBX=%08x", M.x86.R_EBX );
xprintf(" ECX=%08x", M.x86.R_ECX );
xprintf(" EDX=%08x", M.x86.R_EDX );
xprintf("\r\n");
xprintf(" ESP=%08x", M.x86.R_ESP );
xprintf(" EBP=%08x", M.x86.R_EBP );
xprintf(" ESI=%08x", M.x86.R_ESI );
xprintf(" EDI=%08x", M.x86.R_EDI );
xprintf("\r\n");
xprintf(" DS=%08x", M.x86.R_DS );
xprintf(" ES=%08x", M.x86.R_ES );
xprintf(" SS=%08x", M.x86.R_SS );
xprintf(" CS=%08x", M.x86.R_CS );
xprintf(" EIP%08x=", M.x86.R_EIP );
xprintf("\r\n\t");
if (ACCESS_FLAG(F_OF)) xprintf("OV "); /* CHECKED... */
else xprintf("NV ");
if (ACCESS_FLAG(F_DF)) xprintf("DN ");
else xprintf("UP ");
if (ACCESS_FLAG(F_IF)) xprintf("EI ");
else xprintf("DI ");
if (ACCESS_FLAG(F_SF)) xprintf("NG ");
else xprintf("PL ");
if (ACCESS_FLAG(F_ZF)) xprintf("ZR ");
else xprintf("NZ ");
if (ACCESS_FLAG(F_AF)) xprintf("AC ");
else xprintf("NA ");
if (ACCESS_FLAG(F_PF)) xprintf("PE ");
else xprintf("PO ");
if (ACCESS_FLAG(F_CF)) xprintf("CY ");
else xprintf("NC ");
xprintf("\r\n");
}

File diff suppressed because it is too large Load Diff

8112
BaS_gcc/x86emu/x86emu.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,999 +0,0 @@
/****************************************************************************
*
* Realmode X86 Emulator Library
*
* Copyright (C) 1991-2004 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 "x86debug.h"
#include "x86emui.h"
#include "x86fpu.h"
#include "x86fpu_regs.h"
/*----------------------------- Implementation ----------------------------*/
/* opcode=0xd8 */
void x86emuOp_esc_coprocess_d8(uint8_t X86EMU_UNUSED(op1))
{
START_OF_INSTR();
DECODE_PRINTF("ESC D8\r\n");
DECODE_CLEAR_SEGOVR();
END_OF_INSTR_NO_TRACE();
}
#ifdef DBG_X86EMU
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 /* DBG_X86EMU */
/* opcode=0xd9 */
void x86emuOp_esc_coprocess_d9(uint8_t X86EMU_UNUSED(op1))
{
int mod, rl, rh;
unsigned int destoffset;
uint8_t stkelem;
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DBG_X86EMU
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("\r\n");
break;
case 1:
destoffset = decode_rm01_address(rl);
DECODE_PRINTF("\r\n");
break;
case 2:
destoffset = decode_rm10_address(rl);
DECODE_PRINTF("\r\n");
break;
case 3: /* register to register */
stkelem = (uint8_t)rl;
if (rh < 4)
{
DECODE_PRINTF2("ST(%d)\r\n", stkelem);
}
else
{
DECODE_PRINTF("\r\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;
}
}
}
#endif /* X86EMU_FPU_PRESENT */
DECODE_CLEAR_SEGOVR();
END_OF_INSTR_NO_TRACE();
}
#ifdef DBG_X86EMU
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 /* DBG_X86EMU */
/* opcode=0xda */
void x86emuOp_esc_coprocess_da(uint8_t X86EMU_UNUSED(op1))
{
int mod, rl, rh;
unsigned int destoffset;
uint8_t stkelem;
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("\r\n");
break;
case 1:
destoffset = decode_rm01_address(rl);
DECODE_PRINTF("\r\n");
break;
case 2:
destoffset = decode_rm10_address(rl);
DECODE_PRINTF("\r\n");
break;
case 3: /* register to register */
stkelem = (uint8_t)rl;
DECODE_PRINTF2("\tST(%d),ST\r\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;
}
}
#endif
DECODE_CLEAR_SEGOVR();
END_OF_INSTR_NO_TRACE();
}
#ifdef DBG_X86EMU
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 /* DBG_X86EMU */
/* opcode=0xdb */
void x86emuOp_esc_coprocess_db(uint8_t X86EMU_UNUSED(op1))
{
int mod, rl, rh;
unsigned int destoffset;
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DBG_X86EMU
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\r\n");
break;
case 1:
DECODE_PRINTF("FDISI\r\n");
break;
case 2:
DECODE_PRINTF("FCLEX\r\n");
break;
case 3:
DECODE_PRINTF("FINIT\r\n");
break;
}
}
else
{
DECODE_PRINTF2("ESC_DB %0x\r\n", (mod << 6) + (rh << 3) + (rl));
}
#endif /* DBG_X86EMU */
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;
}
}
#endif
DECODE_CLEAR_SEGOVR();
END_OF_INSTR_NO_TRACE();
}
#ifdef DBG_X86EMU
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 /* DBG_X86EMU */
/* opcode=0xdc */
void x86emuOp_esc_coprocess_dc(uint8_t X86EMU_UNUSED(op1))
{
int mod, rl, rh;
unsigned int destoffset;
uint8_t stkelem;
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("\r\n");
break;
case 1:
destoffset = decode_rm01_address(rl);
DECODE_PRINTF("\r\n");
break;
case 2:
destoffset = decode_rm10_address(rl);
DECODE_PRINTF("\r\n");
break;
case 3: /* register to register */
stkelem = (uint8_t)rl;
DECODE_PRINTF2("\tST(%d),ST\r\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;
}
}
#endif
DECODE_CLEAR_SEGOVR();
END_OF_INSTR_NO_TRACE();
}
#ifdef DBG_X86EMU
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 /* DBG_X86EMU */
/* opcode=0xdd */
void x86emuOp_esc_coprocess_dd(uint8_t X86EMU_UNUSED(op1))
{
int mod, rl, rh;
unsigned int destoffset;
uint8_t stkelem;
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("\r\n");
break;
case 1:
destoffset = decode_rm01_address(rl);
DECODE_PRINTF("\r\n");
break;
case 2:
destoffset = decode_rm10_address(rl);
DECODE_PRINTF("\r\n");
break;
case 3: /* register to register */
stkelem = (uint8_t)rl;
DECODE_PRINTF2("\tST(%d),ST\r\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;
}
}
#endif
DECODE_CLEAR_SEGOVR();
END_OF_INSTR_NO_TRACE();
}
#ifdef DBG_X86EMU
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 /* DBG_X86EMU */
/* opcode=0xde */
void x86emuOp_esc_coprocess_de(uint8_t X86EMU_UNUSED(op1))
{
int mod, rl, rh;
unsigned int destoffset;
uint8_t stkelem;
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("\r\n");
break;
case 1:
destoffset = decode_rm01_address(rl);
DECODE_PRINTF("\r\n");
break;
case 2:
destoffset = decode_rm10_address(rl);
DECODE_PRINTF("\r\n");
break;
case 3: /* register to register */
stkelem = (uint8_t)rl;
DECODE_PRINTF2("\tST(%d),ST\r\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;
}
}
#endif
DECODE_CLEAR_SEGOVR();
END_OF_INSTR_NO_TRACE();
}
#ifdef DBG_X86EMU
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 /* DBG_X86EMU */
/* opcode=0xdf */
void x86emuOp_esc_coprocess_df(uint8_t X86EMU_UNUSED(op1))
{
int mod, rl, rh;
unsigned int destoffset;
uint8_t stkelem;
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("\r\n");
break;
case 1:
destoffset = decode_rm01_address(rl);
DECODE_PRINTF("\r\n");
break;
case 2:
destoffset = decode_rm10_address(rl);
DECODE_PRINTF("\r\n");
break;
case 3: /* register to register */
stkelem = (uint8_t)rl;
DECODE_PRINTF2("\tST(%d)\r\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;
}
}
#endif
DECODE_CLEAR_SEGOVR();
END_OF_INSTR_NO_TRACE();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@
#include "pci.h"
#include "x86emu.h"
#include "x86pcibios.h"
#include "x86debug.h"
extern unsigned short offset_port;

File diff suppressed because it is too large Load Diff

View File

@@ -1,470 +0,0 @@
/****************************************************************************
*
* 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.
*
****************************************************************************/
/* $XFree86: xc/extras/x86emu/src/x86emu/sys.c,v 1.5 2000/08/23 22:10:01 tsi Exp $ */
#include "radeonfb.h"
#include "pci.h"
#include "x86emu.h"
#include "x86regs.h"
#include "x86debug.h"
#include "x86prim_ops.h"
extern uint8_t inb(uint16_t port);
extern uint16_t inw(uint16_t port);
extern uint32_t inl(uint16_t port);
extern void outb(uint8_t val, uint16_t port);
extern void outw(uint16_t val, uint16_t port);
extern void outl(uint32_t val, uint16_t port);
/*------------------------- Global Variables ------------------------------*/
X86EMU_sysEnv _X86EMU_env; /* Global emulator machine state */
X86EMU_intrFuncs _X86EMU_intrTab[256];
extern struct radeonfb_info *rinfo_biosemu;
extern uint32_t offset_mem;
/*----------------------------- Implementation ----------------------------*/
/*
* PARAMETERS:
* addr - Emulator memory address to read
*
* RETURNS:
* Byte value read from emulator memory.
*
* REMARKS:
* Reads a byte value from the emulator memory.
*/
inline uint8_t X86API rdb(uint32_t addr)
{
uint8_t val;
if ((addr >= 0xA0000) && (addr <= 0xBFFFF))
{
val = *(uint8_t *) (offset_mem + addr);
dbg("%s: rdb(%x) = %x\r\n", __FUNCTION__, addr, val);
}
else
{
DB(if (DEBUG_MEM_TRACE())
{
dbg("%s: %p 1 -> %x\r\n", __FUNCTION__, 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.
*/
uint16_t X86API rdw(uint32_t addr)
{
uint16_t val;
if ((addr >= 0xA0000) && (addr <= 0xBFFFF))
{
val = swpw(*(uint16_t *)(offset_mem+addr));
dbg("%s: rdw(%x) = %x\r\n", __FUNCTION__, addr, val);
}
else
{
val = (uint16_t) (* (uint8_t *)(M.mem_base + addr));
val |= (((uint16_t)( *(uint8_t *)(M.mem_base + addr + 1))) << 8);
}
DB(if (DEBUG_MEM_TRACE())
{
dbg("%s: %p 2 -> %x\r\n", __FUNCTION__, 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.
*/
inline uint32_t X86API rdl(uint32_t addr)
{
uint32_t val;
if ((addr >= 0xA0000) && (addr <= 0xBFFFF))
{
val = swpl(*(uint32_t *)(offset_mem + addr));
dbg("%s: rdl(%x) = %x\r\n", __FUNCTION__, addr, val);
}
else
{
val = swpl(*(uint32_t *)(M.mem_base + addr));
}
DB(if (DEBUG_MEM_TRACE())
{
dbg("%s: %p 4 -> %x\r\n", __FUNCTION__, addr, val);
} )
return val;
}
/*
* PARAMETERS:
* addr - Emulator memory address to read
* val - Value to store
*
* REMARKS:
* Writes a byte value to emulator memory.
*/
inline void X86API wrb(uint32_t addr, uint8_t val)
{
if ((addr >= 0xA0000) && (addr <= 0xBFFFF))
{
*(uint8_t *)(offset_mem + addr) = val;
dbg("%s: wrb(%x) = %x\r\n", __FUNCTION__, addr, val);
}
else
{
if (addr >= M.mem_size)
{
DB(
{
dbg("%s: mem_ptr: %p out of range!\r\n", __FUNCTION__, addr);
})
HALT_SYS();
}
*(uint8_t *)(M.mem_base + addr) = val;
}
DB(if (DEBUG_MEM_TRACE())
{
dbg("%s: %p 1 < %x\r\n", __FUNCTION__, addr, val);
} )
}
/*
* PARAMETERS:
* addr - Emulator memory address to read
* val - Value to store
*
* REMARKS:
* Writes a word value to emulator memory.
*/
inline void X86API wrw(uint32_t addr, uint16_t val)
{
if ((addr >= 0xA0000) && (addr <= 0xBFFFF))
{
dbg("%s: wrw(%x) = %x\r\n", __FUNCTION__, addr, val);
*(uint16_t *)(offset_mem+addr) = swpw(val);
}
else
{
if (addr > M.mem_size - 2)
{
DB(
{
dbg("%s: mem_ptr: %p out of range\r\n", __FUNCTION__, addr);
})
HALT_SYS();
}
*(uint8_t *)(M.mem_base + addr) = (uint8_t) val;
*(uint8_t *)(M.mem_base + addr + 1) = (uint8_t) (val >> 8);
}
DB(if (DEBUG_MEM_TRACE())
{
dbg("%s: %p 2 <- %x\r\n", __FUNCTION__, addr, val);
} )
}
/*
* PARAMETERS:
* addr - Emulator memory address to read
* val - Value to store
*
* REMARKS:
* Writes a long value to emulator memory.
*/
inline void X86API wrl(uint32_t addr, uint32_t val)
{
if ((addr >= 0xA0000) && (addr <= 0xBFFFF))
{
dbg("%s: wrl(%x) = %x\r\n", __FUNCTION__, addr, val);
*(uint32_t *)(offset_mem+addr) = swpl(val);
}
else
{
if (addr > M.mem_size - 4)
{
DB(
{
dbg("%s: mem_ptr: address %x out of range!\r\n", __FUNCTION__, addr);
}
)
HALT_SYS();
}
*(uint32_t *)(M.mem_base + addr) = swpl(val);
}
DB(if (DEBUG_MEM_TRACE())
{
dbg("%s: %p 4 <- %x\r\n", __FUNCTION__, addr, val);
} )
}
/*
* PARAMETERS:
* addr - PIO address to read
* RETURN:
* 0
* REMARKS:
* Default PIO byte read function. Doesn't perform real inb.
*/
inline uint8_t X86API p_inb(X86EMU_pioAddr addr)
{
DB(if (DEBUG_IO_TRACE())
{
dbg("%s: inb(%p)\r\n", __FUNCTION__);
} )
return inb(addr);
}
/*
* PARAMETERS:
* addr - PIO address to read
* RETURN:
* 0
* REMARKS:
* Default PIO word read function. Doesn't perform real inw.
*/
inline uint16_t X86API p_inw(X86EMU_pioAddr addr)
{
DB(if (DEBUG_IO_TRACE())
{
dbg("%s: inw(%p)\r\n", __FUNCTION__, addr);
} )
return inw(addr);
}
/*
* PARAMETERS:
* addr - PIO address to read
* RETURN:
* 0
* REMARKS:
* Default PIO long read function. Doesn't perform real inl.
*/
inline uint32_t X86API p_inl(X86EMU_pioAddr addr)
{
DB(if (DEBUG_IO_TRACE())
{
dbg("%s: inl %p\r\n", __FUNCTION__, addr);
} )
return inl(addr);
}
/*
* PARAMETERS:
* addr - PIO address to write
* val - Value to store
* REMARKS:
* Default PIO byte write function. Doesn't perform real outb.
*/
inline void X86API p_outb(X86EMU_pioAddr addr, uint8_t val)
{
DB(if (DEBUG_IO_TRACE())
{
dbg("%s: outb %x -> %x\r\n", __FUNCTION__, val, addr);
} )
outb(val, addr);
return;
}
/*
* PARAMETERS:
* addr - PIO address to write
* val - Value to store
* REMARKS:
* Default PIO word write function. Doesn't perform real outw.
*/
inline void X86API p_outw(X86EMU_pioAddr addr, uint16_t val)
{
DB(if (DEBUG_IO_TRACE())
{
dbg("outw %x -> %x\r\n", __FUNCTION__, val, addr);
} )
outw(val, addr);
return;
}
/*
* PARAMETERS:
* addr - PIO address to write
* val - Value to store
* REMARKS:
* Default PIO ;ong write function. Doesn't perform real outl.
*/
inline void X86API p_outl(X86EMU_pioAddr addr, uint32_t val)
{
DB(if (DEBUG_IO_TRACE())
{
dbg("%s: outl %x -> %x\r\n", __FUNCTION__, val, addr);
} )
outl(val, addr);
return;
}
/*------------------------- Global Variables ------------------------------*/
uint8_t(X86APIP sys_rdb) (uint32_t addr) = rdb;
uint16_t(X86APIP sys_rdw) (uint32_t addr) = rdw;
uint32_t(X86APIP sys_rdl) (uint32_t addr) = rdl;
void (X86APIP sys_wrb) (uint32_t addr, uint8_t val) = wrb;
void (X86APIP sys_wrw) (uint32_t addr, uint16_t val) = wrw;
void (X86APIP sys_wrl) (uint32_t addr, uint32_t val) = wrl;
uint8_t(X86APIP sys_inb) (X86EMU_pioAddr addr) = p_inb;
uint16_t(X86APIP sys_inw) (X86EMU_pioAddr addr) = p_inw;
uint32_t(X86APIP sys_inl) (X86EMU_pioAddr addr) = p_inl;
void (X86APIP sys_outb) (X86EMU_pioAddr addr, uint8_t val) = p_outb;
void (X86APIP sys_outw) (X86EMU_pioAddr addr, uint16_t val) = p_outw;
void (X86APIP sys_outl) (X86EMU_pioAddr addr, uint32_t val) = p_outl;
/*----------------------------- Setup -------------------------------------*/
#if 0 // cannot works whith data in flash
/****************************************************************************
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;
}
#endif
/****************************************************************************
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((uint16_t) 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;
}
void X86EMU_setMemBase(void *base, unsigned long size)
{
M.mem_base = (int) base;
M.mem_size = size;
}