drop extensions directory. it has never been used.
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2382 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
1ac1cf527d
commit
60902ed3a1
|
@ -1,3 +0,0 @@
|
||||||
Here you will find several extensions to LinuxBIOS that are implemented
|
|
||||||
as ELF payloads. They can be used either with the LinuxBIOS ELF loader
|
|
||||||
or by etherboot.
|
|
|
@ -1,71 +0,0 @@
|
||||||
# tag: Makefile for the legacy bios emulation
|
|
||||||
#
|
|
||||||
# Copyright (C) 2003 Stefan Reinauer
|
|
||||||
#
|
|
||||||
# See the file "COPYING" for further information about
|
|
||||||
# the copyright and warranty status of this work.
|
|
||||||
#
|
|
||||||
|
|
||||||
# FIXME: limitations of this makefile:
|
|
||||||
# - needs vgabios.rom even if its not used
|
|
||||||
# - builds x86emu even if it's not used.
|
|
||||||
|
|
||||||
|
|
||||||
ARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/ -e s/x86_64/amd64/)
|
|
||||||
TOPDIR := $(shell /bin/pwd)
|
|
||||||
BUILDDIR ?= $(TOPDIR)/obj-$(ARCH)
|
|
||||||
VPATH := $(TOPDIR)/include:$(TOPDIR)/util:$(BUILDDIR)
|
|
||||||
|
|
||||||
include $(TOPDIR)/Rules.make
|
|
||||||
|
|
||||||
CFLAGS_DEBUG := -Wall -Wstrict-prototypes -Wshadow
|
|
||||||
|
|
||||||
CFLAGS ?= -Os -fcaller-saves -fomit-frame-pointer $(CFLAGS_ARCH) $(CFLAGS_DEBUG)
|
|
||||||
|
|
||||||
export ARCH TOPDIR VPATH CFLAGS BUILDDIR
|
|
||||||
|
|
||||||
all: main $(ARCH)
|
|
||||||
@echo -e "\nlegacy bios plugin build finished for platform $(ARCH).\n"
|
|
||||||
|
|
||||||
.PHONY: kernel $(ARCH)
|
|
||||||
|
|
||||||
types.h: types.sh
|
|
||||||
@echo -n "Checking types..."
|
|
||||||
@cd $(BUILDDIR) && $(TOPDIR)/util/types.sh
|
|
||||||
|
|
||||||
bin2hex: bin2hex.c
|
|
||||||
@echo -n "Building binary converter..."
|
|
||||||
@cd $(BUILDDIR) && $(CC) -o bin2hex $(TOPDIR)/util/bin2hex.c
|
|
||||||
@echo -e "\t\tok"
|
|
||||||
|
|
||||||
kernel:
|
|
||||||
@make -s -C kernel
|
|
||||||
|
|
||||||
main:
|
|
||||||
@echo -e "\nWelcome to LegacyBIOS..."
|
|
||||||
@test -r $(BUILDDIR) || ( mkdir -p $(BUILDDIR); \
|
|
||||||
echo -e "\nCreating build directory $(BUILDDIR)" )
|
|
||||||
|
|
||||||
libx86emu.a:
|
|
||||||
make -s -C arch/x86emu/src/x86emu
|
|
||||||
|
|
||||||
$(ARCH): types.h bin2hex kernel vgabios.rom libx86emu.a
|
|
||||||
@make -s -C arch/$(ARCH)
|
|
||||||
|
|
||||||
vgabios.rom:
|
|
||||||
@cp $(TOPDIR)/roms/vgabios.rom $(BUILDDIR)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
@test ! -d $(BUILDDIR) && \
|
|
||||||
echo "Architecture $(ARCH) is already clean." || \
|
|
||||||
( \
|
|
||||||
echo "Cleaning up architecture $(ARCH)"; \
|
|
||||||
rm -rf $(BUILDDIR) \
|
|
||||||
rm forth.dict.core \
|
|
||||||
)
|
|
||||||
|
|
||||||
indent:
|
|
||||||
find -path './{arch}' -prune -o -name '*.[ch]' \
|
|
||||||
-exec indent -kr -i8 {} \;
|
|
||||||
find -name '*~' -exec rm {} \;
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
Legacy bios emulation
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
goal of this software is to initialize pci devices with legacy x86
|
|
||||||
option roms with no regard to the underlying platform. Use legacybios
|
|
||||||
as an ELF payload to LinuxBIOS/etherboot.
|
|
||||||
|
|
||||||
Currently this is really hackish and it does not work, but it's on the way.
|
|
||||||
|
|
||||||
Using a trampoline, this code could be shrinked to be really small
|
|
||||||
on the x86 platform, since no cpu emulation is needed.
|
|
||||||
Currently all platforms use x86emu for testing.
|
|
||||||
|
|
||||||
--- to be done ---
|
|
||||||
|
|
||||||
Stefan <stepan@openbios.info>
|
|
|
@ -1,17 +0,0 @@
|
||||||
# tag: Makefile rules
|
|
||||||
|
|
||||||
VPATH := $(VPATH):.
|
|
||||||
|
|
||||||
.S.o:
|
|
||||||
echo -n " assembling $<... "
|
|
||||||
$(CC) -c -nostdlib $(INCLUDES) $(CFLAGS) $< -o $(BUILDDIR)/$@ && \
|
|
||||||
echo -e " \t\tok" || \
|
|
||||||
echo -e " \t\tfailed"
|
|
||||||
|
|
||||||
.c.o:
|
|
||||||
echo -n " compiling $<... "
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $< -o $(BUILDDIR)/$@ && \
|
|
||||||
echo -e " \t\tok" || \
|
|
||||||
echo -e " \t\failed"
|
|
||||||
|
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
# Copyright (C) 2003 Stefan Reinauer
|
|
||||||
#
|
|
||||||
# See the file "COPYING" for further information about
|
|
||||||
# the copyright and warranty status of this work.
|
|
||||||
#
|
|
||||||
|
|
||||||
VPATH := $(TOPDIR)/include:$(BUILDDIR):$(TOPDIR)/arch/$(ARCH)/include
|
|
||||||
|
|
||||||
BINARIES := legacybios.multiboot legacybios legacybios.full
|
|
||||||
|
|
||||||
|
|
||||||
all: core link $(BINARIES)
|
|
||||||
|
|
||||||
LDFLAGS_OPENBIOS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000
|
|
||||||
|
|
||||||
OBJS_GENERIC = lib.o legacybios.o console.o pcibios.o malloc.o pci.o libx86emu.a
|
|
||||||
OBJS_MULTIBOOT = mboot.o multiboot.o
|
|
||||||
OBJS_PLAIN = boot.o plainboot.o
|
|
||||||
OBJS_BUILTIN = boot.o builtin.o
|
|
||||||
|
|
||||||
INCLUDES := -Iinclude -I$(TOPDIR)/include -I$(BUILDDIR)
|
|
||||||
|
|
||||||
include $(TOPDIR)/Rules.make
|
|
||||||
|
|
||||||
core:
|
|
||||||
echo -e "\nCompiling $(ARCH) architecture specific binaries"
|
|
||||||
|
|
||||||
link: $(OBJS_MULTIBOOT) $(OBJS_PLAIN) $(OBJS_BUILTIN) $(OBJS_GENERIC)
|
|
||||||
cd $(BUILDDIR) && if [ ! -r legacybios.multiboot -o ! -r legacybios \
|
|
||||||
-o ! -r legacybios.full ]; then echo -e "\nLinking:"; fi
|
|
||||||
|
|
||||||
legacybios.multiboot: $(OBJS_MULTIBOOT) $(OBJS_GENERIC)
|
|
||||||
echo -ne " multiboot image for grub... "
|
|
||||||
cd $(BUILDDIR) && $(CC) $(LDFLAGS_OPENBIOS) -o $@.nostrip $^ -lgcc
|
|
||||||
echo -e "\tok"
|
|
||||||
cd $(BUILDDIR) && objcopy -O binary -R .note -R .comment $@.nostrip $@
|
|
||||||
|
|
||||||
legacybios: $(OBJS_PLAIN) $(OBJS_GENERIC)
|
|
||||||
echo -n " elf image (for LinuxBIOS)... "
|
|
||||||
cd $(BUILDDIR) && $(CC) $(LDFLAGS_OPENBIOS) -o $@.nostrip $^ -lgcc
|
|
||||||
echo -e "\tok"
|
|
||||||
cd $(BUILDDIR) && objcopy -R .note -R .comment $@.nostrip $@ && strip -s $@
|
|
||||||
|
|
||||||
|
|
||||||
rom.h: vgabios.rom
|
|
||||||
echo -n " generating linkable rom..."
|
|
||||||
cd $(BUILDDIR) && ./bin2hex < $^ > $@
|
|
||||||
echo -e "\tok"
|
|
||||||
|
|
||||||
legacybios.full: $(OBJS_BUILTIN) $(OBJS_GENERIC)
|
|
||||||
echo -n " elf image with rom... "
|
|
||||||
cd $(BUILDDIR) && $(CC) $(LDFLAGS_OPENBIOS) -o $@.nostrip $(OBJS_BUILTIN) $(OBJS_GENERIC) -lgcc
|
|
||||||
echo -e "\tok"
|
|
||||||
cd $(BUILDDIR) && objcopy -R .note -R .comment $@.nostrip $@ && strip -s $@
|
|
||||||
|
|
||||||
|
|
||||||
# dependencies. these are so small that we write them manually.
|
|
||||||
|
|
||||||
multiboot.o: multiboot.c types.h config.h multiboot.h
|
|
||||||
boot.o: boot.S multiboot.h
|
|
||||||
mboot.o: mboot.S multiboot.h
|
|
||||||
console.o: console.c types.h config.h
|
|
||||||
plainboot.o: types.h config.h
|
|
||||||
builtin.o: rom.h
|
|
|
@ -1,39 +0,0 @@
|
||||||
/* boot.S
|
|
||||||
* assembler bootstrap
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ASM 1
|
|
||||||
#include <multiboot.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
.code32
|
|
||||||
.globl start, _start
|
|
||||||
|
|
||||||
/* unused */
|
|
||||||
start:
|
|
||||||
_start:
|
|
||||||
/* Initialize stack pointer. */
|
|
||||||
movl $(stack + STACK_SIZE), %esp
|
|
||||||
|
|
||||||
/* Reset EFLAGS. */
|
|
||||||
pushl $0
|
|
||||||
popf
|
|
||||||
|
|
||||||
/* parameter 2 */
|
|
||||||
pushl %ebx
|
|
||||||
/* parameter 1 */
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
/* jump to C main function... */
|
|
||||||
call EXT_C(cmain)
|
|
||||||
|
|
||||||
loop: hlt
|
|
||||||
jmp loop
|
|
||||||
|
|
||||||
.comm stack, STACK_SIZE /* stack area. */
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2003 Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* wrap an array around the hex'ed dictionary file
|
|
||||||
*/
|
|
||||||
|
|
||||||
static char romimage[] = {
|
|
||||||
#include "rom.h"
|
|
||||||
};
|
|
||||||
|
|
||||||
void legacybios(ucell romstart, ucell romend);
|
|
||||||
|
|
||||||
void cmain(void)
|
|
||||||
{
|
|
||||||
legacybios((ucell) romimage,
|
|
||||||
(ucell) romimage + sizeof(romimage));
|
|
||||||
return;
|
|
||||||
}
|
|
|
@ -1,395 +0,0 @@
|
||||||
/* small console implementation */
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2003 Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include <types.h>
|
|
||||||
#include <io.h>
|
|
||||||
#ifdef DEBUG_CONSOLE
|
|
||||||
|
|
||||||
/* ******************************************************************
|
|
||||||
* serial console functions
|
|
||||||
* ****************************************************************** */
|
|
||||||
|
|
||||||
#ifdef DEBUG_CONSOLE_SERIAL
|
|
||||||
|
|
||||||
#define RBR(x) x==2?0x2f8:0x3f8
|
|
||||||
#define THR(x) x==2?0x2f8:0x3f8
|
|
||||||
#define IER(x) x==2?0x2f9:0x3f9
|
|
||||||
#define IIR(x) x==2?0x2fa:0x3fa
|
|
||||||
#define LCR(x) x==2?0x2fb:0x3fb
|
|
||||||
#define MCR(x) x==2?0x2fc:0x3fc
|
|
||||||
#define LSR(x) x==2?0x2fd:0x3fd
|
|
||||||
#define MSR(x) x==2?0x2fe:0x3fe
|
|
||||||
#define SCR(x) x==2?0x2ff:0x3ff
|
|
||||||
#define DLL(x) x==2?0x2f8:0x3f8
|
|
||||||
#define DLM(x) x==2?0x2f9:0x3f9
|
|
||||||
|
|
||||||
static int uart_charav(int port)
|
|
||||||
{
|
|
||||||
if (!port)
|
|
||||||
return -1;
|
|
||||||
return ((inb(LSR(port)) & 1) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char uart_getchar(int port)
|
|
||||||
{
|
|
||||||
if (!port)
|
|
||||||
return -1;
|
|
||||||
while (!uart_charav(port));
|
|
||||||
return ((char) inb(RBR(port)) & 0177);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void uart_putchar(int port, unsigned char c)
|
|
||||||
{
|
|
||||||
if (!port)
|
|
||||||
return;
|
|
||||||
if (c == '\n')
|
|
||||||
uart_putchar(port, '\r');
|
|
||||||
while (!(inb(LSR(port)) & 0x20));
|
|
||||||
outb(THR(port), c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void uart_init_line(int port, unsigned long baud)
|
|
||||||
{
|
|
||||||
int i, baudconst;
|
|
||||||
|
|
||||||
if (!port)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (baud) {
|
|
||||||
case 115200:
|
|
||||||
baudconst = 1;
|
|
||||||
break;
|
|
||||||
case 57600:
|
|
||||||
baudconst = 2;
|
|
||||||
break;
|
|
||||||
case 38400:
|
|
||||||
baudconst = 3;
|
|
||||||
break;
|
|
||||||
case 19200:
|
|
||||||
baudconst = 6;
|
|
||||||
break;
|
|
||||||
case 9600:
|
|
||||||
default:
|
|
||||||
baudconst = 12;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
outb(LCR(port), 0x87);
|
|
||||||
outb(DLM(port), 0);
|
|
||||||
outb(DLL(port), baudconst);
|
|
||||||
outb(LCR(port), 0x07);
|
|
||||||
outb(MCR(port), 0x0f);
|
|
||||||
|
|
||||||
for (i = 10; i > 0; i--) {
|
|
||||||
if (inb(LSR(port)) == (unsigned int) 0)
|
|
||||||
break;
|
|
||||||
inb(RBR(port));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int uart_init(int port, unsigned long speed)
|
|
||||||
{
|
|
||||||
if (port)
|
|
||||||
uart_init_line(port, speed);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void serial_putchar(int c)
|
|
||||||
{
|
|
||||||
uart_putchar(SERIAL_PORT, (unsigned char) (c & 0xff));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void serial_cls(void)
|
|
||||||
{
|
|
||||||
serial_putchar(27);
|
|
||||||
serial_putchar('[');
|
|
||||||
serial_putchar('H');
|
|
||||||
serial_putchar(27);
|
|
||||||
serial_putchar('[');
|
|
||||||
serial_putchar('J');
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ******************************************************************
|
|
||||||
* simple polling video/keyboard console functions
|
|
||||||
* ****************************************************************** */
|
|
||||||
|
|
||||||
#ifdef DEBUG_CONSOLE_VGA
|
|
||||||
|
|
||||||
/* raw vga text mode */
|
|
||||||
#define COLUMNS 80 /* The number of columns. */
|
|
||||||
#define LINES 25 /* The number of lines. */
|
|
||||||
#define ATTRIBUTE 7 /* The attribute of an character. */
|
|
||||||
|
|
||||||
#define VGA_BASE 0xB8000 /* The video memory address. */
|
|
||||||
|
|
||||||
/* VGA Index and Data Registers */
|
|
||||||
#define VGA_REG_INDEX 0x03D4 /* VGA index register */
|
|
||||||
#define VGA_REG_DATA 0x03D5 /* VGA data register */
|
|
||||||
|
|
||||||
#define VGA_IDX_CURMSL 0x09 /* cursor maximum scan line */
|
|
||||||
#define VGA_IDX_CURSTART 0x0A /* cursor start */
|
|
||||||
#define VGA_IDX_CUREND 0x0B /* cursor end */
|
|
||||||
#define VGA_IDX_CURLO 0x0F /* cursor position (low 8 bits)*/
|
|
||||||
#define VGA_IDX_CURHI 0x0E /* cursor position (high 8 bits) */
|
|
||||||
|
|
||||||
/* Save the X and Y position. */
|
|
||||||
static int xpos, ypos;
|
|
||||||
/* Point to the video memory. */
|
|
||||||
static volatile unsigned char *const video = (unsigned char *) VGA_BASE;
|
|
||||||
|
|
||||||
static void video_initcursor(void)
|
|
||||||
{
|
|
||||||
u8 val;
|
|
||||||
outb(VGA_REG_INDEX, VGA_IDX_CURMSL);
|
|
||||||
val = inb(VGA_REG_DATA) & 0x1f; /* maximum scan line -1 */
|
|
||||||
|
|
||||||
outb(VGA_REG_INDEX, VGA_IDX_CURSTART);
|
|
||||||
outb(VGA_REG_DATA, 0);
|
|
||||||
|
|
||||||
outb(VGA_REG_INDEX, VGA_IDX_CUREND);
|
|
||||||
outb(VGA_REG_DATA, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void video_poscursor(unsigned int x, unsigned int y)
|
|
||||||
{
|
|
||||||
unsigned short pos;
|
|
||||||
|
|
||||||
/* Calculate new cursor position as a function of x and y */
|
|
||||||
pos = (y*COLUMNS) + x;
|
|
||||||
|
|
||||||
/* Output the new position to VGA card */
|
|
||||||
outb(VGA_REG_INDEX, VGA_IDX_CURLO); /* output low 8 bits */
|
|
||||||
outb(VGA_REG_DATA, (u8) (pos));
|
|
||||||
outb(VGA_REG_INDEX, VGA_IDX_CURHI); /* output high 8 bits */
|
|
||||||
outb(VGA_REG_DATA, (u8) (pos >> 8));
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static void video_newline(void)
|
|
||||||
{
|
|
||||||
xpos = 0;
|
|
||||||
|
|
||||||
if (ypos < LINES-1) {
|
|
||||||
ypos++;
|
|
||||||
} else {
|
|
||||||
int i;
|
|
||||||
memmove((void *)video, (void *)(video+2*COLUMNS), (LINES-1)*COLUMNS*2);
|
|
||||||
|
|
||||||
for(i=( (LINES-1) *2*COLUMNS ); i<2*COLUMNS*LINES;) {
|
|
||||||
video[i++]=0;
|
|
||||||
video[i++]=ATTRIBUTE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put the character C on the screen. */
|
|
||||||
static void video_putchar(int c)
|
|
||||||
{
|
|
||||||
if (c == '\n' || c == '\r') {
|
|
||||||
video_newline();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xpos >= COLUMNS)
|
|
||||||
video_newline();
|
|
||||||
|
|
||||||
*(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
|
|
||||||
*(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
|
|
||||||
|
|
||||||
xpos++;
|
|
||||||
|
|
||||||
video_poscursor(xpos, ypos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void video_cls(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i=0; i<2*COLUMNS*LINES;) {
|
|
||||||
video[i++]=0;
|
|
||||||
video[i++]=ATTRIBUTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
xpos = 0; ypos = 0;
|
|
||||||
|
|
||||||
video_initcursor();
|
|
||||||
video_poscursor(xpos,ypos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* keyboard driver
|
|
||||||
*/
|
|
||||||
|
|
||||||
static char normal[] = {
|
|
||||||
0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
|
|
||||||
'=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o',
|
|
||||||
'p', '[', ']', 0xa, 0x0, 'a', 's', 'd', 'f', 'g', 'h', 'j',
|
|
||||||
'k', 'l', ';', 0x27, 0x60, 0x0, 0x5c, 'z', 'x', 'c', 'v', 'b',
|
|
||||||
'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
|
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '0', 0x7f
|
|
||||||
};
|
|
||||||
|
|
||||||
static char shifted[] = {
|
|
||||||
0x0, 0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
|
|
||||||
'+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O',
|
|
||||||
'P', '{', '}', 0xa, 0x0, 'A', 'S', 'D', 'F', 'G', 'H', 'J',
|
|
||||||
'K', 'L', ':', 0x22, '~', 0x0, '|', 'Z', 'X', 'C', 'V', 'B',
|
|
||||||
'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
|
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8',
|
|
||||||
'9', 0x0, '4', '5', '6', 0x0, '1', '2', '3', '0', 0x7f
|
|
||||||
};
|
|
||||||
|
|
||||||
static int key_ext;
|
|
||||||
static int key_lshift = 0, key_rshift = 0, key_caps = 0;
|
|
||||||
|
|
||||||
static char last_key;
|
|
||||||
|
|
||||||
static void keyboard_cmd(unsigned char cmd, unsigned char val)
|
|
||||||
{
|
|
||||||
outb(0x60, cmd);
|
|
||||||
/* wait until keyboard controller accepts cmds: */
|
|
||||||
while (inb(0x64) & 2);
|
|
||||||
outb(0x60, val);
|
|
||||||
while (inb(0x64) & 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char keyboard_poll(void)
|
|
||||||
{
|
|
||||||
unsigned int c;
|
|
||||||
if (inb(0x64) & 1) {
|
|
||||||
c = inb(0x60);
|
|
||||||
switch (c) {
|
|
||||||
case 0xe0:
|
|
||||||
key_ext = 1;
|
|
||||||
return 0;
|
|
||||||
case 0x2a:
|
|
||||||
key_lshift = 1;
|
|
||||||
return 0;
|
|
||||||
case 0x36:
|
|
||||||
key_rshift = 1;
|
|
||||||
return 0;
|
|
||||||
case 0xaa:
|
|
||||||
key_lshift = 0;
|
|
||||||
return 0;
|
|
||||||
case 0xb6:
|
|
||||||
key_rshift = 0;
|
|
||||||
return 0;
|
|
||||||
case 0x3a:
|
|
||||||
if (key_caps) {
|
|
||||||
key_caps = 0;
|
|
||||||
keyboard_cmd(0xed, 0);
|
|
||||||
} else {
|
|
||||||
key_caps = 1;
|
|
||||||
keyboard_cmd(0xed, 4); /* set caps led */
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key_ext) {
|
|
||||||
void printk(const char *format, ...);
|
|
||||||
printk("extended keycode: %x\n", c);
|
|
||||||
|
|
||||||
key_ext = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c & 0x80) /* unhandled key release */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (key_lshift || key_rshift)
|
|
||||||
return key_caps ? normal[c] : shifted[c];
|
|
||||||
else
|
|
||||||
return key_caps ? shifted[c] : normal[c];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int keyboard_dataready(void)
|
|
||||||
{
|
|
||||||
if (last_key)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
last_key = keyboard_poll();
|
|
||||||
|
|
||||||
return (last_key != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned char keyboard_readdata(void)
|
|
||||||
{
|
|
||||||
char tmp;
|
|
||||||
while (!keyboard_dataready());
|
|
||||||
tmp = last_key;
|
|
||||||
last_key = 0;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ******************************************************************
|
|
||||||
* common functions, implementing simple concurrent console
|
|
||||||
* ****************************************************************** */
|
|
||||||
|
|
||||||
int putchar(int c)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_CONSOLE_SERIAL
|
|
||||||
serial_putchar(c);
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_CONSOLE_VGA
|
|
||||||
video_putchar(c);
|
|
||||||
#endif
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
int availchar(void)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_CONSOLE_SERIAL
|
|
||||||
if (uart_charav(SERIAL_PORT))
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_CONSOLE_VGA
|
|
||||||
if (keyboard_dataready())
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getchar(void)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_CONSOLE_SERIAL
|
|
||||||
if (uart_charav(SERIAL_PORT))
|
|
||||||
return (uart_getchar(SERIAL_PORT));
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_CONSOLE_VGA
|
|
||||||
if (keyboard_dataready())
|
|
||||||
return (keyboard_readdata());
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cls(void)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_CONSOLE_SERIAL
|
|
||||||
serial_cls();
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_CONSOLE_VGA
|
|
||||||
video_cls();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // DEBUG_CONSOLE
|
|
|
@ -1,55 +0,0 @@
|
||||||
/* I/O implementation
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*
|
|
||||||
* this code is inspired by the linux kernel
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef IO_H
|
|
||||||
#define IO_H
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
#define __EXTERN__ extern
|
|
||||||
|
|
||||||
__EXTERN__ inline u8 inb(u32 port)
|
|
||||||
{
|
|
||||||
u8 result;
|
|
||||||
__asm__ __volatile__ ( "inb %w1,%0" :"=a" (result) :"Nd" (port));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
__EXTERN__ inline u16 inw(u32 port)
|
|
||||||
{
|
|
||||||
u16 result;
|
|
||||||
__asm__ __volatile__ ( "inw %w1,%0" :"=a" (result) :"Nd" (port));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
__EXTERN__ inline u32 inl(u32 port)
|
|
||||||
{
|
|
||||||
u32 result;
|
|
||||||
__asm__ __volatile__ ( "inl %w1,%0" :"=a" (result) :"Nd" (port));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
__EXTERN__ inline void outb (u32 port, u8 value)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__ ( "outb %b0,%w1" : :"a" (value), "Nd" (port));
|
|
||||||
}
|
|
||||||
|
|
||||||
__EXTERN__ inline void outw (u32 port, u16 value)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__ ( "outw %w0,%w1" : :"a" (value), "Nd" (port));
|
|
||||||
}
|
|
||||||
|
|
||||||
__EXTERN__ inline void outl (u32 port, u32 value)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__ ( "outl %0,%w1" : :"a" (value), "Nd" (port));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* IO_H */
|
|
|
@ -1,96 +0,0 @@
|
||||||
/* multiboot.h
|
|
||||||
* header for multiboot
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* magic number for multiboot header */
|
|
||||||
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
|
||||||
|
|
||||||
/* flags for multiboot header */
|
|
||||||
#define MULTIBOOT_HEADER_FLAGS 0x00010003
|
|
||||||
|
|
||||||
/* magic number passed by multiboot-compliant boot loader. */
|
|
||||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
|
||||||
|
|
||||||
/* The size of our stack (8KB). */
|
|
||||||
#define STACK_SIZE 0x2000
|
|
||||||
|
|
||||||
/* C symbol format. HAVE_ASM_USCORE is defined by configure. */
|
|
||||||
#ifdef HAVE_ASM_USCORE
|
|
||||||
# define EXT_C(sym) _ ## sym
|
|
||||||
#else
|
|
||||||
# define EXT_C(sym) sym
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ASM
|
|
||||||
/* We don't want these declarations in boot.S */
|
|
||||||
|
|
||||||
/* multiboot header */
|
|
||||||
typedef struct multiboot_header {
|
|
||||||
unsigned long magic;
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned long checksum;
|
|
||||||
unsigned long header_addr;
|
|
||||||
unsigned long load_addr;
|
|
||||||
unsigned long load_end_addr;
|
|
||||||
unsigned long bss_end_addr;
|
|
||||||
unsigned long entry_addr;
|
|
||||||
} multiboot_header_t;
|
|
||||||
|
|
||||||
/* symbol table for a.out */
|
|
||||||
typedef struct aout_symbol_table {
|
|
||||||
unsigned long tabsize;
|
|
||||||
unsigned long strsize;
|
|
||||||
unsigned long addr;
|
|
||||||
unsigned long reserved;
|
|
||||||
} aout_symbol_table_t;
|
|
||||||
|
|
||||||
/* section header table for ELF */
|
|
||||||
typedef struct elf_section_header_table {
|
|
||||||
unsigned long num;
|
|
||||||
unsigned long size;
|
|
||||||
unsigned long addr;
|
|
||||||
unsigned long shndx;
|
|
||||||
} elf_section_header_table_t;
|
|
||||||
|
|
||||||
/* multiboot information */
|
|
||||||
typedef struct multiboot_info {
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned long mem_lower;
|
|
||||||
unsigned long mem_upper;
|
|
||||||
unsigned long boot_device;
|
|
||||||
unsigned long cmdline;
|
|
||||||
unsigned long mods_count;
|
|
||||||
unsigned long mods_addr;
|
|
||||||
union {
|
|
||||||
aout_symbol_table_t aout_sym;
|
|
||||||
elf_section_header_table_t elf_sec;
|
|
||||||
} u;
|
|
||||||
unsigned long mmap_length;
|
|
||||||
unsigned long mmap_addr;
|
|
||||||
} multiboot_info_t;
|
|
||||||
|
|
||||||
/* module structure */
|
|
||||||
typedef struct module {
|
|
||||||
unsigned long mod_start;
|
|
||||||
unsigned long mod_end;
|
|
||||||
unsigned long string;
|
|
||||||
unsigned long reserved;
|
|
||||||
} module_t;
|
|
||||||
|
|
||||||
/* memory map. Be careful that the offset 0 is base_addr_low
|
|
||||||
but no size. */
|
|
||||||
typedef struct memory_map {
|
|
||||||
unsigned long size;
|
|
||||||
unsigned long base_addr_low;
|
|
||||||
unsigned long base_addr_high;
|
|
||||||
unsigned long length_low;
|
|
||||||
unsigned long length_high;
|
|
||||||
unsigned long type;
|
|
||||||
} memory_map_t;
|
|
||||||
|
|
||||||
#endif /* ! ASM */
|
|
|
@ -1,57 +0,0 @@
|
||||||
/* mboot.S
|
|
||||||
* legacybios assembler bootstrap for multiboot
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ASM 1
|
|
||||||
#include <multiboot.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
.code32
|
|
||||||
.globl start, _start
|
|
||||||
|
|
||||||
/* unused */
|
|
||||||
start:
|
|
||||||
_start:
|
|
||||||
jmp multiboot_entry
|
|
||||||
|
|
||||||
/* Align 32 bits boundary. */
|
|
||||||
.align 4
|
|
||||||
|
|
||||||
/* Multiboot header. */
|
|
||||||
multiboot_header:
|
|
||||||
.long MULTIBOOT_HEADER_MAGIC /* magic */
|
|
||||||
.long MULTIBOOT_HEADER_FLAGS /* flags */
|
|
||||||
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
|
||||||
/* checksum */
|
|
||||||
.long multiboot_header /* header_addr */
|
|
||||||
.long _start /* load_addr */
|
|
||||||
.long _edata /* load_end_addr */
|
|
||||||
.long _end /* bss_end_addr */
|
|
||||||
.long multiboot_entry /* entry_addr */
|
|
||||||
|
|
||||||
multiboot_entry:
|
|
||||||
/* Initialize stack pointer. */
|
|
||||||
movl $(stack + STACK_SIZE), %esp
|
|
||||||
|
|
||||||
/* Reset EFLAGS. */
|
|
||||||
pushl $0
|
|
||||||
popf
|
|
||||||
|
|
||||||
/* pointer to multiboot information structure. */
|
|
||||||
pushl %ebx
|
|
||||||
/* magic value. */
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
/* jump to C main function... */
|
|
||||||
call EXT_C(cmain)
|
|
||||||
|
|
||||||
loop: hlt
|
|
||||||
jmp loop
|
|
||||||
|
|
||||||
.comm stack, STACK_SIZE /* stack area. */
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2003 Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "multiboot.h"
|
|
||||||
|
|
||||||
/* Multiboot: Check if the bit BIT in FLAGS is set. */
|
|
||||||
#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
|
|
||||||
|
|
||||||
#ifdef DEBUG_CONSOLE
|
|
||||||
void cls(void);
|
|
||||||
void printk(const char *fmt, ...);
|
|
||||||
int uart_init(int port, unsigned long speed);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void legacybios(ucell romstart, ucell romend);
|
|
||||||
|
|
||||||
/* Check if MAGIC is valid and print the Multiboot information structure
|
|
||||||
pointed by ADDR. */
|
|
||||||
|
|
||||||
void cmain(unsigned long magic, unsigned long addr)
|
|
||||||
{
|
|
||||||
multiboot_info_t *mbi;
|
|
||||||
|
|
||||||
#ifdef DEBUG_CONSOLE
|
|
||||||
uart_init(SERIAL_PORT, SERIAL_SPEED);
|
|
||||||
/* Clear the screen. */
|
|
||||||
cls();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Am I booted by a Multiboot-compliant boot loader? */
|
|
||||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
|
||||||
printk("legacybios: loader not multiboot capable\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set MBI to the address of the Multiboot information structure. */
|
|
||||||
mbi = (multiboot_info_t *) addr;
|
|
||||||
|
|
||||||
#ifdef DEBUG_BOOT
|
|
||||||
/* Print out the flags. */
|
|
||||||
printk("flags = 0x%x\n", mbi->flags);
|
|
||||||
|
|
||||||
/* Are mem_* valid? */
|
|
||||||
if (CHECK_FLAG(mbi->flags, 0))
|
|
||||||
printk("mem_lower = %dKB, mem_upper = %dKB\n",
|
|
||||||
mbi->mem_lower, mbi->mem_upper);
|
|
||||||
|
|
||||||
/* Is boot_device valid? */
|
|
||||||
if (CHECK_FLAG(mbi->flags, 1))
|
|
||||||
printk("boot_device = 0x%x\n", mbi->boot_device);
|
|
||||||
|
|
||||||
/* Is the command line passed? */
|
|
||||||
if (CHECK_FLAG(mbi->flags, 2))
|
|
||||||
printk("cmdline = %s\n", (char *) mbi->cmdline);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG_BOOT
|
|
||||||
/* Bits 4 and 5 are mutually exclusive! */
|
|
||||||
if (CHECK_FLAG(mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)) {
|
|
||||||
printk("panic: binary claims to be a.out and elf.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Are mods_* valid? */
|
|
||||||
if (CHECK_FLAG(mbi->flags, 3)) {
|
|
||||||
module_t *mod;
|
|
||||||
unsigned int i;
|
|
||||||
#ifdef DEBUG_BOOT
|
|
||||||
printk("mods_count = %d, mods_addr = 0x%x\n",
|
|
||||||
mbi->mods_count, mbi->mods_addr);
|
|
||||||
#endif
|
|
||||||
for (i = 0, mod = (module_t *) mbi->mods_addr;
|
|
||||||
i < mbi->mods_count; i++, mod += sizeof(module_t)) {
|
|
||||||
legacybios(mod->mod_start, mod->mod_end);
|
|
||||||
#ifdef DEBUG_BOOT
|
|
||||||
printk
|
|
||||||
(" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
|
|
||||||
mod->mod_start, mod->mod_end,
|
|
||||||
(char *) mod->string);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
|
@ -1,126 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <io.h>
|
|
||||||
#include <pci.h>
|
|
||||||
|
|
||||||
void *malloc(unsigned int size);
|
|
||||||
void *memset(void *s, int c, size_t count);
|
|
||||||
|
|
||||||
#define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus << 16) | (dev->devfn << 8) | (where & ~3))
|
|
||||||
|
|
||||||
static struct pci_dev *pcidevices = NULL;
|
|
||||||
|
|
||||||
struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device,
|
|
||||||
struct pci_dev *from)
|
|
||||||
{
|
|
||||||
struct pci_dev *curr = from ? from : pcidevices;
|
|
||||||
|
|
||||||
while (curr) {
|
|
||||||
if (curr->vendor == vendor && curr->device == device)
|
|
||||||
return curr;
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
|
|
||||||
{
|
|
||||||
struct pci_dev *curr = pcidevices;
|
|
||||||
|
|
||||||
while (curr) {
|
|
||||||
if (curr->devfn == devfn && curr->bus == bus)
|
|
||||||
return curr;
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pci_read_config_byte(struct pci_dev *dev, u8 where, u8 * val)
|
|
||||||
{
|
|
||||||
outl(0xcf8, CONFIG_CMD(dev, where));
|
|
||||||
*val = inb(0xCFC + (where & 3));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pci_read_config_word(struct pci_dev *dev, u8 where, u16 * val)
|
|
||||||
{
|
|
||||||
outl(0xcf8, CONFIG_CMD(dev, where));
|
|
||||||
*val = inb(0xCFC + (where & 2));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pci_read_config_dword(struct pci_dev *dev, u8 where, u32 * val)
|
|
||||||
{
|
|
||||||
outl(0xcf8, CONFIG_CMD(dev, where));
|
|
||||||
*val = inb(0xCFC);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val)
|
|
||||||
{
|
|
||||||
outl(0xcf8, CONFIG_CMD(dev, where));
|
|
||||||
outb(0xCFC + (where & 3), val);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pci_write_config_word(struct pci_dev *dev, u8 where, u16 val)
|
|
||||||
{
|
|
||||||
outl(0xcf8, CONFIG_CMD(dev, where));
|
|
||||||
outb(0xCFC + (where & 2), val);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val)
|
|
||||||
{
|
|
||||||
outl(0xcf8, CONFIG_CMD(dev, where));
|
|
||||||
outb(0xCFC, where);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FUNC(x) ((x) & 7)
|
|
||||||
#define SLOT(x) ((x) >> 3)
|
|
||||||
#define MAX_DEV (20 << 3)
|
|
||||||
|
|
||||||
void pci_init(void)
|
|
||||||
{
|
|
||||||
struct pci_dev *pdev, **p, current;
|
|
||||||
int dev, bus = 0, multi = 0;
|
|
||||||
|
|
||||||
pcidevices = NULL;
|
|
||||||
|
|
||||||
for (dev = 0; dev < MAX_DEV; dev++) {
|
|
||||||
u16 vendor, device;
|
|
||||||
|
|
||||||
if (!multi && FUNC(dev))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
current.bus = bus; // FIXME
|
|
||||||
current.devfn = dev;
|
|
||||||
|
|
||||||
pci_read_config_word(¤t, PCI_VENDOR_ID, &vendor);
|
|
||||||
pci_read_config_word(¤t, PCI_DEVICE_ID, &device);
|
|
||||||
|
|
||||||
if (vendor == 0xffff || vendor == 0x0000 ||
|
|
||||||
device == 0xffff || device == 0x0000)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pdev = malloc(sizeof(*pdev));
|
|
||||||
memset(pdev, 0, sizeof(*pdev));
|
|
||||||
|
|
||||||
pdev->vendor = vendor;
|
|
||||||
pdev->device = device;
|
|
||||||
pdev->bus = current.bus;
|
|
||||||
|
|
||||||
pci_read_config_byte(pdev, PCI_HEADER_TYPE, &(pdev->header));
|
|
||||||
pci_read_config_word(pdev, PCI_COMMAND, &(pdev->command));
|
|
||||||
pci_read_config_byte(pdev, PCI_CLASS_PROG, &(pdev->progif));
|
|
||||||
pci_read_config_word(pdev, PCI_CLASS_DEVICE, &(pdev->class));
|
|
||||||
pdev->devfn = dev;
|
|
||||||
|
|
||||||
multi = pdev->header & 0x80;
|
|
||||||
for (p = &pcidevices; *p; p = &(*p)->next);
|
|
||||||
*p = pdev;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
/* tag: legacybios starter
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
#define FIXED_ROMSTART 0xc0000
|
|
||||||
#define FIXED_ROMEND 0xcffff
|
|
||||||
|
|
||||||
void legacybios(ucell romstart, ucell romend);
|
|
||||||
|
|
||||||
void cmain(void)
|
|
||||||
{
|
|
||||||
legacybios(FIXED_ROMSTART,FIXED_ROMEND);
|
|
||||||
return;
|
|
||||||
}
|
|
|
@ -1,194 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Header file for public specific functions.
|
|
||||||
* Any application linking against us should only
|
|
||||||
* include this header
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
/* $XFree86: xc/extras/x86emu/include/x86emu.h,v 1.2 2000/11/21 23:10:25 tsi Exp $ */
|
|
||||||
|
|
||||||
#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 ----------------------*/
|
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
REMARKS:
|
|
||||||
Data structure containing ponters to programmed I/O functions used by the
|
|
||||||
emulator. This is used so that the user program can hook all programmed
|
|
||||||
I/O for the emulator to handled as necessary by the user program. By
|
|
||||||
default the emulator contains simple functions that do not do access the
|
|
||||||
hardware in any way. To allow the emualtor access the hardware, you will
|
|
||||||
need to override the programmed I/O functions using the X86EMU_setupPioFuncs
|
|
||||||
function.
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
/*--------------------- 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_FS_F 0x000080
|
|
||||||
#define DEBUG_PROC_F 0x000100
|
|
||||||
#define DEBUG_SYSINT_F 0x000200 /* bios system interrupts. */
|
|
||||||
#define DEBUG_TRACECALL_F 0x000400
|
|
||||||
#define DEBUG_INSTRUMENT_F 0x000800
|
|
||||||
#define DEBUG_MEM_TRACE_F 0x001000
|
|
||||||
#define DEBUG_IO_TRACE_F 0x002000
|
|
||||||
#define DEBUG_TRACECALL_REGS_F 0x004000
|
|
||||||
#define DEBUG_DECODE_NOPRINT_F 0x008000
|
|
||||||
#define DEBUG_SAVE_IP_CS_F 0x010000
|
|
||||||
#define DEBUG_SYS_F (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F)
|
|
||||||
|
|
||||||
void X86EMU_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 */
|
|
|
@ -1,115 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Header file for FPU register definitions.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __X86EMU_FPU_REGS_H
|
|
||||||
#define __X86EMU_FPU_REGS_H
|
|
||||||
|
|
||||||
#ifdef X86_FPU_SUPPORT
|
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
/* Basic 8087 register can hold any of the following values: */
|
|
||||||
|
|
||||||
union x86_fpu_reg_u {
|
|
||||||
s8 tenbytes[10];
|
|
||||||
double dval;
|
|
||||||
float fval;
|
|
||||||
s16 sval;
|
|
||||||
s32 lval;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct x86_fpu_reg {
|
|
||||||
union x86_fpu_reg_u reg;
|
|
||||||
char tag;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Since we are not going to worry about the problems of aliasing
|
|
||||||
* registers, every time a register is modified, its result type is
|
|
||||||
* set in the tag fields for that register. If some operation
|
|
||||||
* attempts to access the type in a way inconsistent with its current
|
|
||||||
* storage format, then we flag the operation. If common, we'll
|
|
||||||
* attempt the conversion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define X86_FPU_VALID 0x80
|
|
||||||
#define X86_FPU_REGTYP(r) ((r) & 0x7F)
|
|
||||||
|
|
||||||
#define X86_FPU_WORD 0x0
|
|
||||||
#define X86_FPU_SHORT 0x1
|
|
||||||
#define X86_FPU_LONG 0x2
|
|
||||||
#define X86_FPU_FLOAT 0x3
|
|
||||||
#define X86_FPU_DOUBLE 0x4
|
|
||||||
#define X86_FPU_LDBL 0x5
|
|
||||||
#define X86_FPU_BSD 0x6
|
|
||||||
|
|
||||||
#define X86_FPU_STKTOP 0
|
|
||||||
|
|
||||||
struct x86_fpu_registers {
|
|
||||||
struct x86_fpu_reg x86_fpu_stack[8];
|
|
||||||
int x86_fpu_flags;
|
|
||||||
int x86_fpu_config; /* rounding modes, etc. */
|
|
||||||
short x86_fpu_tos, x86_fpu_bos;
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There are two versions of the following macro.
|
|
||||||
*
|
|
||||||
* One version is for opcode D9, for which there are more than 32
|
|
||||||
* instructions encoded in the second byte of the opcode.
|
|
||||||
*
|
|
||||||
* The other version, deals with all the other 7 i87 opcodes, for
|
|
||||||
* which there are only 32 strings needed to describe the
|
|
||||||
* instructions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* X86_FPU_SUPPORT */
|
|
||||||
|
|
||||||
#ifdef 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 */
|
|
|
@ -1,334 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Header file for x86 register definitions.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
/* $XFree86: xc/extras/x86emu/include/x86emu/regs.h,v 1.3 2001/10/28 03:32:25 tsi Exp $ */
|
|
||||||
|
|
||||||
#ifndef __X86EMU_REGS_H
|
|
||||||
#define __X86EMU_REGS_H
|
|
||||||
|
|
||||||
/*---------------------- Macros and type definitions ----------------------*/
|
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* General EAX, EBX, ECX, EDX type registers. Note that for
|
|
||||||
* portability, and speed, the issue of byte swapping is not addressed
|
|
||||||
* in the registers. All registers are stored in the default format
|
|
||||||
* available on the host machine. The only critical issue is that the
|
|
||||||
* registers should line up EXACTLY in the same manner as they do in
|
|
||||||
* the 386. That is:
|
|
||||||
*
|
|
||||||
* EAX & 0xff === AL
|
|
||||||
* EAX & 0xffff == AX
|
|
||||||
*
|
|
||||||
* etc. The result is that alot of the calculations can then be
|
|
||||||
* done using the native instruction set fully.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u32 e_reg;
|
|
||||||
} I32_reg_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u16 filler0, x_reg;
|
|
||||||
} I16_reg_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u8 filler0, filler1, h_reg, l_reg;
|
|
||||||
} I8_reg_t;
|
|
||||||
|
|
||||||
#else /* !__BIG_ENDIAN__ */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u32 e_reg;
|
|
||||||
} I32_reg_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u16 x_reg;
|
|
||||||
} I16_reg_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u8 l_reg, h_reg;
|
|
||||||
} I8_reg_t;
|
|
||||||
|
|
||||||
#endif /* BIG_ENDIAN */
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
I32_reg_t I32_reg;
|
|
||||||
I16_reg_t I16_reg;
|
|
||||||
I8_reg_t I8_reg;
|
|
||||||
} i386_general_register;
|
|
||||||
|
|
||||||
struct i386_general_regs {
|
|
||||||
i386_general_register A, B, C, D;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct i386_general_regs Gen_reg_t;
|
|
||||||
|
|
||||||
struct i386_special_regs {
|
|
||||||
i386_general_register SP, BP, SI, DI, IP;
|
|
||||||
u32 FLAGS;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Segment registers here represent the 16 bit quantities
|
|
||||||
* CS, DS, ES, SS.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct i386_segment_regs {
|
|
||||||
u16 CS, DS, SS, ES, FS, GS;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 8 bit registers */
|
|
||||||
#define R_AH gen.A.I8_reg.h_reg
|
|
||||||
#define R_AL gen.A.I8_reg.l_reg
|
|
||||||
#define R_BH gen.B.I8_reg.h_reg
|
|
||||||
#define R_BL gen.B.I8_reg.l_reg
|
|
||||||
#define R_CH gen.C.I8_reg.h_reg
|
|
||||||
#define R_CL gen.C.I8_reg.l_reg
|
|
||||||
#define R_DH gen.D.I8_reg.h_reg
|
|
||||||
#define R_DL gen.D.I8_reg.l_reg
|
|
||||||
|
|
||||||
/* 16 bit registers */
|
|
||||||
#define R_AX gen.A.I16_reg.x_reg
|
|
||||||
#define R_BX gen.B.I16_reg.x_reg
|
|
||||||
#define R_CX gen.C.I16_reg.x_reg
|
|
||||||
#define R_DX gen.D.I16_reg.x_reg
|
|
||||||
|
|
||||||
/* 32 bit extended registers */
|
|
||||||
#define R_EAX gen.A.I32_reg.e_reg
|
|
||||||
#define R_EBX gen.B.I32_reg.e_reg
|
|
||||||
#define R_ECX gen.C.I32_reg.e_reg
|
|
||||||
#define R_EDX gen.D.I32_reg.e_reg
|
|
||||||
|
|
||||||
/* special registers */
|
|
||||||
#define R_SP spc.SP.I16_reg.x_reg
|
|
||||||
#define R_BP spc.BP.I16_reg.x_reg
|
|
||||||
#define R_SI spc.SI.I16_reg.x_reg
|
|
||||||
#define R_DI spc.DI.I16_reg.x_reg
|
|
||||||
#define R_IP spc.IP.I16_reg.x_reg
|
|
||||||
#define R_FLG spc.FLAGS
|
|
||||||
|
|
||||||
/* special registers */
|
|
||||||
#define R_SP spc.SP.I16_reg.x_reg
|
|
||||||
#define R_BP spc.BP.I16_reg.x_reg
|
|
||||||
#define R_SI spc.SI.I16_reg.x_reg
|
|
||||||
#define R_DI spc.DI.I16_reg.x_reg
|
|
||||||
#define R_IP spc.IP.I16_reg.x_reg
|
|
||||||
#define R_FLG spc.FLAGS
|
|
||||||
|
|
||||||
/* special registers */
|
|
||||||
#define R_ESP spc.SP.I32_reg.e_reg
|
|
||||||
#define R_EBP spc.BP.I32_reg.e_reg
|
|
||||||
#define R_ESI spc.SI.I32_reg.e_reg
|
|
||||||
#define R_EDI spc.DI.I32_reg.e_reg
|
|
||||||
#define R_EIP spc.IP.I32_reg.e_reg
|
|
||||||
#define R_EFLG spc.FLAGS
|
|
||||||
|
|
||||||
/* segment registers */
|
|
||||||
#define R_CS seg.CS
|
|
||||||
#define R_DS seg.DS
|
|
||||||
#define R_SS seg.SS
|
|
||||||
#define R_ES seg.ES
|
|
||||||
#define R_FS seg.FS
|
|
||||||
#define R_GS seg.GS
|
|
||||||
|
|
||||||
/* flag conditions */
|
|
||||||
#define FB_CF 0x0001 /* CARRY flag */
|
|
||||||
#define FB_PF 0x0004 /* PARITY flag */
|
|
||||||
#define FB_AF 0x0010 /* AUX flag */
|
|
||||||
#define FB_ZF 0x0040 /* ZERO flag */
|
|
||||||
#define FB_SF 0x0080 /* SIGN flag */
|
|
||||||
#define FB_TF 0x0100 /* TRAP flag */
|
|
||||||
#define FB_IF 0x0200 /* INTERRUPT ENABLE flag */
|
|
||||||
#define FB_DF 0x0400 /* DIR flag */
|
|
||||||
#define FB_OF 0x0800 /* OVERFLOW flag */
|
|
||||||
|
|
||||||
/* 80286 and above always have bit#1 set */
|
|
||||||
#define F_ALWAYS_ON (0x0002) /* flag bits always on */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Define a mask for only those flag bits we will ever pass back
|
|
||||||
* (via PUSHF)
|
|
||||||
*/
|
|
||||||
#define F_MSK (FB_CF|FB_PF|FB_AF|FB_ZF|FB_SF|FB_TF|FB_IF|FB_DF|FB_OF)
|
|
||||||
|
|
||||||
/* following bits masked in to a 16bit quantity */
|
|
||||||
|
|
||||||
#define F_CF 0x0001 /* CARRY flag */
|
|
||||||
#define F_PF 0x0004 /* PARITY flag */
|
|
||||||
#define F_AF 0x0010 /* AUX flag */
|
|
||||||
#define F_ZF 0x0040 /* ZERO flag */
|
|
||||||
#define F_SF 0x0080 /* SIGN flag */
|
|
||||||
#define F_TF 0x0100 /* TRAP flag */
|
|
||||||
#define F_IF 0x0200 /* INTERRUPT ENABLE flag */
|
|
||||||
#define F_DF 0x0400 /* DIR flag */
|
|
||||||
#define F_OF 0x0800 /* OVERFLOW flag */
|
|
||||||
|
|
||||||
#define TOGGLE_FLAG(flag) (M.x86.R_FLG ^= (flag))
|
|
||||||
#define SET_FLAG(flag) (M.x86.R_FLG |= (flag))
|
|
||||||
#define CLEAR_FLAG(flag) (M.x86.R_FLG &= ~(flag))
|
|
||||||
#define ACCESS_FLAG(flag) (M.x86.R_FLG & (flag))
|
|
||||||
#define CLEARALL_FLAG(m) (M.x86.R_FLG = 0)
|
|
||||||
|
|
||||||
#define CONDITIONAL_SET_FLAG(COND,FLAG) \
|
|
||||||
if (COND) SET_FLAG(FLAG); else CLEAR_FLAG(FLAG)
|
|
||||||
|
|
||||||
#define F_PF_CALC 0x010000 /* PARITY flag has been calced */
|
|
||||||
#define F_ZF_CALC 0x020000 /* ZERO flag has been calced */
|
|
||||||
#define F_SF_CALC 0x040000 /* SIGN flag has been calced */
|
|
||||||
|
|
||||||
#define F_ALL_CALC 0xff0000 /* All have been calced */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Emulator machine state.
|
|
||||||
* Segment usage control.
|
|
||||||
*/
|
|
||||||
#define SYSMODE_SEG_DS_SS 0x00000001
|
|
||||||
#define SYSMODE_SEGOVR_CS 0x00000002
|
|
||||||
#define SYSMODE_SEGOVR_DS 0x00000004
|
|
||||||
#define SYSMODE_SEGOVR_ES 0x00000008
|
|
||||||
#define SYSMODE_SEGOVR_FS 0x00000010
|
|
||||||
#define SYSMODE_SEGOVR_GS 0x00000020
|
|
||||||
#define SYSMODE_SEGOVR_SS 0x00000040
|
|
||||||
#define SYSMODE_PREFIX_REPE 0x00000080
|
|
||||||
#define SYSMODE_PREFIX_REPNE 0x00000100
|
|
||||||
#define SYSMODE_PREFIX_DATA 0x00000200
|
|
||||||
#define SYSMODE_PREFIX_ADDR 0x00000400
|
|
||||||
#define SYSMODE_INTR_PENDING 0x10000000
|
|
||||||
#define SYSMODE_EXTRN_INTR 0x20000000
|
|
||||||
#define SYSMODE_HALTED 0x40000000
|
|
||||||
|
|
||||||
#define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS | \
|
|
||||||
SYSMODE_SEGOVR_CS | \
|
|
||||||
SYSMODE_SEGOVR_DS | \
|
|
||||||
SYSMODE_SEGOVR_ES | \
|
|
||||||
SYSMODE_SEGOVR_FS | \
|
|
||||||
SYSMODE_SEGOVR_GS | \
|
|
||||||
SYSMODE_SEGOVR_SS)
|
|
||||||
#define SYSMODE_CLRMASK (SYSMODE_SEG_DS_SS | \
|
|
||||||
SYSMODE_SEGOVR_CS | \
|
|
||||||
SYSMODE_SEGOVR_DS | \
|
|
||||||
SYSMODE_SEGOVR_ES | \
|
|
||||||
SYSMODE_SEGOVR_FS | \
|
|
||||||
SYSMODE_SEGOVR_GS | \
|
|
||||||
SYSMODE_SEGOVR_SS | \
|
|
||||||
SYSMODE_PREFIX_DATA | \
|
|
||||||
SYSMODE_PREFIX_ADDR)
|
|
||||||
|
|
||||||
#define INTR_SYNCH 0x1
|
|
||||||
#define INTR_ASYNCH 0x2
|
|
||||||
#define INTR_HALTED 0x4
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct i386_general_regs gen;
|
|
||||||
struct i386_special_regs spc;
|
|
||||||
struct i386_segment_regs seg;
|
|
||||||
/*
|
|
||||||
* MODE contains information on:
|
|
||||||
* REPE prefix 2 bits repe,repne
|
|
||||||
* SEGMENT overrides 5 bits normal,DS,SS,CS,ES
|
|
||||||
* Delayed flag set 3 bits (zero, signed, parity)
|
|
||||||
* reserved 6 bits
|
|
||||||
* interrupt # 8 bits instruction raised interrupt
|
|
||||||
* BIOS video segregs 4 bits
|
|
||||||
* Interrupt Pending 1 bits
|
|
||||||
* Extern interrupt 1 bits
|
|
||||||
* Halted 1 bits
|
|
||||||
*/
|
|
||||||
u32 mode;
|
|
||||||
volatile int intr; /* mask of pending interrupts */
|
|
||||||
int debug;
|
|
||||||
#ifdef DEBUG
|
|
||||||
int check;
|
|
||||||
u16 saved_ip;
|
|
||||||
u16 saved_cs;
|
|
||||||
int enc_pos;
|
|
||||||
int enc_str_pos;
|
|
||||||
char decode_buf[32]; /* encoded byte stream */
|
|
||||||
char decoded_buf[256]; /* disassembled strings */
|
|
||||||
#endif
|
|
||||||
u8 intno;
|
|
||||||
u8 __pad[3];
|
|
||||||
} X86EMU_regs;
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
REMARKS:
|
|
||||||
Structure maintaining the emulator machine state.
|
|
||||||
|
|
||||||
MEMBERS:
|
|
||||||
mem_base - Base real mode memory for the emulator
|
|
||||||
mem_size - Size of the real mode memory block for the emulator
|
|
||||||
private - private data pointer
|
|
||||||
x86 - X86 registers
|
|
||||||
****************************************************************************/
|
|
||||||
typedef struct {
|
|
||||||
unsigned long mem_base;
|
|
||||||
unsigned long mem_size;
|
|
||||||
void* private;
|
|
||||||
X86EMU_regs x86;
|
|
||||||
} X86EMU_sysEnv;
|
|
||||||
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
/*----------------------------- Global Variables --------------------------*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Global emulator machine state.
|
|
||||||
*
|
|
||||||
* We keep it global to avoid pointer dereferences in the code for speed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern X86EMU_sysEnv _X86EMU_env;
|
|
||||||
#define M _X86EMU_env
|
|
||||||
|
|
||||||
/*-------------------------- Function Prototypes --------------------------*/
|
|
||||||
|
|
||||||
/* Function to log information at runtime */
|
|
||||||
|
|
||||||
//void printk(const char *fmt, ...);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* End of "C" linkage for C++ */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __X86EMU_REGS_H */
|
|
|
@ -1,89 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Header file for x86 emulator type definitions.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/* $XFree86: xc/extras/x86emu/include/x86emu/types.h,v 1.4 2000/09/26 15:56:44 tsi Exp $ */
|
|
||||||
|
|
||||||
#ifndef __X86EMU_TYPES_H
|
|
||||||
#define __X86EMU_TYPES_H
|
|
||||||
|
|
||||||
#ifndef IN_MODULE
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following kludge is an attempt to work around typedef conflicts with
|
|
||||||
* <sys/types.h>.
|
|
||||||
*/
|
|
||||||
#define u8 x86emuu8
|
|
||||||
#define u16 x86emuu16
|
|
||||||
#define u32 x86emuu32
|
|
||||||
#define u64 x86emuu64
|
|
||||||
#define s8 x86emus8
|
|
||||||
#define s16 x86emus16
|
|
||||||
#define s32 x86emus32
|
|
||||||
#define s64 x86emus64
|
|
||||||
#define uint x86emuuint
|
|
||||||
#define sint x86emusint
|
|
||||||
|
|
||||||
/*---------------------- Macros and type definitions ----------------------*/
|
|
||||||
|
|
||||||
/* Currently only for Linux/32bit */
|
|
||||||
#if defined(__GNUC__) && !defined(NO_LONG_LONG)
|
|
||||||
#define __HAS_LONG_LONG__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef unsigned char u8;
|
|
||||||
typedef unsigned short u16;
|
|
||||||
typedef unsigned int u32;
|
|
||||||
#ifdef __HAS_LONG_LONG__
|
|
||||||
typedef unsigned long long u64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef char s8;
|
|
||||||
typedef short s16;
|
|
||||||
typedef int s32;
|
|
||||||
#ifdef __HAS_LONG_LONG__
|
|
||||||
typedef long long s64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef unsigned int uint;
|
|
||||||
typedef int sint;
|
|
||||||
|
|
||||||
typedef u16 X86EMU_pioAddr;
|
|
||||||
|
|
||||||
#endif /* __X86EMU_TYPES_H */
|
|
|
@ -1,17 +0,0 @@
|
||||||
License information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
The x86emu library is under a BSD style license, comaptible
|
|
||||||
with the XFree86 and X licenses used by XFree86. The
|
|
||||||
original x86emu libraries were under the GNU General Public
|
|
||||||
License. Due to license incompatibilities between the GPL
|
|
||||||
and the XFree86 license, the original authors of the code
|
|
||||||
decided to allow a license change. If you have submitted
|
|
||||||
code to the original x86emu project, and you don't agree
|
|
||||||
with the license change, please contact us and let you
|
|
||||||
know. Your code will be removed to comply with your wishes.
|
|
||||||
|
|
||||||
If you have any questions about this, please send email to
|
|
||||||
x86emu@linuxlabs.com or KendallB@scitechsoft.com for
|
|
||||||
clarification.
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
TARGETLIB = libx86emu.a
|
|
||||||
OBJS = debug.o decode.o fpu.o ops.o ops2.o prim_ops.o sys.o
|
|
||||||
INCLUDES = -I$(TOPDIR)/arch/x86emu/src/x86emu -I$(TOPDIR)/arch/x86emu/src/x86emu/x86emu -I$(TOPDIR)/arch/x86emu/include
|
|
||||||
CFLAGS := -D__DRIVER__ -DFORCE_POST -D_CEXPORT= -DNO_LONG_LONG -DDEBUG $(CFLAGS)
|
|
||||||
|
|
||||||
include $(TOPDIR)/Rules.make
|
|
||||||
|
|
||||||
$(TARGETLIB): $(OBJS)
|
|
||||||
cd $(BUILDDIR) && ar rv $(TARGETLIB) $(OBJS)
|
|
||||||
|
|
|
@ -1,435 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: This file contains the code to handle debugging of the
|
|
||||||
* emulator.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
/* $XFree86: xc/extras/x86emu/src/x86emu/debug.c,v 1.4 2000/04/17 16:29:45 eich Exp $ */
|
|
||||||
|
|
||||||
#include "x86emu/x86emui.h"
|
|
||||||
#ifdef IN_MODULE
|
|
||||||
#include "xf86_ansic.h"
|
|
||||||
#else
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*----------------------------- Implementation ----------------------------*/
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
|
|
||||||
static void print_encoded_bytes (u16 s, u16 o);
|
|
||||||
static void print_decoded_instruction (void);
|
|
||||||
static int parse_line (char *s, int *ps, int *n);
|
|
||||||
|
|
||||||
/* should look something like debug's output. */
|
|
||||||
void X86EMU_trace_regs (void)
|
|
||||||
{
|
|
||||||
if (DEBUG_TRACE()) {
|
|
||||||
x86emu_dump_regs();
|
|
||||||
}
|
|
||||||
if (DEBUG_DECODE() && ! DEBUG_DECODE_NOPRINT()) {
|
|
||||||
printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
|
|
||||||
print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
|
|
||||||
print_decoded_instruction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void X86EMU_trace_xregs (void)
|
|
||||||
{
|
|
||||||
if (DEBUG_TRACE()) {
|
|
||||||
x86emu_dump_xregs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_just_disassemble (void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* This routine called if the flag DEBUG_DISASSEMBLE is set kind
|
|
||||||
* of a hack!
|
|
||||||
*/
|
|
||||||
printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
|
|
||||||
print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
|
|
||||||
print_decoded_instruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void disassemble_forward (u16 seg, u16 off, int n)
|
|
||||||
{
|
|
||||||
X86EMU_sysEnv tregs;
|
|
||||||
int i;
|
|
||||||
u8 op1;
|
|
||||||
/*
|
|
||||||
* hack, hack, hack. What we do is use the exact machinery set up
|
|
||||||
* for execution, except that now there is an additional state
|
|
||||||
* flag associated with the "execution", and we are using a copy
|
|
||||||
* of the register struct. All the major opcodes, once fully
|
|
||||||
* decoded, have the following two steps: TRACE_REGS(r,m);
|
|
||||||
* SINGLE_STEP(r,m); which disappear if DEBUG is not defined to
|
|
||||||
* the preprocessor. The TRACE_REGS macro expands to:
|
|
||||||
*
|
|
||||||
* if (debug&DEBUG_DISASSEMBLE)
|
|
||||||
* {just_disassemble(); goto EndOfInstruction;}
|
|
||||||
* if (debug&DEBUG_TRACE) trace_regs(r,m);
|
|
||||||
*
|
|
||||||
* ...... and at the last line of the routine.
|
|
||||||
*
|
|
||||||
* EndOfInstruction: end_instr();
|
|
||||||
*
|
|
||||||
* Up to the point where TRACE_REG is expanded, NO modifications
|
|
||||||
* are done to any register EXCEPT the IP register, for fetch and
|
|
||||||
* decoding purposes.
|
|
||||||
*
|
|
||||||
* This was done for an entirely different reason, but makes a
|
|
||||||
* nice way to get the system to help debug codes.
|
|
||||||
*/
|
|
||||||
tregs = M;
|
|
||||||
tregs.x86.R_IP = off;
|
|
||||||
tregs.x86.R_CS = seg;
|
|
||||||
|
|
||||||
/* reset the decoding buffers */
|
|
||||||
tregs.x86.enc_str_pos = 0;
|
|
||||||
tregs.x86.enc_pos = 0;
|
|
||||||
|
|
||||||
/* turn on the "disassemble only, no execute" flag */
|
|
||||||
tregs.x86.debug |= DEBUG_DISASSEMBLE_F;
|
|
||||||
|
|
||||||
/* DUMP NEXT n instructions to screen in straight_line fashion */
|
|
||||||
/*
|
|
||||||
* This looks like the regular instruction fetch stream, except
|
|
||||||
* that when this occurs, each fetched opcode, upon seeing the
|
|
||||||
* DEBUG_DISASSEMBLE flag set, exits immediately after decoding
|
|
||||||
* the instruction. XXX --- CHECK THAT MEM IS NOT AFFECTED!!!
|
|
||||||
* Note the use of a copy of the register structure...
|
|
||||||
*/
|
|
||||||
for (i=0; i<n; i++) {
|
|
||||||
op1 = (*sys_rdb)(((u32)M.x86.R_CS<<4) + (M.x86.R_IP++));
|
|
||||||
(x86emu_optab[op1])(op1);
|
|
||||||
}
|
|
||||||
/* end major hack mode. */
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_check_ip_access (void)
|
|
||||||
{
|
|
||||||
/* NULL as of now */
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_check_sp_access (void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_check_mem_access (u32 dummy)
|
|
||||||
{
|
|
||||||
/* check bounds, etc */
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_check_data_access (uint dummy1, uint dummy2)
|
|
||||||
{
|
|
||||||
/* check bounds, etc */
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_inc_decoded_inst_len (int x)
|
|
||||||
{
|
|
||||||
M.x86.enc_pos += x;
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_decode_printf (char *x)
|
|
||||||
{
|
|
||||||
sprintf(M.x86.decoded_buf+M.x86.enc_str_pos,"%s",x);
|
|
||||||
M.x86.enc_str_pos += strlen(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_decode_printf2 (char *x, int y)
|
|
||||||
{
|
|
||||||
char temp[100];
|
|
||||||
sprintf(temp,x,y);
|
|
||||||
sprintf(M.x86.decoded_buf+M.x86.enc_str_pos,"%s",temp);
|
|
||||||
M.x86.enc_str_pos += strlen(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_end_instr (void)
|
|
||||||
{
|
|
||||||
M.x86.enc_str_pos = 0;
|
|
||||||
M.x86.enc_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_encoded_bytes (u16 s, u16 o)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char buf1[64];
|
|
||||||
for (i=0; i< M.x86.enc_pos; i++) {
|
|
||||||
sprintf(buf1+2*i,"%02x", fetch_data_byte_abs(s,o+i));
|
|
||||||
}
|
|
||||||
printk("%-20s",buf1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_decoded_instruction (void)
|
|
||||||
{
|
|
||||||
printk("%s", M.x86.decoded_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_print_int_vect (u16 iv)
|
|
||||||
{
|
|
||||||
u16 seg,off;
|
|
||||||
|
|
||||||
if (iv > 256) return;
|
|
||||||
seg = fetch_data_word_abs(0,iv*4);
|
|
||||||
off = fetch_data_word_abs(0,iv*4+2);
|
|
||||||
printk("%04x:%04x ", seg, off);
|
|
||||||
}
|
|
||||||
|
|
||||||
void X86EMU_dump_memory (u16 seg, u16 off, u32 amt)
|
|
||||||
{
|
|
||||||
u32 start = off & 0xfffffff0;
|
|
||||||
u32 end = (off+16) & 0xfffffff0;
|
|
||||||
u32 i;
|
|
||||||
u32 current;
|
|
||||||
|
|
||||||
current = start;
|
|
||||||
while (end <= off + amt) {
|
|
||||||
printk("%04x:%04x ", seg, start);
|
|
||||||
for (i=start; i< off; i++)
|
|
||||||
printk(" ");
|
|
||||||
for ( ; i< end; i++)
|
|
||||||
printk("%02x ", fetch_data_byte_abs(seg,i));
|
|
||||||
printk("\n");
|
|
||||||
start = end;
|
|
||||||
end = start + 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86emu_single_step (void)
|
|
||||||
{
|
|
||||||
char s[1024];
|
|
||||||
int ps[10];
|
|
||||||
int ntok;
|
|
||||||
int cmd;
|
|
||||||
int done;
|
|
||||||
int segment;
|
|
||||||
int offset;
|
|
||||||
static int breakpoint;
|
|
||||||
static int noDecode = 1;
|
|
||||||
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
if (DEBUG_BREAK()) {
|
|
||||||
if (M.x86.saved_ip != breakpoint) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
|
|
||||||
M.x86.debug |= DEBUG_TRACE_F;
|
|
||||||
M.x86.debug &= ~DEBUG_BREAK_F;
|
|
||||||
print_decoded_instruction ();
|
|
||||||
X86EMU_trace_regs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
done=0;
|
|
||||||
offset = M.x86.saved_ip;
|
|
||||||
while (!done) {
|
|
||||||
printk("%x:%x -", M.x86.saved_cs, offset);
|
|
||||||
p = fgets(s, 1023, stdin);
|
|
||||||
cmd = parse_line(s, ps, &ntok);
|
|
||||||
switch(cmd) {
|
|
||||||
case 'u':
|
|
||||||
disassemble_forward(M.x86.saved_cs,(u16)offset,10);
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
if (ntok == 2) {
|
|
||||||
segment = M.x86.saved_cs;
|
|
||||||
offset = ps[1];
|
|
||||||
X86EMU_dump_memory(segment,(u16)offset,16);
|
|
||||||
offset += 16;
|
|
||||||
} else if (ntok == 3) {
|
|
||||||
segment = ps[1];
|
|
||||||
offset = ps[2];
|
|
||||||
X86EMU_dump_memory(segment,(u16)offset,16);
|
|
||||||
offset += 16;
|
|
||||||
} else {
|
|
||||||
segment = M.x86.saved_cs;
|
|
||||||
X86EMU_dump_memory(segment,(u16)offset,16);
|
|
||||||
offset += 16;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
M.x86.debug ^= DEBUG_TRACECALL_F;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
M.x86.debug ^= DEBUG_SVC_F | DEBUG_SYS_F | DEBUG_SYSINT_F;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
X86EMU_trace_regs();
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
X86EMU_trace_xregs();
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
if (ntok == 2) {
|
|
||||||
breakpoint = ps[1];
|
|
||||||
if (noDecode) {
|
|
||||||
M.x86.debug |= DEBUG_DECODE_NOPRINT_F;
|
|
||||||
} else {
|
|
||||||
M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
|
|
||||||
}
|
|
||||||
M.x86.debug &= ~DEBUG_TRACE_F;
|
|
||||||
M.x86.debug |= DEBUG_BREAK_F;
|
|
||||||
done = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
exit(1);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
int X86EMU_set_debug(int debug)
|
|
||||||
{
|
|
||||||
return M.x86.debug = debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
|
@ -1,865 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: This file includes subroutines which are related to
|
|
||||||
* instruction decoding and accessess of immediate data via IP. etc.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/* $XFree86: xc/extras/x86emu/src/x86emu/decode.c,v 1.9 2001/01/06 20:19:03 tsi Exp $ */
|
|
||||||
|
|
||||||
#include "x86emu/x86emui.h"
|
|
||||||
|
|
||||||
/*----------------------------- Implementation ----------------------------*/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
REMARKS:
|
|
||||||
Handles any pending asychronous interrupts.
|
|
||||||
****************************************************************************/
|
|
||||||
static void x86emu_intr_handle(void)
|
|
||||||
{
|
|
||||||
u8 intno;
|
|
||||||
|
|
||||||
if (M.x86.intr & INTR_SYNCH) {
|
|
||||||
intno = M.x86.intno;
|
|
||||||
if (_X86EMU_intrTab[intno]) {
|
|
||||||
(*_X86EMU_intrTab[intno])(intno);
|
|
||||||
} else {
|
|
||||||
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(intno * 4 + 2);
|
|
||||||
push_word(M.x86.R_IP);
|
|
||||||
M.x86.R_IP = mem_access_word(intno * 4);
|
|
||||||
M.x86.intr = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
intrnum - Interrupt number to raise
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Raise the specified interrupt to be handled before the execution of the
|
|
||||||
next instruction.
|
|
||||||
****************************************************************************/
|
|
||||||
void x86emu_intr_raise(
|
|
||||||
u8 intrnum)
|
|
||||||
{
|
|
||||||
M.x86.intno = intrnum;
|
|
||||||
M.x86.intr |= INTR_SYNCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
REMARKS:
|
|
||||||
Main execution loop for the emulator. We return from here when the system
|
|
||||||
halts, which is normally caused by a stack fault when we return from the
|
|
||||||
original real mode call.
|
|
||||||
****************************************************************************/
|
|
||||||
void X86EMU_exec(void)
|
|
||||||
{
|
|
||||||
u8 op1;
|
|
||||||
|
|
||||||
M.x86.intr = 0;
|
|
||||||
DB(x86emu_end_instr();)
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
DB( if (CHECK_IP_FETCH())
|
|
||||||
x86emu_check_ip_access();)
|
|
||||||
/* If debugging, save the IP and CS values. */
|
|
||||||
SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
|
|
||||||
INC_DECODED_INST_LEN(1);
|
|
||||||
if (M.x86.intr) {
|
|
||||||
if (M.x86.intr & INTR_HALTED) {
|
|
||||||
DB( printk("halted\n");
|
|
||||||
X86EMU_trace_regs();)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) ||
|
|
||||||
!ACCESS_FLAG(F_IF)) {
|
|
||||||
x86emu_intr_handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
op1 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
|
|
||||||
(*x86emu_optab[op1])(op1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
REMARKS:
|
|
||||||
Halts the system by setting the halted system flag.
|
|
||||||
****************************************************************************/
|
|
||||||
void X86EMU_halt_sys(void)
|
|
||||||
{
|
|
||||||
M.x86.intr |= INTR_HALTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
mod - Mod value from decoded byte
|
|
||||||
regh - Reg h value from decoded byte
|
|
||||||
regl - Reg l value from decoded byte
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Raise the specified interrupt to be handled before the execution of the
|
|
||||||
next instruction.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function, as (*sys_rdb) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
void fetch_decode_modrm(
|
|
||||||
int *mod,
|
|
||||||
int *regh,
|
|
||||||
int *regl)
|
|
||||||
{
|
|
||||||
int fetched;
|
|
||||||
|
|
||||||
DB( if (CHECK_IP_FETCH())
|
|
||||||
x86emu_check_ip_access();)
|
|
||||||
fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
|
|
||||||
INC_DECODED_INST_LEN(1);
|
|
||||||
*mod = (fetched >> 6) & 0x03;
|
|
||||||
*regh = (fetched >> 3) & 0x07;
|
|
||||||
*regl = (fetched >> 0) & 0x07;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
RETURNS:
|
|
||||||
Immediate byte value read from instruction queue
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
This function returns the immediate byte from the instruction queue, and
|
|
||||||
moves the instruction pointer to the next value.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function, as (*sys_rdb) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
u8 fetch_byte_imm(void)
|
|
||||||
{
|
|
||||||
u8 fetched;
|
|
||||||
|
|
||||||
DB( if (CHECK_IP_FETCH())
|
|
||||||
x86emu_check_ip_access();)
|
|
||||||
fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
|
|
||||||
INC_DECODED_INST_LEN(1);
|
|
||||||
return fetched;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
RETURNS:
|
|
||||||
Immediate word value read from instruction queue
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
This function returns the immediate byte from the instruction queue, and
|
|
||||||
moves the instruction pointer to the next value.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function, as (*sys_rdw) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
u16 fetch_word_imm(void)
|
|
||||||
{
|
|
||||||
u16 fetched;
|
|
||||||
|
|
||||||
DB( if (CHECK_IP_FETCH())
|
|
||||||
x86emu_check_ip_access();)
|
|
||||||
fetched = (*sys_rdw)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP));
|
|
||||||
M.x86.R_IP += 2;
|
|
||||||
INC_DECODED_INST_LEN(2);
|
|
||||||
return fetched;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
RETURNS:
|
|
||||||
Immediate lone value read from instruction queue
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
This function returns the immediate byte from the instruction queue, and
|
|
||||||
moves the instruction pointer to the next value.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function, as (*sys_rdw) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
u32 fetch_long_imm(void)
|
|
||||||
{
|
|
||||||
u32 fetched;
|
|
||||||
|
|
||||||
DB( if (CHECK_IP_FETCH())
|
|
||||||
x86emu_check_ip_access();)
|
|
||||||
fetched = (*sys_rdl)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP));
|
|
||||||
M.x86.R_IP += 4;
|
|
||||||
INC_DECODED_INST_LEN(4);
|
|
||||||
return fetched;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
RETURNS:
|
|
||||||
Value of the default data segment
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Inline function that returns the default data segment for the current
|
|
||||||
instruction.
|
|
||||||
|
|
||||||
On the x86 processor, the default segment is not always DS if there is
|
|
||||||
no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
|
|
||||||
addresses relative to SS (ie: on the stack). So, at the minimum, all
|
|
||||||
decodings of addressing modes would have to set/clear a bit describing
|
|
||||||
whether the access is relative to DS or SS. That is the function of the
|
|
||||||
cpu-state-varible M.x86.mode. There are several potential states:
|
|
||||||
|
|
||||||
repe prefix seen (handled elsewhere)
|
|
||||||
repne prefix seen (ditto)
|
|
||||||
|
|
||||||
cs segment override
|
|
||||||
ds segment override
|
|
||||||
es segment override
|
|
||||||
fs segment override
|
|
||||||
gs segment override
|
|
||||||
ss segment override
|
|
||||||
|
|
||||||
ds/ss select (in absense of override)
|
|
||||||
|
|
||||||
Each of the above 7 items are handled with a bit in the mode field.
|
|
||||||
****************************************************************************/
|
|
||||||
_INLINE u32 get_data_segment(void)
|
|
||||||
{
|
|
||||||
#define GET_SEGMENT(segment)
|
|
||||||
switch (M.x86.mode & SYSMODE_SEGMASK) {
|
|
||||||
case 0: /* default case: use ds register */
|
|
||||||
case SYSMODE_SEGOVR_DS:
|
|
||||||
case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
|
|
||||||
return M.x86.R_DS;
|
|
||||||
case SYSMODE_SEG_DS_SS: /* non-overridden, use ss register */
|
|
||||||
return M.x86.R_SS;
|
|
||||||
case SYSMODE_SEGOVR_CS:
|
|
||||||
case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
|
|
||||||
return M.x86.R_CS;
|
|
||||||
case SYSMODE_SEGOVR_ES:
|
|
||||||
case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
|
|
||||||
return M.x86.R_ES;
|
|
||||||
case SYSMODE_SEGOVR_FS:
|
|
||||||
case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
|
|
||||||
return M.x86.R_FS;
|
|
||||||
case SYSMODE_SEGOVR_GS:
|
|
||||||
case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
|
|
||||||
return M.x86.R_GS;
|
|
||||||
case SYSMODE_SEGOVR_SS:
|
|
||||||
case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
|
|
||||||
return M.x86.R_SS;
|
|
||||||
default:
|
|
||||||
#ifdef DEBUG
|
|
||||||
printk("error: should not happen: multiple overrides.\n");
|
|
||||||
#endif
|
|
||||||
HALT_SYS();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
offset - Offset to load data from
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Byte value read from the absolute memory location.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_rdX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
u8 fetch_data_byte(
|
|
||||||
uint offset)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access((u16)get_data_segment(), offset);
|
|
||||||
#endif
|
|
||||||
return (*sys_rdb)((get_data_segment() << 4) + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
offset - Offset to load data from
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Word value read from the absolute memory location.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_rdX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
u16 fetch_data_word(
|
|
||||||
uint offset)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access((u16)get_data_segment(), offset);
|
|
||||||
#endif
|
|
||||||
return (*sys_rdw)((get_data_segment() << 4) + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
offset - Offset to load data from
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Long value read from the absolute memory location.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_rdX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
u32 fetch_data_long(
|
|
||||||
uint offset)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access((u16)get_data_segment(), offset);
|
|
||||||
#endif
|
|
||||||
return (*sys_rdl)((get_data_segment() << 4) + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
segment - Segment to load data from
|
|
||||||
offset - Offset to load data from
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Byte value read from the absolute memory location.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_rdX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
u8 fetch_data_byte_abs(
|
|
||||||
uint segment,
|
|
||||||
uint offset)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access(segment, offset);
|
|
||||||
#endif
|
|
||||||
return (*sys_rdb)(((u32)segment << 4) + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
segment - Segment to load data from
|
|
||||||
offset - Offset to load data from
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Word value read from the absolute memory location.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_rdX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
u16 fetch_data_word_abs(
|
|
||||||
uint segment,
|
|
||||||
uint offset)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access(segment, offset);
|
|
||||||
#endif
|
|
||||||
return (*sys_rdw)(((u32)segment << 4) + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
segment - Segment to load data from
|
|
||||||
offset - Offset to load data from
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Long value read from the absolute memory location.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_rdX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
u32 fetch_data_long_abs(
|
|
||||||
uint segment,
|
|
||||||
uint offset)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access(segment, offset);
|
|
||||||
#endif
|
|
||||||
return (*sys_rdl)(((u32)segment << 4) + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
offset - Offset to store data at
|
|
||||||
val - Value to store
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Writes a word value to an segmented memory location. The segment used is
|
|
||||||
the current 'default' segment, which may have been overridden.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_wrX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
void store_data_byte(
|
|
||||||
uint offset,
|
|
||||||
u8 val)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access((u16)get_data_segment(), offset);
|
|
||||||
#endif
|
|
||||||
(*sys_wrb)((get_data_segment() << 4) + offset, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
offset - Offset to store data at
|
|
||||||
val - Value to store
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Writes a word value to an segmented memory location. The segment used is
|
|
||||||
the current 'default' segment, which may have been overridden.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_wrX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
void store_data_word(
|
|
||||||
uint offset,
|
|
||||||
u16 val)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access((u16)get_data_segment(), offset);
|
|
||||||
#endif
|
|
||||||
(*sys_wrw)((get_data_segment() << 4) + offset, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
offset - Offset to store data at
|
|
||||||
val - Value to store
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Writes a long value to an segmented memory location. The segment used is
|
|
||||||
the current 'default' segment, which may have been overridden.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_wrX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
void store_data_long(
|
|
||||||
uint offset,
|
|
||||||
u32 val)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access((u16)get_data_segment(), offset);
|
|
||||||
#endif
|
|
||||||
(*sys_wrl)((get_data_segment() << 4) + offset, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
segment - Segment to store data at
|
|
||||||
offset - Offset to store data at
|
|
||||||
val - Value to store
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Writes a byte value to an absolute memory location.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_wrX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
void store_data_byte_abs(
|
|
||||||
uint segment,
|
|
||||||
uint offset,
|
|
||||||
u8 val)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access(segment, offset);
|
|
||||||
#endif
|
|
||||||
(*sys_wrb)(((u32)segment << 4) + offset, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
segment - Segment to store data at
|
|
||||||
offset - Offset to store data at
|
|
||||||
val - Value to store
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Writes a word value to an absolute memory location.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_wrX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
void store_data_word_abs(
|
|
||||||
uint segment,
|
|
||||||
uint offset,
|
|
||||||
u16 val)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access(segment, offset);
|
|
||||||
#endif
|
|
||||||
(*sys_wrw)(((u32)segment << 4) + offset, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
segment - Segment to store data at
|
|
||||||
offset - Offset to store data at
|
|
||||||
val - Value to store
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Writes a long value to an absolute memory location.
|
|
||||||
|
|
||||||
NOTE: Do not inline this function as (*sys_wrX) is already inline!
|
|
||||||
****************************************************************************/
|
|
||||||
void store_data_long_abs(
|
|
||||||
uint segment,
|
|
||||||
uint offset,
|
|
||||||
u32 val)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (CHECK_DATA_ACCESS())
|
|
||||||
x86emu_check_data_access(segment, offset);
|
|
||||||
#endif
|
|
||||||
(*sys_wrl)(((u32)segment << 4) + offset, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
reg - Register to decode
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Pointer to the appropriate register
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Return a pointer to the register given by the R/RM field of the
|
|
||||||
modrm byte, for byte operands. Also enables the decoding of instructions.
|
|
||||||
****************************************************************************/
|
|
||||||
u8* decode_rm_byte_register(
|
|
||||||
int reg)
|
|
||||||
{
|
|
||||||
switch (reg) {
|
|
||||||
case 0:
|
|
||||||
DECODE_PRINTF("AL");
|
|
||||||
return &M.x86.R_AL;
|
|
||||||
case 1:
|
|
||||||
DECODE_PRINTF("CL");
|
|
||||||
return &M.x86.R_CL;
|
|
||||||
case 2:
|
|
||||||
DECODE_PRINTF("DL");
|
|
||||||
return &M.x86.R_DL;
|
|
||||||
case 3:
|
|
||||||
DECODE_PRINTF("BL");
|
|
||||||
return &M.x86.R_BL;
|
|
||||||
case 4:
|
|
||||||
DECODE_PRINTF("AH");
|
|
||||||
return &M.x86.R_AH;
|
|
||||||
case 5:
|
|
||||||
DECODE_PRINTF("CH");
|
|
||||||
return &M.x86.R_CH;
|
|
||||||
case 6:
|
|
||||||
DECODE_PRINTF("DH");
|
|
||||||
return &M.x86.R_DH;
|
|
||||||
case 7:
|
|
||||||
DECODE_PRINTF("BH");
|
|
||||||
return &M.x86.R_BH;
|
|
||||||
}
|
|
||||||
HALT_SYS();
|
|
||||||
return NULL; /* NOT REACHED OR REACHED ON ERROR */
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
reg - Register to decode
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Pointer to the appropriate register
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Return a pointer to the register given by the R/RM field of the
|
|
||||||
modrm byte, for word operands. Also enables the decoding of instructions.
|
|
||||||
****************************************************************************/
|
|
||||||
u16* decode_rm_word_register(
|
|
||||||
int reg)
|
|
||||||
{
|
|
||||||
switch (reg) {
|
|
||||||
case 0:
|
|
||||||
DECODE_PRINTF("AX");
|
|
||||||
return &M.x86.R_AX;
|
|
||||||
case 1:
|
|
||||||
DECODE_PRINTF("CX");
|
|
||||||
return &M.x86.R_CX;
|
|
||||||
case 2:
|
|
||||||
DECODE_PRINTF("DX");
|
|
||||||
return &M.x86.R_DX;
|
|
||||||
case 3:
|
|
||||||
DECODE_PRINTF("BX");
|
|
||||||
return &M.x86.R_BX;
|
|
||||||
case 4:
|
|
||||||
DECODE_PRINTF("SP");
|
|
||||||
return &M.x86.R_SP;
|
|
||||||
case 5:
|
|
||||||
DECODE_PRINTF("BP");
|
|
||||||
return &M.x86.R_BP;
|
|
||||||
case 6:
|
|
||||||
DECODE_PRINTF("SI");
|
|
||||||
return &M.x86.R_SI;
|
|
||||||
case 7:
|
|
||||||
DECODE_PRINTF("DI");
|
|
||||||
return &M.x86.R_DI;
|
|
||||||
}
|
|
||||||
HALT_SYS();
|
|
||||||
return NULL; /* NOTREACHED OR REACHED ON ERROR */
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
reg - Register to decode
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Pointer to the appropriate register
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Return a pointer to the register given by the R/RM field of the
|
|
||||||
modrm byte, for dword operands. Also enables the decoding of instructions.
|
|
||||||
****************************************************************************/
|
|
||||||
u32* decode_rm_long_register(
|
|
||||||
int reg)
|
|
||||||
{
|
|
||||||
switch (reg) {
|
|
||||||
case 0:
|
|
||||||
DECODE_PRINTF("EAX");
|
|
||||||
return &M.x86.R_EAX;
|
|
||||||
case 1:
|
|
||||||
DECODE_PRINTF("ECX");
|
|
||||||
return &M.x86.R_ECX;
|
|
||||||
case 2:
|
|
||||||
DECODE_PRINTF("EDX");
|
|
||||||
return &M.x86.R_EDX;
|
|
||||||
case 3:
|
|
||||||
DECODE_PRINTF("EBX");
|
|
||||||
return &M.x86.R_EBX;
|
|
||||||
case 4:
|
|
||||||
DECODE_PRINTF("ESP");
|
|
||||||
return &M.x86.R_ESP;
|
|
||||||
case 5:
|
|
||||||
DECODE_PRINTF("EBP");
|
|
||||||
return &M.x86.R_EBP;
|
|
||||||
case 6:
|
|
||||||
DECODE_PRINTF("ESI");
|
|
||||||
return &M.x86.R_ESI;
|
|
||||||
case 7:
|
|
||||||
DECODE_PRINTF("EDI");
|
|
||||||
return &M.x86.R_EDI;
|
|
||||||
}
|
|
||||||
HALT_SYS();
|
|
||||||
return NULL; /* NOTREACHED OR REACHED ON ERROR */
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
reg - Register to decode
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Pointer to the appropriate register
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Return a pointer to the register given by the R/RM field of the
|
|
||||||
modrm byte, for word operands, modified from above for the weirdo
|
|
||||||
special case of segreg operands. Also enables the decoding of instructions.
|
|
||||||
****************************************************************************/
|
|
||||||
u16* decode_rm_seg_register(
|
|
||||||
int reg)
|
|
||||||
{
|
|
||||||
switch (reg) {
|
|
||||||
case 0:
|
|
||||||
DECODE_PRINTF("ES");
|
|
||||||
return &M.x86.R_ES;
|
|
||||||
case 1:
|
|
||||||
DECODE_PRINTF("CS");
|
|
||||||
return &M.x86.R_CS;
|
|
||||||
case 2:
|
|
||||||
DECODE_PRINTF("SS");
|
|
||||||
return &M.x86.R_SS;
|
|
||||||
case 3:
|
|
||||||
DECODE_PRINTF("DS");
|
|
||||||
return &M.x86.R_DS;
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
DECODE_PRINTF("ILLEGAL SEGREG");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
HALT_SYS();
|
|
||||||
return NULL; /* NOT REACHED OR REACHED ON ERROR */
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
rm - RM value to decode
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Offset in memory for the address decoding
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Return the offset given by mod=00 addressing. Also enables the
|
|
||||||
decoding of instructions.
|
|
||||||
|
|
||||||
NOTE: The code which specifies the corresponding segment (ds vs ss)
|
|
||||||
below in the case of [BP+..]. The assumption here is that at the
|
|
||||||
point that this subroutine is called, the bit corresponding to
|
|
||||||
SYSMODE_SEG_DS_SS will be zero. After every instruction
|
|
||||||
except the segment override instructions, this bit (as well
|
|
||||||
as any bits indicating segment overrides) will be clear. So
|
|
||||||
if a SS access is needed, set this bit. Otherwise, DS access
|
|
||||||
occurs (unless any of the segment override bits are set).
|
|
||||||
****************************************************************************/
|
|
||||||
unsigned decode_rm00_address(
|
|
||||||
int rm)
|
|
||||||
{
|
|
||||||
unsigned offset;
|
|
||||||
|
|
||||||
switch (rm) {
|
|
||||||
case 0:
|
|
||||||
DECODE_PRINTF("[BX+SI]");
|
|
||||||
return M.x86.R_BX + M.x86.R_SI;
|
|
||||||
case 1:
|
|
||||||
DECODE_PRINTF("[BX+DI]");
|
|
||||||
return M.x86.R_BX + M.x86.R_DI;
|
|
||||||
case 2:
|
|
||||||
DECODE_PRINTF("[BP+SI]");
|
|
||||||
M.x86.mode |= SYSMODE_SEG_DS_SS;
|
|
||||||
return M.x86.R_BP + M.x86.R_SI;
|
|
||||||
case 3:
|
|
||||||
DECODE_PRINTF("[BP+DI]");
|
|
||||||
M.x86.mode |= SYSMODE_SEG_DS_SS;
|
|
||||||
return M.x86.R_BP + M.x86.R_DI;
|
|
||||||
case 4:
|
|
||||||
DECODE_PRINTF("[SI]");
|
|
||||||
return M.x86.R_SI;
|
|
||||||
case 5:
|
|
||||||
DECODE_PRINTF("[DI]");
|
|
||||||
return M.x86.R_DI;
|
|
||||||
case 6:
|
|
||||||
offset = fetch_word_imm();
|
|
||||||
DECODE_PRINTF2("[%04x]", offset);
|
|
||||||
return offset;
|
|
||||||
case 7:
|
|
||||||
DECODE_PRINTF("[BX]");
|
|
||||||
return M.x86.R_BX;
|
|
||||||
}
|
|
||||||
HALT_SYS();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
rm - RM value to decode
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Offset in memory for the address decoding
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Return the offset given by mod=01 addressing. Also enables the
|
|
||||||
decoding of instructions.
|
|
||||||
****************************************************************************/
|
|
||||||
unsigned decode_rm01_address(
|
|
||||||
int rm)
|
|
||||||
{
|
|
||||||
int displacement = (s8)fetch_byte_imm();
|
|
||||||
switch (rm) {
|
|
||||||
case 0:
|
|
||||||
DECODE_PRINTF2("%d[BX+SI]", displacement);
|
|
||||||
return M.x86.R_BX + M.x86.R_SI + displacement;
|
|
||||||
case 1:
|
|
||||||
DECODE_PRINTF2("%d[BX+DI]", displacement);
|
|
||||||
return M.x86.R_BX + M.x86.R_DI + displacement;
|
|
||||||
case 2:
|
|
||||||
DECODE_PRINTF2("%d[BP+SI]", displacement);
|
|
||||||
M.x86.mode |= SYSMODE_SEG_DS_SS;
|
|
||||||
return M.x86.R_BP + M.x86.R_SI + displacement;
|
|
||||||
case 3:
|
|
||||||
DECODE_PRINTF2("%d[BP+DI]", displacement);
|
|
||||||
M.x86.mode |= SYSMODE_SEG_DS_SS;
|
|
||||||
return M.x86.R_BP + M.x86.R_DI + displacement;
|
|
||||||
case 4:
|
|
||||||
DECODE_PRINTF2("%d[SI]", displacement);
|
|
||||||
return M.x86.R_SI + displacement;
|
|
||||||
case 5:
|
|
||||||
DECODE_PRINTF2("%d[DI]", displacement);
|
|
||||||
return M.x86.R_DI + displacement;
|
|
||||||
case 6:
|
|
||||||
DECODE_PRINTF2("%d[BP]", displacement);
|
|
||||||
M.x86.mode |= SYSMODE_SEG_DS_SS;
|
|
||||||
return M.x86.R_BP + displacement;
|
|
||||||
case 7:
|
|
||||||
DECODE_PRINTF2("%d[BX]", displacement);
|
|
||||||
return M.x86.R_BX + displacement;
|
|
||||||
}
|
|
||||||
HALT_SYS();
|
|
||||||
return 0; /* SHOULD NOT HAPPEN */
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
rm - RM value to decode
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Offset in memory for the address decoding
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Return the offset given by mod=10 addressing. Also enables the
|
|
||||||
decoding of instructions.
|
|
||||||
****************************************************************************/
|
|
||||||
unsigned decode_rm10_address(
|
|
||||||
int rm)
|
|
||||||
{
|
|
||||||
unsigned displacement = (u16)fetch_word_imm();
|
|
||||||
switch (rm) {
|
|
||||||
case 0:
|
|
||||||
DECODE_PRINTF2("%04x[BX+SI]", displacement);
|
|
||||||
return M.x86.R_BX + M.x86.R_SI + displacement;
|
|
||||||
case 1:
|
|
||||||
DECODE_PRINTF2("%04x[BX+DI]", displacement);
|
|
||||||
return M.x86.R_BX + M.x86.R_DI + displacement;
|
|
||||||
case 2:
|
|
||||||
DECODE_PRINTF2("%04x[BP+SI]", displacement);
|
|
||||||
M.x86.mode |= SYSMODE_SEG_DS_SS;
|
|
||||||
return M.x86.R_BP + M.x86.R_SI + displacement;
|
|
||||||
case 3:
|
|
||||||
DECODE_PRINTF2("%04x[BP+DI]", displacement);
|
|
||||||
M.x86.mode |= SYSMODE_SEG_DS_SS;
|
|
||||||
return M.x86.R_BP + M.x86.R_DI + displacement;
|
|
||||||
case 4:
|
|
||||||
DECODE_PRINTF2("%04x[SI]", displacement);
|
|
||||||
return M.x86.R_SI + displacement;
|
|
||||||
case 5:
|
|
||||||
DECODE_PRINTF2("%04x[DI]", displacement);
|
|
||||||
return M.x86.R_DI + displacement;
|
|
||||||
case 6:
|
|
||||||
DECODE_PRINTF2("%04x[BP]", displacement);
|
|
||||||
M.x86.mode |= SYSMODE_SEG_DS_SS;
|
|
||||||
return M.x86.R_BP + displacement;
|
|
||||||
case 7:
|
|
||||||
DECODE_PRINTF2("%04x[BX]", displacement);
|
|
||||||
return M.x86.R_BX + displacement;
|
|
||||||
}
|
|
||||||
HALT_SYS();
|
|
||||||
return 0;
|
|
||||||
/*NOTREACHED */
|
|
||||||
}
|
|
|
@ -1,945 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: This file 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 char *x86emu_fpu_op_d9_tab[] = {
|
|
||||||
"FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
|
|
||||||
"FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
|
|
||||||
|
|
||||||
"FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
|
|
||||||
"FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
|
|
||||||
|
|
||||||
"FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
|
|
||||||
"FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
|
|
||||||
};
|
|
||||||
|
|
||||||
static char *x86emu_fpu_op_d9_tab1[] = {
|
|
||||||
"FLD\t", "FLD\t", "FLD\t", "FLD\t",
|
|
||||||
"FLD\t", "FLD\t", "FLD\t", "FLD\t",
|
|
||||||
|
|
||||||
"FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
|
|
||||||
"FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
|
|
||||||
|
|
||||||
"FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
|
|
||||||
"ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",
|
|
||||||
|
|
||||||
"FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
|
|
||||||
"FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
|
|
||||||
|
|
||||||
"FCHS", "FABS", "ESC_D9", "ESC_D9",
|
|
||||||
"FTST", "FXAM", "ESC_D9", "ESC_D9",
|
|
||||||
|
|
||||||
"FLD1", "FLDL2T", "FLDL2E", "FLDPI",
|
|
||||||
"FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",
|
|
||||||
|
|
||||||
"F2XM1", "FYL2X", "FPTAN", "FPATAN",
|
|
||||||
"FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",
|
|
||||||
|
|
||||||
"FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
|
|
||||||
"FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/* opcode=0xd9 */
|
|
||||||
void x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1))
|
|
||||||
{
|
|
||||||
int mod, rl, rh;
|
|
||||||
uint destoffset;
|
|
||||||
u8 stkelem;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* X86EMU_FPU_PRESENT */
|
|
||||||
DECODE_CLEAR_SEGOVR();
|
|
||||||
END_OF_INSTR_NO_TRACE();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
|
|
||||||
char *x86emu_fpu_op_da_tab[] = {
|
|
||||||
"FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
|
|
||||||
"FICOMP\tDWORD PTR ",
|
|
||||||
"FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
|
|
||||||
"FIDIVR\tDWORD PTR ",
|
|
||||||
|
|
||||||
"FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
|
|
||||||
"FICOMP\tDWORD PTR ",
|
|
||||||
"FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
|
|
||||||
"FIDIVR\tDWORD PTR ",
|
|
||||||
|
|
||||||
"FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
|
|
||||||
"FICOMP\tDWORD PTR ",
|
|
||||||
"FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
|
|
||||||
"FIDIVR\tDWORD PTR ",
|
|
||||||
|
|
||||||
"ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
|
|
||||||
"ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/* opcode=0xda */
|
|
||||||
void x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1))
|
|
||||||
{
|
|
||||||
int mod, rl, rh;
|
|
||||||
uint destoffset;
|
|
||||||
u8 stkelem;
|
|
||||||
|
|
||||||
START_OF_INSTR();
|
|
||||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
|
||||||
DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
|
|
||||||
switch (mod) {
|
|
||||||
case 0:
|
|
||||||
destoffset = decode_rm00_address(rl);
|
|
||||||
DECODE_PRINTF("\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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
DECODE_CLEAR_SEGOVR();
|
|
||||||
END_OF_INSTR_NO_TRACE();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
|
|
||||||
char *x86emu_fpu_op_db_tab[] = {
|
|
||||||
"FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
|
|
||||||
"ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
|
|
||||||
|
|
||||||
"FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
|
|
||||||
"ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
|
|
||||||
|
|
||||||
"FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
|
|
||||||
"ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/* opcode=0xdb */
|
|
||||||
void x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1))
|
|
||||||
{
|
|
||||||
int mod, rl, rh;
|
|
||||||
uint destoffset;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
DECODE_CLEAR_SEGOVR();
|
|
||||||
END_OF_INSTR_NO_TRACE();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
char *x86emu_fpu_op_dc_tab[] = {
|
|
||||||
"FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
|
|
||||||
"FCOMP\tQWORD PTR ",
|
|
||||||
"FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
|
|
||||||
"FDIVR\tQWORD PTR ",
|
|
||||||
|
|
||||||
"FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
|
|
||||||
"FCOMP\tQWORD PTR ",
|
|
||||||
"FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
|
|
||||||
"FDIVR\tQWORD PTR ",
|
|
||||||
|
|
||||||
"FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
|
|
||||||
"FCOMP\tQWORD PTR ",
|
|
||||||
"FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
|
|
||||||
"FDIVR\tQWORD PTR ",
|
|
||||||
|
|
||||||
"FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
|
|
||||||
"FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
|
|
||||||
};
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/* opcode=0xdc */
|
|
||||||
void x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1))
|
|
||||||
{
|
|
||||||
int mod, rl, rh;
|
|
||||||
uint destoffset;
|
|
||||||
u8 stkelem;
|
|
||||||
|
|
||||||
START_OF_INSTR();
|
|
||||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
|
||||||
DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
|
|
||||||
switch (mod) {
|
|
||||||
case 0:
|
|
||||||
destoffset = decode_rm00_address(rl);
|
|
||||||
DECODE_PRINTF("\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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
DECODE_CLEAR_SEGOVR();
|
|
||||||
END_OF_INSTR_NO_TRACE();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
|
|
||||||
static char *x86emu_fpu_op_dd_tab[] = {
|
|
||||||
"FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
|
|
||||||
"FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
|
|
||||||
|
|
||||||
"FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
|
|
||||||
"FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
|
|
||||||
|
|
||||||
"FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
|
|
||||||
"FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
|
|
||||||
|
|
||||||
"FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
|
|
||||||
"ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/* opcode=0xdd */
|
|
||||||
void x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1))
|
|
||||||
{
|
|
||||||
int mod, rl, rh;
|
|
||||||
uint destoffset;
|
|
||||||
u8 stkelem;
|
|
||||||
|
|
||||||
START_OF_INSTR();
|
|
||||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
|
||||||
DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
|
|
||||||
switch (mod) {
|
|
||||||
case 0:
|
|
||||||
destoffset = decode_rm00_address(rl);
|
|
||||||
DECODE_PRINTF("\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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
DECODE_CLEAR_SEGOVR();
|
|
||||||
END_OF_INSTR_NO_TRACE();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
|
|
||||||
static char *x86emu_fpu_op_de_tab[] =
|
|
||||||
{
|
|
||||||
"FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
|
|
||||||
"FICOMP\tWORD PTR ",
|
|
||||||
"FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
|
|
||||||
"FIDIVR\tWORD PTR ",
|
|
||||||
|
|
||||||
"FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
|
|
||||||
"FICOMP\tWORD PTR ",
|
|
||||||
"FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
|
|
||||||
"FIDIVR\tWORD PTR ",
|
|
||||||
|
|
||||||
"FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
|
|
||||||
"FICOMP\tWORD PTR ",
|
|
||||||
"FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
|
|
||||||
"FIDIVR\tWORD PTR ",
|
|
||||||
|
|
||||||
"FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
|
|
||||||
"FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/* opcode=0xde */
|
|
||||||
void x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1))
|
|
||||||
{
|
|
||||||
int mod, rl, rh;
|
|
||||||
uint destoffset;
|
|
||||||
u8 stkelem;
|
|
||||||
|
|
||||||
START_OF_INSTR();
|
|
||||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
|
||||||
DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
|
|
||||||
switch (mod) {
|
|
||||||
case 0:
|
|
||||||
destoffset = decode_rm00_address(rl);
|
|
||||||
DECODE_PRINTF("\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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
DECODE_CLEAR_SEGOVR();
|
|
||||||
END_OF_INSTR_NO_TRACE();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
|
|
||||||
static char *x86emu_fpu_op_df_tab[] = {
|
|
||||||
/* mod == 00 */
|
|
||||||
"FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
|
|
||||||
"FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
|
|
||||||
"FISTP\tQWORD PTR ",
|
|
||||||
|
|
||||||
/* mod == 01 */
|
|
||||||
"FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
|
|
||||||
"FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
|
|
||||||
"FISTP\tQWORD PTR ",
|
|
||||||
|
|
||||||
/* mod == 10 */
|
|
||||||
"FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
|
|
||||||
"FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
|
|
||||||
"FISTP\tQWORD PTR ",
|
|
||||||
|
|
||||||
/* mod == 11 */
|
|
||||||
"FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
|
|
||||||
"ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/* opcode=0xdf */
|
|
||||||
void x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1))
|
|
||||||
{
|
|
||||||
int mod, rl, rh;
|
|
||||||
uint destoffset;
|
|
||||||
u8 stkelem;
|
|
||||||
|
|
||||||
START_OF_INSTR();
|
|
||||||
FETCH_DECODE_MODRM(mod, rh, rl);
|
|
||||||
DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
|
|
||||||
switch (mod) {
|
|
||||||
case 0:
|
|
||||||
destoffset = decode_rm00_address(rl);
|
|
||||||
DECODE_PRINTF("\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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
DECODE_CLEAR_SEGOVR();
|
|
||||||
END_OF_INSTR_NO_TRACE();
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,609 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: This file includes subroutines which are related to
|
|
||||||
* programmed I/O and memory access. Included in this module
|
|
||||||
* are default functions with limited usefulness. For real
|
|
||||||
* uses these functions will most likely be overriden by the
|
|
||||||
* user library.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
/* $XFree86: xc/extras/x86emu/src/x86emu/sys.c,v 1.5 2000/08/23 22:10:01 tsi Exp $ */
|
|
||||||
|
|
||||||
#include "x86emu.h"
|
|
||||||
#include "x86emu/regs.h"
|
|
||||||
#include "x86emu/debug.h"
|
|
||||||
#include "x86emu/prim_ops.h"
|
|
||||||
#ifdef IN_MODULE
|
|
||||||
#include "xf86_ansic.h"
|
|
||||||
#else
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
/*------------------------- Global Variables ------------------------------*/
|
|
||||||
|
|
||||||
X86EMU_sysEnv _X86EMU_env; /* Global emulator machine state */
|
|
||||||
X86EMU_intrFuncs _X86EMU_intrTab[256];
|
|
||||||
|
|
||||||
/*----------------------------- Implementation ----------------------------*/
|
|
||||||
#if defined(__alpha__) || defined(__alpha)
|
|
||||||
/* to cope with broken egcs-1.1.2 :-(((( */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* inline functions to do unaligned accesses
|
|
||||||
* from linux/include/asm-alpha/unaligned.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* EGCS 1.1 knows about arbitrary unaligned loads. Define some
|
|
||||||
* packed structures to talk about such things with.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
|
|
||||||
struct __una_u64 { unsigned long x __attribute__((packed)); };
|
|
||||||
struct __una_u32 { unsigned int x __attribute__((packed)); };
|
|
||||||
struct __una_u16 { unsigned short x __attribute__((packed)); };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static __inline__ unsigned long ldq_u(unsigned long * r11)
|
|
||||||
{
|
|
||||||
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
|
|
||||||
const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
|
|
||||||
return ptr->x;
|
|
||||||
#else
|
|
||||||
unsigned long r1,r2;
|
|
||||||
__asm__("ldq_u %0,%3\n\t"
|
|
||||||
"ldq_u %1,%4\n\t"
|
|
||||||
"extql %0,%2,%0\n\t"
|
|
||||||
"extqh %1,%2,%1"
|
|
||||||
:"=&r" (r1), "=&r" (r2)
|
|
||||||
:"r" (r11),
|
|
||||||
"m" (*r11),
|
|
||||||
"m" (*(const unsigned long *)(7+(char *) r11)));
|
|
||||||
return r1 | r2;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ unsigned long ldl_u(unsigned int * r11)
|
|
||||||
{
|
|
||||||
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
|
|
||||||
const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
|
|
||||||
return ptr->x;
|
|
||||||
#else
|
|
||||||
unsigned long r1,r2;
|
|
||||||
__asm__("ldq_u %0,%3\n\t"
|
|
||||||
"ldq_u %1,%4\n\t"
|
|
||||||
"extll %0,%2,%0\n\t"
|
|
||||||
"extlh %1,%2,%1"
|
|
||||||
:"=&r" (r1), "=&r" (r2)
|
|
||||||
:"r" (r11),
|
|
||||||
"m" (*r11),
|
|
||||||
"m" (*(const unsigned long *)(3+(char *) r11)));
|
|
||||||
return r1 | r2;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ unsigned long ldw_u(unsigned short * r11)
|
|
||||||
{
|
|
||||||
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
|
|
||||||
const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
|
|
||||||
return ptr->x;
|
|
||||||
#else
|
|
||||||
unsigned long r1,r2;
|
|
||||||
__asm__("ldq_u %0,%3\n\t"
|
|
||||||
"ldq_u %1,%4\n\t"
|
|
||||||
"extwl %0,%2,%0\n\t"
|
|
||||||
"extwh %1,%2,%1"
|
|
||||||
:"=&r" (r1), "=&r" (r2)
|
|
||||||
:"r" (r11),
|
|
||||||
"m" (*r11),
|
|
||||||
"m" (*(const unsigned long *)(1+(char *) r11)));
|
|
||||||
return r1 | r2;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Elemental unaligned stores
|
|
||||||
*/
|
|
||||||
|
|
||||||
static __inline__ void stq_u(unsigned long r5, unsigned long * r11)
|
|
||||||
{
|
|
||||||
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
|
|
||||||
struct __una_u64 *ptr = (struct __una_u64 *) r11;
|
|
||||||
ptr->x = r5;
|
|
||||||
#else
|
|
||||||
unsigned long r1,r2,r3,r4;
|
|
||||||
|
|
||||||
__asm__("ldq_u %3,%1\n\t"
|
|
||||||
"ldq_u %2,%0\n\t"
|
|
||||||
"insqh %6,%7,%5\n\t"
|
|
||||||
"insql %6,%7,%4\n\t"
|
|
||||||
"mskqh %3,%7,%3\n\t"
|
|
||||||
"mskql %2,%7,%2\n\t"
|
|
||||||
"bis %3,%5,%3\n\t"
|
|
||||||
"bis %2,%4,%2\n\t"
|
|
||||||
"stq_u %3,%1\n\t"
|
|
||||||
"stq_u %2,%0"
|
|
||||||
:"=m" (*r11),
|
|
||||||
"=m" (*(unsigned long *)(7+(char *) r11)),
|
|
||||||
"=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4)
|
|
||||||
:"r" (r5), "r" (r11));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ void stl_u(unsigned long r5, unsigned int * r11)
|
|
||||||
{
|
|
||||||
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
|
|
||||||
struct __una_u32 *ptr = (struct __una_u32 *) r11;
|
|
||||||
ptr->x = r5;
|
|
||||||
#else
|
|
||||||
unsigned long r1,r2,r3,r4;
|
|
||||||
|
|
||||||
__asm__("ldq_u %3,%1\n\t"
|
|
||||||
"ldq_u %2,%0\n\t"
|
|
||||||
"inslh %6,%7,%5\n\t"
|
|
||||||
"insll %6,%7,%4\n\t"
|
|
||||||
"msklh %3,%7,%3\n\t"
|
|
||||||
"mskll %2,%7,%2\n\t"
|
|
||||||
"bis %3,%5,%3\n\t"
|
|
||||||
"bis %2,%4,%2\n\t"
|
|
||||||
"stq_u %3,%1\n\t"
|
|
||||||
"stq_u %2,%0"
|
|
||||||
:"=m" (*r11),
|
|
||||||
"=m" (*(unsigned long *)(3+(char *) r11)),
|
|
||||||
"=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4)
|
|
||||||
:"r" (r5), "r" (r11));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ void stw_u(unsigned long r5, unsigned short * r11)
|
|
||||||
{
|
|
||||||
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
|
|
||||||
struct __una_u16 *ptr = (struct __una_u16 *) r11;
|
|
||||||
ptr->x = r5;
|
|
||||||
#else
|
|
||||||
unsigned long r1,r2,r3,r4;
|
|
||||||
|
|
||||||
__asm__("ldq_u %3,%1\n\t"
|
|
||||||
"ldq_u %2,%0\n\t"
|
|
||||||
"inswh %6,%7,%5\n\t"
|
|
||||||
"inswl %6,%7,%4\n\t"
|
|
||||||
"mskwh %3,%7,%3\n\t"
|
|
||||||
"mskwl %2,%7,%2\n\t"
|
|
||||||
"bis %3,%5,%3\n\t"
|
|
||||||
"bis %2,%4,%2\n\t"
|
|
||||||
"stq_u %3,%1\n\t"
|
|
||||||
"stq_u %2,%0"
|
|
||||||
:"=m" (*r11),
|
|
||||||
"=m" (*(unsigned long *)(1+(char *) r11)),
|
|
||||||
"=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4)
|
|
||||||
:"r" (r5), "r" (r11));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - Emulator memory address to read
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Byte value read from emulator memory.
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Reads a byte value from the emulator memory.
|
|
||||||
****************************************************************************/
|
|
||||||
u8 X86API rdb(
|
|
||||||
u32 addr)
|
|
||||||
{
|
|
||||||
u8 val;
|
|
||||||
|
|
||||||
if (addr > M.mem_size - 1) {
|
|
||||||
DB(printk("mem_read: address %#lx out of range!\n", addr);)
|
|
||||||
HALT_SYS();
|
|
||||||
}
|
|
||||||
val = *(u8*)(M.mem_base + addr);
|
|
||||||
DB( if (DEBUG_MEM_TRACE())
|
|
||||||
printk("%#08x 1 -> %#x\n", addr, val);)
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - Emulator memory address to read
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Word value read from emulator memory.
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Reads a word value from the emulator memory.
|
|
||||||
****************************************************************************/
|
|
||||||
u16 X86API rdw(
|
|
||||||
u32 addr)
|
|
||||||
{
|
|
||||||
u16 val = 0;
|
|
||||||
|
|
||||||
if (addr > M.mem_size - 2) {
|
|
||||||
DB(printk("mem_read: address %#lx out of range!\n", addr);)
|
|
||||||
HALT_SYS();
|
|
||||||
}
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
if (addr & 0x1) {
|
|
||||||
val = (*(u8*)(M.mem_base + addr) |
|
|
||||||
(*(u8*)(M.mem_base + addr + 1) << 8));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#if defined(__alpha__) || defined(__alpha)
|
|
||||||
val = ldw_u((u16*)(M.mem_base + addr));
|
|
||||||
#else
|
|
||||||
val = *(u16*)(M.mem_base + addr);
|
|
||||||
#endif
|
|
||||||
DB( if (DEBUG_MEM_TRACE())
|
|
||||||
printk("%#08x 2 -> %#x\n", addr, val);)
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - Emulator memory address to read
|
|
||||||
|
|
||||||
RETURNS:
|
|
||||||
Long value read from emulator memory.
|
|
||||||
REMARKS:
|
|
||||||
Reads a long value from the emulator memory.
|
|
||||||
****************************************************************************/
|
|
||||||
u32 X86API rdl(
|
|
||||||
u32 addr)
|
|
||||||
{
|
|
||||||
u32 val = 0;
|
|
||||||
|
|
||||||
if (addr > M.mem_size - 4) {
|
|
||||||
DB(printk("mem_read: address %#lx out of range!\n", addr);)
|
|
||||||
HALT_SYS();
|
|
||||||
}
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
if (addr & 0x3) {
|
|
||||||
val = (*(u8*)(M.mem_base + addr + 0) |
|
|
||||||
(*(u8*)(M.mem_base + addr + 1) << 8) |
|
|
||||||
(*(u8*)(M.mem_base + addr + 2) << 16) |
|
|
||||||
(*(u8*)(M.mem_base + addr + 3) << 24));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#if defined(__alpha__) || defined(__alpha)
|
|
||||||
val = ldl_u((u32*)(M.mem_base + addr));
|
|
||||||
#else
|
|
||||||
val = *(u32*)(M.mem_base + addr);
|
|
||||||
#endif
|
|
||||||
DB( if (DEBUG_MEM_TRACE())
|
|
||||||
printk("%#08x 4 -> %#x\n", addr, val);)
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - Emulator memory address to read
|
|
||||||
val - Value to store
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Writes a byte value to emulator memory.
|
|
||||||
****************************************************************************/
|
|
||||||
void X86API wrb(
|
|
||||||
u32 addr,
|
|
||||||
u8 val)
|
|
||||||
{
|
|
||||||
DB( if (DEBUG_MEM_TRACE())
|
|
||||||
printk("%#08x 1 <- %#x\n", addr, val);)
|
|
||||||
if (addr > M.mem_size - 1) {
|
|
||||||
DB(printk("mem_write: address %#lx out of range!\n", addr);)
|
|
||||||
HALT_SYS();
|
|
||||||
}
|
|
||||||
*(u8*)(M.mem_base + addr) = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - Emulator memory address to read
|
|
||||||
val - Value to store
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Writes a word value to emulator memory.
|
|
||||||
****************************************************************************/
|
|
||||||
void X86API wrw(
|
|
||||||
u32 addr,
|
|
||||||
u16 val)
|
|
||||||
{
|
|
||||||
DB( if (DEBUG_MEM_TRACE())
|
|
||||||
printk("%#08x 2 <- %#x\n", addr, val);)
|
|
||||||
if (addr > M.mem_size - 2) {
|
|
||||||
DB(printk("mem_write: address %#lx out of range!\n", addr);)
|
|
||||||
HALT_SYS();
|
|
||||||
}
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
if (addr & 0x1) {
|
|
||||||
*(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
|
|
||||||
*(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#if defined(__alpha__) || defined(__alpha)
|
|
||||||
stw_u(val,(u16*)(M.mem_base + addr));
|
|
||||||
#else
|
|
||||||
*(u16*)(M.mem_base + addr) = val;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - Emulator memory address to read
|
|
||||||
val - Value to store
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
Writes a long value to emulator memory.
|
|
||||||
****************************************************************************/
|
|
||||||
void X86API wrl(
|
|
||||||
u32 addr,
|
|
||||||
u32 val)
|
|
||||||
{
|
|
||||||
DB( if (DEBUG_MEM_TRACE())
|
|
||||||
printk("%#08x 4 <- %#x\n", addr, val);)
|
|
||||||
if (addr > M.mem_size - 4) {
|
|
||||||
DB(printk("mem_write: address %#lx out of range!\n", addr);)
|
|
||||||
HALT_SYS();
|
|
||||||
}
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
if (addr & 0x1) {
|
|
||||||
*(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
|
|
||||||
*(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
|
|
||||||
*(u8*)(M.mem_base + addr + 2) = (val >> 16) & 0xff;
|
|
||||||
*(u8*)(M.mem_base + addr + 3) = (val >> 24) & 0xff;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#if defined(__alpha__) || defined(__alpha)
|
|
||||||
stl_u(val,(u32*)(M.mem_base + addr));
|
|
||||||
#else
|
|
||||||
*(u32*)(M.mem_base + addr) = val;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - PIO address to read
|
|
||||||
RETURN:
|
|
||||||
0
|
|
||||||
REMARKS:
|
|
||||||
Default PIO byte read function. Doesn't perform real inb.
|
|
||||||
****************************************************************************/
|
|
||||||
static u8 X86API p_inb(
|
|
||||||
X86EMU_pioAddr addr)
|
|
||||||
{
|
|
||||||
DB( if (DEBUG_IO_TRACE())
|
|
||||||
printk("inb %#04x \n", addr);)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - PIO address to read
|
|
||||||
RETURN:
|
|
||||||
0
|
|
||||||
REMARKS:
|
|
||||||
Default PIO word read function. Doesn't perform real inw.
|
|
||||||
****************************************************************************/
|
|
||||||
static u16 X86API p_inw(
|
|
||||||
X86EMU_pioAddr addr)
|
|
||||||
{
|
|
||||||
DB( if (DEBUG_IO_TRACE())
|
|
||||||
printk("inw %#04x \n", addr);)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - PIO address to read
|
|
||||||
RETURN:
|
|
||||||
0
|
|
||||||
REMARKS:
|
|
||||||
Default PIO long read function. Doesn't perform real inl.
|
|
||||||
****************************************************************************/
|
|
||||||
static u32 X86API p_inl(
|
|
||||||
X86EMU_pioAddr addr)
|
|
||||||
{
|
|
||||||
DB( if (DEBUG_IO_TRACE())
|
|
||||||
printk("inl %#04x \n", addr);)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - PIO address to write
|
|
||||||
val - Value to store
|
|
||||||
REMARKS:
|
|
||||||
Default PIO byte write function. Doesn't perform real outb.
|
|
||||||
****************************************************************************/
|
|
||||||
static void X86API p_outb(
|
|
||||||
X86EMU_pioAddr addr,
|
|
||||||
u8 val)
|
|
||||||
{
|
|
||||||
DB( if (DEBUG_IO_TRACE())
|
|
||||||
printk("outb %#02x -> %#04x \n", val, addr);)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - PIO address to write
|
|
||||||
val - Value to store
|
|
||||||
REMARKS:
|
|
||||||
Default PIO word write function. Doesn't perform real outw.
|
|
||||||
****************************************************************************/
|
|
||||||
static void X86API p_outw(
|
|
||||||
X86EMU_pioAddr addr,
|
|
||||||
u16 val)
|
|
||||||
{
|
|
||||||
DB( if (DEBUG_IO_TRACE())
|
|
||||||
printk("outw %#04x -> %#04x \n", val, addr);)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
addr - PIO address to write
|
|
||||||
val - Value to store
|
|
||||||
REMARKS:
|
|
||||||
Default PIO ;ong write function. Doesn't perform real outl.
|
|
||||||
****************************************************************************/
|
|
||||||
static void X86API p_outl(
|
|
||||||
X86EMU_pioAddr addr,
|
|
||||||
u32 val)
|
|
||||||
{
|
|
||||||
DB( if (DEBUG_IO_TRACE())
|
|
||||||
printk("outl %#08x -> %#04x \n", val, addr);)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------- Global Variables ------------------------------*/
|
|
||||||
|
|
||||||
u8 (X86APIP sys_rdb)(u32 addr) = rdb;
|
|
||||||
u16 (X86APIP sys_rdw)(u32 addr) = rdw;
|
|
||||||
u32 (X86APIP sys_rdl)(u32 addr) = rdl;
|
|
||||||
void (X86APIP sys_wrb)(u32 addr,u8 val) = wrb;
|
|
||||||
void (X86APIP sys_wrw)(u32 addr,u16 val) = wrw;
|
|
||||||
void (X86APIP sys_wrl)(u32 addr,u32 val) = wrl;
|
|
||||||
u8 (X86APIP sys_inb)(X86EMU_pioAddr addr) = p_inb;
|
|
||||||
u16 (X86APIP sys_inw)(X86EMU_pioAddr addr) = p_inw;
|
|
||||||
u32 (X86APIP sys_inl)(X86EMU_pioAddr addr) = p_inl;
|
|
||||||
void (X86APIP sys_outb)(X86EMU_pioAddr addr, u8 val) = p_outb;
|
|
||||||
void (X86APIP sys_outw)(X86EMU_pioAddr addr, u16 val) = p_outw;
|
|
||||||
void (X86APIP sys_outl)(X86EMU_pioAddr addr, u32 val) = p_outl;
|
|
||||||
|
|
||||||
/*----------------------------- Setup -------------------------------------*/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
funcs - New memory function pointers to make active
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
This function is used to set the pointers to functions which access
|
|
||||||
memory space, allowing the user application to override these functions
|
|
||||||
and hook them out as necessary for their application.
|
|
||||||
****************************************************************************/
|
|
||||||
void X86EMU_setupMemFuncs(
|
|
||||||
X86EMU_memFuncs *funcs)
|
|
||||||
{
|
|
||||||
sys_rdb = funcs->rdb;
|
|
||||||
sys_rdw = funcs->rdw;
|
|
||||||
sys_rdl = funcs->rdl;
|
|
||||||
sys_wrb = funcs->wrb;
|
|
||||||
sys_wrw = funcs->wrw;
|
|
||||||
sys_wrl = funcs->wrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
funcs - New programmed I/O function pointers to make active
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
This function is used to set the pointers to functions which access
|
|
||||||
I/O space, allowing the user application to override these functions
|
|
||||||
and hook them out as necessary for their application.
|
|
||||||
****************************************************************************/
|
|
||||||
void X86EMU_setupPioFuncs(
|
|
||||||
X86EMU_pioFuncs *funcs)
|
|
||||||
{
|
|
||||||
sys_inb = funcs->inb;
|
|
||||||
sys_inw = funcs->inw;
|
|
||||||
sys_inl = funcs->inl;
|
|
||||||
sys_outb = funcs->outb;
|
|
||||||
sys_outw = funcs->outw;
|
|
||||||
sys_outl = funcs->outl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
funcs - New interrupt vector table to make active
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
This function is used to set the pointers to functions which handle
|
|
||||||
interrupt processing in the emulator, allowing the user application to
|
|
||||||
hook interrupts as necessary for their application. Any interrupts that
|
|
||||||
are not hooked by the user application, and reflected and handled internally
|
|
||||||
in the emulator via the interrupt vector table. This allows the application
|
|
||||||
to get control when the code being emulated executes specific software
|
|
||||||
interrupts.
|
|
||||||
****************************************************************************/
|
|
||||||
void X86EMU_setupIntrFuncs(
|
|
||||||
X86EMU_intrFuncs funcs[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i < 256; i++)
|
|
||||||
_X86EMU_intrTab[i] = NULL;
|
|
||||||
if (funcs) {
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
_X86EMU_intrTab[i] = funcs[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
PARAMETERS:
|
|
||||||
int - New software interrupt to prepare for
|
|
||||||
|
|
||||||
REMARKS:
|
|
||||||
This function is used to set up the emulator state to exceute a software
|
|
||||||
interrupt. This can be used by the user application code to allow an
|
|
||||||
interrupt to be hooked, examined and then reflected back to the emulator
|
|
||||||
so that the code in the emulator will continue processing the software
|
|
||||||
interrupt as per normal. This essentially allows system code to actively
|
|
||||||
hook and handle certain software interrupts as necessary.
|
|
||||||
****************************************************************************/
|
|
||||||
void X86EMU_prepareForInt(
|
|
||||||
int num)
|
|
||||||
{
|
|
||||||
push_word((u16)M.x86.R_FLG);
|
|
||||||
CLEAR_FLAG(F_IF);
|
|
||||||
CLEAR_FLAG(F_TF);
|
|
||||||
push_word(M.x86.R_CS);
|
|
||||||
M.x86.R_CS = mem_access_word(num * 4 + 2);
|
|
||||||
push_word(M.x86.R_IP);
|
|
||||||
M.x86.R_IP = mem_access_word(num * 4);
|
|
||||||
M.x86.intr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
X86EMU_setMemBase(void *base, size_t size)
|
|
||||||
{
|
|
||||||
M.mem_base = base;
|
|
||||||
M.mem_size = size;
|
|
||||||
}
|
|
|
@ -1,765 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: Watcom C 10.6 or later
|
|
||||||
* Environment: 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;
|
|
||||||
}
|
|
|
@ -1,211 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Header file for debug definitions.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
/* $XFree86: xc/extras/x86emu/src/x86emu/x86emu/debug.h,v 1.4 2000/11/21 23:10:27 tsi Exp $ */
|
|
||||||
|
|
||||||
#ifndef __X86EMU_DEBUG_H
|
|
||||||
#define __X86EMU_DEBUG_H
|
|
||||||
|
|
||||||
/*---------------------- Macros and type definitions ----------------------*/
|
|
||||||
|
|
||||||
/* checks to be enabled for "runtime" */
|
|
||||||
|
|
||||||
#define CHECK_IP_FETCH_F 0x1
|
|
||||||
#define CHECK_SP_ACCESS_F 0x2
|
|
||||||
#define CHECK_MEM_ACCESS_F 0x4 /*using regular linear pointer */
|
|
||||||
#define CHECK_DATA_ACCESS_F 0x8 /*using segment:offset*/
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
# define CHECK_IP_FETCH() (M.x86.check & CHECK_IP_FETCH_F)
|
|
||||||
# define CHECK_SP_ACCESS() (M.x86.check & CHECK_SP_ACCESS_F)
|
|
||||||
# define CHECK_MEM_ACCESS() (M.x86.check & CHECK_MEM_ACCESS_F)
|
|
||||||
# define CHECK_DATA_ACCESS() (M.x86.check & CHECK_DATA_ACCESS_F)
|
|
||||||
#else
|
|
||||||
# define CHECK_IP_FETCH()
|
|
||||||
# define CHECK_SP_ACCESS()
|
|
||||||
# define CHECK_MEM_ACCESS()
|
|
||||||
# define CHECK_DATA_ACCESS()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
# define DEBUG_INSTRUMENT() (M.x86.debug & DEBUG_INSTRUMENT_F)
|
|
||||||
# define DEBUG_DECODE() (M.x86.debug & DEBUG_DECODE_F)
|
|
||||||
# define DEBUG_TRACE() (M.x86.debug & DEBUG_TRACE_F)
|
|
||||||
# define DEBUG_STEP() (M.x86.debug & DEBUG_STEP_F)
|
|
||||||
# define DEBUG_DISASSEMBLE() (M.x86.debug & DEBUG_DISASSEMBLE_F)
|
|
||||||
# define DEBUG_BREAK() (M.x86.debug & DEBUG_BREAK_F)
|
|
||||||
# define DEBUG_SVC() (M.x86.debug & DEBUG_SVC_F)
|
|
||||||
# define DEBUG_SAVE_IP_CS() (M.x86.debug & DEBUG_SAVE_IP_CS_F)
|
|
||||||
|
|
||||||
# define DEBUG_FS() (M.x86.debug & DEBUG_FS_F)
|
|
||||||
# define DEBUG_PROC() (M.x86.debug & DEBUG_PROC_F)
|
|
||||||
# define DEBUG_SYSINT() (M.x86.debug & DEBUG_SYSINT_F)
|
|
||||||
# define DEBUG_TRACECALL() (M.x86.debug & DEBUG_TRACECALL_F)
|
|
||||||
# define DEBUG_TRACECALLREGS() (M.x86.debug & DEBUG_TRACECALL_REGS_F)
|
|
||||||
# define DEBUG_SYS() (M.x86.debug & DEBUG_SYS_F)
|
|
||||||
# define DEBUG_MEM_TRACE() (M.x86.debug & DEBUG_MEM_TRACE_F)
|
|
||||||
# define DEBUG_IO_TRACE() (M.x86.debug & DEBUG_IO_TRACE_F)
|
|
||||||
# define DEBUG_DECODE_NOPRINT() (M.x86.debug & DEBUG_DECODE_NOPRINT_F)
|
|
||||||
#else
|
|
||||||
# define DEBUG_INSTRUMENT() 0
|
|
||||||
# define DEBUG_DECODE() 0
|
|
||||||
# define DEBUG_TRACE() 0
|
|
||||||
# define DEBUG_STEP() 0
|
|
||||||
# define DEBUG_DISASSEMBLE() 0
|
|
||||||
# define DEBUG_BREAK() 0
|
|
||||||
# define DEBUG_SVC() 0
|
|
||||||
# define DEBUG_SAVE_IP_CS() 0
|
|
||||||
# define DEBUG_FS() 0
|
|
||||||
# define DEBUG_PROC() 0
|
|
||||||
# define DEBUG_SYSINT() 0
|
|
||||||
# define DEBUG_TRACECALL() 0
|
|
||||||
# define DEBUG_TRACECALLREGS() 0
|
|
||||||
# define DEBUG_SYS() 0
|
|
||||||
# define DEBUG_MEM_TRACE() 0
|
|
||||||
# define DEBUG_IO_TRACE() 0
|
|
||||||
# define DEBUG_DECODE_NOPRINT() 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
|
|
||||||
# define DECODE_PRINTF(x) if (DEBUG_DECODE()) \
|
|
||||||
x86emu_decode_printf(x)
|
|
||||||
# define DECODE_PRINTF2(x,y) if (DEBUG_DECODE()) \
|
|
||||||
x86emu_decode_printf2(x,y)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following allow us to look at the bytes of an instruction. The
|
|
||||||
* first INCR_INSTRN_LEN, is called everytime bytes are consumed in
|
|
||||||
* the decoding process. The SAVE_IP_CS is called initially when the
|
|
||||||
* major opcode of the instruction is accessed.
|
|
||||||
*/
|
|
||||||
#define INC_DECODED_INST_LEN(x) \
|
|
||||||
if (DEBUG_DECODE()) \
|
|
||||||
x86emu_inc_decoded_inst_len(x)
|
|
||||||
|
|
||||||
#define SAVE_IP_CS(x,y) \
|
|
||||||
if (DEBUG_DECODE() | DEBUG_TRACECALL() | DEBUG_BREAK() \
|
|
||||||
| DEBUG_IO_TRACE() | DEBUG_SAVE_IP_CS()) { \
|
|
||||||
M.x86.saved_cs = x; \
|
|
||||||
M.x86.saved_ip = y; \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# define INC_DECODED_INST_LEN(x)
|
|
||||||
# define DECODE_PRINTF(x)
|
|
||||||
# define DECODE_PRINTF2(x,y)
|
|
||||||
# define SAVE_IP_CS(x,y)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#define TRACE_REGS() \
|
|
||||||
if (DEBUG_DISASSEMBLE()) { \
|
|
||||||
x86emu_just_disassemble(); \
|
|
||||||
goto EndOfTheInstructionProcedure; \
|
|
||||||
} \
|
|
||||||
if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs()
|
|
||||||
#else
|
|
||||||
# define TRACE_REGS()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
# define SINGLE_STEP() if (DEBUG_STEP()) x86emu_single_step()
|
|
||||||
#else
|
|
||||||
# define SINGLE_STEP()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TRACE_AND_STEP() \
|
|
||||||
TRACE_REGS(); \
|
|
||||||
SINGLE_STEP()
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
# define START_OF_INSTR()
|
|
||||||
# define END_OF_INSTR() EndOfTheInstructionProcedure: x86emu_end_instr();
|
|
||||||
# define END_OF_INSTR_NO_TRACE() x86emu_end_instr();
|
|
||||||
#else
|
|
||||||
# define START_OF_INSTR()
|
|
||||||
# define END_OF_INSTR()
|
|
||||||
# define END_OF_INSTR_NO_TRACE()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
# define CALL_TRACE(u,v,w,x,s) \
|
|
||||||
if (DEBUG_TRACECALLREGS()) \
|
|
||||||
x86emu_dump_regs(); \
|
|
||||||
if (DEBUG_TRACECALL()) \
|
|
||||||
printk("%04x:%04x: CALL %s%04x:%04x\n", u , v, s, w, x);
|
|
||||||
# define RETURN_TRACE(n,u,v) \
|
|
||||||
if (DEBUG_TRACECALLREGS()) \
|
|
||||||
x86emu_dump_regs(); \
|
|
||||||
if (DEBUG_TRACECALL()) \
|
|
||||||
printk("%04x:%04x: %s\n",u,v,n);
|
|
||||||
#else
|
|
||||||
# define CALL_TRACE(u,v,w,x,s)
|
|
||||||
# define RETURN_TRACE(n,u,v)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#define DB(x) x
|
|
||||||
#else
|
|
||||||
#define DB(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------- Function Prototypes --------------------------*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void x86emu_inc_decoded_inst_len (int x);
|
|
||||||
extern void x86emu_decode_printf (char *x);
|
|
||||||
extern void x86emu_decode_printf2 (char *x, int y);
|
|
||||||
extern void x86emu_just_disassemble (void);
|
|
||||||
extern void x86emu_single_step (void);
|
|
||||||
extern void x86emu_end_instr (void);
|
|
||||||
extern void x86emu_dump_regs (void);
|
|
||||||
extern void x86emu_dump_xregs (void);
|
|
||||||
extern void x86emu_print_int_vect (u16 iv);
|
|
||||||
extern void x86emu_instrument_instruction (void);
|
|
||||||
extern void x86emu_check_ip_access (void);
|
|
||||||
extern void x86emu_check_sp_access (void);
|
|
||||||
extern void x86emu_check_mem_access (u32 p);
|
|
||||||
extern void x86emu_check_data_access (uint s, uint o);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* End of "C" linkage for C++ */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __X86EMU_DEBUG_H */
|
|
|
@ -1,87 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Header file for instruction decoding logic.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __X86EMU_DECODE_H
|
|
||||||
#define __X86EMU_DECODE_H
|
|
||||||
|
|
||||||
/*---------------------- Macros and type definitions ----------------------*/
|
|
||||||
|
|
||||||
/* Instruction Decoding Stuff */
|
|
||||||
|
|
||||||
#define FETCH_DECODE_MODRM(mod,rh,rl) fetch_decode_modrm(&mod,&rh,&rl)
|
|
||||||
#define DECODE_RM_BYTE_REGISTER(r) decode_rm_byte_register(r)
|
|
||||||
#define DECODE_RM_WORD_REGISTER(r) decode_rm_word_register(r)
|
|
||||||
#define DECODE_RM_LONG_REGISTER(r) decode_rm_long_register(r)
|
|
||||||
#define DECODE_CLEAR_SEGOVR() M.x86.mode &= ~SYSMODE_CLRMASK
|
|
||||||
|
|
||||||
/*-------------------------- Function Prototypes --------------------------*/
|
|
||||||
|
|
||||||
#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);
|
|
||||||
unsigned decode_rm00_address(int rm);
|
|
||||||
unsigned decode_rm01_address(int rm);
|
|
||||||
unsigned decode_rm10_address(int rm);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* End of "C" linkage for C++ */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __X86EMU_DECODE_H */
|
|
|
@ -1,61 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Header file for FPU instruction decoding.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __X86EMU_FPU_H
|
|
||||||
#define __X86EMU_FPU_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* these have to be defined, whether 8087 support compiled in or not. */
|
|
||||||
|
|
||||||
extern void x86emuOp_esc_coprocess_d8 (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 */
|
|
|
@ -1,45 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Header file for operand decoding functions.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __X86EMU_OPS_H
|
|
||||||
#define __X86EMU_OPS_H
|
|
||||||
|
|
||||||
extern void (*x86emu_optab[0x100])(u8 op1);
|
|
||||||
extern void (*x86emu_optab2[0x100])(u8 op2);
|
|
||||||
|
|
||||||
#endif /* __X86EMU_OPS_H */
|
|
|
@ -1,971 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: Watcom C++ 10.6 or later
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Inline assembler versions of the primitive operand
|
|
||||||
* functions for faster performance. At the moment this is
|
|
||||||
* x86 inline assembler, but these functions could be replaced
|
|
||||||
* with native inline assembler for each supported processor
|
|
||||||
* platform.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
/* $XFree86: xc/extras/x86emu/src/x86emu/x86emu/prim_asm.h,v 1.3 2000/04/19 15:48:15 tsi Exp $ */
|
|
||||||
|
|
||||||
#ifndef __X86EMU_PRIM_ASM_H
|
|
||||||
#define __X86EMU_PRIM_ASM_H
|
|
||||||
|
|
||||||
#ifdef __WATCOMC__
|
|
||||||
|
|
||||||
#ifndef VALIDATE
|
|
||||||
#define __HAVE_INLINE_ASSEMBLER__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
u32 get_flags_asm(void);
|
|
||||||
#pragma aux get_flags_asm = \
|
|
||||||
"pushf" \
|
|
||||||
"pop eax" \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax];
|
|
||||||
|
|
||||||
u16 aaa_word_asm(u32 *flags,u16 d);
|
|
||||||
#pragma aux aaa_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"aaa" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax];
|
|
||||||
|
|
||||||
u16 aas_word_asm(u32 *flags,u16 d);
|
|
||||||
#pragma aux aas_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"aas" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax];
|
|
||||||
|
|
||||||
u16 aad_word_asm(u32 *flags,u16 d);
|
|
||||||
#pragma aux aad_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"aad" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax];
|
|
||||||
|
|
||||||
u16 aam_word_asm(u32 *flags,u8 d);
|
|
||||||
#pragma aux aam_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"aam" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax];
|
|
||||||
|
|
||||||
u8 adc_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux adc_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"adc al,bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [bl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al bl];
|
|
||||||
|
|
||||||
u16 adc_word_asm(u32 *flags,u16 d, u16 s);
|
|
||||||
#pragma aux adc_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"adc ax,bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [bx] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax bx];
|
|
||||||
|
|
||||||
u32 adc_long_asm(u32 *flags,u32 d, u32 s);
|
|
||||||
#pragma aux adc_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"adc eax,ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [ebx] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax ebx];
|
|
||||||
|
|
||||||
u8 add_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux add_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"add al,bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [bl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al bl];
|
|
||||||
|
|
||||||
u16 add_word_asm(u32 *flags,u16 d, u16 s);
|
|
||||||
#pragma aux add_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"add ax,bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [bx] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax bx];
|
|
||||||
|
|
||||||
u32 add_long_asm(u32 *flags,u32 d, u32 s);
|
|
||||||
#pragma aux add_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"add eax,ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [ebx] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax ebx];
|
|
||||||
|
|
||||||
u8 and_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux and_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"and al,bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [bl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al bl];
|
|
||||||
|
|
||||||
u16 and_word_asm(u32 *flags,u16 d, u16 s);
|
|
||||||
#pragma aux and_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"and ax,bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [bx] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax bx];
|
|
||||||
|
|
||||||
u32 and_long_asm(u32 *flags,u32 d, u32 s);
|
|
||||||
#pragma aux and_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"and eax,ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [ebx] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax ebx];
|
|
||||||
|
|
||||||
u8 cmp_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux cmp_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"cmp al,bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [bl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al bl];
|
|
||||||
|
|
||||||
u16 cmp_word_asm(u32 *flags,u16 d, u16 s);
|
|
||||||
#pragma aux cmp_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"cmp ax,bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [bx] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax bx];
|
|
||||||
|
|
||||||
u32 cmp_long_asm(u32 *flags,u32 d, u32 s);
|
|
||||||
#pragma aux cmp_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"cmp eax,ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [ebx] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax ebx];
|
|
||||||
|
|
||||||
u8 daa_byte_asm(u32 *flags,u8 d);
|
|
||||||
#pragma aux daa_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"daa" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al];
|
|
||||||
|
|
||||||
u8 das_byte_asm(u32 *flags,u8 d);
|
|
||||||
#pragma aux das_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"das" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al];
|
|
||||||
|
|
||||||
u8 dec_byte_asm(u32 *flags,u8 d);
|
|
||||||
#pragma aux dec_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"dec al" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al];
|
|
||||||
|
|
||||||
u16 dec_word_asm(u32 *flags,u16 d);
|
|
||||||
#pragma aux dec_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"dec ax" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax];
|
|
||||||
|
|
||||||
u32 dec_long_asm(u32 *flags,u32 d);
|
|
||||||
#pragma aux dec_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"dec eax" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax];
|
|
||||||
|
|
||||||
u8 inc_byte_asm(u32 *flags,u8 d);
|
|
||||||
#pragma aux inc_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"inc al" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al];
|
|
||||||
|
|
||||||
u16 inc_word_asm(u32 *flags,u16 d);
|
|
||||||
#pragma aux inc_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"inc ax" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax];
|
|
||||||
|
|
||||||
u32 inc_long_asm(u32 *flags,u32 d);
|
|
||||||
#pragma aux inc_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"inc eax" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax];
|
|
||||||
|
|
||||||
u8 or_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux or_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"or al,bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [bl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al bl];
|
|
||||||
|
|
||||||
u16 or_word_asm(u32 *flags,u16 d, u16 s);
|
|
||||||
#pragma aux or_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"or ax,bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [bx] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax bx];
|
|
||||||
|
|
||||||
u32 or_long_asm(u32 *flags,u32 d, u32 s);
|
|
||||||
#pragma aux or_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"or eax,ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [ebx] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax ebx];
|
|
||||||
|
|
||||||
u8 neg_byte_asm(u32 *flags,u8 d);
|
|
||||||
#pragma aux neg_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"neg al" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al];
|
|
||||||
|
|
||||||
u16 neg_word_asm(u32 *flags,u16 d);
|
|
||||||
#pragma aux neg_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"neg ax" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax];
|
|
||||||
|
|
||||||
u32 neg_long_asm(u32 *flags,u32 d);
|
|
||||||
#pragma aux neg_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"neg eax" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax];
|
|
||||||
|
|
||||||
u8 not_byte_asm(u32 *flags,u8 d);
|
|
||||||
#pragma aux not_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"not al" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al];
|
|
||||||
|
|
||||||
u16 not_word_asm(u32 *flags,u16 d);
|
|
||||||
#pragma aux not_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"not ax" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax];
|
|
||||||
|
|
||||||
u32 not_long_asm(u32 *flags,u32 d);
|
|
||||||
#pragma aux not_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"not eax" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax];
|
|
||||||
|
|
||||||
u8 rcl_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux rcl_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"rcl al,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [cl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al cl];
|
|
||||||
|
|
||||||
u16 rcl_word_asm(u32 *flags,u16 d, u8 s);
|
|
||||||
#pragma aux rcl_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"rcl ax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [cl] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax cl];
|
|
||||||
|
|
||||||
u32 rcl_long_asm(u32 *flags,u32 d, u8 s);
|
|
||||||
#pragma aux rcl_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"rcl eax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [cl] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax cl];
|
|
||||||
|
|
||||||
u8 rcr_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux rcr_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"rcr al,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [cl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al cl];
|
|
||||||
|
|
||||||
u16 rcr_word_asm(u32 *flags,u16 d, u8 s);
|
|
||||||
#pragma aux rcr_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"rcr ax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [cl] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax cl];
|
|
||||||
|
|
||||||
u32 rcr_long_asm(u32 *flags,u32 d, u8 s);
|
|
||||||
#pragma aux rcr_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"rcr eax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [cl] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax cl];
|
|
||||||
|
|
||||||
u8 rol_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux rol_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"rol al,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [cl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al cl];
|
|
||||||
|
|
||||||
u16 rol_word_asm(u32 *flags,u16 d, u8 s);
|
|
||||||
#pragma aux rol_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"rol ax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [cl] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax cl];
|
|
||||||
|
|
||||||
u32 rol_long_asm(u32 *flags,u32 d, u8 s);
|
|
||||||
#pragma aux rol_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"rol eax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [cl] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax cl];
|
|
||||||
|
|
||||||
u8 ror_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux ror_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"ror al,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [cl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al cl];
|
|
||||||
|
|
||||||
u16 ror_word_asm(u32 *flags,u16 d, u8 s);
|
|
||||||
#pragma aux ror_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"ror ax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [cl] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax cl];
|
|
||||||
|
|
||||||
u32 ror_long_asm(u32 *flags,u32 d, u8 s);
|
|
||||||
#pragma aux ror_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"ror eax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [cl] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax cl];
|
|
||||||
|
|
||||||
u8 shl_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux shl_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"shl al,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [cl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al cl];
|
|
||||||
|
|
||||||
u16 shl_word_asm(u32 *flags,u16 d, u8 s);
|
|
||||||
#pragma aux shl_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"shl ax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [cl] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax cl];
|
|
||||||
|
|
||||||
u32 shl_long_asm(u32 *flags,u32 d, u8 s);
|
|
||||||
#pragma aux shl_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"shl eax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [cl] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax cl];
|
|
||||||
|
|
||||||
u8 shr_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux shr_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"shr al,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [cl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al cl];
|
|
||||||
|
|
||||||
u16 shr_word_asm(u32 *flags,u16 d, u8 s);
|
|
||||||
#pragma aux shr_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"shr ax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [cl] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax cl];
|
|
||||||
|
|
||||||
u32 shr_long_asm(u32 *flags,u32 d, u8 s);
|
|
||||||
#pragma aux shr_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"shr eax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [cl] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax cl];
|
|
||||||
|
|
||||||
u8 sar_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux sar_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"sar al,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [cl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al cl];
|
|
||||||
|
|
||||||
u16 sar_word_asm(u32 *flags,u16 d, u8 s);
|
|
||||||
#pragma aux sar_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"sar ax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [cl] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax cl];
|
|
||||||
|
|
||||||
u32 sar_long_asm(u32 *flags,u32 d, u8 s);
|
|
||||||
#pragma aux sar_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"sar eax,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [cl] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax cl];
|
|
||||||
|
|
||||||
u16 shld_word_asm(u32 *flags,u16 d, u16 fill, u8 s);
|
|
||||||
#pragma aux shld_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"shld ax,dx,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [dx] [cl] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax dx cl];
|
|
||||||
|
|
||||||
u32 shld_long_asm(u32 *flags,u32 d, u32 fill, u8 s);
|
|
||||||
#pragma aux shld_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"shld eax,edx,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [edx] [cl] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax edx cl];
|
|
||||||
|
|
||||||
u16 shrd_word_asm(u32 *flags,u16 d, u16 fill, u8 s);
|
|
||||||
#pragma aux shrd_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"shrd ax,dx,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [dx] [cl] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax dx cl];
|
|
||||||
|
|
||||||
u32 shrd_long_asm(u32 *flags,u32 d, u32 fill, u8 s);
|
|
||||||
#pragma aux shrd_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"shrd eax,edx,cl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [edx] [cl] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax edx cl];
|
|
||||||
|
|
||||||
u8 sbb_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux sbb_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"sbb al,bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [bl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al bl];
|
|
||||||
|
|
||||||
u16 sbb_word_asm(u32 *flags,u16 d, u16 s);
|
|
||||||
#pragma aux sbb_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"sbb ax,bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [bx] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax bx];
|
|
||||||
|
|
||||||
u32 sbb_long_asm(u32 *flags,u32 d, u32 s);
|
|
||||||
#pragma aux sbb_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"sbb eax,ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [ebx] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax ebx];
|
|
||||||
|
|
||||||
u8 sub_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux sub_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"sub al,bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [bl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al bl];
|
|
||||||
|
|
||||||
u16 sub_word_asm(u32 *flags,u16 d, u16 s);
|
|
||||||
#pragma aux sub_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"sub ax,bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [bx] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax bx];
|
|
||||||
|
|
||||||
u32 sub_long_asm(u32 *flags,u32 d, u32 s);
|
|
||||||
#pragma aux sub_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"sub eax,ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [ebx] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax ebx];
|
|
||||||
|
|
||||||
void test_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux test_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"test al,bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [bl] \
|
|
||||||
modify exact [al bl];
|
|
||||||
|
|
||||||
void test_word_asm(u32 *flags,u16 d, u16 s);
|
|
||||||
#pragma aux test_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"test ax,bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [bx] \
|
|
||||||
modify exact [ax bx];
|
|
||||||
|
|
||||||
void test_long_asm(u32 *flags,u32 d, u32 s);
|
|
||||||
#pragma aux test_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"test eax,ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [ebx] \
|
|
||||||
modify exact [eax ebx];
|
|
||||||
|
|
||||||
u8 xor_byte_asm(u32 *flags,u8 d, u8 s);
|
|
||||||
#pragma aux xor_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"xor al,bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [al] [bl] \
|
|
||||||
value [al] \
|
|
||||||
modify exact [al bl];
|
|
||||||
|
|
||||||
u16 xor_word_asm(u32 *flags,u16 d, u16 s);
|
|
||||||
#pragma aux xor_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"xor ax,bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [ax] [bx] \
|
|
||||||
value [ax] \
|
|
||||||
modify exact [ax bx];
|
|
||||||
|
|
||||||
u32 xor_long_asm(u32 *flags,u32 d, u32 s);
|
|
||||||
#pragma aux xor_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"xor eax,ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
parm [edi] [eax] [ebx] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax ebx];
|
|
||||||
|
|
||||||
void imul_byte_asm(u32 *flags,u16 *ax,u8 d,u8 s);
|
|
||||||
#pragma aux imul_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"imul bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],ax" \
|
|
||||||
parm [edi] [esi] [al] [bl] \
|
|
||||||
modify exact [esi ax bl];
|
|
||||||
|
|
||||||
void imul_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 d,u16 s);
|
|
||||||
#pragma aux imul_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"imul bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],ax" \
|
|
||||||
"mov [ecx],dx" \
|
|
||||||
parm [edi] [esi] [ecx] [ax] [bx]\
|
|
||||||
modify exact [esi edi ax bx dx];
|
|
||||||
|
|
||||||
void imul_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 d,u32 s);
|
|
||||||
#pragma aux imul_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"imul ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],eax" \
|
|
||||||
"mov [ecx],edx" \
|
|
||||||
parm [edi] [esi] [ecx] [eax] [ebx] \
|
|
||||||
modify exact [esi edi eax ebx edx];
|
|
||||||
|
|
||||||
void mul_byte_asm(u32 *flags,u16 *ax,u8 d,u8 s);
|
|
||||||
#pragma aux mul_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"mul bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],ax" \
|
|
||||||
parm [edi] [esi] [al] [bl] \
|
|
||||||
modify exact [esi ax bl];
|
|
||||||
|
|
||||||
void mul_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 d,u16 s);
|
|
||||||
#pragma aux mul_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"mul bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],ax" \
|
|
||||||
"mov [ecx],dx" \
|
|
||||||
parm [edi] [esi] [ecx] [ax] [bx]\
|
|
||||||
modify exact [esi edi ax bx dx];
|
|
||||||
|
|
||||||
void mul_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 d,u32 s);
|
|
||||||
#pragma aux mul_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"mul ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],eax" \
|
|
||||||
"mov [ecx],edx" \
|
|
||||||
parm [edi] [esi] [ecx] [eax] [ebx] \
|
|
||||||
modify exact [esi edi eax ebx edx];
|
|
||||||
|
|
||||||
void idiv_byte_asm(u32 *flags,u8 *al,u8 *ah,u16 d,u8 s);
|
|
||||||
#pragma aux idiv_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"idiv bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],al" \
|
|
||||||
"mov [ecx],ah" \
|
|
||||||
parm [edi] [esi] [ecx] [ax] [bl]\
|
|
||||||
modify exact [esi edi ax bl];
|
|
||||||
|
|
||||||
void idiv_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 dlo,u16 dhi,u16 s);
|
|
||||||
#pragma aux idiv_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"idiv bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],ax" \
|
|
||||||
"mov [ecx],dx" \
|
|
||||||
parm [edi] [esi] [ecx] [ax] [dx] [bx]\
|
|
||||||
modify exact [esi edi ax dx bx];
|
|
||||||
|
|
||||||
void idiv_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 dlo,u32 dhi,u32 s);
|
|
||||||
#pragma aux idiv_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"idiv ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],eax" \
|
|
||||||
"mov [ecx],edx" \
|
|
||||||
parm [edi] [esi] [ecx] [eax] [edx] [ebx]\
|
|
||||||
modify exact [esi edi eax edx ebx];
|
|
||||||
|
|
||||||
void div_byte_asm(u32 *flags,u8 *al,u8 *ah,u16 d,u8 s);
|
|
||||||
#pragma aux div_byte_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"div bl" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],al" \
|
|
||||||
"mov [ecx],ah" \
|
|
||||||
parm [edi] [esi] [ecx] [ax] [bl]\
|
|
||||||
modify exact [esi edi ax bl];
|
|
||||||
|
|
||||||
void div_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 dlo,u16 dhi,u16 s);
|
|
||||||
#pragma aux div_word_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"div bx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],ax" \
|
|
||||||
"mov [ecx],dx" \
|
|
||||||
parm [edi] [esi] [ecx] [ax] [dx] [bx]\
|
|
||||||
modify exact [esi edi ax dx bx];
|
|
||||||
|
|
||||||
void div_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 dlo,u32 dhi,u32 s);
|
|
||||||
#pragma aux div_long_asm = \
|
|
||||||
"push [edi]" \
|
|
||||||
"popf" \
|
|
||||||
"div ebx" \
|
|
||||||
"pushf" \
|
|
||||||
"pop [edi]" \
|
|
||||||
"mov [esi],eax" \
|
|
||||||
"mov [ecx],edx" \
|
|
||||||
parm [edi] [esi] [ecx] [eax] [edx] [ebx]\
|
|
||||||
modify exact [esi edi eax edx ebx];
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __X86EMU_PRIM_ASM_H */
|
|
|
@ -1,231 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Header file for primitive operation functions.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __X86EMU_PRIM_OPS_H
|
|
||||||
#define __X86EMU_PRIM_OPS_H
|
|
||||||
|
|
||||||
#include "x86emu/prim_asm.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);
|
|
||||||
|
|
||||||
#if defined(__HAVE_INLINE_ASSEMBLER__) && !defined(PRIM_OPS_NO_REDEFINE_ASM)
|
|
||||||
|
|
||||||
#define aaa_word(d) aaa_word_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define aas_word(d) aas_word_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define aad_word(d) aad_word_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define aam_word(d) aam_word_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define adc_byte(d,s) adc_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define adc_word(d,s) adc_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define adc_long(d,s) adc_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define add_byte(d,s) add_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define add_word(d,s) add_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define add_long(d,s) add_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define and_byte(d,s) and_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define and_word(d,s) and_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define and_long(d,s) and_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define cmp_byte(d,s) cmp_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define cmp_word(d,s) cmp_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define cmp_long(d,s) cmp_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define daa_byte(d) daa_byte_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define das_byte(d) das_byte_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define dec_byte(d) dec_byte_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define dec_word(d) dec_word_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define dec_long(d) dec_long_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define inc_byte(d) inc_byte_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define inc_word(d) inc_word_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define inc_long(d) inc_long_asm(&M.x86.R_EFLG,d)
|
|
||||||
#define or_byte(d,s) or_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define or_word(d,s) or_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define or_long(d,s) or_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define neg_byte(s) neg_byte_asm(&M.x86.R_EFLG,s)
|
|
||||||
#define neg_word(s) neg_word_asm(&M.x86.R_EFLG,s)
|
|
||||||
#define neg_long(s) neg_long_asm(&M.x86.R_EFLG,s)
|
|
||||||
#define not_byte(s) not_byte_asm(&M.x86.R_EFLG,s)
|
|
||||||
#define not_word(s) not_word_asm(&M.x86.R_EFLG,s)
|
|
||||||
#define not_long(s) not_long_asm(&M.x86.R_EFLG,s)
|
|
||||||
#define rcl_byte(d,s) rcl_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define rcl_word(d,s) rcl_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define rcl_long(d,s) rcl_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define rcr_byte(d,s) rcr_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define rcr_word(d,s) rcr_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define rcr_long(d,s) rcr_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define rol_byte(d,s) rol_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define rol_word(d,s) rol_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define rol_long(d,s) rol_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define ror_byte(d,s) ror_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define ror_word(d,s) ror_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define ror_long(d,s) ror_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define shl_byte(d,s) shl_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define shl_word(d,s) shl_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define shl_long(d,s) shl_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define shr_byte(d,s) shr_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define shr_word(d,s) shr_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define shr_long(d,s) shr_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define sar_byte(d,s) sar_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define sar_word(d,s) sar_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define sar_long(d,s) sar_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define shld_word(d,fill,s) shld_word_asm(&M.x86.R_EFLG,d,fill,s)
|
|
||||||
#define shld_long(d,fill,s) shld_long_asm(&M.x86.R_EFLG,d,fill,s)
|
|
||||||
#define shrd_word(d,fill,s) shrd_word_asm(&M.x86.R_EFLG,d,fill,s)
|
|
||||||
#define shrd_long(d,fill,s) shrd_long_asm(&M.x86.R_EFLG,d,fill,s)
|
|
||||||
#define sbb_byte(d,s) sbb_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define sbb_word(d,s) sbb_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define sbb_long(d,s) sbb_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define sub_byte(d,s) sub_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define sub_word(d,s) sub_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define sub_long(d,s) sub_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define test_byte(d,s) test_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define test_word(d,s) test_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define test_long(d,s) test_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define xor_byte(d,s) xor_byte_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define xor_word(d,s) xor_word_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define xor_long(d,s) xor_long_asm(&M.x86.R_EFLG,d,s)
|
|
||||||
#define imul_byte(s) imul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s)
|
|
||||||
#define imul_word(s) imul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s)
|
|
||||||
#define imul_long(s) imul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s)
|
|
||||||
#define imul_long_direct(res_lo,res_hi,d,s) imul_long_asm(&M.x86.R_EFLG,res_lo,res_hi,d,s)
|
|
||||||
#define mul_byte(s) mul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s)
|
|
||||||
#define mul_word(s) mul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s)
|
|
||||||
#define mul_long(s) mul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s)
|
|
||||||
#define idiv_byte(s) idiv_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s)
|
|
||||||
#define idiv_word(s) idiv_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s)
|
|
||||||
#define idiv_long(s) idiv_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s)
|
|
||||||
#define div_byte(s) div_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s)
|
|
||||||
#define div_word(s) div_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s)
|
|
||||||
#define div_long(s) div_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* End of "C" linkage for C++ */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __X86EMU_PRIM_OPS_H */
|
|
|
@ -1,105 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Realmode X86 Emulator Library
|
|
||||||
*
|
|
||||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
||||||
* Copyright (C) David Mosberger-Tang
|
|
||||||
* Copyright (C) 1999 Egbert Eich
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
* its documentation for any purpose is hereby granted without fee,
|
|
||||||
* provided that the above copyright notice appear in all copies and that
|
|
||||||
* both that copyright notice and this permission notice appear in
|
|
||||||
* supporting documentation, and that the name of the authors not be used
|
|
||||||
* in advertising or publicity pertaining to distribution of the software
|
|
||||||
* without specific, written prior permission. The authors makes no
|
|
||||||
* representations about the suitability of this software for any purpose.
|
|
||||||
* It is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
||||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* ========================================================================
|
|
||||||
*
|
|
||||||
* Language: ANSI C
|
|
||||||
* Environment: Any
|
|
||||||
* Developer: Kendall Bennett
|
|
||||||
*
|
|
||||||
* Description: Header file for system specific functions. These functions
|
|
||||||
* are always compiled and linked in the OS depedent libraries,
|
|
||||||
* and never in a binary portable driver.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/* $XFree86: xc/extras/x86emu/src/x86emu/x86emu/x86emui.h,v 1.4 2001/04/01 13:59:58 tsi Exp $ */
|
|
||||||
|
|
||||||
#ifndef __X86EMU_X86EMUI_H
|
|
||||||
#define __X86EMU_X86EMUI_H
|
|
||||||
|
|
||||||
/* If we are compiling in C++ mode, we can compile some functions as
|
|
||||||
* inline to increase performance (however the code size increases quite
|
|
||||||
* dramatically in this case).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__cplusplus) && !defined(_NO_INLINE)
|
|
||||||
#define _INLINE inline
|
|
||||||
#else
|
|
||||||
#define _INLINE static
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get rid of unused parameters in C++ compilation mode */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define X86EMU_UNUSED(v)
|
|
||||||
#else
|
|
||||||
#define X86EMU_UNUSED(v) v
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "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"
|
|
||||||
|
|
||||||
#ifdef IN_MODULE
|
|
||||||
#include <xf86_ansic.h>
|
|
||||||
#else
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
/*--------------------------- Inline Functions ----------------------------*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern u8 (X86APIP sys_rdb)(u32 addr);
|
|
||||||
extern u16 (X86APIP sys_rdw)(u32 addr);
|
|
||||||
extern u32 (X86APIP sys_rdl)(u32 addr);
|
|
||||||
extern void (X86APIP sys_wrb)(u32 addr,u8 val);
|
|
||||||
extern void (X86APIP sys_wrw)(u32 addr,u16 val);
|
|
||||||
extern void (X86APIP sys_wrl)(u32 addr,u32 val);
|
|
||||||
|
|
||||||
extern u8 (X86APIP sys_inb)(X86EMU_pioAddr addr);
|
|
||||||
extern u16 (X86APIP sys_inw)(X86EMU_pioAddr addr);
|
|
||||||
extern u32 (X86APIP sys_inl)(X86EMU_pioAddr addr);
|
|
||||||
extern void (X86APIP sys_outb)(X86EMU_pioAddr addr,u8 val);
|
|
||||||
extern void (X86APIP sys_outw)(X86EMU_pioAddr addr,u16 val);
|
|
||||||
extern void (X86APIP sys_outl)(X86EMU_pioAddr addr,u32 val);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* End of "C" linkage for C++ */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __X86EMU_X86EMUI_H */
|
|
|
@ -1,55 +0,0 @@
|
||||||
/* tag: compile time configuration options
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Patrick Mauritz, Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
|
||||||
#define __CONFIG_H
|
|
||||||
|
|
||||||
/* Console options
|
|
||||||
*
|
|
||||||
* DEBUG_CONSOLE_VGA
|
|
||||||
* use vga textmode and keyboard console
|
|
||||||
*
|
|
||||||
* DEBUG_CONSOLE_SERIAL
|
|
||||||
* use serial console. If this is enabled, see
|
|
||||||
* options below.
|
|
||||||
*
|
|
||||||
* SERIAL_PORT:
|
|
||||||
* 0 for none, 1 for ttyS0, 2 for ttyS1
|
|
||||||
*
|
|
||||||
* SERIAL_SPEED:
|
|
||||||
* supported speeds are: 115200, 57600, 38400, 19200, 9600
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DEBUG_CONSOLE_SERIAL
|
|
||||||
// #define DEBUG_CONSOLE_VGA
|
|
||||||
|
|
||||||
#define SERIAL_PORT 1
|
|
||||||
#define SERIAL_SPEED 115200
|
|
||||||
|
|
||||||
|
|
||||||
/* Debugging switches
|
|
||||||
*
|
|
||||||
* these switches enable debugging code snippets spread all over
|
|
||||||
* the code. You should not need to change these settings unless
|
|
||||||
* you know what you are doing.
|
|
||||||
*
|
|
||||||
* DEBUG_BOOT:
|
|
||||||
* early boot code (multiboot parsing etc)
|
|
||||||
*
|
|
||||||
* DEBUG_CONSOLE:
|
|
||||||
* use builtin C console code for user interaction. There is no
|
|
||||||
* real alternative to this until someone writes a display/kbd or
|
|
||||||
* serial driver in forth.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define DEBUG_BOOT
|
|
||||||
#endif
|
|
||||||
#define DEBUG_CONSOLE
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,342 +0,0 @@
|
||||||
/*
|
|
||||||
* pci.h
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PCI_H
|
|
||||||
#define PCI_H
|
|
||||||
|
|
||||||
#define PCI_VENDOR_ID 0x00 /* 16 bits */
|
|
||||||
#define PCI_DEVICE_ID 0x02 /* 16 bits */
|
|
||||||
#define PCI_COMMAND 0x04 /* 16 bits */
|
|
||||||
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
|
|
||||||
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
|
|
||||||
#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
|
|
||||||
#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
|
|
||||||
#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
|
|
||||||
#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
|
|
||||||
#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
|
|
||||||
#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
|
|
||||||
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
|
|
||||||
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
|
|
||||||
|
|
||||||
#define PCI_STATUS 0x06 /* 16 bits */
|
|
||||||
#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
|
|
||||||
#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
|
|
||||||
#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
|
|
||||||
#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
|
|
||||||
#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
|
|
||||||
#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
|
|
||||||
#define PCI_STATUS_DEVSEL_FAST 0x000
|
|
||||||
#define PCI_STATUS_DEVSEL_MEDIUM 0x200
|
|
||||||
#define PCI_STATUS_DEVSEL_SLOW 0x400
|
|
||||||
#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
|
|
||||||
#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
|
|
||||||
#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
|
|
||||||
#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
|
|
||||||
#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
|
|
||||||
|
|
||||||
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8
|
|
||||||
revision */
|
|
||||||
#define PCI_REVISION_ID 0x08 /* Revision ID */
|
|
||||||
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
|
|
||||||
#define PCI_CLASS_DEVICE 0x0a /* Device class */
|
|
||||||
|
|
||||||
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
|
|
||||||
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
|
|
||||||
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
|
|
||||||
#define PCI_HEADER_TYPE_NORMAL 0
|
|
||||||
#define PCI_HEADER_TYPE_BRIDGE 1
|
|
||||||
#define PCI_HEADER_TYPE_CARDBUS 2
|
|
||||||
|
|
||||||
#define PCI_BIST 0x0f /* 8 bits */
|
|
||||||
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
|
|
||||||
#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
|
|
||||||
#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Base addresses specify locations in memory or I/O space.
|
|
||||||
* Decoded size can be determined by writing a value of
|
|
||||||
* 0xffffffff to the register, and reading it back. Only
|
|
||||||
* 1 bits are decoded.
|
|
||||||
*/
|
|
||||||
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
|
|
||||||
#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
|
|
||||||
#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
|
|
||||||
#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
|
|
||||||
#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
|
|
||||||
#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
|
|
||||||
#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
|
|
||||||
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
|
|
||||||
#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
|
|
||||||
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
|
|
||||||
#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
|
|
||||||
#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
|
|
||||||
#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
|
|
||||||
#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
|
|
||||||
#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
|
|
||||||
#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
|
|
||||||
/* bit 1 is reserved if address_space = 1 */
|
|
||||||
|
|
||||||
/* Header type 0 (normal devices) */
|
|
||||||
#define PCI_CARDBUS_CIS 0x28
|
|
||||||
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
|
|
||||||
#define PCI_SUBSYSTEM_ID 0x2e
|
|
||||||
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
|
|
||||||
#define PCI_ROM_ADDRESS_ENABLE 0x01
|
|
||||||
#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
|
|
||||||
|
|
||||||
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
|
|
||||||
|
|
||||||
/* 0x35-0x3b are reserved */
|
|
||||||
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
|
|
||||||
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
|
|
||||||
#define PCI_MIN_GNT 0x3e /* 8 bits */
|
|
||||||
#define PCI_MAX_LAT 0x3f /* 8 bits */
|
|
||||||
|
|
||||||
/* Header type 1 (PCI-to-PCI bridges) */
|
|
||||||
#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
|
|
||||||
#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
|
|
||||||
#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
|
|
||||||
#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
|
|
||||||
#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
|
|
||||||
#define PCI_IO_LIMIT 0x1d
|
|
||||||
#define PCI_IO_RANGE_TYPE_MASK 0x0f /* I/O bridging type */
|
|
||||||
#define PCI_IO_RANGE_TYPE_16 0x00
|
|
||||||
#define PCI_IO_RANGE_TYPE_32 0x01
|
|
||||||
#define PCI_IO_RANGE_MASK ~0x0f
|
|
||||||
#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
|
|
||||||
#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
|
|
||||||
#define PCI_MEMORY_LIMIT 0x22
|
|
||||||
#define PCI_MEMORY_RANGE_TYPE_MASK 0x0f
|
|
||||||
#define PCI_MEMORY_RANGE_MASK ~0x0f
|
|
||||||
#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
|
|
||||||
#define PCI_PREF_MEMORY_LIMIT 0x26
|
|
||||||
#define PCI_PREF_RANGE_TYPE_MASK 0x0f
|
|
||||||
#define PCI_PREF_RANGE_TYPE_32 0x00
|
|
||||||
#define PCI_PREF_RANGE_TYPE_64 0x01
|
|
||||||
#define PCI_PREF_RANGE_MASK ~0x0f
|
|
||||||
#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
|
|
||||||
#define PCI_PREF_LIMIT_UPPER32 0x2c
|
|
||||||
#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
|
|
||||||
#define PCI_IO_LIMIT_UPPER16 0x32
|
|
||||||
/* 0x34 same as for htype 0 */
|
|
||||||
/* 0x35-0x3b is reserved */
|
|
||||||
#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
|
|
||||||
/* 0x3c-0x3d are same as for htype 0 */
|
|
||||||
#define PCI_BRIDGE_CONTROL 0x3e
|
|
||||||
#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
|
|
||||||
#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
|
|
||||||
#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
|
|
||||||
#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
|
|
||||||
#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
|
|
||||||
#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
|
|
||||||
#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
|
|
||||||
|
|
||||||
/* Header type 2 (CardBus bridges) */
|
|
||||||
#define PCI_CB_CAPABILITY_LIST 0x14
|
|
||||||
/* 0x15 reserved */
|
|
||||||
#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */
|
|
||||||
#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */
|
|
||||||
#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */
|
|
||||||
#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */
|
|
||||||
#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */
|
|
||||||
#define PCI_CB_MEMORY_BASE_0 0x1c
|
|
||||||
#define PCI_CB_MEMORY_LIMIT_0 0x20
|
|
||||||
#define PCI_CB_MEMORY_BASE_1 0x24
|
|
||||||
#define PCI_CB_MEMORY_LIMIT_1 0x28
|
|
||||||
#define PCI_CB_IO_BASE_0 0x2c
|
|
||||||
#define PCI_CB_IO_BASE_0_HI 0x2e
|
|
||||||
#define PCI_CB_IO_LIMIT_0 0x30
|
|
||||||
#define PCI_CB_IO_LIMIT_0_HI 0x32
|
|
||||||
#define PCI_CB_IO_BASE_1 0x34
|
|
||||||
#define PCI_CB_IO_BASE_1_HI 0x36
|
|
||||||
#define PCI_CB_IO_LIMIT_1 0x38
|
|
||||||
#define PCI_CB_IO_LIMIT_1_HI 0x3a
|
|
||||||
#define PCI_CB_IO_RANGE_MASK ~0x03
|
|
||||||
/* 0x3c-0x3d are same as for htype 0 */
|
|
||||||
#define PCI_CB_BRIDGE_CONTROL 0x3e
|
|
||||||
#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */
|
|
||||||
#define PCI_CB_BRIDGE_CTL_SERR 0x02
|
|
||||||
#define PCI_CB_BRIDGE_CTL_ISA 0x04
|
|
||||||
#define PCI_CB_BRIDGE_CTL_VGA 0x08
|
|
||||||
#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
|
|
||||||
#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
|
|
||||||
#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */
|
|
||||||
#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
|
|
||||||
#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
|
|
||||||
#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
|
|
||||||
#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
|
|
||||||
#define PCI_CB_SUBSYSTEM_ID 0x42
|
|
||||||
#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */
|
|
||||||
/* 0x48-0x7f reserved */
|
|
||||||
|
|
||||||
/* Capability lists */
|
|
||||||
|
|
||||||
#define PCI_CAP_LIST_ID 0 /* Capability ID */
|
|
||||||
#define PCI_CAP_ID_PM 0x01 /* Power Management */
|
|
||||||
#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
|
|
||||||
#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
|
|
||||||
#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
|
|
||||||
#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
|
|
||||||
#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
|
|
||||||
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
|
|
||||||
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
|
|
||||||
#define PCI_CAP_SIZEOF 4
|
|
||||||
|
|
||||||
/* Power Management Registers */
|
|
||||||
|
|
||||||
#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
|
|
||||||
#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
|
|
||||||
#define PCI_PM_CAP_AUX_POWER 0x0010 /* Auxilliary power support */
|
|
||||||
#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
|
|
||||||
#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
|
|
||||||
#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
|
|
||||||
#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
|
|
||||||
#define PCI_PM_CTRL 4 /* PM control and status register */
|
|
||||||
#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
|
|
||||||
#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
|
|
||||||
#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
|
|
||||||
#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
|
|
||||||
#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
|
|
||||||
#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
|
|
||||||
#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
|
|
||||||
#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
|
|
||||||
#define PCI_PM_DATA_REGISTER 7 /* (??) */
|
|
||||||
#define PCI_PM_SIZEOF 8
|
|
||||||
|
|
||||||
/* AGP registers */
|
|
||||||
|
|
||||||
#define PCI_AGP_VERSION 2 /* BCD version number */
|
|
||||||
#define PCI_AGP_RFU 3 /* Rest of capability flags */
|
|
||||||
#define PCI_AGP_STATUS 4 /* Status register */
|
|
||||||
#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
|
|
||||||
#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
|
|
||||||
#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
|
|
||||||
#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
|
|
||||||
#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
|
|
||||||
#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
|
|
||||||
#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
|
|
||||||
#define PCI_AGP_COMMAND 8 /* Control register */
|
|
||||||
#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
|
|
||||||
#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
|
|
||||||
#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
|
|
||||||
#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
|
|
||||||
#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
|
|
||||||
#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
|
|
||||||
#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 4x rate */
|
|
||||||
#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 4x rate */
|
|
||||||
#define PCI_AGP_SIZEOF 12
|
|
||||||
|
|
||||||
/* Slot Identification */
|
|
||||||
|
|
||||||
#define PCI_SID_ESR 2 /* Expansion Slot Register */
|
|
||||||
#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
|
|
||||||
#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
|
|
||||||
#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
|
|
||||||
|
|
||||||
/* Message Signalled Interrupts registers */
|
|
||||||
|
|
||||||
#define PCI_MSI_FLAGS 2 /* Various flags */
|
|
||||||
#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
|
|
||||||
#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
|
|
||||||
#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
|
|
||||||
#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
|
|
||||||
#define PCI_MSI_RFU 3 /* Rest of capability flags */
|
|
||||||
#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
|
|
||||||
#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
|
|
||||||
#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
|
|
||||||
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The PCI interface treats multi-function devices as independent
|
|
||||||
* devices. The slot/function address of each device is encoded
|
|
||||||
* in a single byte as follows:
|
|
||||||
*
|
|
||||||
* 7:3 = slot
|
|
||||||
* 2:0 = function
|
|
||||||
*/
|
|
||||||
#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
|
|
||||||
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
|
|
||||||
#define PCI_FUNC(devfn) ((devfn) & 0x07)
|
|
||||||
#define PCI_BDF(bus,dev,func) ((bus) << 16 | (dev) << 11 | (func) << 8)
|
|
||||||
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
#include <resource.h>
|
|
||||||
|
|
||||||
#define MAX_RESOURCES 6
|
|
||||||
|
|
||||||
struct pci_dev;
|
|
||||||
/*
|
|
||||||
* There is one pci_dev structure for each slot-number/function-number
|
|
||||||
* combination:
|
|
||||||
*/
|
|
||||||
struct pci_dev {
|
|
||||||
struct pci_dev *next; /* chain of all devices */
|
|
||||||
unsigned int bus;
|
|
||||||
unsigned int devfn; /* encoded device & function index */
|
|
||||||
unsigned short vendor;
|
|
||||||
unsigned short device;
|
|
||||||
unsigned short command;
|
|
||||||
unsigned short class; /* 3 bytes: (base,sub,prog-if) */
|
|
||||||
unsigned char progif;
|
|
||||||
unsigned char header; /* PCI header type */
|
|
||||||
unsigned int irq; /* irq generated by this device */
|
|
||||||
struct resource resource[MAX_RESOURCES];
|
|
||||||
unsigned int resources;
|
|
||||||
unsigned long rom_address;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Error values that may be returned by the PCI bios.
|
|
||||||
*/
|
|
||||||
#define PCIBIOS_SUCCESSFUL 0x00
|
|
||||||
#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81
|
|
||||||
#define PCIBIOS_BAD_VENDOR_ID 0x83
|
|
||||||
#define PCIBIOS_DEVICE_NOT_FOUND 0x86
|
|
||||||
#define PCIBIOS_BAD_REGISTER_NUMBER 0x87
|
|
||||||
#define PCIBIOS_SET_FAILED 0x88
|
|
||||||
#define PCIBIOS_BUFFER_TOO_SMALL 0x89
|
|
||||||
|
|
||||||
/* Low-level architecture-dependent routines */
|
|
||||||
|
|
||||||
/* Generic PCI interface functions */
|
|
||||||
unsigned int pci_scan_bus(struct pci_dev *bus, unsigned int max);
|
|
||||||
unsigned int pci_scan_bridge(struct pci_dev *bus, unsigned int max);
|
|
||||||
|
|
||||||
struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, struct pci_dev *from);
|
|
||||||
struct pci_dev *pci_find_class (unsigned int class, struct pci_dev *from);
|
|
||||||
struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
|
|
||||||
|
|
||||||
int pci_read_config_byte(struct pci_dev *dev, u8 where, u8 *val);
|
|
||||||
int pci_read_config_word(struct pci_dev *dev, u8 where, u16 *val);
|
|
||||||
int pci_read_config_dword(struct pci_dev *dev, u8 where, u32 *val);
|
|
||||||
int pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val);
|
|
||||||
int pci_write_config_word(struct pci_dev *dev, u8 where, u16 val);
|
|
||||||
int pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val);
|
|
||||||
int pci_debugwrite_config_byte(struct pci_dev *dev, u8 where, u8 val);
|
|
||||||
int pci_debugwrite_config_word(struct pci_dev *dev, u8 where, u16 val);
|
|
||||||
int pci_debugwrite_config_dword(struct pci_dev *dev, u8 where, u32 val);
|
|
||||||
void pci_set_master(struct pci_dev *dev);
|
|
||||||
void pci_set_method(void);
|
|
||||||
void pci_init(void);
|
|
||||||
|
|
||||||
// Rounding for boundaries.
|
|
||||||
// Due to some chip bugs, go ahead and roung IO to 16
|
|
||||||
#define IO_ALIGN 16
|
|
||||||
#define MEM_ALIGN 4096
|
|
||||||
#define IO_BRIDGE_ALIGN 4096
|
|
||||||
#define MEM_BRIDGE_ALIGN (1024*1024)
|
|
||||||
|
|
||||||
extern void compute_allocate_resource(struct pci_dev *bus, struct resource *bridge,
|
|
||||||
unsigned long type_mask, unsigned long type);
|
|
||||||
extern void assign_resources(struct pci_dev *bus);
|
|
||||||
extern void enumerate_static_device(void);
|
|
||||||
extern unsigned long pci_memory_base;
|
|
||||||
|
|
||||||
#endif /* PCI_H */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,70 +0,0 @@
|
||||||
#ifndef RESOURCE_H
|
|
||||||
#define RESOURCE_H
|
|
||||||
|
|
||||||
|
|
||||||
#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
|
|
||||||
|
|
||||||
#define IORESOURCE_IO 0x00000100 /* Resource type */
|
|
||||||
#define IORESOURCE_MEM 0x00000200
|
|
||||||
#define IORESOURCE_IRQ 0x00000400
|
|
||||||
#define IORESOURCE_DMA 0x00000800
|
|
||||||
|
|
||||||
#define IORESOURCE_PREFETCH 0x00001000 /* No side effects */
|
|
||||||
#define IORESOURCE_READONLY 0x00002000
|
|
||||||
#define IORESOURCE_CACHEABLE 0x00004000
|
|
||||||
#define IORESOURCE_RANGELENGTH 0x00008000
|
|
||||||
#define IORESOURCE_SHADOWABLE 0x00010000
|
|
||||||
#define IORESOURCE_BUS_HAS_VGA 0x00020000
|
|
||||||
|
|
||||||
#define IORESOURCE_SET 0x80000000
|
|
||||||
|
|
||||||
/* PCI specific resource bits */
|
|
||||||
#define IORESOURCE_PCI64 (1<<0) /* 64bit long pci resource */
|
|
||||||
#define IORESOURCE_PCI_BRIDGE (1<<1) /* A bridge pci resource */
|
|
||||||
|
|
||||||
/* ISA PnP IRQ specific bits (IORESOURCE_BITS) */
|
|
||||||
#define IORESOURCE_IRQ_HIGHEDGE (1<<0)
|
|
||||||
#define IORESOURCE_IRQ_LOWEDGE (1<<1)
|
|
||||||
#define IORESOURCE_IRQ_HIGHLEVEL (1<<2)
|
|
||||||
#define IORESOURCE_IRQ_LOWLEVEL (1<<3)
|
|
||||||
|
|
||||||
/* ISA PnP DMA specific bits (IORESOURCE_BITS) */
|
|
||||||
#define IORESOURCE_DMA_TYPE_MASK (3<<0)
|
|
||||||
#define IORESOURCE_DMA_8BIT (0<<0)
|
|
||||||
#define IORESOURCE_DMA_8AND16BIT (1<<0)
|
|
||||||
#define IORESOURCE_DMA_16BIT (2<<0)
|
|
||||||
|
|
||||||
#define IORESOURCE_DMA_MASTER (1<<2)
|
|
||||||
#define IORESOURCE_DMA_BYTE (1<<3)
|
|
||||||
#define IORESOURCE_DMA_WORD (1<<4)
|
|
||||||
|
|
||||||
#define IORESOURCE_DMA_SPEED_MASK (3<<6)
|
|
||||||
#define IORESOURCE_DMA_COMPATIBLE (0<<6)
|
|
||||||
#define IORESOURCE_DMA_TYPEA (1<<6)
|
|
||||||
#define IORESOURCE_DMA_TYPEB (2<<6)
|
|
||||||
#define IORESOURCE_DMA_TYPEF (3<<6)
|
|
||||||
|
|
||||||
|
|
||||||
/* ISA PnP memory I/O specific bits (IORESOURCE_BITS) */
|
|
||||||
#define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */
|
|
||||||
#define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */
|
|
||||||
#define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */
|
|
||||||
#define IORESOURCE_MEM_TYPE_MASK (3<<3)
|
|
||||||
#define IORESOURCE_MEM_8BIT (0<<3)
|
|
||||||
#define IORESOURCE_MEM_16BIT (1<<3)
|
|
||||||
#define IORESOURCE_MEM_8AND16BIT (2<<3)
|
|
||||||
#define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */
|
|
||||||
#define IORESOURCE_MEM_EXPANSIONROM (1<<6)
|
|
||||||
|
|
||||||
struct resource {
|
|
||||||
unsigned long base; /* Base address of the resource */
|
|
||||||
unsigned long size; /* Size of the resource */
|
|
||||||
unsigned long limit; /* Largest valid value base + size -1 */
|
|
||||||
unsigned long flags; /* Descriptions of the kind of resource */
|
|
||||||
unsigned long index; /* Bus specific per device resource id */
|
|
||||||
unsigned char align; /* Required alignment (base 2) of the resource */
|
|
||||||
unsigned char gran; /* Granularity (base 2) of the resource */
|
|
||||||
/* Alignment must be >= the granularity of the resource */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* RESOURCE_H */
|
|
|
@ -1,89 +0,0 @@
|
||||||
/* $XFree86: xc/programs/Xserver/hw/xfree86/int10/xf86x86emu.h,v 1.2 2001/01/06 20:19:13 tsi Exp $ */
|
|
||||||
/*
|
|
||||||
* XFree86 int10 module
|
|
||||||
* execute BIOS int 10h calls in x86 real mode environment
|
|
||||||
* Copyright 1999 Egbert Eich
|
|
||||||
*/
|
|
||||||
#ifndef XF86X86EMU_H_
|
|
||||||
#define XF86X86EMU_H_
|
|
||||||
#include <x86emu.h>
|
|
||||||
|
|
||||||
#define M _X86EMU_env
|
|
||||||
|
|
||||||
#define X86_EAX M.x86.R_EAX
|
|
||||||
#define X86_EBX M.x86.R_EBX
|
|
||||||
#define X86_ECX M.x86.R_ECX
|
|
||||||
#define X86_EDX M.x86.R_EDX
|
|
||||||
#define X86_ESI M.x86.R_ESI
|
|
||||||
#define X86_EDI M.x86.R_EDI
|
|
||||||
#define X86_EBP M.x86.R_EBP
|
|
||||||
#define X86_EIP M.x86.R_EIP
|
|
||||||
#define X86_ESP M.x86.R_ESP
|
|
||||||
#define X86_EFLAGS M.x86.R_EFLG
|
|
||||||
|
|
||||||
#define X86_FLAGS M.x86.R_FLG
|
|
||||||
#define X86_AX M.x86.R_AX
|
|
||||||
#define X86_BX M.x86.R_BX
|
|
||||||
#define X86_CX M.x86.R_CX
|
|
||||||
#define X86_DX M.x86.R_DX
|
|
||||||
#define X86_SI M.x86.R_SI
|
|
||||||
#define X86_DI M.x86.R_DI
|
|
||||||
#define X86_BP M.x86.R_BP
|
|
||||||
#define X86_IP M.x86.R_IP
|
|
||||||
#define X86_SP M.x86.R_SP
|
|
||||||
#define X86_CS M.x86.R_CS
|
|
||||||
#define X86_DS M.x86.R_DS
|
|
||||||
#define X86_ES M.x86.R_ES
|
|
||||||
#define X86_SS M.x86.R_SS
|
|
||||||
#define X86_FS M.x86.R_FS
|
|
||||||
#define X86_GS M.x86.R_GS
|
|
||||||
|
|
||||||
#define X86_AL M.x86.R_AL
|
|
||||||
#define X86_BL M.x86.R_BL
|
|
||||||
#define X86_CL M.x86.R_CL
|
|
||||||
#define X86_DL M.x86.R_DL
|
|
||||||
|
|
||||||
#define X86_AH M.x86.R_AH
|
|
||||||
#define X86_BH M.x86.R_BH
|
|
||||||
#define X86_CH M.x86.R_CH
|
|
||||||
#define X86_DH M.x86.R_DH
|
|
||||||
|
|
||||||
|
|
||||||
/* int10 info structure */
|
|
||||||
typedef struct {
|
|
||||||
u16 BIOSseg;
|
|
||||||
u16 inb40time;
|
|
||||||
struct _mem *mem;
|
|
||||||
int num;
|
|
||||||
int ax;
|
|
||||||
int bx;
|
|
||||||
int cx;
|
|
||||||
int dx;
|
|
||||||
int si;
|
|
||||||
int di;
|
|
||||||
int es;
|
|
||||||
int bp;
|
|
||||||
int flags;
|
|
||||||
int stackseg;
|
|
||||||
} _ptr, *ptr;
|
|
||||||
|
|
||||||
typedef struct _mem {
|
|
||||||
u8(*rb)(ptr, int);
|
|
||||||
u16(*rw)(ptr, int);
|
|
||||||
u32(*rl)(ptr, int);
|
|
||||||
void(*wb)(ptr, int, u8);
|
|
||||||
void(*ww)(ptr, int, u16);
|
|
||||||
void(*wl)(ptr, int, u32);
|
|
||||||
} mem;
|
|
||||||
|
|
||||||
#define MEM_WB(where, what) wrb(where,what)
|
|
||||||
#define MEM_WW(where, what) wrw(where, what)
|
|
||||||
#define MEM_WL(where, what) wrl(where, what)
|
|
||||||
|
|
||||||
#define MEM_RB(where) rdb(where)
|
|
||||||
#define MEM_RW(where) rdw(where)
|
|
||||||
#define MEM_RL(where) rdl(where)
|
|
||||||
|
|
||||||
extern ptr current;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Makefile for the kernel
|
|
||||||
#
|
|
||||||
# Copyright (C) 2003 Stefan Reinauer
|
|
||||||
#
|
|
||||||
# See the file "COPYING" for further information about
|
|
||||||
# the copyright and warranty status of this work.
|
|
||||||
#
|
|
||||||
|
|
||||||
OBJS_KERNEL = lib.o legacybios.o pcibios.o malloc.o x86glue.o
|
|
||||||
INCLUDES := -I$(TOPDIR)/include -I$(BUILDDIR) -I $(TOPDIR)/arch/$(ARCH)/include -I$(TOPDIR)/arch/x86emu/include
|
|
||||||
|
|
||||||
include $(TOPDIR)/Rules.make
|
|
||||||
|
|
||||||
all: core $(OBJS_KERNEL)
|
|
||||||
|
|
||||||
core:
|
|
||||||
echo -e "\nBuilding common core files for architecture $(ARCH)"
|
|
||||||
|
|
||||||
# dependencies. these are so small that we write them manually.
|
|
||||||
lib.o: types.h lib.c
|
|
||||||
legacybios.o: config.h types.h legacybios.c
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/* tag: legacybios environment, executable code
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
void printk(const char *fmt, ...);
|
|
||||||
void cls(void);
|
|
||||||
#ifdef DEBUG_CONSOLE
|
|
||||||
int uart_init(int port, unsigned long speed);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void legacybios(ucell romstart, ucell romend)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_CONSOLE
|
|
||||||
uart_init(SERIAL_PORT, SERIAL_SPEED);
|
|
||||||
/* Clear the screen. */
|
|
||||||
cls();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG_BOOT
|
|
||||||
printk("LegacyBIOS started.\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
|
@ -1,170 +0,0 @@
|
||||||
/* lib.c
|
|
||||||
* tag: simple function library
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file "COPYING" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
int putchar(int c);
|
|
||||||
|
|
||||||
/* ****************************************************************** */
|
|
||||||
|
|
||||||
/* Convert the integer D to a string and save the string in BUF. If
|
|
||||||
* BASE is equal to 'd', interpret that D is decimal, and if BASE is
|
|
||||||
* equal to 'x', interpret that D is hexadecimal.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void itoa(char *buf, int base, int d)
|
|
||||||
{
|
|
||||||
char *p = buf;
|
|
||||||
char *p1, *p2;
|
|
||||||
unsigned long ud = d;
|
|
||||||
int divisor = 10;
|
|
||||||
|
|
||||||
/* If %d is specified and D is minus, put `-' in the head. */
|
|
||||||
if (base == 'd' && d < 0) {
|
|
||||||
*p++ = '-';
|
|
||||||
buf++;
|
|
||||||
ud = -d;
|
|
||||||
} else if (base == 'x')
|
|
||||||
divisor = 16;
|
|
||||||
|
|
||||||
/* Divide UD by DIVISOR until UD == 0. */
|
|
||||||
do {
|
|
||||||
int remainder = ud % divisor;
|
|
||||||
|
|
||||||
*p++ =
|
|
||||||
(remainder <
|
|
||||||
10) ? remainder + '0' : remainder + 'a' - 10;
|
|
||||||
}
|
|
||||||
while (ud /= divisor);
|
|
||||||
|
|
||||||
/* Terminate BUF. */
|
|
||||||
*p = 0;
|
|
||||||
|
|
||||||
/* Reverse BUF. */
|
|
||||||
p1 = buf;
|
|
||||||
p2 = p - 1;
|
|
||||||
while (p1 < p2) {
|
|
||||||
char tmp = *p1;
|
|
||||||
*p1 = *p2;
|
|
||||||
*p2 = tmp;
|
|
||||||
p1++;
|
|
||||||
p2--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Format a string and print it on the screen, just like the libc
|
|
||||||
* function printf.
|
|
||||||
*/
|
|
||||||
void printk(const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
int c, d;
|
|
||||||
char buf[20];
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
while ((c = *format++) != 0) {
|
|
||||||
char *p;
|
|
||||||
if (c != '%') {
|
|
||||||
putchar(c);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = *format++;
|
|
||||||
switch (c) {
|
|
||||||
case 'd':
|
|
||||||
case 'u':
|
|
||||||
case 'x':
|
|
||||||
d = va_arg(ap, int);
|
|
||||||
itoa(buf, c, d);
|
|
||||||
p = buf;
|
|
||||||
goto string;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 's':
|
|
||||||
p = va_arg(ap, char *);
|
|
||||||
if (!p)
|
|
||||||
p = "(null)";
|
|
||||||
|
|
||||||
string:
|
|
||||||
while (*p)
|
|
||||||
putchar(*p++);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
putchar(va_arg(ap, int));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* memset might be a macro or alike. Disable it to be sure */
|
|
||||||
#undef memset
|
|
||||||
|
|
||||||
void *memset(void *s, int c, size_t count)
|
|
||||||
{
|
|
||||||
char *xs = (char *) s;
|
|
||||||
while (count--)
|
|
||||||
*xs++ = c;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *memmove(void *dest, const void *src, size_t count)
|
|
||||||
{
|
|
||||||
char *tmp, *s;
|
|
||||||
if (dest <= src) {
|
|
||||||
tmp = (char *) dest;
|
|
||||||
s = (char *) src;
|
|
||||||
while (count--)
|
|
||||||
*tmp++ = *s++;
|
|
||||||
} else {
|
|
||||||
tmp = (char *) dest + count;
|
|
||||||
s = (char *) src + count;
|
|
||||||
while (count--)
|
|
||||||
*--tmp = *--s;
|
|
||||||
}
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_GDB
|
|
||||||
void *memcpy(void *dest, const void *src, size_t count)
|
|
||||||
{
|
|
||||||
char *tmp = (char *) dest, *s = (char *) src;
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
*tmp++ = *s++;
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef strncmp
|
|
||||||
int strncmp(const char *cs, const char *ct, size_t count)
|
|
||||||
{
|
|
||||||
register signed char __res = 0;
|
|
||||||
|
|
||||||
while (count) {
|
|
||||||
if ((__res = *cs - *ct++) != 0 || !*cs++)
|
|
||||||
break;
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return __res;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t strlen(const char *s)
|
|
||||||
{
|
|
||||||
const char *sc;
|
|
||||||
|
|
||||||
for (sc = s; *sc != '\0'; ++sc)
|
|
||||||
/* nothing */ ;
|
|
||||||
return sc - s;
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,35 +0,0 @@
|
||||||
|
|
||||||
// 32k heap
|
|
||||||
|
|
||||||
|
|
||||||
void printk(const char *fmt, ...);
|
|
||||||
#define error printk
|
|
||||||
|
|
||||||
static unsigned long free_mem_ptr = 0x20000; /* Start of heap */
|
|
||||||
static unsigned long free_mem_end_ptr = 0x28000; /* End of heap */
|
|
||||||
|
|
||||||
|
|
||||||
void *malloc(unsigned int size)
|
|
||||||
{
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
if (size < 0)
|
|
||||||
error("Error! malloc: Size < 0");
|
|
||||||
if (free_mem_ptr <= 0)
|
|
||||||
error("Error! malloc: Free_mem_ptr <= 0");
|
|
||||||
|
|
||||||
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
|
|
||||||
|
|
||||||
p = (void *) free_mem_ptr;
|
|
||||||
free_mem_ptr += size;
|
|
||||||
|
|
||||||
if (free_mem_ptr >= free_mem_end_ptr)
|
|
||||||
error("Error! malloc: Free_mem_ptr >= free_mem_end_ptr");
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free(void *where)
|
|
||||||
{
|
|
||||||
/* Don't care */
|
|
||||||
}
|
|
|
@ -1,155 +0,0 @@
|
||||||
/*
|
|
||||||
* pcibios code from linuxbios
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <pci.h>
|
|
||||||
#undef __KERNEL__
|
|
||||||
#include <io.h>
|
|
||||||
|
|
||||||
void printk(const char *fmt, ...);
|
|
||||||
|
|
||||||
#define printk_debug printk
|
|
||||||
#define printk_err printk
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CHECK = 0xb001,
|
|
||||||
FINDDEV = 0xb102,
|
|
||||||
READCONFBYTE = 0xb108,
|
|
||||||
READCONFWORD = 0xb109,
|
|
||||||
READCONFDWORD = 0xb10a,
|
|
||||||
WRITECONFBYTE = 0xb10b,
|
|
||||||
WRITECONFWORD = 0xb10c,
|
|
||||||
WRITECONFDWORD = 0xb10d
|
|
||||||
};
|
|
||||||
|
|
||||||
// errors go in AH. Just set these up so that word assigns
|
|
||||||
// will work. KISS.
|
|
||||||
enum {
|
|
||||||
PCIBIOS_NODEV = 0x8600,
|
|
||||||
PCIBIOS_BADREG = 0x8700
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
pcibios(
|
|
||||||
unsigned long *pedi,
|
|
||||||
unsigned long *pesi,
|
|
||||||
unsigned long *pebp,
|
|
||||||
unsigned long *pesp,
|
|
||||||
unsigned long *pebx,
|
|
||||||
unsigned long *pedx,
|
|
||||||
unsigned long *pecx,
|
|
||||||
unsigned long *peax,
|
|
||||||
unsigned long *pflags
|
|
||||||
) {
|
|
||||||
unsigned long edi = *pedi;
|
|
||||||
unsigned long esi = *pesi;
|
|
||||||
unsigned long ebp = *pebp;
|
|
||||||
unsigned long esp = *pesp;
|
|
||||||
unsigned long ebx = *pebx;
|
|
||||||
unsigned long edx = *pedx;
|
|
||||||
unsigned long ecx = *pecx;
|
|
||||||
unsigned long eax = *peax;
|
|
||||||
unsigned long flags = *pflags;
|
|
||||||
unsigned short func = (unsigned short) eax;
|
|
||||||
int retval = -1;
|
|
||||||
unsigned short devid, vendorid, devfn;
|
|
||||||
short devindex; /* Use short to get rid of gabage in upper half of 32-bit register */
|
|
||||||
unsigned char bus;
|
|
||||||
struct pci_dev *dev;
|
|
||||||
|
|
||||||
switch(func) {
|
|
||||||
case CHECK:
|
|
||||||
*pedx = 0x4350;
|
|
||||||
*pecx = 0x2049;
|
|
||||||
retval = 0;
|
|
||||||
break;
|
|
||||||
case FINDDEV:
|
|
||||||
{
|
|
||||||
devid = *pecx;
|
|
||||||
vendorid = *pedx;
|
|
||||||
devindex = *pesi;
|
|
||||||
dev = 0;
|
|
||||||
while ((dev = pci_find_device(vendorid, devid, dev))) {
|
|
||||||
if (devindex <= 0)
|
|
||||||
break;
|
|
||||||
devindex--;
|
|
||||||
}
|
|
||||||
if (dev) {
|
|
||||||
unsigned short busdevfn;
|
|
||||||
*peax = 0;
|
|
||||||
// busnum is an unsigned char;
|
|
||||||
// devfn is an int, so we mask it off.
|
|
||||||
busdevfn = (dev->bus << 8)
|
|
||||||
| (dev->devfn & 0xff);
|
|
||||||
printk_debug("0x%x: return 0x%x\n", func, busdevfn);
|
|
||||||
*pebx = busdevfn;
|
|
||||||
retval = 0;
|
|
||||||
} else {
|
|
||||||
*peax = PCIBIOS_NODEV;
|
|
||||||
retval = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case READCONFDWORD:
|
|
||||||
case READCONFWORD:
|
|
||||||
case READCONFBYTE:
|
|
||||||
case WRITECONFDWORD:
|
|
||||||
case WRITECONFWORD:
|
|
||||||
case WRITECONFBYTE:
|
|
||||||
{
|
|
||||||
unsigned int dword;
|
|
||||||
unsigned short word;
|
|
||||||
unsigned char byte;
|
|
||||||
unsigned char reg;
|
|
||||||
|
|
||||||
devfn = *pebx & 0xff;
|
|
||||||
bus = *pebx >> 8;
|
|
||||||
reg = *pedi;
|
|
||||||
dev = pci_find_slot(bus, devfn);
|
|
||||||
if (! dev) {
|
|
||||||
printk_debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, bus, devfn);
|
|
||||||
// idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
|
|
||||||
*peax = PCIBIOS_BADREG;
|
|
||||||
retval = -1;
|
|
||||||
}
|
|
||||||
switch(func) {
|
|
||||||
case READCONFBYTE:
|
|
||||||
retval = pci_read_config_byte(dev, reg, &byte);
|
|
||||||
*pecx = byte;
|
|
||||||
break;
|
|
||||||
case READCONFWORD:
|
|
||||||
retval = pci_read_config_word(dev, reg, &word);
|
|
||||||
*pecx = word;
|
|
||||||
break;
|
|
||||||
case READCONFDWORD:
|
|
||||||
retval = pci_read_config_dword(dev, reg, &dword);
|
|
||||||
*pecx = dword;
|
|
||||||
break;
|
|
||||||
case WRITECONFBYTE:
|
|
||||||
byte = *pecx;
|
|
||||||
retval = pci_write_config_byte(dev, reg, byte);
|
|
||||||
break;
|
|
||||||
case WRITECONFWORD:
|
|
||||||
word = *pecx;
|
|
||||||
retval = pci_write_config_word(dev, reg, word);
|
|
||||||
break;
|
|
||||||
case WRITECONFDWORD:
|
|
||||||
word = *pecx;
|
|
||||||
retval = pci_write_config_dword(dev, reg, dword);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retval)
|
|
||||||
retval = PCIBIOS_BADREG;
|
|
||||||
printk_debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%lx\n", func, bus, devfn, reg, *pecx);
|
|
||||||
*peax = 0;
|
|
||||||
retval = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printk_err("UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
|
@ -1,137 +0,0 @@
|
||||||
#include <types.h>
|
|
||||||
#include <io.h>
|
|
||||||
#include <x86emu.h>
|
|
||||||
#include <x86glue.h>
|
|
||||||
|
|
||||||
void printk(const char *fmt, ...);
|
|
||||||
void x86emu_dump_xregs(void);
|
|
||||||
void pci_init(void);
|
|
||||||
|
|
||||||
int int10_handler(void);
|
|
||||||
int int1a_handler(void);
|
|
||||||
|
|
||||||
void pushw(u16 val);
|
|
||||||
unsigned char biosmem[1024 * 1024];
|
|
||||||
int verbose = 0;
|
|
||||||
|
|
||||||
u8 x_inb(u16 port)
|
|
||||||
{
|
|
||||||
return inb(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 x_inw(u16 port)
|
|
||||||
{
|
|
||||||
return inw(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 x_inl(u16 port)
|
|
||||||
{
|
|
||||||
return inb(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void x_outb(u16 port, u8 val)
|
|
||||||
{
|
|
||||||
outb(port, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void x_outw(u16 port, u16 val)
|
|
||||||
{
|
|
||||||
outb(port, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void x_outl(u16 port, u32 val)
|
|
||||||
{
|
|
||||||
outb(port, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
X86EMU_pioFuncs myfuncs = {
|
|
||||||
x_inb, x_inw, x_inl,
|
|
||||||
x_outb, x_outw, x_outl
|
|
||||||
};
|
|
||||||
|
|
||||||
void irq_multiplexer(int num)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
switch (num) {
|
|
||||||
case 0x10:
|
|
||||||
case 0x42:
|
|
||||||
case 0x6d:
|
|
||||||
ret = int10_handler();
|
|
||||||
break;
|
|
||||||
case 0x1a:
|
|
||||||
ret = int1a_handler();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
|
||||||
printk("int%x not implemented\n", num);
|
|
||||||
x86emu_dump_xregs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr current = 0;
|
|
||||||
int startrom(unsigned char *addr)
|
|
||||||
{
|
|
||||||
X86EMU_intrFuncs intFuncs[256];
|
|
||||||
void X86EMU_setMemBase(void *base, size_t size);
|
|
||||||
int trace = 1;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
int devfn=0x18; // FIXME
|
|
||||||
int size=64*1024; // FIXME
|
|
||||||
int initialcs=0xc000;
|
|
||||||
int initialip=0x0003;
|
|
||||||
int base=0xc0000;
|
|
||||||
|
|
||||||
X86EMU_setMemBase(biosmem, sizeof(biosmem));
|
|
||||||
X86EMU_setupPioFuncs(&myfuncs);
|
|
||||||
pci_init();
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
intFuncs[i] = irq_multiplexer;
|
|
||||||
X86EMU_setupIntrFuncs(intFuncs);
|
|
||||||
|
|
||||||
|
|
||||||
current->ax = devfn ? devfn : 0xff; // FIXME
|
|
||||||
/* above we need to search the device on the bus */
|
|
||||||
|
|
||||||
current->dx = 0x80;
|
|
||||||
// current->ip = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
|
||||||
wrb(base + i, addr[i]);
|
|
||||||
|
|
||||||
/* cpu setup */
|
|
||||||
X86_AX = devfn ? devfn : 0xff;
|
|
||||||
X86_DX = 0x80;
|
|
||||||
X86_EIP = initialip;
|
|
||||||
X86_CS = initialcs;
|
|
||||||
|
|
||||||
/* Initialize stack and data segment */
|
|
||||||
X86_SS = 0x0030;
|
|
||||||
X86_DS = 0x0040;
|
|
||||||
X86_SP = 0xfffe;
|
|
||||||
|
|
||||||
/* We need a sane way to return from bios
|
|
||||||
* execution. A hlt instruction and a pointer
|
|
||||||
* to it, both kept on the stack, will do.
|
|
||||||
*/
|
|
||||||
|
|
||||||
pushw(0xf4f4); /* hlt; hlt */
|
|
||||||
pushw(X86_SS);
|
|
||||||
pushw(X86_SP + 2);
|
|
||||||
|
|
||||||
X86_ES = 0x0000;
|
|
||||||
|
|
||||||
if (trace) {
|
|
||||||
printk("Switching to single step mode.\n");
|
|
||||||
X86EMU_trace_on();
|
|
||||||
}
|
|
||||||
|
|
||||||
X86EMU_exec();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
place your roms here
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* bin2hex - binary to hexadecimal converter
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* 8 values per line */
|
|
||||||
#define SPLIT 8
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int c, i;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while ((c = getchar()) != EOF) {
|
|
||||||
if ((i % SPLIT) != 0) {
|
|
||||||
putchar(' ');
|
|
||||||
}
|
|
||||||
printf("0x%02x,", c);
|
|
||||||
i++;
|
|
||||||
if ((i % SPLIT) == 0) {
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
putchar('\n');
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// tag: bin2hex
|
|
|
@ -1,68 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Copyright (C) 2003 Stefan Reinauer
|
|
||||||
#
|
|
||||||
# See the file "COPYING" for further information about
|
|
||||||
# the copyright and warranty status of this work.
|
|
||||||
#
|
|
||||||
# tag: target system test script.
|
|
||||||
|
|
||||||
if [ "$CC" == "" ]; then
|
|
||||||
CC=gcc
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "void *pointersize;" > types.c
|
|
||||||
${CC} -c -o types.o types.c
|
|
||||||
PTRSIZE=$(( 8 * 0x`nm types.o| grep pointersize | cut -f1 -d\ ` ))
|
|
||||||
rm -f types.c types.o
|
|
||||||
|
|
||||||
case "$PTRSIZE" in
|
|
||||||
32) cell="int32_t "; ucell="uint32_t ";
|
|
||||||
dcell="int64_t "; ducell="uint64_t"
|
|
||||||
;;
|
|
||||||
64) cell="int64_t "; ucell="uint64_t "
|
|
||||||
dcell="__int128_t "; ducell="__uint128_t"
|
|
||||||
;;
|
|
||||||
*) echo "Unsupported ${PTRSIZE}bit platform. please report."; exit 1 ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
echo -e "found ${PTRSIZE}bit platform, creating \"types.h\""
|
|
||||||
|
|
||||||
echo "/* tag: data types for forth engine
|
|
||||||
*
|
|
||||||
* This file is autogenerated by types.sh. Do not edit!
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Patrick Mauritz, Stefan Reinauer
|
|
||||||
*
|
|
||||||
* See the file \"COPYING\" for further information about
|
|
||||||
* the copyright and warranty status of this work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __TYPES_H
|
|
||||||
#define __TYPES_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/* cell based types */
|
|
||||||
|
|
||||||
typedef $cell cell;
|
|
||||||
typedef $ucell ucell;
|
|
||||||
typedef $dcell dcell;
|
|
||||||
typedef $ducell ducell;
|
|
||||||
|
|
||||||
#define bitspercell (sizeof(cell)<<3)
|
|
||||||
#define bitsperdcell (sizeof(dcell)<<3)
|
|
||||||
|
|
||||||
/* size named types */
|
|
||||||
|
|
||||||
typedef unsigned char u8;
|
|
||||||
typedef unsigned short u16;
|
|
||||||
typedef unsigned int u32;
|
|
||||||
|
|
||||||
typedef char s8;
|
|
||||||
typedef short s16;
|
|
||||||
typedef int s32;
|
|
||||||
|
|
||||||
#endif" > types.h.new
|
|
||||||
|
|
||||||
test -r types.h || mv types.h.new types.h
|
|
Loading…
Reference in New Issue