Add a clean copy of the x86emu library.
This commit is contained in:
parent
b8cb840c12
commit
eb96ea5d28
1
plat/pc86/emu/README.md
Normal file
1
plat/pc86/emu/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
The x86emu directory contains a copy of the xorg 8086 emulation library from
the X server. It's distributable under the MIT/X11 license, and so is
compatible with the ACK.
|
1847
plat/pc86/emu/x86emu/COPYING
Normal file
1847
plat/pc86/emu/x86emu/COPYING
Normal file
File diff suppressed because it is too large
Load diff
29
plat/pc86/emu/x86emu/Makefile.am
Normal file
29
plat/pc86/emu/x86emu/Makefile.am
Normal file
|
@ -0,0 +1,29 @@
|
|||
if INT10_X86EMU
|
||||
noinst_LTLIBRARIES = libx86emu.la
|
||||
endif
|
||||
|
||||
libx86emu_la_SOURCES = debug.c \
|
||||
decode.c \
|
||||
fpu.c \
|
||||
ops2.c \
|
||||
ops.c \
|
||||
prim_ops.c \
|
||||
sys.c \
|
||||
x86emu.h
|
||||
|
||||
AM_CPPFLAGS =
|
||||
|
||||
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
|
||||
|
||||
EXTRA_DIST = validate.c \
|
||||
x86emu/debug.h \
|
||||
x86emu/decode.h \
|
||||
x86emu/fpu.h \
|
||||
x86emu/fpu_regs.h \
|
||||
x86emu/ops.h \
|
||||
x86emu/prim_asm.h \
|
||||
x86emu/prim_ops.h \
|
||||
x86emu/prim_x86_gcc.h \
|
||||
x86emu/regs.h \
|
||||
x86emu/types.h \
|
||||
x86emu/x86emui.h
|
487
plat/pc86/emu/x86emu/debug.c
Normal file
487
plat/pc86/emu/x86emu/debug.c
Normal file
|
@ -0,0 +1,487 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: This file contains the code to handle debugging of the
|
||||
* emulator.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "x86emu/x86emui.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#ifndef NO_SYS_HEADERS
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/*----------------------------- Implementation ----------------------------*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static void print_encoded_bytes(u16 s, u16 o);
|
||||
static void print_decoded_instruction(void);
|
||||
static int parse_line(char *s, int *ps, int *n);
|
||||
|
||||
/* should look something like debug's output. */
|
||||
void
|
||||
X86EMU_trace_regs(void)
|
||||
{
|
||||
if (DEBUG_TRACE()) {
|
||||
x86emu_dump_regs();
|
||||
}
|
||||
if (DEBUG_DECODE() && !DEBUG_DECODE_NOPRINT()) {
|
||||
printk("%04x:%04x ", M.x86.saved_cs, M.x86.saved_ip);
|
||||
print_encoded_bytes(M.x86.saved_cs, M.x86.saved_ip);
|
||||
print_decoded_instruction();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
X86EMU_trace_xregs(void)
|
||||
{
|
||||
if (DEBUG_TRACE()) {
|
||||
x86emu_dump_xregs();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_just_disassemble(void)
|
||||
{
|
||||
/*
|
||||
* This routine called if the flag DEBUG_DISASSEMBLE is set kind
|
||||
* of a hack!
|
||||
*/
|
||||
printk("%04x:%04x ", M.x86.saved_cs, M.x86.saved_ip);
|
||||
print_encoded_bytes(M.x86.saved_cs, M.x86.saved_ip);
|
||||
print_decoded_instruction();
|
||||
}
|
||||
|
||||
static void
|
||||
disassemble_forward(u16 seg, u16 off, int n)
|
||||
{
|
||||
X86EMU_sysEnv tregs;
|
||||
int i;
|
||||
u8 op1;
|
||||
|
||||
/*
|
||||
* hack, hack, hack. What we do is use the exact machinery set up
|
||||
* for execution, except that now there is an additional state
|
||||
* flag associated with the "execution", and we are using a copy
|
||||
* of the register struct. All the major opcodes, once fully
|
||||
* decoded, have the following two steps: TRACE_REGS(r,m);
|
||||
* SINGLE_STEP(r,m); which disappear if DEBUG is not defined to
|
||||
* the preprocessor. The TRACE_REGS macro expands to:
|
||||
*
|
||||
* if (debug&DEBUG_DISASSEMBLE)
|
||||
* {just_disassemble(); goto EndOfInstruction;}
|
||||
* if (debug&DEBUG_TRACE) trace_regs(r,m);
|
||||
*
|
||||
* ...... and at the last line of the routine.
|
||||
*
|
||||
* EndOfInstruction: end_instr();
|
||||
*
|
||||
* Up to the point where TRACE_REG is expanded, NO modifications
|
||||
* are done to any register EXCEPT the IP register, for fetch and
|
||||
* decoding purposes.
|
||||
*
|
||||
* This was done for an entirely different reason, but makes a
|
||||
* nice way to get the system to help debug codes.
|
||||
*/
|
||||
tregs = M;
|
||||
tregs.x86.R_IP = off;
|
||||
tregs.x86.R_CS = seg;
|
||||
|
||||
/* reset the decoding buffers */
|
||||
tregs.x86.enc_str_pos = 0;
|
||||
tregs.x86.enc_pos = 0;
|
||||
|
||||
/* turn on the "disassemble only, no execute" flag */
|
||||
tregs.x86.debug |= DEBUG_DISASSEMBLE_F;
|
||||
|
||||
/* DUMP NEXT n instructions to screen in straight_line fashion */
|
||||
/*
|
||||
* This looks like the regular instruction fetch stream, except
|
||||
* that when this occurs, each fetched opcode, upon seeing the
|
||||
* DEBUG_DISASSEMBLE flag set, exits immediately after decoding
|
||||
* the instruction. XXX --- CHECK THAT MEM IS NOT AFFECTED!!!
|
||||
* Note the use of a copy of the register structure...
|
||||
*/
|
||||
for (i = 0; i < n; i++) {
|
||||
op1 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
|
||||
(x86emu_optab[op1]) (op1);
|
||||
}
|
||||
/* end major hack mode. */
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_check_ip_access(void)
|
||||
{
|
||||
/* NULL as of now */
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_check_sp_access(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_check_mem_access(u32 dummy)
|
||||
{
|
||||
/* check bounds, etc */
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_check_data_access(uint dummy1, uint dummy2)
|
||||
{
|
||||
/* check bounds, etc */
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_inc_decoded_inst_len(int x)
|
||||
{
|
||||
M.x86.enc_pos += x;
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_decode_printf(const char *x, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char temp[100];
|
||||
|
||||
va_start(ap, x);
|
||||
vsnprintf(temp, sizeof(temp), x, ap);
|
||||
va_end(ap);
|
||||
sprintf(M.x86.decoded_buf + M.x86.enc_str_pos, "%s", temp);
|
||||
M.x86.enc_str_pos += strlen(temp);
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_end_instr(void)
|
||||
{
|
||||
M.x86.enc_str_pos = 0;
|
||||
M.x86.enc_pos = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
print_encoded_bytes(u16 s, u16 o)
|
||||
{
|
||||
int i;
|
||||
char buf1[64];
|
||||
|
||||
for (i = 0; i < M.x86.enc_pos; i++) {
|
||||
sprintf(buf1 + 2 * i, "%02x", fetch_data_byte_abs(s, o + i));
|
||||
}
|
||||
printk("%-20s", buf1);
|
||||
}
|
||||
|
||||
static void
|
||||
print_decoded_instruction(void)
|
||||
{
|
||||
printk("%s", M.x86.decoded_buf);
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_print_int_vect(u16 iv)
|
||||
{
|
||||
u16 seg, off;
|
||||
|
||||
if (iv > 256)
|
||||
return;
|
||||
seg = fetch_data_word_abs(0, iv * 4);
|
||||
off = fetch_data_word_abs(0, iv * 4 + 2);
|
||||
printk("%04x:%04x ", seg, off);
|
||||
}
|
||||
|
||||
void
|
||||
X86EMU_dump_memory(u16 seg, u16 off, u32 amt)
|
||||
{
|
||||
u32 start = off & 0xfffffff0;
|
||||
u32 end = (off + 16) & 0xfffffff0;
|
||||
u32 i;
|
||||
|
||||
while (end <= off + amt) {
|
||||
printk("%04x:%04x ", seg, start);
|
||||
for (i = start; i < off; i++)
|
||||
printk(" ");
|
||||
for (; i < end; i++)
|
||||
printk("%02x ", fetch_data_byte_abs(seg, i));
|
||||
printk("\n");
|
||||
start = end;
|
||||
end = start + 16;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_single_step(void)
|
||||
{
|
||||
char s[1024];
|
||||
int ps[10];
|
||||
int ntok;
|
||||
int cmd;
|
||||
int done;
|
||||
int segment;
|
||||
int offset;
|
||||
static int breakpoint;
|
||||
static int noDecode = 1;
|
||||
|
||||
if (DEBUG_BREAK()) {
|
||||
if (M.x86.saved_ip != breakpoint) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
|
||||
M.x86.debug |= DEBUG_TRACE_F;
|
||||
M.x86.debug &= ~DEBUG_BREAK_F;
|
||||
print_decoded_instruction();
|
||||
X86EMU_trace_regs();
|
||||
}
|
||||
}
|
||||
done = 0;
|
||||
offset = M.x86.saved_ip;
|
||||
while (!done) {
|
||||
printk("-");
|
||||
(void)fgets(s, 1023, stdin);
|
||||
cmd = parse_line(s, ps, &ntok);
|
||||
switch (cmd) {
|
||||
case 'u':
|
||||
disassemble_forward(M.x86.saved_cs, (u16) offset, 10);
|
||||
break;
|
||||
case 'd':
|
||||
if (ntok == 2) {
|
||||
segment = M.x86.saved_cs;
|
||||
offset = ps[1];
|
||||
X86EMU_dump_memory(segment, (u16) offset, 16);
|
||||
offset += 16;
|
||||
}
|
||||
else if (ntok == 3) {
|
||||
segment = ps[1];
|
||||
offset = ps[2];
|
||||
X86EMU_dump_memory(segment, (u16) offset, 16);
|
||||
offset += 16;
|
||||
}
|
||||
else {
|
||||
segment = M.x86.saved_cs;
|
||||
X86EMU_dump_memory(segment, (u16) offset, 16);
|
||||
offset += 16;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
M.x86.debug ^= DEBUG_TRACECALL_F;
|
||||
break;
|
||||
case 's':
|
||||
M.x86.debug ^= DEBUG_SVC_F | DEBUG_SYS_F | DEBUG_SYSINT_F;
|
||||
break;
|
||||
case 'r':
|
||||
X86EMU_trace_regs();
|
||||
break;
|
||||
case 'x':
|
||||
X86EMU_trace_xregs();
|
||||
break;
|
||||
case 'g':
|
||||
if (ntok == 2) {
|
||||
breakpoint = ps[1];
|
||||
if (noDecode) {
|
||||
M.x86.debug |= DEBUG_DECODE_NOPRINT_F;
|
||||
}
|
||||
else {
|
||||
M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
|
||||
}
|
||||
M.x86.debug &= ~DEBUG_TRACE_F;
|
||||
M.x86.debug |= DEBUG_BREAK_F;
|
||||
done = 1;
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
M.x86.debug |= DEBUG_EXIT;
|
||||
return;
|
||||
case 'P':
|
||||
noDecode = (noDecode) ? 0 : 1;
|
||||
printk("Toggled decoding to %s\n", (noDecode) ? "FALSE" : "TRUE");
|
||||
break;
|
||||
case 't':
|
||||
case 0:
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
X86EMU_trace_on(void)
|
||||
{
|
||||
return M.x86.debug |= DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F;
|
||||
}
|
||||
|
||||
int
|
||||
X86EMU_trace_off(void)
|
||||
{
|
||||
return M.x86.debug &= ~(DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F);
|
||||
}
|
||||
|
||||
static int
|
||||
parse_line(char *s, int *ps, int *n)
|
||||
{
|
||||
int cmd;
|
||||
|
||||
*n = 0;
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
ps[*n] = *s;
|
||||
switch (*s) {
|
||||
case '\n':
|
||||
*n += 1;
|
||||
return 0;
|
||||
default:
|
||||
cmd = *s;
|
||||
*n += 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
while (*s != ' ' && *s != '\t' && *s != '\n')
|
||||
s++;
|
||||
|
||||
if (*s == '\n')
|
||||
return cmd;
|
||||
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
|
||||
sscanf(s, "%x", &ps[*n]);
|
||||
*n += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
void
|
||||
x86emu_dump_regs(void)
|
||||
{
|
||||
printk("\tAX=%04x ", M.x86.R_AX);
|
||||
printk("BX=%04x ", M.x86.R_BX);
|
||||
printk("CX=%04x ", M.x86.R_CX);
|
||||
printk("DX=%04x ", M.x86.R_DX);
|
||||
printk("SP=%04x ", M.x86.R_SP);
|
||||
printk("BP=%04x ", M.x86.R_BP);
|
||||
printk("SI=%04x ", M.x86.R_SI);
|
||||
printk("DI=%04x\n", M.x86.R_DI);
|
||||
printk("\tDS=%04x ", M.x86.R_DS);
|
||||
printk("ES=%04x ", M.x86.R_ES);
|
||||
printk("SS=%04x ", M.x86.R_SS);
|
||||
printk("CS=%04x ", M.x86.R_CS);
|
||||
printk("IP=%04x ", M.x86.R_IP);
|
||||
if (ACCESS_FLAG(F_OF))
|
||||
printk("OV "); /* CHECKED... */
|
||||
else
|
||||
printk("NV ");
|
||||
if (ACCESS_FLAG(F_DF))
|
||||
printk("DN ");
|
||||
else
|
||||
printk("UP ");
|
||||
if (ACCESS_FLAG(F_IF))
|
||||
printk("EI ");
|
||||
else
|
||||
printk("DI ");
|
||||
if (ACCESS_FLAG(F_SF))
|
||||
printk("NG ");
|
||||
else
|
||||
printk("PL ");
|
||||
if (ACCESS_FLAG(F_ZF))
|
||||
printk("ZR ");
|
||||
else
|
||||
printk("NZ ");
|
||||
if (ACCESS_FLAG(F_AF))
|
||||
printk("AC ");
|
||||
else
|
||||
printk("NA ");
|
||||
if (ACCESS_FLAG(F_PF))
|
||||
printk("PE ");
|
||||
else
|
||||
printk("PO ");
|
||||
if (ACCESS_FLAG(F_CF))
|
||||
printk("CY ");
|
||||
else
|
||||
printk("NC ");
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
void
|
||||
x86emu_dump_xregs(void)
|
||||
{
|
||||
printk("\tEAX=%08x ", M.x86.R_EAX);
|
||||
printk("EBX=%08x ", M.x86.R_EBX);
|
||||
printk("ECX=%08x ", M.x86.R_ECX);
|
||||
printk("EDX=%08x \n", M.x86.R_EDX);
|
||||
printk("\tESP=%08x ", M.x86.R_ESP);
|
||||
printk("EBP=%08x ", M.x86.R_EBP);
|
||||
printk("ESI=%08x ", M.x86.R_ESI);
|
||||
printk("EDI=%08x\n", M.x86.R_EDI);
|
||||
printk("\tDS=%04x ", M.x86.R_DS);
|
||||
printk("ES=%04x ", M.x86.R_ES);
|
||||
printk("SS=%04x ", M.x86.R_SS);
|
||||
printk("CS=%04x ", M.x86.R_CS);
|
||||
printk("EIP=%08x\n\t", M.x86.R_EIP);
|
||||
if (ACCESS_FLAG(F_OF))
|
||||
printk("OV "); /* CHECKED... */
|
||||
else
|
||||
printk("NV ");
|
||||
if (ACCESS_FLAG(F_DF))
|
||||
printk("DN ");
|
||||
else
|
||||
printk("UP ");
|
||||
if (ACCESS_FLAG(F_IF))
|
||||
printk("EI ");
|
||||
else
|
||||
printk("DI ");
|
||||
if (ACCESS_FLAG(F_SF))
|
||||
printk("NG ");
|
||||
else
|
||||
printk("PL ");
|
||||
if (ACCESS_FLAG(F_ZF))
|
||||
printk("ZR ");
|
||||
else
|
||||
printk("NZ ");
|
||||
if (ACCESS_FLAG(F_AF))
|
||||
printk("AC ");
|
||||
else
|
||||
printk("NA ");
|
||||
if (ACCESS_FLAG(F_PF))
|
||||
printk("PE ");
|
||||
else
|
||||
printk("PO ");
|
||||
if (ACCESS_FLAG(F_CF))
|
||||
printk("CY ");
|
||||
else
|
||||
printk("NC ");
|
||||
printk("\n");
|
||||
}
|
1102
plat/pc86/emu/x86emu/decode.c
Normal file
1102
plat/pc86/emu/x86emu/decode.c
Normal file
File diff suppressed because it is too large
Load diff
976
plat/pc86/emu/x86emu/fpu.c
Normal file
976
plat/pc86/emu/x86emu/fpu.c
Normal file
|
@ -0,0 +1,976 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: This file contains the code to implement the decoding and
|
||||
* emulation of the FPU instructions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "x86emu/x86emui.h"
|
||||
|
||||
/*----------------------------- Implementation ----------------------------*/
|
||||
|
||||
/* opcode=0xd8 */
|
||||
void
|
||||
x86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1))
|
||||
{
|
||||
START_OF_INSTR();
|
||||
DECODE_PRINTF("ESC D8\n");
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR_NO_TRACE();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static const 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 const char *x86emu_fpu_op_d9_tab1[] = {
|
||||
"FLD\t", "FLD\t", "FLD\t", "FLD\t",
|
||||
"FLD\t", "FLD\t", "FLD\t", "FLD\t",
|
||||
|
||||
"FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
|
||||
"FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
|
||||
|
||||
"FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
|
||||
"ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",
|
||||
|
||||
"FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
|
||||
"FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
|
||||
|
||||
"FCHS", "FABS", "ESC_D9", "ESC_D9",
|
||||
"FTST", "FXAM", "ESC_D9", "ESC_D9",
|
||||
|
||||
"FLD1", "FLDL2T", "FLDL2E", "FLDPI",
|
||||
"FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",
|
||||
|
||||
"F2XM1", "FYL2X", "FPTAN", "FPATAN",
|
||||
"FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",
|
||||
|
||||
"FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
|
||||
"FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
|
||||
};
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* opcode=0xd9 */
|
||||
void
|
||||
x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1))
|
||||
{
|
||||
int mod, rl, rh;
|
||||
uint destoffset = 0;
|
||||
u8 stkelem = 0;
|
||||
|
||||
START_OF_INSTR();
|
||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
||||
#ifdef DEBUG
|
||||
if (mod != 3) {
|
||||
DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl);
|
||||
}
|
||||
else {
|
||||
DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]);
|
||||
}
|
||||
#endif
|
||||
switch (mod) {
|
||||
case 0:
|
||||
destoffset = decode_rm00_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 1:
|
||||
destoffset = decode_rm01_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 2:
|
||||
destoffset = decode_rm10_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 3: /* register to register */
|
||||
stkelem = (u8) rl;
|
||||
if (rh < 4) {
|
||||
DECODE_PRINTF2("ST(%d)\n", stkelem);
|
||||
}
|
||||
else {
|
||||
DECODE_PRINTF("\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef X86EMU_FPU_PRESENT
|
||||
/* execute */
|
||||
switch (mod) {
|
||||
case 3:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem);
|
||||
break;
|
||||
case 2:
|
||||
switch (rl) {
|
||||
case 0:
|
||||
x86emu_fpu_R_nop();
|
||||
break;
|
||||
default:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem);
|
||||
break;
|
||||
case 4:
|
||||
switch (rl) {
|
||||
case 0:
|
||||
x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
default:
|
||||
/* 2,3,6,7 */
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
switch (rl) {
|
||||
case 0:
|
||||
x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
default:
|
||||
/* 7 */
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
switch (rl) {
|
||||
case 0:
|
||||
x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_R_decstp();
|
||||
break;
|
||||
case 7:
|
||||
x86emu_fpu_R_incstp();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
switch (rl) {
|
||||
case 0:
|
||||
x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
default:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 7:
|
||||
x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) destoffset;
|
||||
(void) stkelem;
|
||||
#endif /* X86EMU_FPU_PRESENT */
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR_NO_TRACE();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static const char *x86emu_fpu_op_da_tab[] = {
|
||||
"FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
|
||||
"FICOMP\tDWORD PTR ",
|
||||
"FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
|
||||
"FIDIVR\tDWORD PTR ",
|
||||
|
||||
"FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
|
||||
"FICOMP\tDWORD PTR ",
|
||||
"FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
|
||||
"FIDIVR\tDWORD PTR ",
|
||||
|
||||
"FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
|
||||
"FICOMP\tDWORD PTR ",
|
||||
"FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
|
||||
"FIDIVR\tDWORD PTR ",
|
||||
|
||||
"ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
|
||||
"ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
|
||||
};
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* opcode=0xda */
|
||||
void
|
||||
x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1))
|
||||
{
|
||||
int mod, rl, rh;
|
||||
uint destoffset = 0;
|
||||
u8 stkelem = 0;
|
||||
|
||||
START_OF_INSTR();
|
||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
||||
DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
|
||||
switch (mod) {
|
||||
case 0:
|
||||
destoffset = decode_rm00_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 1:
|
||||
destoffset = decode_rm01_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 2:
|
||||
destoffset = decode_rm10_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 3: /* register to register */
|
||||
stkelem = (u8) rl;
|
||||
DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
|
||||
break;
|
||||
}
|
||||
#ifdef X86EMU_FPU_PRESENT
|
||||
switch (mod) {
|
||||
case 3:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
default:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
case 7:
|
||||
x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) destoffset;
|
||||
(void) stkelem;
|
||||
#endif
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR_NO_TRACE();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static const char *x86emu_fpu_op_db_tab[] = {
|
||||
"FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
|
||||
"ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
|
||||
|
||||
"FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
|
||||
"ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
|
||||
|
||||
"FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
|
||||
"ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
|
||||
};
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* opcode=0xdb */
|
||||
void
|
||||
x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1))
|
||||
{
|
||||
int mod, rl, rh;
|
||||
uint destoffset = 0;
|
||||
|
||||
START_OF_INSTR();
|
||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
||||
#ifdef DEBUG
|
||||
if (mod != 3) {
|
||||
DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl);
|
||||
}
|
||||
else if (rh == 4) { /* === 11 10 0 nnn */
|
||||
switch (rl) {
|
||||
case 0:
|
||||
DECODE_PRINTF("FENI\n");
|
||||
break;
|
||||
case 1:
|
||||
DECODE_PRINTF("FDISI\n");
|
||||
break;
|
||||
case 2:
|
||||
DECODE_PRINTF("FCLEX\n");
|
||||
break;
|
||||
case 3:
|
||||
DECODE_PRINTF("FINIT\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl));
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
switch (mod) {
|
||||
case 0:
|
||||
destoffset = decode_rm00_address(rl);
|
||||
break;
|
||||
case 1:
|
||||
destoffset = decode_rm01_address(rl);
|
||||
break;
|
||||
case 2:
|
||||
destoffset = decode_rm10_address(rl);
|
||||
break;
|
||||
case 3: /* register to register */
|
||||
break;
|
||||
}
|
||||
#ifdef X86EMU_FPU_PRESENT
|
||||
/* execute */
|
||||
switch (mod) {
|
||||
case 3:
|
||||
switch (rh) {
|
||||
case 4:
|
||||
switch (rl) {
|
||||
case 0:
|
||||
x86emu_fpu_R_feni();
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_R_fdisi();
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_R_fclex();
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_R_finit();
|
||||
break;
|
||||
default:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset);
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
case 7:
|
||||
x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) destoffset;
|
||||
#endif
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR_NO_TRACE();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char *x86emu_fpu_op_dc_tab[] = {
|
||||
"FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
|
||||
"FCOMP\tQWORD PTR ",
|
||||
"FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
|
||||
"FDIVR\tQWORD PTR ",
|
||||
|
||||
"FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
|
||||
"FCOMP\tQWORD PTR ",
|
||||
"FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
|
||||
"FDIVR\tQWORD PTR ",
|
||||
|
||||
"FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
|
||||
"FCOMP\tQWORD PTR ",
|
||||
"FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
|
||||
"FDIVR\tQWORD PTR ",
|
||||
|
||||
"FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
|
||||
"FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
|
||||
};
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* opcode=0xdc */
|
||||
void
|
||||
x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1))
|
||||
{
|
||||
int mod, rl, rh;
|
||||
uint destoffset = 0;
|
||||
u8 stkelem = 0;
|
||||
|
||||
START_OF_INSTR();
|
||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
||||
DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
|
||||
switch (mod) {
|
||||
case 0:
|
||||
destoffset = decode_rm00_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 1:
|
||||
destoffset = decode_rm01_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 2:
|
||||
destoffset = decode_rm10_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 3: /* register to register */
|
||||
stkelem = (u8) rl;
|
||||
DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
|
||||
break;
|
||||
}
|
||||
#ifdef X86EMU_FPU_PRESENT
|
||||
/* execute */
|
||||
switch (mod) {
|
||||
case 3:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 7:
|
||||
x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
case 7:
|
||||
x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) destoffset;
|
||||
(void) stkelem;
|
||||
#endif
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR_NO_TRACE();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static const char *x86emu_fpu_op_dd_tab[] = {
|
||||
"FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
|
||||
"FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
|
||||
|
||||
"FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
|
||||
"FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
|
||||
|
||||
"FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
|
||||
"FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
|
||||
|
||||
"FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
|
||||
"ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
|
||||
};
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* opcode=0xdd */
|
||||
void
|
||||
x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1))
|
||||
{
|
||||
int mod, rl, rh;
|
||||
uint destoffset = 0;
|
||||
u8 stkelem = 0;
|
||||
|
||||
START_OF_INSTR();
|
||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
||||
DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
|
||||
switch (mod) {
|
||||
case 0:
|
||||
destoffset = decode_rm00_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 1:
|
||||
destoffset = decode_rm01_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 2:
|
||||
destoffset = decode_rm10_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 3: /* register to register */
|
||||
stkelem = (u8) rl;
|
||||
DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
|
||||
break;
|
||||
}
|
||||
#ifdef X86EMU_FPU_PRESENT
|
||||
switch (mod) {
|
||||
case 3:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_R_ffree(stkelem);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_R_fxch(stkelem);
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_R_fst(stkelem); /* register version */
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_R_fstp(stkelem); /* register version */
|
||||
break;
|
||||
default:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 7:
|
||||
x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) destoffset;
|
||||
(void) stkelem;
|
||||
#endif
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR_NO_TRACE();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static const char *x86emu_fpu_op_de_tab[] = {
|
||||
"FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
|
||||
"FICOMP\tWORD PTR ",
|
||||
"FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
|
||||
"FIDIVR\tWORD PTR ",
|
||||
|
||||
"FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
|
||||
"FICOMP\tWORD PTR ",
|
||||
"FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
|
||||
"FIDIVR\tWORD PTR ",
|
||||
|
||||
"FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
|
||||
"FICOMP\tWORD PTR ",
|
||||
"FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
|
||||
"FIDIVR\tWORD PTR ",
|
||||
|
||||
"FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
|
||||
"FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
|
||||
};
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* opcode=0xde */
|
||||
void
|
||||
x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1))
|
||||
{
|
||||
int mod, rl, rh;
|
||||
uint destoffset = 0;
|
||||
u8 stkelem = 0;
|
||||
|
||||
START_OF_INSTR();
|
||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
||||
DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
|
||||
switch (mod) {
|
||||
case 0:
|
||||
destoffset = decode_rm00_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 1:
|
||||
destoffset = decode_rm01_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 2:
|
||||
destoffset = decode_rm10_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 3: /* register to register */
|
||||
stkelem = (u8) rl;
|
||||
DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
|
||||
break;
|
||||
}
|
||||
#ifdef X86EMU_FPU_PRESENT
|
||||
switch (mod) {
|
||||
case 3:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 3:
|
||||
if (stkelem == 1)
|
||||
x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP);
|
||||
else
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
case 7:
|
||||
x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 7:
|
||||
x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) destoffset;
|
||||
(void) stkelem;
|
||||
#endif
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR_NO_TRACE();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static const char *x86emu_fpu_op_df_tab[] = {
|
||||
/* mod == 00 */
|
||||
"FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
|
||||
"FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
|
||||
"FISTP\tQWORD PTR ",
|
||||
|
||||
/* mod == 01 */
|
||||
"FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
|
||||
"FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
|
||||
"FISTP\tQWORD PTR ",
|
||||
|
||||
/* mod == 10 */
|
||||
"FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
|
||||
"FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
|
||||
"FISTP\tQWORD PTR ",
|
||||
|
||||
/* mod == 11 */
|
||||
"FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
|
||||
"ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
|
||||
};
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* opcode=0xdf */
|
||||
void
|
||||
x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1))
|
||||
{
|
||||
int mod, rl, rh;
|
||||
uint destoffset = 0;
|
||||
u8 stkelem = 0;
|
||||
|
||||
START_OF_INSTR();
|
||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
||||
DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
|
||||
switch (mod) {
|
||||
case 0:
|
||||
destoffset = decode_rm00_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 1:
|
||||
destoffset = decode_rm01_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 2:
|
||||
destoffset = decode_rm10_address(rl);
|
||||
DECODE_PRINTF("\n");
|
||||
break;
|
||||
case 3: /* register to register */
|
||||
stkelem = (u8) rl;
|
||||
DECODE_PRINTF2("\tST(%d)\n", stkelem);
|
||||
break;
|
||||
}
|
||||
#ifdef X86EMU_FPU_PRESENT
|
||||
switch (mod) {
|
||||
case 3:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_R_ffree(stkelem);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_R_fxch(stkelem);
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_R_fst(stkelem); /* register version */
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_R_fstp(stkelem); /* register version */
|
||||
break;
|
||||
default:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch (rh) {
|
||||
case 0:
|
||||
x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 1:
|
||||
x86emu_fpu_illegal();
|
||||
break;
|
||||
case 2:
|
||||
x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 3:
|
||||
x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset);
|
||||
break;
|
||||
case 4:
|
||||
x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset);
|
||||
break;
|
||||
case 5:
|
||||
x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset);
|
||||
break;
|
||||
case 6:
|
||||
x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset);
|
||||
break;
|
||||
case 7:
|
||||
x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) destoffset;
|
||||
(void) stkelem;
|
||||
#endif
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR_NO_TRACE();
|
||||
}
|
15
plat/pc86/emu/x86emu/meson.build
Normal file
15
plat/pc86/emu/x86emu/meson.build
Normal file
|
@ -0,0 +1,15 @@
|
|||
srcs_xorg_x86emu = [
|
||||
'debug.c',
|
||||
'decode.c',
|
||||
'fpu.c',
|
||||
'ops2.c',
|
||||
'ops.c',
|
||||
'prim_ops.c',
|
||||
'sys.c',
|
||||
]
|
||||
|
||||
xorg_x86emu = static_library('x86emu',
|
||||
srcs_xorg_x86emu,
|
||||
include_directories: [inc, xorg_inc],
|
||||
dependencies: common_dep,
|
||||
)
|
12399
plat/pc86/emu/x86emu/ops.c
Normal file
12399
plat/pc86/emu/x86emu/ops.c
Normal file
File diff suppressed because it is too large
Load diff
BIN
plat/pc86/emu/x86emu/ops.o
Normal file
BIN
plat/pc86/emu/x86emu/ops.o
Normal file
Binary file not shown.
3008
plat/pc86/emu/x86emu/ops2.c
Normal file
3008
plat/pc86/emu/x86emu/ops2.c
Normal file
File diff suppressed because it is too large
Load diff
2859
plat/pc86/emu/x86emu/prim_ops.c
Normal file
2859
plat/pc86/emu/x86emu/prim_ops.c
Normal file
File diff suppressed because it is too large
Load diff
550
plat/pc86/emu/x86emu/sys.c
Normal file
550
plat/pc86/emu/x86emu/sys.c
Normal file
|
@ -0,0 +1,550 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: This file includes subroutines which are related to
|
||||
* programmed I/O and memory access. Included in this module
|
||||
* are default functions with limited usefulness. For real
|
||||
* uses these functions will most likely be overriden by the
|
||||
* user library.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "x86emu.h"
|
||||
#include "x86emu/x86emui.h"
|
||||
#include "x86emu/regs.h"
|
||||
#include "x86emu/debug.h"
|
||||
#include "x86emu/prim_ops.h"
|
||||
#ifndef NO_SYS_HEADERS
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
/* Define some packed structures to use with unaligned accesses */
|
||||
|
||||
struct __una_u64 {
|
||||
u64 x __attribute__ ((packed));
|
||||
};
|
||||
struct __una_u32 {
|
||||
u32 x __attribute__ ((packed));
|
||||
};
|
||||
struct __una_u16 {
|
||||
u16 x __attribute__ ((packed));
|
||||
};
|
||||
|
||||
/* Elemental unaligned loads */
|
||||
|
||||
static __inline__ u64
|
||||
ldq_u(u64 * p)
|
||||
{
|
||||
const struct __una_u64 *ptr = (const struct __una_u64 *) p;
|
||||
|
||||
return ptr->x;
|
||||
}
|
||||
|
||||
static __inline__ u32
|
||||
ldl_u(u32 * p)
|
||||
{
|
||||
const struct __una_u32 *ptr = (const struct __una_u32 *) p;
|
||||
|
||||
return ptr->x;
|
||||
}
|
||||
|
||||
static __inline__ u16
|
||||
ldw_u(u16 * p)
|
||||
{
|
||||
const struct __una_u16 *ptr = (const struct __una_u16 *) p;
|
||||
|
||||
return ptr->x;
|
||||
}
|
||||
|
||||
/* Elemental unaligned stores */
|
||||
|
||||
static __inline__ void
|
||||
stq_u(u64 val, u64 * p)
|
||||
{
|
||||
struct __una_u64 *ptr = (struct __una_u64 *) p;
|
||||
|
||||
ptr->x = val;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
stl_u(u32 val, u32 * p)
|
||||
{
|
||||
struct __una_u32 *ptr = (struct __una_u32 *) p;
|
||||
|
||||
ptr->x = val;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
stw_u(u16 val, u16 * p)
|
||||
{
|
||||
struct __una_u16 *ptr = (struct __una_u16 *) p;
|
||||
|
||||
ptr->x = val;
|
||||
}
|
||||
#else /* !__GNUC__ */
|
||||
|
||||
static __inline__ u64
|
||||
ldq_u(u64 * p)
|
||||
{
|
||||
u64 ret;
|
||||
|
||||
memmove(&ret, p, sizeof(*p));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ u32
|
||||
ldl_u(u32 * p)
|
||||
{
|
||||
u32 ret;
|
||||
|
||||
memmove(&ret, p, sizeof(*p));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ u16
|
||||
ldw_u(u16 * p)
|
||||
{
|
||||
u16 ret;
|
||||
|
||||
memmove(&ret, p, sizeof(*p));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
stq_u(u64 val, u64 * p)
|
||||
{
|
||||
u64 tmp = val;
|
||||
|
||||
memmove(p, &tmp, sizeof(*p));
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
stl_u(u32 val, u32 * p)
|
||||
{
|
||||
u32 tmp = val;
|
||||
|
||||
memmove(p, &tmp, sizeof(*p));
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
stw_u(u16 val, u16 * p)
|
||||
{
|
||||
u16 tmp = val;
|
||||
|
||||
memmove(p, &tmp, sizeof(*p));
|
||||
}
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
/*------------------------- Global Variables ------------------------------*/
|
||||
|
||||
X86EMU_sysEnv _X86EMU_env; /* Global emulator machine state */
|
||||
X86EMU_intrFuncs _X86EMU_intrTab[256];
|
||||
|
||||
/*----------------------------- Implementation ----------------------------*/
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
|
||||
RETURNS:
|
||||
Byte value read from emulator memory.
|
||||
|
||||
REMARKS:
|
||||
Reads a byte value from the emulator memory.
|
||||
****************************************************************************/
|
||||
u8 X86API
|
||||
rdb(u32 addr)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
if (addr > M.mem_size - 1) {
|
||||
DB(printk("mem_read: address %#" PRIx32 " out of range!\n", addr);
|
||||
)
|
||||
HALT_SYS();
|
||||
}
|
||||
val = *(u8 *) (M.mem_base + addr);
|
||||
DB(if (DEBUG_MEM_TRACE())
|
||||
printk("%#08x 1 -> %#x\n", addr, val);)
|
||||
return val;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
|
||||
RETURNS:
|
||||
Word value read from emulator memory.
|
||||
|
||||
REMARKS:
|
||||
Reads a word value from the emulator memory.
|
||||
****************************************************************************/
|
||||
u16 X86API
|
||||
rdw(u32 addr)
|
||||
{
|
||||
u16 val = 0;
|
||||
|
||||
if (addr > M.mem_size - 2) {
|
||||
DB(printk("mem_read: address %#" PRIx32 " out of range!\n", addr);
|
||||
)
|
||||
HALT_SYS();
|
||||
}
|
||||
#ifdef __BIG_ENDIAN__
|
||||
if (addr & 0x1) {
|
||||
val = (*(u8 *) (M.mem_base + addr) |
|
||||
(*(u8 *) (M.mem_base + addr + 1) << 8));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
val = ldw_u((u16 *) (M.mem_base + addr));
|
||||
DB(if (DEBUG_MEM_TRACE())
|
||||
printk("%#08x 2 -> %#x\n", addr, val);)
|
||||
return val;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
|
||||
RETURNS:
|
||||
Long value read from emulator memory.
|
||||
REMARKS:
|
||||
Reads a long value from the emulator memory.
|
||||
****************************************************************************/
|
||||
u32 X86API
|
||||
rdl(u32 addr)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
if (addr > M.mem_size - 4) {
|
||||
DB(printk("mem_read: address %#" PRIx32 " out of range!\n", addr);
|
||||
)
|
||||
HALT_SYS();
|
||||
}
|
||||
#ifdef __BIG_ENDIAN__
|
||||
if (addr & 0x3) {
|
||||
val = (*(u8 *) (M.mem_base + addr + 0) |
|
||||
(*(u8 *) (M.mem_base + addr + 1) << 8) |
|
||||
(*(u8 *) (M.mem_base + addr + 2) << 16) |
|
||||
(*(u8 *) (M.mem_base + addr + 3) << 24));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
val = ldl_u((u32 *) (M.mem_base + addr));
|
||||
DB(if (DEBUG_MEM_TRACE())
|
||||
printk("%#08x 4 -> %#x\n", addr, val);)
|
||||
return val;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
val - Value to store
|
||||
|
||||
REMARKS:
|
||||
Writes a byte value to emulator memory.
|
||||
****************************************************************************/
|
||||
void X86API
|
||||
wrb(u32 addr, u8 val)
|
||||
{
|
||||
DB(if (DEBUG_MEM_TRACE())
|
||||
printk("%#08x 1 <- %#x\n", addr, val);)
|
||||
if (addr > M.mem_size - 1) {
|
||||
DB(printk("mem_write: address %#" PRIx32 " out of range!\n",addr);
|
||||
)
|
||||
HALT_SYS();
|
||||
}
|
||||
*(u8 *) (M.mem_base + addr) = val;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
val - Value to store
|
||||
|
||||
REMARKS:
|
||||
Writes a word value to emulator memory.
|
||||
****************************************************************************/
|
||||
void X86API
|
||||
wrw(u32 addr, u16 val)
|
||||
{
|
||||
DB(if (DEBUG_MEM_TRACE())
|
||||
printk("%#08x 2 <- %#x\n", addr, val);)
|
||||
if (addr > M.mem_size - 2) {
|
||||
DB(printk("mem_write: address %#" PRIx32 " out of range!\n",addr);
|
||||
)
|
||||
HALT_SYS();
|
||||
}
|
||||
#ifdef __BIG_ENDIAN__
|
||||
if (addr & 0x1) {
|
||||
*(u8 *) (M.mem_base + addr + 0) = (val >> 0) & 0xff;
|
||||
*(u8 *) (M.mem_base + addr + 1) = (val >> 8) & 0xff;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
stw_u(val, (u16 *) (M.mem_base + addr));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
val - Value to store
|
||||
|
||||
REMARKS:
|
||||
Writes a long value to emulator memory.
|
||||
****************************************************************************/
|
||||
void X86API
|
||||
wrl(u32 addr, u32 val)
|
||||
{
|
||||
DB(if (DEBUG_MEM_TRACE())
|
||||
printk("%#08x 4 <- %#x\n", addr, val);)
|
||||
if (addr > M.mem_size - 4) {
|
||||
DB(printk("mem_write: address %#" PRIx32 " out of range!\n",addr);
|
||||
)
|
||||
HALT_SYS();
|
||||
}
|
||||
#ifdef __BIG_ENDIAN__
|
||||
if (addr & 0x1) {
|
||||
*(u8 *) (M.mem_base + addr + 0) = (val >> 0) & 0xff;
|
||||
*(u8 *) (M.mem_base + addr + 1) = (val >> 8) & 0xff;
|
||||
*(u8 *) (M.mem_base + addr + 2) = (val >> 16) & 0xff;
|
||||
*(u8 *) (M.mem_base + addr + 3) = (val >> 24) & 0xff;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
stl_u(val, (u32 *) (M.mem_base + addr));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to read
|
||||
RETURN:
|
||||
0
|
||||
REMARKS:
|
||||
Default PIO byte read function. Doesn't perform real inb.
|
||||
****************************************************************************/
|
||||
static u8 X86API
|
||||
p_inb(X86EMU_pioAddr addr)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("inb %#04x \n", addr);)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to read
|
||||
RETURN:
|
||||
0
|
||||
REMARKS:
|
||||
Default PIO word read function. Doesn't perform real inw.
|
||||
****************************************************************************/
|
||||
static u16 X86API
|
||||
p_inw(X86EMU_pioAddr addr)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("inw %#04x \n", addr);)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to read
|
||||
RETURN:
|
||||
0
|
||||
REMARKS:
|
||||
Default PIO long read function. Doesn't perform real inl.
|
||||
****************************************************************************/
|
||||
static u32 X86API
|
||||
p_inl(X86EMU_pioAddr addr)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("inl %#04x \n", addr);)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to write
|
||||
val - Value to store
|
||||
REMARKS:
|
||||
Default PIO byte write function. Doesn't perform real outb.
|
||||
****************************************************************************/
|
||||
static void X86API
|
||||
p_outb(X86EMU_pioAddr addr, u8 val)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("outb %#02x -> %#04x \n", val, addr);)
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to write
|
||||
val - Value to store
|
||||
REMARKS:
|
||||
Default PIO word write function. Doesn't perform real outw.
|
||||
****************************************************************************/
|
||||
static void X86API
|
||||
p_outw(X86EMU_pioAddr addr, u16 val)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("outw %#04x -> %#04x \n", val, addr);)
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to write
|
||||
val - Value to store
|
||||
REMARKS:
|
||||
Default PIO ;ong write function. Doesn't perform real outl.
|
||||
****************************************************************************/
|
||||
static void X86API
|
||||
p_outl(X86EMU_pioAddr addr, u32 val)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("outl %#08x -> %#04x \n", val, addr);)
|
||||
return;
|
||||
}
|
||||
|
||||
/*------------------------- Global Variables ------------------------------*/
|
||||
|
||||
u8(X86APIP sys_rdb) (u32 addr) = rdb;
|
||||
u16(X86APIP sys_rdw) (u32 addr) = rdw;
|
||||
u32(X86APIP sys_rdl) (u32 addr) = rdl;
|
||||
void (X86APIP sys_wrb) (u32 addr, u8 val) = wrb;
|
||||
void (X86APIP sys_wrw) (u32 addr, u16 val) = wrw;
|
||||
void (X86APIP sys_wrl) (u32 addr, u32 val) = wrl;
|
||||
|
||||
u8(X86APIP sys_inb) (X86EMU_pioAddr addr) = p_inb;
|
||||
u16(X86APIP sys_inw) (X86EMU_pioAddr addr) = p_inw;
|
||||
u32(X86APIP sys_inl) (X86EMU_pioAddr addr) = p_inl;
|
||||
void (X86APIP sys_outb) (X86EMU_pioAddr addr, u8 val) = p_outb;
|
||||
void (X86APIP sys_outw) (X86EMU_pioAddr addr, u16 val) = p_outw;
|
||||
void (X86APIP sys_outl) (X86EMU_pioAddr addr, u32 val) = p_outl;
|
||||
|
||||
/*----------------------------- Setup -------------------------------------*/
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
funcs - New memory function pointers to make active
|
||||
|
||||
REMARKS:
|
||||
This function is used to set the pointers to functions which access
|
||||
memory space, allowing the user application to override these functions
|
||||
and hook them out as necessary for their application.
|
||||
****************************************************************************/
|
||||
void
|
||||
X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs)
|
||||
{
|
||||
sys_rdb = funcs->rdb;
|
||||
sys_rdw = funcs->rdw;
|
||||
sys_rdl = funcs->rdl;
|
||||
sys_wrb = funcs->wrb;
|
||||
sys_wrw = funcs->wrw;
|
||||
sys_wrl = funcs->wrl;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
funcs - New programmed I/O function pointers to make active
|
||||
|
||||
REMARKS:
|
||||
This function is used to set the pointers to functions which access
|
||||
I/O space, allowing the user application to override these functions
|
||||
and hook them out as necessary for their application.
|
||||
****************************************************************************/
|
||||
void
|
||||
X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs)
|
||||
{
|
||||
sys_inb = funcs->inb;
|
||||
sys_inw = funcs->inw;
|
||||
sys_inl = funcs->inl;
|
||||
sys_outb = funcs->outb;
|
||||
sys_outw = funcs->outw;
|
||||
sys_outl = funcs->outl;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
funcs - New interrupt vector table to make active
|
||||
|
||||
REMARKS:
|
||||
This function is used to set the pointers to functions which handle
|
||||
interrupt processing in the emulator, allowing the user application to
|
||||
hook interrupts as necessary for their application. Any interrupts that
|
||||
are not hooked by the user application, and reflected and handled internally
|
||||
in the emulator via the interrupt vector table. This allows the application
|
||||
to get control when the code being emulated executes specific software
|
||||
interrupts.
|
||||
****************************************************************************/
|
||||
void
|
||||
X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
_X86EMU_intrTab[i] = NULL;
|
||||
if (funcs) {
|
||||
for (i = 0; i < 256; i++)
|
||||
_X86EMU_intrTab[i] = funcs[i];
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
int - New software interrupt to prepare for
|
||||
|
||||
REMARKS:
|
||||
This function is used to set up the emulator state to exceute a software
|
||||
interrupt. This can be used by the user application code to allow an
|
||||
interrupt to be hooked, examined and then reflected back to the emulator
|
||||
so that the code in the emulator will continue processing the software
|
||||
interrupt as per normal. This essentially allows system code to actively
|
||||
hook and handle certain software interrupts as necessary.
|
||||
****************************************************************************/
|
||||
void
|
||||
X86EMU_prepareForInt(int num)
|
||||
{
|
||||
push_word((u16) M.x86.R_FLG);
|
||||
CLEAR_FLAG(F_IF);
|
||||
CLEAR_FLAG(F_TF);
|
||||
push_word(M.x86.R_CS);
|
||||
M.x86.R_CS = mem_access_word(num * 4 + 2);
|
||||
push_word(M.x86.R_IP);
|
||||
M.x86.R_IP = mem_access_word(num * 4);
|
||||
M.x86.intr = 0;
|
||||
}
|
769
plat/pc86/emu/x86emu/validate.c
Normal file
769
plat/pc86/emu/x86emu/validate.c
Normal file
|
@ -0,0 +1,769 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: Watcom C 10.6 or later
|
||||
* Environment: 32-bit DOS
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Program to validate the x86 emulator library for
|
||||
* correctness. We run the emulator primitive operations
|
||||
* functions against the real x86 CPU, and compare the result
|
||||
* and flags to ensure correctness.
|
||||
*
|
||||
* We use inline assembler to compile and build this program.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "x86emu.h"
|
||||
#include "x86emu/prim_asm.h"
|
||||
|
||||
/*-------------------------- Implementation -------------------------------*/
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define ALL_FLAGS (F_CF | F_PF | F_AF | F_ZF | F_SF | F_OF)
|
||||
|
||||
#define VAL_START_BINARY(parm_type,res_type,dmax,smax,dincr,sincr) \
|
||||
{ \
|
||||
parm_type d,s; \
|
||||
res_type r,r_asm; \
|
||||
ulong flags,inflags; \
|
||||
int f,failed = false; \
|
||||
char buf1[80],buf2[80]; \
|
||||
for (d = 0; d < dmax; d += dincr) { \
|
||||
for (s = 0; s < smax; s += sincr) { \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags; \
|
||||
for (f = 0; f < 2; f++) {
|
||||
|
||||
#define VAL_TEST_BINARY(name) \
|
||||
r_asm = name##_asm(&flags,d,s); \
|
||||
r = name(d,s); \
|
||||
if (r != r_asm || M.x86.R_EFLG != flags) \
|
||||
failed = true; \
|
||||
if (failed || trace) {
|
||||
|
||||
#define VAL_TEST_BINARY_VOID(name) \
|
||||
name##_asm(&flags,d,s); \
|
||||
name(d,s); \
|
||||
r = r_asm = 0; \
|
||||
if (M.x86.R_EFLG != flags) \
|
||||
failed = true; \
|
||||
if (failed || trace) {
|
||||
|
||||
#define VAL_FAIL_BYTE_BYTE_BINARY(name) \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \
|
||||
r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \
|
||||
r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));
|
||||
|
||||
#define VAL_FAIL_WORD_WORD_BINARY(name) \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \
|
||||
r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \
|
||||
r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));
|
||||
|
||||
#define VAL_FAIL_LONG_LONG_BINARY(name) \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \
|
||||
r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \
|
||||
r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));
|
||||
|
||||
#define VAL_END_BINARY() \
|
||||
} \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (!failed) \
|
||||
printk("passed\n"); \
|
||||
}
|
||||
|
||||
#define VAL_BYTE_BYTE_BINARY(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1) \
|
||||
VAL_TEST_BINARY(name) \
|
||||
VAL_FAIL_BYTE_BYTE_BINARY(name) \
|
||||
VAL_END_BINARY()
|
||||
|
||||
#define VAL_WORD_WORD_BINARY(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \
|
||||
VAL_TEST_BINARY(name) \
|
||||
VAL_FAIL_WORD_WORD_BINARY(name) \
|
||||
VAL_END_BINARY()
|
||||
|
||||
#define VAL_LONG_LONG_BINARY(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \
|
||||
VAL_TEST_BINARY(name) \
|
||||
VAL_FAIL_LONG_LONG_BINARY(name) \
|
||||
VAL_END_BINARY()
|
||||
|
||||
#define VAL_VOID_BYTE_BINARY(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1) \
|
||||
VAL_TEST_BINARY_VOID(name) \
|
||||
VAL_FAIL_BYTE_BYTE_BINARY(name) \
|
||||
VAL_END_BINARY()
|
||||
|
||||
#define VAL_VOID_WORD_BINARY(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \
|
||||
VAL_TEST_BINARY_VOID(name) \
|
||||
VAL_FAIL_WORD_WORD_BINARY(name) \
|
||||
VAL_END_BINARY()
|
||||
|
||||
#define VAL_VOID_LONG_BINARY(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \
|
||||
VAL_TEST_BINARY_VOID(name) \
|
||||
VAL_FAIL_LONG_LONG_BINARY(name) \
|
||||
VAL_END_BINARY()
|
||||
|
||||
#define VAL_BYTE_ROTATE(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_BINARY(u8,u8,0xFF,8,1,1) \
|
||||
VAL_TEST_BINARY(name) \
|
||||
VAL_FAIL_BYTE_BYTE_BINARY(name) \
|
||||
VAL_END_BINARY()
|
||||
|
||||
#define VAL_WORD_ROTATE(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_BINARY(u16,u16,0xFF00,16,0x100,1) \
|
||||
VAL_TEST_BINARY(name) \
|
||||
VAL_FAIL_WORD_WORD_BINARY(name) \
|
||||
VAL_END_BINARY()
|
||||
|
||||
#define VAL_LONG_ROTATE(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_BINARY(u32,u32,0xFF000000,32,0x1000000,1) \
|
||||
VAL_TEST_BINARY(name) \
|
||||
VAL_FAIL_LONG_LONG_BINARY(name) \
|
||||
VAL_END_BINARY()
|
||||
|
||||
#define VAL_START_TERNARY(parm_type,res_type,dmax,smax,dincr,sincr,maxshift)\
|
||||
{ \
|
||||
parm_type d,s; \
|
||||
res_type r,r_asm; \
|
||||
u8 shift; \
|
||||
u32 flags,inflags; \
|
||||
int f,failed = false; \
|
||||
char buf1[80],buf2[80]; \
|
||||
for (d = 0; d < dmax; d += dincr) { \
|
||||
for (s = 0; s < smax; s += sincr) { \
|
||||
for (shift = 0; shift < maxshift; shift += 1) { \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags; \
|
||||
for (f = 0; f < 2; f++) {
|
||||
|
||||
#define VAL_TEST_TERNARY(name) \
|
||||
r_asm = name##_asm(&flags,d,s,shift); \
|
||||
r = name(d,s,shift); \
|
||||
if (r != r_asm || M.x86.R_EFLG != flags) \
|
||||
failed = true; \
|
||||
if (failed || trace) {
|
||||
|
||||
#define VAL_FAIL_WORD_WORD_TERNARY(name) \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n", \
|
||||
r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n", \
|
||||
r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags));
|
||||
|
||||
#define VAL_FAIL_LONG_LONG_TERNARY(name) \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n", \
|
||||
r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n", \
|
||||
r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags));
|
||||
|
||||
#define VAL_END_TERNARY() \
|
||||
} \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (!failed) \
|
||||
printk("passed\n"); \
|
||||
}
|
||||
|
||||
#define VAL_WORD_ROTATE_DBL(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_TERNARY(u16,u16,0xFF00,0xFF00,0x100,0x100,16) \
|
||||
VAL_TEST_TERNARY(name) \
|
||||
VAL_FAIL_WORD_WORD_TERNARY(name) \
|
||||
VAL_END_TERNARY()
|
||||
|
||||
#define VAL_LONG_ROTATE_DBL(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_TERNARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000,32) \
|
||||
VAL_TEST_TERNARY(name) \
|
||||
VAL_FAIL_LONG_LONG_TERNARY(name) \
|
||||
VAL_END_TERNARY()
|
||||
|
||||
#define VAL_START_UNARY(parm_type,max,incr) \
|
||||
{ \
|
||||
parm_type d,r,r_asm; \
|
||||
u32 flags,inflags; \
|
||||
int f,failed = false; \
|
||||
char buf1[80],buf2[80]; \
|
||||
for (d = 0; d < max; d += incr) { \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags; \
|
||||
for (f = 0; f < 2; f++) {
|
||||
|
||||
#define VAL_TEST_UNARY(name) \
|
||||
r_asm = name##_asm(&flags,d); \
|
||||
r = name(d); \
|
||||
if (r != r_asm || M.x86.R_EFLG != flags) { \
|
||||
failed = true;
|
||||
|
||||
#define VAL_FAIL_BYTE_UNARY(name) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n", \
|
||||
r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n", \
|
||||
r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));
|
||||
|
||||
#define VAL_FAIL_WORD_UNARY(name) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n", \
|
||||
r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n", \
|
||||
r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));
|
||||
|
||||
#define VAL_FAIL_LONG_UNARY(name) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n", \
|
||||
r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n", \
|
||||
r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));
|
||||
|
||||
#define VAL_END_UNARY() \
|
||||
} \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags | ALL_FLAGS; \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (!failed) \
|
||||
printk("passed\n"); \
|
||||
}
|
||||
|
||||
#define VAL_BYTE_UNARY(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_UNARY(u8,0xFF,0x1) \
|
||||
VAL_TEST_UNARY(name) \
|
||||
VAL_FAIL_BYTE_UNARY(name) \
|
||||
VAL_END_UNARY()
|
||||
|
||||
#define VAL_WORD_UNARY(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_UNARY(u16,0xFF00,0x100) \
|
||||
VAL_TEST_UNARY(name) \
|
||||
VAL_FAIL_WORD_UNARY(name) \
|
||||
VAL_END_UNARY()
|
||||
|
||||
#define VAL_WORD_BYTE_UNARY(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_UNARY(u16,0xFF,0x1) \
|
||||
VAL_TEST_UNARY(name) \
|
||||
VAL_FAIL_WORD_UNARY(name) \
|
||||
VAL_END_UNARY()
|
||||
|
||||
#define VAL_LONG_UNARY(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
VAL_START_UNARY(u32,0xFF000000,0x1000000) \
|
||||
VAL_TEST_UNARY(name) \
|
||||
VAL_FAIL_LONG_UNARY(name) \
|
||||
VAL_END_UNARY()
|
||||
|
||||
#define VAL_BYTE_MUL(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
{ \
|
||||
u8 d,s; \
|
||||
u16 r,r_asm; \
|
||||
u32 flags,inflags; \
|
||||
int f,failed = false; \
|
||||
char buf1[80],buf2[80]; \
|
||||
for (d = 0; d < 0xFF; d += 1) { \
|
||||
for (s = 0; s < 0xFF; s += 1) { \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags; \
|
||||
for (f = 0; f < 2; f++) { \
|
||||
name##_asm(&flags,&r_asm,d,s); \
|
||||
M.x86.R_AL = d; \
|
||||
name(s); \
|
||||
r = M.x86.R_AX; \
|
||||
if (r != r_asm || M.x86.R_EFLG != flags) \
|
||||
failed = true; \
|
||||
if (failed || trace) { \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \
|
||||
r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \
|
||||
r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \
|
||||
} \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (!failed) \
|
||||
printk("passed\n"); \
|
||||
}
|
||||
|
||||
#define VAL_WORD_MUL(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
{ \
|
||||
u16 d,s; \
|
||||
u16 r_lo,r_asm_lo; \
|
||||
u16 r_hi,r_asm_hi; \
|
||||
u32 flags,inflags; \
|
||||
int f,failed = false; \
|
||||
char buf1[80],buf2[80]; \
|
||||
for (d = 0; d < 0xFF00; d += 0x100) { \
|
||||
for (s = 0; s < 0xFF00; s += 0x100) { \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags; \
|
||||
for (f = 0; f < 2; f++) { \
|
||||
name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s); \
|
||||
M.x86.R_AX = d; \
|
||||
name(s); \
|
||||
r_lo = M.x86.R_AX; \
|
||||
r_hi = M.x86.R_DX; \
|
||||
if (r_lo != r_asm_lo || r_hi != r_asm_hi || M.x86.R_EFLG != flags)\
|
||||
failed = true; \
|
||||
if (failed || trace) { \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \
|
||||
r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \
|
||||
r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \
|
||||
} \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (!failed) \
|
||||
printk("passed\n"); \
|
||||
}
|
||||
|
||||
#define VAL_LONG_MUL(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
{ \
|
||||
u32 d,s; \
|
||||
u32 r_lo,r_asm_lo; \
|
||||
u32 r_hi,r_asm_hi; \
|
||||
u32 flags,inflags; \
|
||||
int f,failed = false; \
|
||||
char buf1[80],buf2[80]; \
|
||||
for (d = 0; d < 0xFF000000; d += 0x1000000) { \
|
||||
for (s = 0; s < 0xFF000000; s += 0x1000000) { \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags; \
|
||||
for (f = 0; f < 2; f++) { \
|
||||
name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s); \
|
||||
M.x86.R_EAX = d; \
|
||||
name(s); \
|
||||
r_lo = M.x86.R_EAX; \
|
||||
r_hi = M.x86.R_EDX; \
|
||||
if (r_lo != r_asm_lo || r_hi != r_asm_hi || M.x86.R_EFLG != flags)\
|
||||
failed = true; \
|
||||
if (failed || trace) { \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \
|
||||
r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \
|
||||
r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \
|
||||
} \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (!failed) \
|
||||
printk("passed\n"); \
|
||||
}
|
||||
|
||||
#define VAL_BYTE_DIV(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
{ \
|
||||
u16 d,s; \
|
||||
u8 r_quot,r_rem,r_asm_quot,r_asm_rem; \
|
||||
u32 flags,inflags; \
|
||||
int f,failed = false; \
|
||||
char buf1[80],buf2[80]; \
|
||||
for (d = 0; d < 0xFF00; d += 0x100) { \
|
||||
for (s = 1; s < 0xFF; s += 1) { \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags; \
|
||||
for (f = 0; f < 2; f++) { \
|
||||
M.x86.intr = 0; \
|
||||
M.x86.R_AX = d; \
|
||||
name(s); \
|
||||
r_quot = M.x86.R_AL; \
|
||||
r_rem = M.x86.R_AH; \
|
||||
if (M.x86.intr & INTR_SYNCH) \
|
||||
continue; \
|
||||
name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,s); \
|
||||
if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \
|
||||
failed = true; \
|
||||
if (failed || trace) { \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n", \
|
||||
r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n", \
|
||||
r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \
|
||||
} \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (!failed) \
|
||||
printk("passed\n"); \
|
||||
}
|
||||
|
||||
#define VAL_WORD_DIV(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
{ \
|
||||
u32 d,s; \
|
||||
u16 r_quot,r_rem,r_asm_quot,r_asm_rem; \
|
||||
u32 flags,inflags; \
|
||||
int f,failed = false; \
|
||||
char buf1[80],buf2[80]; \
|
||||
for (d = 0; d < 0xFF000000; d += 0x1000000) { \
|
||||
for (s = 0x100; s < 0xFF00; s += 0x100) { \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags; \
|
||||
for (f = 0; f < 2; f++) { \
|
||||
M.x86.intr = 0; \
|
||||
M.x86.R_AX = d & 0xFFFF; \
|
||||
M.x86.R_DX = d >> 16; \
|
||||
name(s); \
|
||||
r_quot = M.x86.R_AX; \
|
||||
r_rem = M.x86.R_DX; \
|
||||
if (M.x86.intr & INTR_SYNCH) \
|
||||
continue; \
|
||||
name##_asm(&flags,&r_asm_quot,&r_asm_rem,d & 0xFFFF,d >> 16,s);\
|
||||
if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \
|
||||
failed = true; \
|
||||
if (failed || trace) { \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n", \
|
||||
r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n", \
|
||||
r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \
|
||||
} \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (!failed) \
|
||||
printk("passed\n"); \
|
||||
}
|
||||
|
||||
#define VAL_LONG_DIV(name) \
|
||||
printk("Validating %s ... ", #name); \
|
||||
{ \
|
||||
u32 d,s; \
|
||||
u32 r_quot,r_rem,r_asm_quot,r_asm_rem; \
|
||||
u32 flags,inflags; \
|
||||
int f,failed = false; \
|
||||
char buf1[80],buf2[80]; \
|
||||
for (d = 0; d < 0xFF000000; d += 0x1000000) { \
|
||||
for (s = 0x100; s < 0xFF00; s += 0x100) { \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags; \
|
||||
for (f = 0; f < 2; f++) { \
|
||||
M.x86.intr = 0; \
|
||||
M.x86.R_EAX = d; \
|
||||
M.x86.R_EDX = 0; \
|
||||
name(s); \
|
||||
r_quot = M.x86.R_EAX; \
|
||||
r_rem = M.x86.R_EDX; \
|
||||
if (M.x86.intr & INTR_SYNCH) \
|
||||
continue; \
|
||||
name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,0,s); \
|
||||
if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \
|
||||
failed = true; \
|
||||
if (failed || trace) { \
|
||||
if (failed) \
|
||||
printk("fail\n"); \
|
||||
printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n", \
|
||||
r_quot, r_rem, #name, 0, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
|
||||
printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n", \
|
||||
r_asm_quot, r_asm_rem, #name"_asm", 0, d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \
|
||||
} \
|
||||
M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (failed) \
|
||||
break; \
|
||||
} \
|
||||
if (!failed) \
|
||||
printk("passed\n"); \
|
||||
}
|
||||
|
||||
void
|
||||
printk(const char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vfprintf(stdout, fmt, argptr);
|
||||
fflush(stdout);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
char *
|
||||
print_flags(char *buf, ulong flags)
|
||||
{
|
||||
char *separator = "";
|
||||
|
||||
buf[0] = 0;
|
||||
if (flags & F_CF) {
|
||||
strcat(buf, separator);
|
||||
strcat(buf, "CF");
|
||||
separator = ",";
|
||||
}
|
||||
if (flags & F_PF) {
|
||||
strcat(buf, separator);
|
||||
strcat(buf, "PF");
|
||||
separator = ",";
|
||||
}
|
||||
if (flags & F_AF) {
|
||||
strcat(buf, separator);
|
||||
strcat(buf, "AF");
|
||||
separator = ",";
|
||||
}
|
||||
if (flags & F_ZF) {
|
||||
strcat(buf, separator);
|
||||
strcat(buf, "ZF");
|
||||
separator = ",";
|
||||
}
|
||||
if (flags & F_SF) {
|
||||
strcat(buf, separator);
|
||||
strcat(buf, "SF");
|
||||
separator = ",";
|
||||
}
|
||||
if (flags & F_OF) {
|
||||
strcat(buf, separator);
|
||||
strcat(buf, "OF");
|
||||
separator = ",";
|
||||
}
|
||||
if (separator[0] == 0)
|
||||
strcpy(buf, "None");
|
||||
return buf;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc)
|
||||
{
|
||||
ulong def_flags;
|
||||
int trace = false;
|
||||
|
||||
if (argc > 1)
|
||||
trace = true;
|
||||
memset(&M, 0, sizeof(M));
|
||||
def_flags = get_flags_asm() & ~ALL_FLAGS;
|
||||
|
||||
VAL_WORD_UNARY(aaa_word);
|
||||
VAL_WORD_UNARY(aas_word);
|
||||
|
||||
VAL_WORD_UNARY(aad_word);
|
||||
VAL_WORD_UNARY(aam_word);
|
||||
|
||||
VAL_BYTE_BYTE_BINARY(adc_byte);
|
||||
VAL_WORD_WORD_BINARY(adc_word);
|
||||
VAL_LONG_LONG_BINARY(adc_long);
|
||||
|
||||
VAL_BYTE_BYTE_BINARY(add_byte);
|
||||
VAL_WORD_WORD_BINARY(add_word);
|
||||
VAL_LONG_LONG_BINARY(add_long);
|
||||
|
||||
VAL_BYTE_BYTE_BINARY(and_byte);
|
||||
VAL_WORD_WORD_BINARY(and_word);
|
||||
VAL_LONG_LONG_BINARY(and_long);
|
||||
|
||||
VAL_BYTE_BYTE_BINARY(cmp_byte);
|
||||
VAL_WORD_WORD_BINARY(cmp_word);
|
||||
VAL_LONG_LONG_BINARY(cmp_long);
|
||||
|
||||
VAL_BYTE_UNARY(daa_byte);
|
||||
VAL_BYTE_UNARY(das_byte); /* Fails for 0x9A (out of range anyway) */
|
||||
|
||||
VAL_BYTE_UNARY(dec_byte);
|
||||
VAL_WORD_UNARY(dec_word);
|
||||
VAL_LONG_UNARY(dec_long);
|
||||
|
||||
VAL_BYTE_UNARY(inc_byte);
|
||||
VAL_WORD_UNARY(inc_word);
|
||||
VAL_LONG_UNARY(inc_long);
|
||||
|
||||
VAL_BYTE_BYTE_BINARY(or_byte);
|
||||
VAL_WORD_WORD_BINARY(or_word);
|
||||
VAL_LONG_LONG_BINARY(or_long);
|
||||
|
||||
VAL_BYTE_UNARY(neg_byte);
|
||||
VAL_WORD_UNARY(neg_word);
|
||||
VAL_LONG_UNARY(neg_long);
|
||||
|
||||
VAL_BYTE_UNARY(not_byte);
|
||||
VAL_WORD_UNARY(not_word);
|
||||
VAL_LONG_UNARY(not_long);
|
||||
|
||||
VAL_BYTE_ROTATE(rcl_byte);
|
||||
VAL_WORD_ROTATE(rcl_word);
|
||||
VAL_LONG_ROTATE(rcl_long);
|
||||
|
||||
VAL_BYTE_ROTATE(rcr_byte);
|
||||
VAL_WORD_ROTATE(rcr_word);
|
||||
VAL_LONG_ROTATE(rcr_long);
|
||||
|
||||
VAL_BYTE_ROTATE(rol_byte);
|
||||
VAL_WORD_ROTATE(rol_word);
|
||||
VAL_LONG_ROTATE(rol_long);
|
||||
|
||||
VAL_BYTE_ROTATE(ror_byte);
|
||||
VAL_WORD_ROTATE(ror_word);
|
||||
VAL_LONG_ROTATE(ror_long);
|
||||
|
||||
VAL_BYTE_ROTATE(shl_byte);
|
||||
VAL_WORD_ROTATE(shl_word);
|
||||
VAL_LONG_ROTATE(shl_long);
|
||||
|
||||
VAL_BYTE_ROTATE(shr_byte);
|
||||
VAL_WORD_ROTATE(shr_word);
|
||||
VAL_LONG_ROTATE(shr_long);
|
||||
|
||||
VAL_BYTE_ROTATE(sar_byte);
|
||||
VAL_WORD_ROTATE(sar_word);
|
||||
VAL_LONG_ROTATE(sar_long);
|
||||
|
||||
VAL_WORD_ROTATE_DBL(shld_word);
|
||||
VAL_LONG_ROTATE_DBL(shld_long);
|
||||
|
||||
VAL_WORD_ROTATE_DBL(shrd_word);
|
||||
VAL_LONG_ROTATE_DBL(shrd_long);
|
||||
|
||||
VAL_BYTE_BYTE_BINARY(sbb_byte);
|
||||
VAL_WORD_WORD_BINARY(sbb_word);
|
||||
VAL_LONG_LONG_BINARY(sbb_long);
|
||||
|
||||
VAL_BYTE_BYTE_BINARY(sub_byte);
|
||||
VAL_WORD_WORD_BINARY(sub_word);
|
||||
VAL_LONG_LONG_BINARY(sub_long);
|
||||
|
||||
VAL_BYTE_BYTE_BINARY(xor_byte);
|
||||
VAL_WORD_WORD_BINARY(xor_word);
|
||||
VAL_LONG_LONG_BINARY(xor_long);
|
||||
|
||||
VAL_VOID_BYTE_BINARY(test_byte);
|
||||
VAL_VOID_WORD_BINARY(test_word);
|
||||
VAL_VOID_LONG_BINARY(test_long);
|
||||
|
||||
VAL_BYTE_MUL(imul_byte);
|
||||
VAL_WORD_MUL(imul_word);
|
||||
VAL_LONG_MUL(imul_long);
|
||||
|
||||
VAL_BYTE_MUL(mul_byte);
|
||||
VAL_WORD_MUL(mul_word);
|
||||
VAL_LONG_MUL(mul_long);
|
||||
|
||||
VAL_BYTE_DIV(idiv_byte);
|
||||
VAL_WORD_DIV(idiv_word);
|
||||
VAL_LONG_DIV(idiv_long);
|
||||
|
||||
VAL_BYTE_DIV(div_byte);
|
||||
VAL_WORD_DIV(div_word);
|
||||
VAL_LONG_DIV(div_long);
|
||||
|
||||
return 0;
|
||||
}
|
197
plat/pc86/emu/x86emu/x86emu.h
Normal file
197
plat/pc86/emu/x86emu/x86emu.h
Normal file
|
@ -0,0 +1,197 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for public specific functions.
|
||||
* Any application linking against us should only
|
||||
* include this header
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_X86EMU_H
|
||||
#define __X86EMU_X86EMU_H
|
||||
|
||||
#ifdef SCITECH
|
||||
#include "scitech.h"
|
||||
#define X86API _ASMAPI
|
||||
#define X86APIP _ASMAPIP
|
||||
typedef int X86EMU_pioAddr;
|
||||
#else
|
||||
#include "x86emu/types.h"
|
||||
#define X86API
|
||||
#define X86APIP *
|
||||
#endif
|
||||
#include "x86emu/regs.h"
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
#ifdef PACK
|
||||
#pragma PACK /* Don't pack structs with function pointers! */
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Data structure containing ponters to programmed I/O functions used by the
|
||||
emulator. This is used so that the user program can hook all programmed
|
||||
I/O for the emulator to handled as necessary by the user program. By
|
||||
default the emulator contains simple functions that do not do access the
|
||||
hardware in any way. To allow the emualtor access the hardware, you will
|
||||
need to override the programmed I/O functions using the X86EMU_setupPioFuncs
|
||||
function.
|
||||
|
||||
HEADER:
|
||||
x86emu.h
|
||||
|
||||
MEMBERS:
|
||||
inb - Function to read a byte from an I/O port
|
||||
inw - Function to read a word from an I/O port
|
||||
inl - Function to read a dword from an I/O port
|
||||
outb - Function to write a byte to an I/O port
|
||||
outw - Function to write a word to an I/O port
|
||||
outl - Function to write a dword to an I/O port
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
u8(X86APIP inb) (X86EMU_pioAddr addr);
|
||||
u16(X86APIP inw) (X86EMU_pioAddr addr);
|
||||
u32(X86APIP inl) (X86EMU_pioAddr addr);
|
||||
void (X86APIP outb) (X86EMU_pioAddr addr, u8 val);
|
||||
void (X86APIP outw) (X86EMU_pioAddr addr, u16 val);
|
||||
void (X86APIP outl) (X86EMU_pioAddr addr, u32 val);
|
||||
} X86EMU_pioFuncs;
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Data structure containing ponters to memory access functions used by the
|
||||
emulator. This is used so that the user program can hook all memory
|
||||
access functions as necessary for the emulator. By default the emulator
|
||||
contains simple functions that only access the internal memory of the
|
||||
emulator. If you need specialised functions to handle access to different
|
||||
types of memory (ie: hardware framebuffer accesses and BIOS memory access
|
||||
etc), you will need to override this using the X86EMU_setupMemFuncs
|
||||
function.
|
||||
|
||||
HEADER:
|
||||
x86emu.h
|
||||
|
||||
MEMBERS:
|
||||
rdb - Function to read a byte from an address
|
||||
rdw - Function to read a word from an address
|
||||
rdl - Function to read a dword from an address
|
||||
wrb - Function to write a byte to an address
|
||||
wrw - Function to write a word to an address
|
||||
wrl - Function to write a dword to an address
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
u8(X86APIP rdb) (u32 addr);
|
||||
u16(X86APIP rdw) (u32 addr);
|
||||
u32(X86APIP rdl) (u32 addr);
|
||||
void (X86APIP wrb) (u32 addr, u8 val);
|
||||
void (X86APIP wrw) (u32 addr, u16 val);
|
||||
void (X86APIP wrl) (u32 addr, u32 val);
|
||||
} X86EMU_memFuncs;
|
||||
|
||||
/****************************************************************************
|
||||
Here are the default memory read and write
|
||||
function in case they are needed as fallbacks.
|
||||
***************************************************************************/
|
||||
extern u8 X86API rdb(u32 addr);
|
||||
extern u16 X86API rdw(u32 addr);
|
||||
extern u32 X86API rdl(u32 addr);
|
||||
extern void X86API wrb(u32 addr, u8 val);
|
||||
extern void X86API wrw(u32 addr, u16 val);
|
||||
extern void X86API wrl(u32 addr, u32 val);
|
||||
|
||||
#ifdef END_PACK
|
||||
#pragma END_PACK
|
||||
#endif
|
||||
|
||||
/*--------------------- type definitions -----------------------------------*/
|
||||
|
||||
typedef void (X86APIP X86EMU_intrFuncs) (int num);
|
||||
extern X86EMU_intrFuncs _X86EMU_intrTab[256];
|
||||
|
||||
/*-------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
void X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs);
|
||||
void X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs);
|
||||
void X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[]);
|
||||
void X86EMU_prepareForInt(int num);
|
||||
|
||||
/* decode.c */
|
||||
|
||||
void X86EMU_exec(void);
|
||||
void X86EMU_halt_sys(void);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define HALT_SYS() \
|
||||
printk("halt_sys: file %s, line %d\n", __FILE__, __LINE__), \
|
||||
X86EMU_halt_sys()
|
||||
#else
|
||||
#define HALT_SYS() X86EMU_halt_sys()
|
||||
#endif
|
||||
|
||||
/* Debug options */
|
||||
|
||||
#define DEBUG_DECODE_F 0x000001 /* print decoded instruction */
|
||||
#define DEBUG_TRACE_F 0x000002 /* dump regs before/after execution */
|
||||
#define DEBUG_STEP_F 0x000004
|
||||
#define DEBUG_DISASSEMBLE_F 0x000008
|
||||
#define DEBUG_BREAK_F 0x000010
|
||||
#define DEBUG_SVC_F 0x000020
|
||||
#define DEBUG_SAVE_IP_CS_F 0x000040
|
||||
#define DEBUG_FS_F 0x000080
|
||||
#define DEBUG_PROC_F 0x000100
|
||||
#define DEBUG_SYSINT_F 0x000200 /* bios system interrupts. */
|
||||
#define DEBUG_TRACECALL_F 0x000400
|
||||
#define DEBUG_INSTRUMENT_F 0x000800
|
||||
#define DEBUG_MEM_TRACE_F 0x001000
|
||||
#define DEBUG_IO_TRACE_F 0x002000
|
||||
#define DEBUG_TRACECALL_REGS_F 0x004000
|
||||
#define DEBUG_DECODE_NOPRINT_F 0x008000
|
||||
#define DEBUG_EXIT 0x010000
|
||||
#define DEBUG_SYS_F (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F)
|
||||
|
||||
void X86EMU_trace_regs(void);
|
||||
void X86EMU_trace_xregs(void);
|
||||
void X86EMU_dump_memory(u16 seg, u16 off, u32 amt);
|
||||
int X86EMU_trace_on(void);
|
||||
int X86EMU_trace_off(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_X86EMU_H */
|
208
plat/pc86/emu/x86emu/x86emu/debug.h
Normal file
208
plat/pc86/emu/x86emu/x86emu/debug.h
Normal file
|
@ -0,0 +1,208 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for debug definitions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_DEBUG_H
|
||||
#define __X86EMU_DEBUG_H
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
/* checks to be enabled for "runtime" */
|
||||
|
||||
#define CHECK_IP_FETCH_F 0x1
|
||||
#define CHECK_SP_ACCESS_F 0x2
|
||||
#define CHECK_MEM_ACCESS_F 0x4 /*using regular linear pointer */
|
||||
#define CHECK_DATA_ACCESS_F 0x8 /*using segment:offset */
|
||||
|
||||
#ifdef DEBUG
|
||||
#define CHECK_IP_FETCH() (M.x86.check & CHECK_IP_FETCH_F)
|
||||
#define CHECK_SP_ACCESS() (M.x86.check & CHECK_SP_ACCESS_F)
|
||||
#define CHECK_MEM_ACCESS() (M.x86.check & CHECK_MEM_ACCESS_F)
|
||||
#define CHECK_DATA_ACCESS() (M.x86.check & CHECK_DATA_ACCESS_F)
|
||||
#else
|
||||
#define CHECK_IP_FETCH()
|
||||
#define CHECK_SP_ACCESS()
|
||||
#define CHECK_MEM_ACCESS()
|
||||
#define CHECK_DATA_ACCESS()
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_INSTRUMENT() (M.x86.debug & DEBUG_INSTRUMENT_F)
|
||||
#define DEBUG_DECODE() (M.x86.debug & DEBUG_DECODE_F)
|
||||
#define DEBUG_TRACE() (M.x86.debug & DEBUG_TRACE_F)
|
||||
#define DEBUG_STEP() (M.x86.debug & DEBUG_STEP_F)
|
||||
#define DEBUG_DISASSEMBLE() (M.x86.debug & DEBUG_DISASSEMBLE_F)
|
||||
#define DEBUG_BREAK() (M.x86.debug & DEBUG_BREAK_F)
|
||||
#define DEBUG_SVC() (M.x86.debug & DEBUG_SVC_F)
|
||||
#define DEBUG_SAVE_IP_CS() (M.x86.debug & DEBUG_SAVE_IP_CS_F)
|
||||
|
||||
#define DEBUG_FS() (M.x86.debug & DEBUG_FS_F)
|
||||
#define DEBUG_PROC() (M.x86.debug & DEBUG_PROC_F)
|
||||
#define DEBUG_SYSINT() (M.x86.debug & DEBUG_SYSINT_F)
|
||||
#define DEBUG_TRACECALL() (M.x86.debug & DEBUG_TRACECALL_F)
|
||||
#define DEBUG_TRACECALLREGS() (M.x86.debug & DEBUG_TRACECALL_REGS_F)
|
||||
#define DEBUG_SYS() (M.x86.debug & DEBUG_SYS_F)
|
||||
#define DEBUG_MEM_TRACE() (M.x86.debug & DEBUG_MEM_TRACE_F)
|
||||
#define DEBUG_IO_TRACE() (M.x86.debug & DEBUG_IO_TRACE_F)
|
||||
#define DEBUG_DECODE_NOPRINT() (M.x86.debug & DEBUG_DECODE_NOPRINT_F)
|
||||
#else
|
||||
#define DEBUG_INSTRUMENT() 0
|
||||
#define DEBUG_DECODE() 0
|
||||
#define DEBUG_TRACE() 0
|
||||
#define DEBUG_STEP() 0
|
||||
#define DEBUG_DISASSEMBLE() 0
|
||||
#define DEBUG_BREAK() 0
|
||||
#define DEBUG_SVC() 0
|
||||
#define DEBUG_SAVE_IP_CS() 0
|
||||
#define DEBUG_FS() 0
|
||||
#define DEBUG_PROC() 0
|
||||
#define DEBUG_SYSINT() 0
|
||||
#define DEBUG_TRACECALL() 0
|
||||
#define DEBUG_TRACECALLREGS() 0
|
||||
#define DEBUG_SYS() 0
|
||||
#define DEBUG_MEM_TRACE() 0
|
||||
#define DEBUG_IO_TRACE() 0
|
||||
#define DEBUG_DECODE_NOPRINT() 0
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#define DECODE_PRINTF(x) if (DEBUG_DECODE()) \
|
||||
x86emu_decode_printf("%s",x)
|
||||
#define DECODE_PRINTF2(x,y) if (DEBUG_DECODE()) \
|
||||
x86emu_decode_printf(x,y)
|
||||
|
||||
/*
|
||||
* The following allow us to look at the bytes of an instruction. The
|
||||
* first INCR_INSTRN_LEN, is called everytime bytes are consumed in
|
||||
* the decoding process. The SAVE_IP_CS is called initially when the
|
||||
* major opcode of the instruction is accessed.
|
||||
*/
|
||||
#define INC_DECODED_INST_LEN(x) \
|
||||
if (DEBUG_DECODE()) \
|
||||
x86emu_inc_decoded_inst_len(x)
|
||||
|
||||
#define SAVE_IP_CS(x,y) \
|
||||
if (DEBUG_DECODE() | DEBUG_TRACECALL() | DEBUG_BREAK() \
|
||||
| DEBUG_IO_TRACE() | DEBUG_SAVE_IP_CS()) { \
|
||||
M.x86.saved_cs = x; \
|
||||
M.x86.saved_ip = y; \
|
||||
}
|
||||
#else
|
||||
#define INC_DECODED_INST_LEN(x)
|
||||
#define DECODE_PRINTF(x)
|
||||
#define DECODE_PRINTF2(x,y)
|
||||
#define SAVE_IP_CS(x,y)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define TRACE_REGS() \
|
||||
if (DEBUG_DISASSEMBLE()) { \
|
||||
x86emu_just_disassemble(); \
|
||||
goto EndOfTheInstructionProcedure; \
|
||||
} \
|
||||
if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs()
|
||||
#else
|
||||
#define TRACE_REGS()
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define SINGLE_STEP() if (DEBUG_STEP()) x86emu_single_step()
|
||||
#else
|
||||
#define SINGLE_STEP()
|
||||
#endif
|
||||
|
||||
#define TRACE_AND_STEP() \
|
||||
TRACE_REGS(); \
|
||||
SINGLE_STEP()
|
||||
|
||||
#ifdef DEBUG
|
||||
#define START_OF_INSTR()
|
||||
#define END_OF_INSTR() EndOfTheInstructionProcedure: x86emu_end_instr();
|
||||
#define END_OF_INSTR_NO_TRACE() x86emu_end_instr();
|
||||
#else
|
||||
#define START_OF_INSTR()
|
||||
#define END_OF_INSTR()
|
||||
#define END_OF_INSTR_NO_TRACE()
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define CALL_TRACE(u,v,w,x,s) \
|
||||
if (DEBUG_TRACECALLREGS()) \
|
||||
x86emu_dump_regs(); \
|
||||
if (DEBUG_TRACECALL()) \
|
||||
printk("%04x:%04x: CALL %s%04x:%04x\n", u , v, s, w, x);
|
||||
#define RETURN_TRACE(n,u,v) \
|
||||
if (DEBUG_TRACECALLREGS()) \
|
||||
x86emu_dump_regs(); \
|
||||
if (DEBUG_TRACECALL()) \
|
||||
printk("%04x:%04x: %s\n",u,v,n);
|
||||
#else
|
||||
#define CALL_TRACE(u,v,w,x,s)
|
||||
#define RETURN_TRACE(n,u,v)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DB(x) x
|
||||
#else
|
||||
#define DB(x)
|
||||
#endif
|
||||
|
||||
/*-------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
extern void x86emu_inc_decoded_inst_len(int x);
|
||||
extern void x86emu_decode_printf(const char *x, ...) _X_ATTRIBUTE_PRINTF(1,2);
|
||||
extern void x86emu_just_disassemble(void);
|
||||
extern void x86emu_single_step(void);
|
||||
extern void x86emu_end_instr(void);
|
||||
extern void x86emu_dump_regs(void);
|
||||
extern void x86emu_dump_xregs(void);
|
||||
extern void x86emu_print_int_vect(u16 iv);
|
||||
extern void x86emu_instrument_instruction(void);
|
||||
extern void x86emu_check_ip_access(void);
|
||||
extern void x86emu_check_sp_access(void);
|
||||
extern void x86emu_check_mem_access(u32 p);
|
||||
extern void x86emu_check_data_access(uint s, uint o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_DEBUG_H */
|
87
plat/pc86/emu/x86emu/x86emu/decode.h
Normal file
87
plat/pc86/emu/x86emu/x86emu/decode.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for instruction decoding logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_DECODE_H
|
||||
#define __X86EMU_DECODE_H
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
/* Instruction Decoding Stuff */
|
||||
|
||||
#define FETCH_DECODE_MODRM(mod,rh,rl) fetch_decode_modrm(&mod,&rh,&rl)
|
||||
#define DECODE_RM_BYTE_REGISTER(r) decode_rm_byte_register(r)
|
||||
#define DECODE_RM_WORD_REGISTER(r) decode_rm_word_register(r)
|
||||
#define DECODE_RM_LONG_REGISTER(r) decode_rm_long_register(r)
|
||||
#define DECODE_CLEAR_SEGOVR() M.x86.mode &= ~SYSMODE_CLRMASK
|
||||
|
||||
/*-------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
void x86emu_intr_raise(u8 type);
|
||||
void fetch_decode_modrm(int *mod, int *regh, int *regl);
|
||||
u8 fetch_byte_imm(void);
|
||||
u16 fetch_word_imm(void);
|
||||
u32 fetch_long_imm(void);
|
||||
u8 fetch_data_byte(uint offset);
|
||||
u8 fetch_data_byte_abs(uint segment, uint offset);
|
||||
u16 fetch_data_word(uint offset);
|
||||
u16 fetch_data_word_abs(uint segment, uint offset);
|
||||
u32 fetch_data_long(uint offset);
|
||||
u32 fetch_data_long_abs(uint segment, uint offset);
|
||||
void store_data_byte(uint offset, u8 val);
|
||||
void store_data_byte_abs(uint segment, uint offset, u8 val);
|
||||
void store_data_word(uint offset, u16 val);
|
||||
void store_data_word_abs(uint segment, uint offset, u16 val);
|
||||
void store_data_long(uint offset, u32 val);
|
||||
void store_data_long_abs(uint segment, uint offset, u32 val);
|
||||
u8 *decode_rm_byte_register(int reg);
|
||||
u16 *decode_rm_word_register(int reg);
|
||||
u32 *decode_rm_long_register(int reg);
|
||||
u16 *decode_rm_seg_register(int reg);
|
||||
u32 decode_rm00_address(int rm);
|
||||
u32 decode_rm01_address(int rm);
|
||||
u32 decode_rm10_address(int rm);
|
||||
u32 decode_sib_address(int sib, int mod);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_DECODE_H */
|
60
plat/pc86/emu/x86emu/x86emu/fpu.h
Normal file
60
plat/pc86/emu/x86emu/x86emu/fpu.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for FPU instruction decoding.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_FPU_H
|
||||
#define __X86EMU_FPU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
/* these have to be defined, whether 8087 support compiled in or not. */
|
||||
|
||||
extern void x86emuOp_esc_coprocess_d8(u8 op1);
|
||||
extern void x86emuOp_esc_coprocess_d9(u8 op1);
|
||||
extern void x86emuOp_esc_coprocess_da(u8 op1);
|
||||
extern void x86emuOp_esc_coprocess_db(u8 op1);
|
||||
extern void x86emuOp_esc_coprocess_dc(u8 op1);
|
||||
extern void x86emuOp_esc_coprocess_dd(u8 op1);
|
||||
extern void x86emuOp_esc_coprocess_de(u8 op1);
|
||||
extern void x86emuOp_esc_coprocess_df(u8 op1);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_FPU_H */
|
119
plat/pc86/emu/x86emu/x86emu/fpu_regs.h
Normal file
119
plat/pc86/emu/x86emu/x86emu/fpu_regs.h
Normal file
|
@ -0,0 +1,119 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for FPU register definitions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_FPU_REGS_H
|
||||
#define __X86EMU_FPU_REGS_H
|
||||
|
||||
#ifdef X86_FPU_SUPPORT
|
||||
|
||||
#ifdef PACK
|
||||
#pragma PACK
|
||||
#endif
|
||||
|
||||
/* Basic 8087 register can hold any of the following values: */
|
||||
|
||||
union x86_fpu_reg_u {
|
||||
s8 tenbytes[10];
|
||||
double dval;
|
||||
float fval;
|
||||
s16 sval;
|
||||
s32 lval;
|
||||
};
|
||||
|
||||
struct x86_fpu_reg {
|
||||
union x86_fpu_reg_u reg;
|
||||
char tag;
|
||||
};
|
||||
|
||||
/*
|
||||
* Since we are not going to worry about the problems of aliasing
|
||||
* registers, every time a register is modified, its result type is
|
||||
* set in the tag fields for that register. If some operation
|
||||
* attempts to access the type in a way inconsistent with its current
|
||||
* storage format, then we flag the operation. If common, we'll
|
||||
* attempt the conversion.
|
||||
*/
|
||||
|
||||
#define X86_FPU_VALID 0x80
|
||||
#define X86_FPU_REGTYP(r) ((r) & 0x7F)
|
||||
|
||||
#define X86_FPU_WORD 0x0
|
||||
#define X86_FPU_SHORT 0x1
|
||||
#define X86_FPU_LONG 0x2
|
||||
#define X86_FPU_FLOAT 0x3
|
||||
#define X86_FPU_DOUBLE 0x4
|
||||
#define X86_FPU_LDBL 0x5
|
||||
#define X86_FPU_BSD 0x6
|
||||
|
||||
#define X86_FPU_STKTOP 0
|
||||
|
||||
struct x86_fpu_registers {
|
||||
struct x86_fpu_reg x86_fpu_stack[8];
|
||||
int x86_fpu_flags;
|
||||
int x86_fpu_config; /* rounding modes, etc. */
|
||||
short x86_fpu_tos, x86_fpu_bos;
|
||||
};
|
||||
|
||||
#ifdef END_PACK
|
||||
#pragma END_PACK
|
||||
#endif
|
||||
|
||||
/*
|
||||
* There are two versions of the following macro.
|
||||
*
|
||||
* One version is for opcode D9, for which there are more than 32
|
||||
* instructions encoded in the second byte of the opcode.
|
||||
*
|
||||
* The other version, deals with all the other 7 i87 opcodes, for
|
||||
* which there are only 32 strings needed to describe the
|
||||
* instructions.
|
||||
*/
|
||||
|
||||
#endif /* X86_FPU_SUPPORT */
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DECODE_PRINTINSTR32(t,mod,rh,rl) \
|
||||
DECODE_PRINTF(t[(mod<<3)+(rh)]);
|
||||
#define DECODE_PRINTINSTR256(t,mod,rh,rl) \
|
||||
DECODE_PRINTF(t[(mod<<6)+(rh<<3)+(rl)]);
|
||||
#else
|
||||
#define DECODE_PRINTINSTR32(t,mod,rh,rl)
|
||||
#define DECODE_PRINTINSTR256(t,mod,rh,rl)
|
||||
#endif
|
||||
|
||||
#endif /* __X86EMU_FPU_REGS_H */
|
45
plat/pc86/emu/x86emu/x86emu/ops.h
Normal file
45
plat/pc86/emu/x86emu/x86emu/ops.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for operand decoding functions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_OPS_H
|
||||
#define __X86EMU_OPS_H
|
||||
|
||||
extern void (*x86emu_optab[0x100]) (u8 op1);
|
||||
extern void (*x86emu_optab2[0x100]) (u8 op2);
|
||||
|
||||
#endif /* __X86EMU_OPS_H */
|
1053
plat/pc86/emu/x86emu/x86emu/prim_asm.h
Normal file
1053
plat/pc86/emu/x86emu/x86emu/prim_asm.h
Normal file
File diff suppressed because it is too large
Load diff
141
plat/pc86/emu/x86emu/x86emu/prim_ops.h
Normal file
141
plat/pc86/emu/x86emu/x86emu/prim_ops.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for primitive operation functions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_PRIM_OPS_H
|
||||
#define __X86EMU_PRIM_OPS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
u16 aaa_word(u16 d);
|
||||
u16 aas_word(u16 d);
|
||||
u16 aad_word(u16 d);
|
||||
u16 aam_word(u8 d);
|
||||
u8 adc_byte(u8 d, u8 s);
|
||||
u16 adc_word(u16 d, u16 s);
|
||||
u32 adc_long(u32 d, u32 s);
|
||||
u8 add_byte(u8 d, u8 s);
|
||||
u16 add_word(u16 d, u16 s);
|
||||
u32 add_long(u32 d, u32 s);
|
||||
u8 and_byte(u8 d, u8 s);
|
||||
u16 and_word(u16 d, u16 s);
|
||||
u32 and_long(u32 d, u32 s);
|
||||
u8 cmp_byte(u8 d, u8 s);
|
||||
u16 cmp_word(u16 d, u16 s);
|
||||
u32 cmp_long(u32 d, u32 s);
|
||||
u8 daa_byte(u8 d);
|
||||
u8 das_byte(u8 d);
|
||||
u8 dec_byte(u8 d);
|
||||
u16 dec_word(u16 d);
|
||||
u32 dec_long(u32 d);
|
||||
u8 inc_byte(u8 d);
|
||||
u16 inc_word(u16 d);
|
||||
u32 inc_long(u32 d);
|
||||
u8 or_byte(u8 d, u8 s);
|
||||
u16 or_word(u16 d, u16 s);
|
||||
u32 or_long(u32 d, u32 s);
|
||||
u8 neg_byte(u8 s);
|
||||
u16 neg_word(u16 s);
|
||||
u32 neg_long(u32 s);
|
||||
u8 not_byte(u8 s);
|
||||
u16 not_word(u16 s);
|
||||
u32 not_long(u32 s);
|
||||
u8 rcl_byte(u8 d, u8 s);
|
||||
u16 rcl_word(u16 d, u8 s);
|
||||
u32 rcl_long(u32 d, u8 s);
|
||||
u8 rcr_byte(u8 d, u8 s);
|
||||
u16 rcr_word(u16 d, u8 s);
|
||||
u32 rcr_long(u32 d, u8 s);
|
||||
u8 rol_byte(u8 d, u8 s);
|
||||
u16 rol_word(u16 d, u8 s);
|
||||
u32 rol_long(u32 d, u8 s);
|
||||
u8 ror_byte(u8 d, u8 s);
|
||||
u16 ror_word(u16 d, u8 s);
|
||||
u32 ror_long(u32 d, u8 s);
|
||||
u8 shl_byte(u8 d, u8 s);
|
||||
u16 shl_word(u16 d, u8 s);
|
||||
u32 shl_long(u32 d, u8 s);
|
||||
u8 shr_byte(u8 d, u8 s);
|
||||
u16 shr_word(u16 d, u8 s);
|
||||
u32 shr_long(u32 d, u8 s);
|
||||
u8 sar_byte(u8 d, u8 s);
|
||||
u16 sar_word(u16 d, u8 s);
|
||||
u32 sar_long(u32 d, u8 s);
|
||||
u16 shld_word(u16 d, u16 fill, u8 s);
|
||||
u32 shld_long(u32 d, u32 fill, u8 s);
|
||||
u16 shrd_word(u16 d, u16 fill, u8 s);
|
||||
u32 shrd_long(u32 d, u32 fill, u8 s);
|
||||
u8 sbb_byte(u8 d, u8 s);
|
||||
u16 sbb_word(u16 d, u16 s);
|
||||
u32 sbb_long(u32 d, u32 s);
|
||||
u8 sub_byte(u8 d, u8 s);
|
||||
u16 sub_word(u16 d, u16 s);
|
||||
u32 sub_long(u32 d, u32 s);
|
||||
void test_byte(u8 d, u8 s);
|
||||
void test_word(u16 d, u16 s);
|
||||
void test_long(u32 d, u32 s);
|
||||
u8 xor_byte(u8 d, u8 s);
|
||||
u16 xor_word(u16 d, u16 s);
|
||||
u32 xor_long(u32 d, u32 s);
|
||||
void imul_byte(u8 s);
|
||||
void imul_word(u16 s);
|
||||
void imul_long(u32 s);
|
||||
void imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s);
|
||||
void mul_byte(u8 s);
|
||||
void mul_word(u16 s);
|
||||
void mul_long(u32 s);
|
||||
void idiv_byte(u8 s);
|
||||
void idiv_word(u16 s);
|
||||
void idiv_long(u32 s);
|
||||
void div_byte(u8 s);
|
||||
void div_word(u16 s);
|
||||
void div_long(u32 s);
|
||||
void ins(int size);
|
||||
void outs(int size);
|
||||
u16 mem_access_word(int addr);
|
||||
void push_word(u16 w);
|
||||
void push_long(u32 w);
|
||||
u16 pop_word(void);
|
||||
u32 pop_long(void);
|
||||
void cpuid(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_PRIM_OPS_H */
|
77
plat/pc86/emu/x86emu/x86emu/prim_x86_gcc.h
Normal file
77
plat/pc86/emu/x86emu/x86emu/prim_x86_gcc.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Inline helpers for x86emu
|
||||
*
|
||||
* Copyright (C) 2008 Bart Trojanowski, Symbio Technologies, LLC
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* 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: GNU C
|
||||
* Environment: GCC on i386 or x86-64
|
||||
* Developer: Bart Trojanowski
|
||||
*
|
||||
* Description: This file defines a few x86 macros that can be used by the
|
||||
* emulator to execute native instructions.
|
||||
*
|
||||
* For PIC vs non-PIC code refer to:
|
||||
* http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef __X86EMU_PRIM_X86_GCC_H
|
||||
#define __X86EMU_PRIM_X86_GCC_H
|
||||
|
||||
#include "x86emu/types.h"
|
||||
|
||||
#if !defined(__GNUC__) || !(defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__amd64__))
|
||||
#error This file is intended to be used by gcc on i386 or x86-64 system
|
||||
#endif
|
||||
|
||||
#if defined(__PIC__) && defined(__i386__)
|
||||
|
||||
#define X86EMU_HAS_HW_CPUID 1
|
||||
static inline void
|
||||
hw_cpuid(u32 * a, u32 * b, u32 * c, u32 * d)
|
||||
{
|
||||
__asm__ __volatile__("pushl %%ebx \n\t"
|
||||
"cpuid \n\t"
|
||||
"movl %%ebx, %1 \n\t"
|
||||
"popl %%ebx \n\t":"=a"(*a), "=r"(*b),
|
||||
"=c"(*c), "=d"(*d)
|
||||
:"a"(*a), "c"(*c)
|
||||
:"cc");
|
||||
}
|
||||
|
||||
#else /* ! (__PIC__ && __i386__) */
|
||||
|
||||
#define x86EMU_HAS_HW_CPUID 1
|
||||
static inline void
|
||||
hw_cpuid(u32 * a, u32 * b, u32 * c, u32 * d)
|
||||
{
|
||||
__asm__ __volatile__("cpuid":"=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d)
|
||||
:"a"(*a), "c"(*c)
|
||||
:"cc");
|
||||
}
|
||||
|
||||
#endif /* __PIC__ && __i386__ */
|
||||
|
||||
#endif /* __X86EMU_PRIM_X86_GCC_H */
|
340
plat/pc86/emu/x86emu/x86emu/regs.h
Normal file
340
plat/pc86/emu/x86emu/x86emu/regs.h
Normal file
|
@ -0,0 +1,340 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for x86 register definitions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_REGS_H
|
||||
#define __X86EMU_REGS_H
|
||||
|
||||
#include <X11/Xfuncproto.h>
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
#ifdef PACK
|
||||
#pragma PACK
|
||||
#endif
|
||||
|
||||
/*
|
||||
* General EAX, EBX, ECX, EDX type registers. Note that for
|
||||
* portability, and speed, the issue of byte swapping is not addressed
|
||||
* in the registers. All registers are stored in the default format
|
||||
* available on the host machine. The only critical issue is that the
|
||||
* registers should line up EXACTLY in the same manner as they do in
|
||||
* the 386. That is:
|
||||
*
|
||||
* EAX & 0xff === AL
|
||||
* EAX & 0xffff == AX
|
||||
*
|
||||
* etc. The result is that alot of the calculations can then be
|
||||
* done using the native instruction set fully.
|
||||
*/
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
|
||||
typedef struct {
|
||||
u32 e_reg;
|
||||
} I32_reg_t;
|
||||
|
||||
typedef struct {
|
||||
u16 filler0, x_reg;
|
||||
} I16_reg_t;
|
||||
|
||||
typedef struct {
|
||||
u8 filler0, filler1, h_reg, l_reg;
|
||||
} I8_reg_t;
|
||||
|
||||
#else /* !__BIG_ENDIAN__ */
|
||||
|
||||
typedef struct {
|
||||
u32 e_reg;
|
||||
} I32_reg_t;
|
||||
|
||||
typedef struct {
|
||||
u16 x_reg;
|
||||
} I16_reg_t;
|
||||
|
||||
typedef struct {
|
||||
u8 l_reg, h_reg;
|
||||
} I8_reg_t;
|
||||
|
||||
#endif /* BIG_ENDIAN */
|
||||
|
||||
typedef union {
|
||||
I32_reg_t I32_reg;
|
||||
I16_reg_t I16_reg;
|
||||
I8_reg_t I8_reg;
|
||||
} i386_general_register;
|
||||
|
||||
struct i386_general_regs {
|
||||
i386_general_register A, B, C, D;
|
||||
};
|
||||
|
||||
typedef struct i386_general_regs Gen_reg_t;
|
||||
|
||||
struct i386_special_regs {
|
||||
i386_general_register SP, BP, SI, DI, IP;
|
||||
u32 FLAGS;
|
||||
};
|
||||
|
||||
/*
|
||||
* Segment registers here represent the 16 bit quantities
|
||||
* CS, DS, ES, SS.
|
||||
*/
|
||||
|
||||
#if defined(__sun) && defined(CS) /* avoid conflicts with Solaris sys/regset.h */
|
||||
# undef CS
|
||||
# undef DS
|
||||
# undef SS
|
||||
# undef ES
|
||||
# undef FS
|
||||
# undef GS
|
||||
#endif
|
||||
|
||||
struct i386_segment_regs {
|
||||
u16 CS, DS, SS, ES, FS, GS;
|
||||
};
|
||||
|
||||
/* 8 bit registers */
|
||||
#define R_AH gen.A.I8_reg.h_reg
|
||||
#define R_AL gen.A.I8_reg.l_reg
|
||||
#define R_BH gen.B.I8_reg.h_reg
|
||||
#define R_BL gen.B.I8_reg.l_reg
|
||||
#define R_CH gen.C.I8_reg.h_reg
|
||||
#define R_CL gen.C.I8_reg.l_reg
|
||||
#define R_DH gen.D.I8_reg.h_reg
|
||||
#define R_DL gen.D.I8_reg.l_reg
|
||||
|
||||
/* 16 bit registers */
|
||||
#define R_AX gen.A.I16_reg.x_reg
|
||||
#define R_BX gen.B.I16_reg.x_reg
|
||||
#define R_CX gen.C.I16_reg.x_reg
|
||||
#define R_DX gen.D.I16_reg.x_reg
|
||||
|
||||
/* 32 bit extended registers */
|
||||
#define R_EAX gen.A.I32_reg.e_reg
|
||||
#define R_EBX gen.B.I32_reg.e_reg
|
||||
#define R_ECX gen.C.I32_reg.e_reg
|
||||
#define R_EDX gen.D.I32_reg.e_reg
|
||||
|
||||
/* special registers */
|
||||
#define R_SP spc.SP.I16_reg.x_reg
|
||||
#define R_BP spc.BP.I16_reg.x_reg
|
||||
#define R_SI spc.SI.I16_reg.x_reg
|
||||
#define R_DI spc.DI.I16_reg.x_reg
|
||||
#define R_IP spc.IP.I16_reg.x_reg
|
||||
#define R_FLG spc.FLAGS
|
||||
|
||||
/* special registers */
|
||||
#define R_ESP spc.SP.I32_reg.e_reg
|
||||
#define R_EBP spc.BP.I32_reg.e_reg
|
||||
#define R_ESI spc.SI.I32_reg.e_reg
|
||||
#define R_EDI spc.DI.I32_reg.e_reg
|
||||
#define R_EIP spc.IP.I32_reg.e_reg
|
||||
#define R_EFLG spc.FLAGS
|
||||
|
||||
/* segment registers */
|
||||
#define R_CS seg.CS
|
||||
#define R_DS seg.DS
|
||||
#define R_SS seg.SS
|
||||
#define R_ES seg.ES
|
||||
#define R_FS seg.FS
|
||||
#define R_GS seg.GS
|
||||
|
||||
/* flag conditions */
|
||||
#define FB_CF 0x0001 /* CARRY flag */
|
||||
#define FB_PF 0x0004 /* PARITY flag */
|
||||
#define FB_AF 0x0010 /* AUX flag */
|
||||
#define FB_ZF 0x0040 /* ZERO flag */
|
||||
#define FB_SF 0x0080 /* SIGN flag */
|
||||
#define FB_TF 0x0100 /* TRAP flag */
|
||||
#define FB_IF 0x0200 /* INTERRUPT ENABLE flag */
|
||||
#define FB_DF 0x0400 /* DIR flag */
|
||||
#define FB_OF 0x0800 /* OVERFLOW flag */
|
||||
|
||||
/* 80286 and above always have bit#1 set */
|
||||
#define F_ALWAYS_ON (0x0002) /* flag bits always on */
|
||||
|
||||
/*
|
||||
* Define a mask for only those flag bits we will ever pass back
|
||||
* (via PUSHF)
|
||||
*/
|
||||
#define F_MSK (FB_CF|FB_PF|FB_AF|FB_ZF|FB_SF|FB_TF|FB_IF|FB_DF|FB_OF)
|
||||
|
||||
/* following bits masked in to a 16bit quantity */
|
||||
|
||||
#define F_CF 0x0001 /* CARRY flag */
|
||||
#define F_PF 0x0004 /* PARITY flag */
|
||||
#define F_AF 0x0010 /* AUX flag */
|
||||
#define F_ZF 0x0040 /* ZERO flag */
|
||||
#define F_SF 0x0080 /* SIGN flag */
|
||||
#define F_TF 0x0100 /* TRAP flag */
|
||||
#define F_IF 0x0200 /* INTERRUPT ENABLE flag */
|
||||
#define F_DF 0x0400 /* DIR flag */
|
||||
#define F_OF 0x0800 /* OVERFLOW flag */
|
||||
|
||||
#define TOGGLE_FLAG(flag) (M.x86.R_FLG ^= (flag))
|
||||
#define SET_FLAG(flag) (M.x86.R_FLG |= (flag))
|
||||
#define CLEAR_FLAG(flag) (M.x86.R_FLG &= ~(flag))
|
||||
#define ACCESS_FLAG(flag) (M.x86.R_FLG & (flag))
|
||||
#define CLEARALL_FLAG(m) (M.x86.R_FLG = 0)
|
||||
|
||||
#define CONDITIONAL_SET_FLAG(COND,FLAG) \
|
||||
if (COND) SET_FLAG(FLAG); else CLEAR_FLAG(FLAG)
|
||||
|
||||
#define F_PF_CALC 0x010000 /* PARITY flag has been calced */
|
||||
#define F_ZF_CALC 0x020000 /* ZERO flag has been calced */
|
||||
#define F_SF_CALC 0x040000 /* SIGN flag has been calced */
|
||||
|
||||
#define F_ALL_CALC 0xff0000 /* All have been calced */
|
||||
|
||||
/*
|
||||
* Emulator machine state.
|
||||
* Segment usage control.
|
||||
*/
|
||||
#define SYSMODE_SEG_DS_SS 0x00000001
|
||||
#define SYSMODE_SEGOVR_CS 0x00000002
|
||||
#define SYSMODE_SEGOVR_DS 0x00000004
|
||||
#define SYSMODE_SEGOVR_ES 0x00000008
|
||||
#define SYSMODE_SEGOVR_FS 0x00000010
|
||||
#define SYSMODE_SEGOVR_GS 0x00000020
|
||||
#define SYSMODE_SEGOVR_SS 0x00000040
|
||||
#define SYSMODE_PREFIX_REPE 0x00000080
|
||||
#define SYSMODE_PREFIX_REPNE 0x00000100
|
||||
#define SYSMODE_PREFIX_DATA 0x00000200
|
||||
#define SYSMODE_PREFIX_ADDR 0x00000400
|
||||
#define SYSMODE_INTR_PENDING 0x10000000
|
||||
#define SYSMODE_EXTRN_INTR 0x20000000
|
||||
#define SYSMODE_HALTED 0x40000000
|
||||
|
||||
#define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS | \
|
||||
SYSMODE_SEGOVR_CS | \
|
||||
SYSMODE_SEGOVR_DS | \
|
||||
SYSMODE_SEGOVR_ES | \
|
||||
SYSMODE_SEGOVR_FS | \
|
||||
SYSMODE_SEGOVR_GS | \
|
||||
SYSMODE_SEGOVR_SS)
|
||||
#define SYSMODE_CLRMASK (SYSMODE_SEG_DS_SS | \
|
||||
SYSMODE_SEGOVR_CS | \
|
||||
SYSMODE_SEGOVR_DS | \
|
||||
SYSMODE_SEGOVR_ES | \
|
||||
SYSMODE_SEGOVR_FS | \
|
||||
SYSMODE_SEGOVR_GS | \
|
||||
SYSMODE_SEGOVR_SS | \
|
||||
SYSMODE_PREFIX_DATA | \
|
||||
SYSMODE_PREFIX_ADDR)
|
||||
|
||||
#define INTR_SYNCH 0x1
|
||||
#define INTR_ASYNCH 0x2
|
||||
#define INTR_HALTED 0x4
|
||||
|
||||
typedef struct {
|
||||
struct i386_general_regs gen;
|
||||
struct i386_special_regs spc;
|
||||
struct i386_segment_regs seg;
|
||||
/*
|
||||
* MODE contains information on:
|
||||
* REPE prefix 2 bits repe,repne
|
||||
* SEGMENT overrides 5 bits normal,DS,SS,CS,ES
|
||||
* Delayed flag set 3 bits (zero, signed, parity)
|
||||
* reserved 6 bits
|
||||
* interrupt # 8 bits instruction raised interrupt
|
||||
* BIOS video segregs 4 bits
|
||||
* Interrupt Pending 1 bits
|
||||
* Extern interrupt 1 bits
|
||||
* Halted 1 bits
|
||||
*/
|
||||
u32 mode;
|
||||
volatile int intr; /* mask of pending interrupts */
|
||||
int debug;
|
||||
#ifdef DEBUG
|
||||
int check;
|
||||
u16 saved_ip;
|
||||
u16 saved_cs;
|
||||
int enc_pos;
|
||||
int enc_str_pos;
|
||||
char decode_buf[32]; /* encoded byte stream */
|
||||
char decoded_buf[256]; /* disassembled strings */
|
||||
#endif
|
||||
u8 intno;
|
||||
u8 __pad[3];
|
||||
} X86EMU_regs;
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Structure maintaining the emulator machine state.
|
||||
|
||||
MEMBERS:
|
||||
mem_base - Base real mode memory for the emulator
|
||||
mem_size - Size of the real mode memory block for the emulator
|
||||
private - private data pointer
|
||||
x86 - X86 registers
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
unsigned long mem_base;
|
||||
unsigned long mem_size;
|
||||
void *private;
|
||||
X86EMU_regs x86;
|
||||
} X86EMU_sysEnv;
|
||||
|
||||
#ifdef END_PACK
|
||||
#pragma END_PACK
|
||||
#endif
|
||||
|
||||
/*----------------------------- Global Variables --------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
/* Global emulator machine state.
|
||||
*
|
||||
* We keep it global to avoid pointer dereferences in the code for speed.
|
||||
*/
|
||||
|
||||
extern X86EMU_sysEnv _X86EMU_env;
|
||||
#define M _X86EMU_env
|
||||
|
||||
/*-------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
/* Function to log information at runtime */
|
||||
|
||||
void printk(const char *fmt, ...)
|
||||
_X_ATTRIBUTE_PRINTF(1, 2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_REGS_H */
|
81
plat/pc86/emu/x86emu/x86emu/types.h
Normal file
81
plat/pc86/emu/x86emu/x86emu/types.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for x86 emulator type definitions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_TYPES_H
|
||||
#define __X86EMU_TYPES_H
|
||||
|
||||
#ifndef NO_SYS_HEADERS
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following kludge is an attempt to work around typedef conflicts with
|
||||
* <sys/types.h>.
|
||||
*/
|
||||
#define u8 x86emuu8
|
||||
#define u16 x86emuu16
|
||||
#define u32 x86emuu32
|
||||
#define u64 x86emuu64
|
||||
#define s8 x86emus8
|
||||
#define s16 x86emus16
|
||||
#define s32 x86emus32
|
||||
#define s64 x86emus64
|
||||
#define uint x86emuuint
|
||||
#define sint x86emusint
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef int sint;
|
||||
|
||||
typedef u16 X86EMU_pioAddr;
|
||||
|
||||
#endif /* __X86EMU_TYPES_H */
|
110
plat/pc86/emu/x86emu/x86emu/x86emui.h
Normal file
110
plat/pc86/emu/x86emu/x86emu/x86emui.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for system specific functions. These functions
|
||||
* are always compiled and linked in the OS depedent libraries,
|
||||
* and never in a binary portable driver.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_X86EMUI_H
|
||||
#define __X86EMU_X86EMUI_H
|
||||
|
||||
/* If we are compiling in C++ mode, we can compile some functions as
|
||||
* inline to increase performance (however the code size increases quite
|
||||
* dramatically in this case).
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#define _INLINE inline
|
||||
#else
|
||||
#define _INLINE static
|
||||
#endif
|
||||
|
||||
/* Get rid of unused parameters in C++ compilation mode */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define X86EMU_UNUSED(v)
|
||||
#else
|
||||
#define X86EMU_UNUSED(v) v
|
||||
#endif
|
||||
|
||||
#include "x86emu.h"
|
||||
#include "x86emu/regs.h"
|
||||
#include "x86emu/debug.h"
|
||||
#include "x86emu/decode.h"
|
||||
#include "x86emu/ops.h"
|
||||
#include "x86emu/prim_ops.h"
|
||||
#include "x86emu/fpu.h"
|
||||
#include "x86emu/fpu_regs.h"
|
||||
|
||||
#ifndef NO_SYS_HEADERS
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
/* avoid conflicts with Solaris sys/regset.h */
|
||||
# if defined(__sun) && defined(CS)
|
||||
# undef CS
|
||||
# undef DS
|
||||
# undef SS
|
||||
# undef ES
|
||||
# undef FS
|
||||
# undef GS
|
||||
# endif
|
||||
#endif /* NO_SYS_HEADERS */
|
||||
|
||||
/*--------------------------- Inline Functions ----------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
extern u8(X86APIP sys_rdb) (u32 addr);
|
||||
extern u16(X86APIP sys_rdw) (u32 addr);
|
||||
extern u32(X86APIP sys_rdl) (u32 addr);
|
||||
extern void (X86APIP sys_wrb) (u32 addr, u8 val);
|
||||
extern void (X86APIP sys_wrw) (u32 addr, u16 val);
|
||||
extern void (X86APIP sys_wrl) (u32 addr, u32 val);
|
||||
|
||||
extern u8(X86APIP sys_inb) (X86EMU_pioAddr addr);
|
||||
extern u16(X86APIP sys_inw) (X86EMU_pioAddr addr);
|
||||
extern u32(X86APIP sys_inl) (X86EMU_pioAddr addr);
|
||||
extern void (X86APIP sys_outb) (X86EMU_pioAddr addr, u8 val);
|
||||
extern void (X86APIP sys_outw) (X86EMU_pioAddr addr, u16 val);
|
||||
extern void (X86APIP sys_outl) (X86EMU_pioAddr addr, u32 val);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_X86EMUI_H */
|
Loading…
Reference in a new issue