Bye bye Soft386, welcome Fast486, courtesy Aleksandar Andrejevic.

[NTVDM]: Define by default NEW_EMULATOR, i.e. use Fast486 instead of softx86.

svn path=/branches/ntvdm/; revision=60703
This commit is contained in:
Hermès Bélusca-Maïto 2013-10-19 16:55:51 +00:00
parent 9b02129308
commit 51040fc61e
21 changed files with 2662 additions and 2662 deletions

View file

@ -0,0 +1,397 @@
/*
* Fast486 386/486 CPU Emulation Library
* fast486.h
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _FAST486_H_
#define _FAST486_H_
/* DEFINES ********************************************************************/
#define FAST486_NUM_GEN_REGS 8
#define FAST486_NUM_SEG_REGS 6
#define FAST486_NUM_CTRL_REGS 8
#define FAST486_NUM_DBG_REGS 8
#define FAST486_CR0_PE (1 << 0)
#define FAST486_CR0_MP (1 << 1)
#define FAST486_CR0_EM (1 << 2)
#define FAST486_CR0_TS (1 << 3)
#define FAST486_CR0_ET (1 << 4)
#define FAST486_CR0_NE (1 << 5)
#define FAST486_CR0_WP (1 << 16)
#define FAST486_CR0_AM (1 << 18)
#define FAST486_CR0_NW (1 << 29)
#define FAST486_CR0_CD (1 << 30)
#define FAST486_CR0_PG (1 << 31)
#define FAST486_IDT_TASK_GATE 0x5
#define FAST486_IDT_INT_GATE 0x6
#define FAST486_IDT_TRAP_GATE 0x7
#define FAST486_IDT_INT_GATE_32 0xE
#define FAST486_IDT_TRAP_GATE_32 0xF
#define FAST486_PREFIX_SEG (1 << 0)
#define FAST486_PREFIX_OPSIZE (1 << 1)
#define FAST486_PREFIX_ADSIZE (1 << 2)
#define FAST486_PREFIX_LOCK (1 << 3)
#define FAST486_PREFIX_REPNZ (1 << 4)
#define FAST486_PREFIX_REP (1 << 5)
struct _FAST486_STATE;
typedef struct _FAST486_STATE FAST486_STATE, *PFAST486_STATE;
typedef enum _FAST486_GEN_REGS
{
FAST486_REG_EAX,
FAST486_REG_ECX,
FAST486_REG_EDX,
FAST486_REG_EBX,
FAST486_REG_ESP,
FAST486_REG_EBP,
FAST486_REG_ESI,
FAST486_REG_EDI
} FAST486_GEN_REGS, *PFAST486_GEN_REGS;
typedef enum _FAST486_SEG_REGS
{
FAST486_REG_ES,
FAST486_REG_CS,
FAST486_REG_SS,
FAST486_REG_DS,
FAST486_REG_FS,
FAST486_REG_GS
} FAST486_SEG_REGS, *PFAST486_SEG_REGS;
typedef enum _FAST486_CTRL_REGS
{
FAST486_REG_CR0,
FAST486_REG_CR1,
FAST486_REG_CR2,
FAST486_REG_CR3,
FAST486_REG_CR4,
FAST486_REG_CR5,
FAST486_REG_CR6,
FAST486_REG_CR7
} FAST486_CTRL_REGS, *PFAST486_CTRL_REGS;
typedef enum _FAST486_DBG_REGS
{
FAST486_REG_DR0,
FAST486_REG_DR1,
FAST486_REG_DR2,
FAST486_REG_DR3,
FAST486_REG_DR4,
FAST486_REG_DR5,
FAST486_REG_DR6,
FAST486_REG_DR7
} FAST486_DBG_REGS, *PFAST486_DBG_REGS;
typedef enum _FAST486_EXCEPTIONS
{
FAST486_EXCEPTION_DE = 0x00,
FAST486_EXCEPTION_DB = 0x01,
FAST486_EXCEPTION_BP = 0x03,
FAST486_EXCEPTION_OF = 0x04,
FAST486_EXCEPTION_BR = 0x05,
FAST486_EXCEPTION_UD = 0x06,
FAST486_EXCEPTION_NM = 0x07,
FAST486_EXCEPTION_DF = 0x08,
FAST486_EXCEPTION_TS = 0x0A,
FAST486_EXCEPTION_NP = 0x0B,
FAST486_EXCEPTION_SS = 0x0C,
FAST486_EXCEPTION_GP = 0x0D,
FAST486_EXCEPTION_PF = 0x0E,
FAST486_EXCEPTION_MF = 0x10,
FAST486_EXCEPTION_AC = 0x11,
FAST486_EXCEPTION_MC = 0x12
} FAST486_EXCEPTIONS, *PFAST486_EXCEPTIONS;
typedef
BOOLEAN
(NTAPI *FAST486_MEM_READ_PROC)
(
PFAST486_STATE State,
ULONG Address,
PVOID Buffer,
ULONG Size
);
typedef
BOOLEAN
(NTAPI *FAST486_MEM_WRITE_PROC)
(
PFAST486_STATE State,
ULONG Address,
PVOID Buffer,
ULONG Size
);
typedef
VOID
(NTAPI *FAST486_IO_READ_PROC)
(
PFAST486_STATE State,
ULONG Port,
PVOID Buffer,
ULONG Size
);
typedef
VOID
(NTAPI *FAST486_IO_WRITE_PROC)
(
PFAST486_STATE State,
ULONG Port,
PVOID Buffer,
ULONG Size
);
typedef
VOID
(NTAPI *FAST486_IDLE_PROC)
(
PFAST486_STATE State
);
typedef
VOID
(NTAPI *FAST486_BOP_PROC)
(
PFAST486_STATE State,
USHORT BopCode
);
typedef union _FAST486_REG
{
union
{
struct
{
UCHAR LowByte;
UCHAR HighByte;
};
USHORT LowWord;
};
ULONG Long;
} FAST486_REG, *PFAST486_REG;
typedef struct _FAST486_SEG_REG
{
USHORT Selector;
/* Descriptor cache */
ULONG Accessed : 1;
ULONG ReadWrite : 1;
ULONG DirConf : 1;
ULONG Executable : 1;
ULONG SystemType : 1;
ULONG Dpl : 2;
ULONG Present : 1;
ULONG Size : 1;
ULONG Limit;
ULONG Base;
} FAST486_SEG_REG, *PFAST486_SEG_REG;
typedef struct
{
ULONG Limit : 16;
ULONG Base : 24;
ULONG Accessed : 1;
ULONG ReadWrite : 1;
ULONG DirConf : 1;
ULONG Executable : 1;
ULONG SystemType : 1;
ULONG Dpl : 2;
ULONG Present : 1;
ULONG LimitHigh : 4;
ULONG Avl : 1;
ULONG Reserved : 1;
ULONG Size : 1;
ULONG Granularity : 1;
ULONG BaseHigh : 8;
} FAST486_GDT_ENTRY, *PFAST486_GDT_ENTRY;
typedef struct
{
ULONG Offset : 16;
ULONG Selector : 16;
ULONG ParamCount : 5;
ULONG Reserved : 3;
ULONG Type : 4;
ULONG SystemType : 1;
ULONG Dpl : 2;
ULONG Present : 1;
ULONG OffsetHigh : 16;
} FAST486_CALL_GATE, *PFAST486_CALL_GATE;
typedef struct
{
ULONG Offset : 16;
ULONG Selector : 16;
ULONG Zero : 8;
ULONG Type : 4;
ULONG Storage : 1;
ULONG Dpl : 2;
ULONG Present : 1;
ULONG OffsetHigh : 16;
} FAST486_IDT_ENTRY, *PFAST486_IDT_ENTRY;
typedef struct _FAST486_TABLE_REG
{
USHORT Size;
ULONG Address;
} FAST486_TABLE_REG, *PFAST486_TABLE_REG;
typedef union _FAST486_FLAGS_REG
{
USHORT LowWord;
ULONG Long;
struct
{
ULONG Cf : 1;
ULONG AlwaysSet : 1;
ULONG Pf : 1;
ULONG Reserved0 : 1;
ULONG Af : 1;
ULONG Reserved1 : 1;
ULONG Zf : 1;
ULONG Sf : 1;
ULONG Tf : 1;
ULONG If : 1;
ULONG Df : 1;
ULONG Of : 1;
ULONG Iopl : 2;
ULONG Nt : 1;
ULONG Reserved2 : 1;
ULONG Rf : 1;
ULONG Vm : 1;
ULONG Ac : 1;
ULONG Vif : 1;
ULONG Vip : 1;
ULONG Id : 1;
// ULONG Reserved : 10;
};
} FAST486_FLAGS_REG, *PFAST486_FLAGS_REG;
typedef struct _FAST486_TSS
{
ULONG Link;
ULONG Esp0;
ULONG Ss0;
ULONG Esp1;
ULONG Ss1;
ULONG Esp2;
ULONG Ss2;
ULONG Cr3;
ULONG Eip;
ULONG Eflags;
ULONG Eax;
ULONG Ecx;
ULONG Edx;
ULONG Ebx;
ULONG Esp;
ULONG Ebp;
ULONG Esi;
ULONG Edi;
ULONG Es;
ULONG Cs;
ULONG Ss;
ULONG Ds;
ULONG Fs;
ULONG Gs;
ULONG Ldtr;
ULONG IopbOffset;
} FAST486_TSS, *PFAST486_TSS;
struct _FAST486_STATE
{
FAST486_MEM_READ_PROC MemReadCallback;
FAST486_MEM_WRITE_PROC MemWriteCallback;
FAST486_IO_READ_PROC IoReadCallback;
FAST486_IO_WRITE_PROC IoWriteCallback;
FAST486_IDLE_PROC IdleCallback;
FAST486_BOP_PROC BopCallback;
FAST486_REG GeneralRegs[FAST486_NUM_GEN_REGS];
FAST486_SEG_REG SegmentRegs[FAST486_NUM_SEG_REGS];
FAST486_REG InstPtr, SavedInstPtr;
FAST486_FLAGS_REG Flags;
FAST486_TABLE_REG Gdtr, Idtr, Ldtr, Tss;
ULONGLONG TimeStampCounter;
ULONG ControlRegisters[FAST486_NUM_CTRL_REGS];
ULONG DebugRegisters[FAST486_NUM_DBG_REGS];
ULONG ExceptionCount;
ULONG PrefixFlags;
FAST486_SEG_REGS SegmentOverride;
BOOLEAN HardwareInt;
UCHAR PendingIntNum;
};
/* FUNCTIONS ******************************************************************/
VOID
NTAPI
Fast486Continue(PFAST486_STATE State);
VOID
NTAPI
Fast486StepInto(PFAST486_STATE State);
VOID
NTAPI
Fast486StepOver(PFAST486_STATE State);
VOID
NTAPI
Fast486StepOut(PFAST486_STATE State);
VOID
NTAPI
Fast486DumpState(PFAST486_STATE State);
VOID
NTAPI
Fast486Reset(PFAST486_STATE State);
VOID
NTAPI
Fast486Interrupt(PFAST486_STATE State, UCHAR Number);
VOID
NTAPI
Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset);
VOID
NTAPI
Fast486SetStack(PFAST486_STATE State, USHORT Segment, ULONG Offset);
VOID
NTAPI
Fast486SetSegment
(
PFAST486_STATE State,
FAST486_SEG_REGS Segment,
USHORT Selector
);
#endif // _FAST486_H_
/* EOF */

View file

@ -1,397 +0,0 @@
/*
* Soft386 386/486 CPU Emulation Library
* soft386.h
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _SOFT386_H_
#define _SOFT386_H_
/* DEFINES ********************************************************************/
#define SOFT386_NUM_GEN_REGS 8
#define SOFT386_NUM_SEG_REGS 6
#define SOFT386_NUM_CTRL_REGS 8
#define SOFT386_NUM_DBG_REGS 8
#define SOFT386_CR0_PE (1 << 0)
#define SOFT386_CR0_MP (1 << 1)
#define SOFT386_CR0_EM (1 << 2)
#define SOFT386_CR0_TS (1 << 3)
#define SOFT386_CR0_ET (1 << 4)
#define SOFT386_CR0_NE (1 << 5)
#define SOFT386_CR0_WP (1 << 16)
#define SOFT386_CR0_AM (1 << 18)
#define SOFT386_CR0_NW (1 << 29)
#define SOFT386_CR0_CD (1 << 30)
#define SOFT386_CR0_PG (1 << 31)
#define SOFT386_IDT_TASK_GATE 0x5
#define SOFT386_IDT_INT_GATE 0x6
#define SOFT386_IDT_TRAP_GATE 0x7
#define SOFT386_IDT_INT_GATE_32 0xE
#define SOFT386_IDT_TRAP_GATE_32 0xF
#define SOFT386_PREFIX_SEG (1 << 0)
#define SOFT386_PREFIX_OPSIZE (1 << 1)
#define SOFT386_PREFIX_ADSIZE (1 << 2)
#define SOFT386_PREFIX_LOCK (1 << 3)
#define SOFT386_PREFIX_REPNZ (1 << 4)
#define SOFT386_PREFIX_REP (1 << 5)
struct _SOFT386_STATE;
typedef struct _SOFT386_STATE SOFT386_STATE, *PSOFT386_STATE;
typedef enum _SOFT386_GEN_REGS
{
SOFT386_REG_EAX,
SOFT386_REG_ECX,
SOFT386_REG_EDX,
SOFT386_REG_EBX,
SOFT386_REG_ESP,
SOFT386_REG_EBP,
SOFT386_REG_ESI,
SOFT386_REG_EDI
} SOFT386_GEN_REGS, *PSOFT386_GEN_REGS;
typedef enum _SOFT386_SEG_REGS
{
SOFT386_REG_ES,
SOFT386_REG_CS,
SOFT386_REG_SS,
SOFT386_REG_DS,
SOFT386_REG_FS,
SOFT386_REG_GS
} SOFT386_SEG_REGS, *PSOFT386_SEG_REGS;
typedef enum _SOFT386_CTRL_REGS
{
SOFT386_REG_CR0,
SOFT386_REG_CR1,
SOFT386_REG_CR2,
SOFT386_REG_CR3,
SOFT386_REG_CR4,
SOFT386_REG_CR5,
SOFT386_REG_CR6,
SOFT386_REG_CR7
} SOFT386_CTRL_REGS, *PSOFT386_CTRL_REGS;
typedef enum _SOFT386_DBG_REGS
{
SOFT386_REG_DR0,
SOFT386_REG_DR1,
SOFT386_REG_DR2,
SOFT386_REG_DR3,
SOFT386_REG_DR4,
SOFT386_REG_DR5,
SOFT386_REG_DR6,
SOFT386_REG_DR7
} SOFT386_DBG_REGS, *PSOFT386_DBG_REGS;
typedef enum _SOFT386_EXCEPTIONS
{
SOFT386_EXCEPTION_DE = 0x00,
SOFT386_EXCEPTION_DB = 0x01,
SOFT386_EXCEPTION_BP = 0x03,
SOFT386_EXCEPTION_OF = 0x04,
SOFT386_EXCEPTION_BR = 0x05,
SOFT386_EXCEPTION_UD = 0x06,
SOFT386_EXCEPTION_NM = 0x07,
SOFT386_EXCEPTION_DF = 0x08,
SOFT386_EXCEPTION_TS = 0x0A,
SOFT386_EXCEPTION_NP = 0x0B,
SOFT386_EXCEPTION_SS = 0x0C,
SOFT386_EXCEPTION_GP = 0x0D,
SOFT386_EXCEPTION_PF = 0x0E,
SOFT386_EXCEPTION_MF = 0x10,
SOFT386_EXCEPTION_AC = 0x11,
SOFT386_EXCEPTION_MC = 0x12
} SOFT386_EXCEPTIONS, *PSOFT386_EXCEPTIONS;
typedef
BOOLEAN
(NTAPI *SOFT386_MEM_READ_PROC)
(
PSOFT386_STATE State,
ULONG Address,
PVOID Buffer,
ULONG Size
);
typedef
BOOLEAN
(NTAPI *SOFT386_MEM_WRITE_PROC)
(
PSOFT386_STATE State,
ULONG Address,
PVOID Buffer,
ULONG Size
);
typedef
VOID
(NTAPI *SOFT386_IO_READ_PROC)
(
PSOFT386_STATE State,
ULONG Port,
PVOID Buffer,
ULONG Size
);
typedef
VOID
(NTAPI *SOFT386_IO_WRITE_PROC)
(
PSOFT386_STATE State,
ULONG Port,
PVOID Buffer,
ULONG Size
);
typedef
VOID
(NTAPI *SOFT386_IDLE_PROC)
(
PSOFT386_STATE State
);
typedef
VOID
(NTAPI *SOFT386_BOP_PROC)
(
PSOFT386_STATE State,
USHORT BopCode
);
typedef union _SOFT386_REG
{
union
{
struct
{
UCHAR LowByte;
UCHAR HighByte;
};
USHORT LowWord;
};
ULONG Long;
} SOFT386_REG, *PSOFT386_REG;
typedef struct _SOFT386_SEG_REG
{
USHORT Selector;
/* Descriptor cache */
ULONG Accessed : 1;
ULONG ReadWrite : 1;
ULONG DirConf : 1;
ULONG Executable : 1;
ULONG SystemType : 1;
ULONG Dpl : 2;
ULONG Present : 1;
ULONG Size : 1;
ULONG Limit;
ULONG Base;
} SOFT386_SEG_REG, *PSOFT386_SEG_REG;
typedef struct
{
ULONG Limit : 16;
ULONG Base : 24;
ULONG Accessed : 1;
ULONG ReadWrite : 1;
ULONG DirConf : 1;
ULONG Executable : 1;
ULONG SystemType : 1;
ULONG Dpl : 2;
ULONG Present : 1;
ULONG LimitHigh : 4;
ULONG Avl : 1;
ULONG Reserved : 1;
ULONG Size : 1;
ULONG Granularity : 1;
ULONG BaseHigh : 8;
} SOFT386_GDT_ENTRY, *PSOFT386_GDT_ENTRY;
typedef struct
{
ULONG Offset : 16;
ULONG Selector : 16;
ULONG ParamCount : 5;
ULONG Reserved : 3;
ULONG Type : 4;
ULONG SystemType : 1;
ULONG Dpl : 2;
ULONG Present : 1;
ULONG OffsetHigh : 16;
} SOFT386_CALL_GATE, *PSOFT386_CALL_GATE;
typedef struct
{
ULONG Offset : 16;
ULONG Selector : 16;
ULONG Zero : 8;
ULONG Type : 4;
ULONG Storage : 1;
ULONG Dpl : 2;
ULONG Present : 1;
ULONG OffsetHigh : 16;
} SOFT386_IDT_ENTRY, *PSOFT386_IDT_ENTRY;
typedef struct _SOFT386_TABLE_REG
{
USHORT Size;
ULONG Address;
} SOFT386_TABLE_REG, *PSOFT386_TABLE_REG;
typedef union _SOFT386_FLAGS_REG
{
USHORT LowWord;
ULONG Long;
struct
{
ULONG Cf : 1;
ULONG AlwaysSet : 1;
ULONG Pf : 1;
ULONG Reserved0 : 1;
ULONG Af : 1;
ULONG Reserved1 : 1;
ULONG Zf : 1;
ULONG Sf : 1;
ULONG Tf : 1;
ULONG If : 1;
ULONG Df : 1;
ULONG Of : 1;
ULONG Iopl : 2;
ULONG Nt : 1;
ULONG Reserved2 : 1;
ULONG Rf : 1;
ULONG Vm : 1;
ULONG Ac : 1;
ULONG Vif : 1;
ULONG Vip : 1;
ULONG Id : 1;
// ULONG Reserved : 10;
};
} SOFT386_FLAGS_REG, *PSOFT386_FLAGS_REG;
typedef struct _SOFT386_TSS
{
ULONG Link;
ULONG Esp0;
ULONG Ss0;
ULONG Esp1;
ULONG Ss1;
ULONG Esp2;
ULONG Ss2;
ULONG Cr3;
ULONG Eip;
ULONG Eflags;
ULONG Eax;
ULONG Ecx;
ULONG Edx;
ULONG Ebx;
ULONG Esp;
ULONG Ebp;
ULONG Esi;
ULONG Edi;
ULONG Es;
ULONG Cs;
ULONG Ss;
ULONG Ds;
ULONG Fs;
ULONG Gs;
ULONG Ldtr;
ULONG IopbOffset;
} SOFT386_TSS, *PSOFT386_TSS;
struct _SOFT386_STATE
{
SOFT386_MEM_READ_PROC MemReadCallback;
SOFT386_MEM_WRITE_PROC MemWriteCallback;
SOFT386_IO_READ_PROC IoReadCallback;
SOFT386_IO_WRITE_PROC IoWriteCallback;
SOFT386_IDLE_PROC IdleCallback;
SOFT386_BOP_PROC BopCallback;
SOFT386_REG GeneralRegs[SOFT386_NUM_GEN_REGS];
SOFT386_SEG_REG SegmentRegs[SOFT386_NUM_SEG_REGS];
SOFT386_REG InstPtr, SavedInstPtr;
SOFT386_FLAGS_REG Flags;
SOFT386_TABLE_REG Gdtr, Idtr, Ldtr, Tss;
ULONGLONG TimeStampCounter;
ULONG ControlRegisters[SOFT386_NUM_CTRL_REGS];
ULONG DebugRegisters[SOFT386_NUM_DBG_REGS];
ULONG ExceptionCount;
ULONG PrefixFlags;
SOFT386_SEG_REGS SegmentOverride;
BOOLEAN HardwareInt;
UCHAR PendingIntNum;
};
/* FUNCTIONS ******************************************************************/
VOID
NTAPI
Soft386Continue(PSOFT386_STATE State);
VOID
NTAPI
Soft386StepInto(PSOFT386_STATE State);
VOID
NTAPI
Soft386StepOver(PSOFT386_STATE State);
VOID
NTAPI
Soft386StepOut(PSOFT386_STATE State);
VOID
NTAPI
Soft386DumpState(PSOFT386_STATE State);
VOID
NTAPI
Soft386Reset(PSOFT386_STATE State);
VOID
NTAPI
Soft386Interrupt(PSOFT386_STATE State, UCHAR Number);
VOID
NTAPI
Soft386ExecuteAt(PSOFT386_STATE State, USHORT Segment, ULONG Offset);
VOID
NTAPI
Soft386SetStack(PSOFT386_STATE State, USHORT Segment, ULONG Offset);
VOID
NTAPI
Soft386SetSegment
(
PSOFT386_STATE State,
SOFT386_SEG_REGS Segment,
USHORT Selector
);
#endif // _SOFT386_H_
/* EOF */

View file

@ -10,6 +10,7 @@ add_subdirectory(cportlib)
#add_subdirectory(dnslib) Nothing links to this lib.
add_subdirectory(drivers)
add_subdirectory(epsapi)
add_subdirectory(fast486)
add_subdirectory(fslib)
add_subdirectory(lsalib)
add_subdirectory(ppcmmu)
@ -24,7 +25,6 @@ add_subdirectory(rtl)
add_subdirectory(sdk)
add_subdirectory(smlib)
add_subdirectory(tdilib)
add_subdirectory(soft386)
else()

View file

@ -0,0 +1,11 @@
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs/fast486)
list(APPEND SOURCE
fast486.c
opcodes.c
opgroups.c
extraops.c
common.c)
add_library(fast486 ${SOURCE})

View file

@ -1,5 +1,5 @@
/*
* Soft386 386/486 CPU Emulation Library
* Fast486 386/486 CPU Emulation Library
* common.c
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
@ -28,14 +28,14 @@
// #define NDEBUG
#include <debug.h>
#include <soft386.h>
#include <fast486.h>
#include "common.h"
/* PRIVATE FUNCTIONS **********************************************************/
static inline
ULONG
Soft386GetPageTableEntry(PSOFT386_STATE State,
Fast486GetPageTableEntry(PFAST486_STATE State,
ULONG VirtualAddress)
{
// TODO: NOT IMPLEMENTED
@ -47,18 +47,18 @@ Soft386GetPageTableEntry(PSOFT386_STATE State,
/* PUBLIC FUNCTIONS ***********************************************************/
BOOLEAN
Soft386ReadMemory(PSOFT386_STATE State,
SOFT386_SEG_REGS SegmentReg,
Fast486ReadMemory(PFAST486_STATE State,
FAST486_SEG_REGS SegmentReg,
ULONG Offset,
BOOLEAN InstFetch,
PVOID Buffer,
ULONG Size)
{
ULONG LinearAddress;
PSOFT386_SEG_REG CachedDescriptor;
INT Cpl = Soft386GetCurrentPrivLevel(State);
PFAST486_SEG_REG CachedDescriptor;
INT Cpl = Fast486GetCurrentPrivLevel(State);
ASSERT(SegmentReg < SOFT386_NUM_SEG_REGS);
ASSERT(SegmentReg < FAST486_NUM_SEG_REGS);
/* Get the cached descriptor */
CachedDescriptor = &State->SegmentRegs[SegmentReg];
@ -66,25 +66,25 @@ Soft386ReadMemory(PSOFT386_STATE State,
if ((Offset + Size - 1) > CachedDescriptor->Limit)
{
/* Read beyond limit */
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
/* Check for protected mode */
if (State->ControlRegisters[0] & SOFT386_CR0_PE)
if (State->ControlRegisters[0] & FAST486_CR0_PE)
{
/* Privilege checks */
if (!CachedDescriptor->Present)
{
Soft386Exception(State, SOFT386_EXCEPTION_NP);
Fast486Exception(State, FAST486_EXCEPTION_NP);
return FALSE;
}
if (GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl)
{
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
@ -94,7 +94,7 @@ Soft386ReadMemory(PSOFT386_STATE State,
{
/* Data segment not executable */
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
}
@ -104,7 +104,7 @@ Soft386ReadMemory(PSOFT386_STATE State,
{
/* Code segment not readable */
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
}
@ -114,10 +114,10 @@ Soft386ReadMemory(PSOFT386_STATE State,
LinearAddress = CachedDescriptor->Base + Offset;
/* Check if paging is enabled */
if (State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_PG)
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PG)
{
ULONG Page;
SOFT386_PAGE_TABLE TableEntry;
FAST486_PAGE_TABLE TableEntry;
for (Page = PAGE_ALIGN(LinearAddress);
Page <= PAGE_ALIGN(LinearAddress + Size - 1);
@ -126,13 +126,13 @@ Soft386ReadMemory(PSOFT386_STATE State,
ULONG PageOffset = 0, PageLength = PAGE_SIZE;
/* Get the table entry */
TableEntry.Value = Soft386GetPageTableEntry(State, Page);
TableEntry.Value = Fast486GetPageTableEntry(State, Page);
if (!TableEntry.Present || (!TableEntry.Usermode && (Cpl > 0)))
{
/* Exception */
Soft386ExceptionWithErrorCode(State,
SOFT386_EXCEPTION_PF,
Fast486ExceptionWithErrorCode(State,
FAST486_EXCEPTION_PF,
TableEntry.Value & 0x07);
return FALSE;
}
@ -188,17 +188,17 @@ Soft386ReadMemory(PSOFT386_STATE State,
}
BOOLEAN
Soft386WriteMemory(PSOFT386_STATE State,
SOFT386_SEG_REGS SegmentReg,
Fast486WriteMemory(PFAST486_STATE State,
FAST486_SEG_REGS SegmentReg,
ULONG Offset,
PVOID Buffer,
ULONG Size)
{
ULONG LinearAddress;
PSOFT386_SEG_REG CachedDescriptor;
INT Cpl = Soft386GetCurrentPrivLevel(State);
PFAST486_SEG_REG CachedDescriptor;
INT Cpl = Fast486GetCurrentPrivLevel(State);
ASSERT(SegmentReg < SOFT386_NUM_SEG_REGS);
ASSERT(SegmentReg < FAST486_NUM_SEG_REGS);
/* Get the cached descriptor */
CachedDescriptor = &State->SegmentRegs[SegmentReg];
@ -206,25 +206,25 @@ Soft386WriteMemory(PSOFT386_STATE State,
if ((Offset + Size - 1) > CachedDescriptor->Limit)
{
/* Write beyond limit */
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
/* Check for protected mode */
if (State->ControlRegisters[0] & SOFT386_CR0_PE)
if (State->ControlRegisters[0] & FAST486_CR0_PE)
{
/* Privilege checks */
if (!CachedDescriptor->Present)
{
Soft386Exception(State, SOFT386_EXCEPTION_NP);
Fast486Exception(State, FAST486_EXCEPTION_NP);
return FALSE;
}
if (GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl)
{
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
@ -232,14 +232,14 @@ Soft386WriteMemory(PSOFT386_STATE State,
{
/* Code segment not writable */
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
else if (!CachedDescriptor->ReadWrite)
{
/* Data segment not writeable */
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
}
@ -248,10 +248,10 @@ Soft386WriteMemory(PSOFT386_STATE State,
LinearAddress = CachedDescriptor->Base + Offset;
/* Check if paging is enabled */
if (State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_PG)
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PG)
{
ULONG Page;
SOFT386_PAGE_TABLE TableEntry;
FAST486_PAGE_TABLE TableEntry;
for (Page = PAGE_ALIGN(LinearAddress);
Page <= PAGE_ALIGN(LinearAddress + Size - 1);
@ -260,15 +260,15 @@ Soft386WriteMemory(PSOFT386_STATE State,
ULONG PageOffset = 0, PageLength = PAGE_SIZE;
/* Get the table entry */
TableEntry.Value = Soft386GetPageTableEntry(State, Page);
TableEntry.Value = Fast486GetPageTableEntry(State, Page);
if ((!TableEntry.Present || (!TableEntry.Usermode && (Cpl > 0)))
|| ((State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_WP)
|| ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_WP)
&& !TableEntry.Writeable))
{
/* Exception */
Soft386ExceptionWithErrorCode(State,
SOFT386_EXCEPTION_PF,
Fast486ExceptionWithErrorCode(State,
FAST486_EXCEPTION_PF,
TableEntry.Value & 0x07);
return FALSE;
}
@ -324,20 +324,20 @@ Soft386WriteMemory(PSOFT386_STATE State,
}
BOOLEAN
Soft386InterruptInternal(PSOFT386_STATE State,
Fast486InterruptInternal(PFAST486_STATE State,
USHORT SegmentSelector,
ULONG Offset,
BOOLEAN InterruptGate)
{
/* Check for protected mode */
if (State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_PE)
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
{
SOFT386_TSS Tss;
USHORT OldSs = State->SegmentRegs[SOFT386_REG_SS].Selector;
ULONG OldEsp = State->GeneralRegs[SOFT386_REG_ESP].Long;
FAST486_TSS Tss;
USHORT OldSs = State->SegmentRegs[FAST486_REG_SS].Selector;
ULONG OldEsp = State->GeneralRegs[FAST486_REG_ESP].Long;
/* Check if the interrupt handler is more privileged */
if (Soft386GetCurrentPrivLevel(State) > GET_SEGMENT_RPL(SegmentSelector))
if (Fast486GetCurrentPrivLevel(State) > GET_SEGMENT_RPL(SegmentSelector))
{
/* Read the TSS */
// FIXME: This code is only correct when paging is disabled!!!
@ -358,36 +358,36 @@ Soft386InterruptInternal(PSOFT386_STATE State,
{
case 0:
{
if (!Soft386LoadSegment(State, SOFT386_REG_SS, Tss.Ss0))
if (!Fast486LoadSegment(State, FAST486_REG_SS, Tss.Ss0))
{
/* Exception occurred */
return FALSE;
}
State->GeneralRegs[SOFT386_REG_ESP].Long = Tss.Esp0;
State->GeneralRegs[FAST486_REG_ESP].Long = Tss.Esp0;
break;
}
case 1:
{
if (!Soft386LoadSegment(State, SOFT386_REG_SS, Tss.Ss1))
if (!Fast486LoadSegment(State, FAST486_REG_SS, Tss.Ss1))
{
/* Exception occurred */
return FALSE;
}
State->GeneralRegs[SOFT386_REG_ESP].Long = Tss.Esp1;
State->GeneralRegs[FAST486_REG_ESP].Long = Tss.Esp1;
break;
}
case 2:
{
if (!Soft386LoadSegment(State, SOFT386_REG_SS, Tss.Ss2))
if (!Fast486LoadSegment(State, FAST486_REG_SS, Tss.Ss2))
{
/* Exception occurred */
return FALSE;
}
State->GeneralRegs[SOFT386_REG_ESP].Long = Tss.Esp2;
State->GeneralRegs[FAST486_REG_ESP].Long = Tss.Esp2;
break;
}
@ -400,21 +400,21 @@ Soft386InterruptInternal(PSOFT386_STATE State,
}
/* Push SS selector */
if (!Soft386StackPush(State, OldSs)) return FALSE;
if (!Fast486StackPush(State, OldSs)) return FALSE;
/* Push stack pointer */
if (!Soft386StackPush(State, OldEsp)) return FALSE;
if (!Fast486StackPush(State, OldEsp)) return FALSE;
}
}
/* Push EFLAGS */
if (!Soft386StackPush(State, State->Flags.Long)) return FALSE;
if (!Fast486StackPush(State, State->Flags.Long)) return FALSE;
/* Push CS selector */
if (!Soft386StackPush(State, State->SegmentRegs[SOFT386_REG_CS].Selector)) return FALSE;
if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector)) return FALSE;
/* Push the instruction pointer */
if (!Soft386StackPush(State, State->InstPtr.Long)) return FALSE;
if (!Fast486StackPush(State, State->InstPtr.Long)) return FALSE;
if (InterruptGate)
{
@ -423,13 +423,13 @@ Soft386InterruptInternal(PSOFT386_STATE State,
}
/* Load new CS */
if (!Soft386LoadSegment(State, SOFT386_REG_CS, SegmentSelector))
if (!Fast486LoadSegment(State, FAST486_REG_CS, SegmentSelector))
{
/* An exception occurred during the jump */
return FALSE;
}
if (State->SegmentRegs[SOFT386_REG_CS].Size)
if (State->SegmentRegs[FAST486_REG_CS].Size)
{
/* 32-bit code segment, use EIP */
State->InstPtr.Long = Offset;
@ -445,11 +445,11 @@ Soft386InterruptInternal(PSOFT386_STATE State,
VOID
FASTCALL
Soft386ExceptionWithErrorCode(PSOFT386_STATE State,
SOFT386_EXCEPTIONS ExceptionCode,
Fast486ExceptionWithErrorCode(PFAST486_STATE State,
FAST486_EXCEPTIONS ExceptionCode,
ULONG ErrorCode)
{
SOFT386_IDT_ENTRY IdtEntry;
FAST486_IDT_ENTRY IdtEntry;
/* Increment the exception count */
State->ExceptionCount++;
@ -458,47 +458,47 @@ Soft386ExceptionWithErrorCode(PSOFT386_STATE State,
if (State->ExceptionCount > 1)
{
/* Then this is a double fault */
ExceptionCode = SOFT386_EXCEPTION_DF;
ExceptionCode = FAST486_EXCEPTION_DF;
}
/* Check if this is a triple fault */
if (State->ExceptionCount == 3)
{
/* Reset the CPU */
Soft386Reset(State);
Fast486Reset(State);
return;
}
/* Restore the IP to the saved IP */
State->InstPtr = State->SavedInstPtr;
if (!Soft386GetIntVector(State, ExceptionCode, &IdtEntry))
if (!Fast486GetIntVector(State, ExceptionCode, &IdtEntry))
{
/*
* If this function failed, that means Soft386Exception
* If this function failed, that means Fast486Exception
* was called again, so just return in this case.
*/
return;
}
/* Perform the interrupt */
if (!Soft386InterruptInternal(State,
if (!Fast486InterruptInternal(State,
IdtEntry.Selector,
MAKELONG(IdtEntry.Offset, IdtEntry.OffsetHigh),
IdtEntry.Type))
{
/*
* If this function failed, that means Soft386Exception
* If this function failed, that means Fast486Exception
* was called again, so just return in this case.
*/
return;
}
if (EXCEPTION_HAS_ERROR_CODE(ExceptionCode)
&& (State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_PE))
&& (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE))
{
/* Push the error code */
Soft386StackPush(State, ErrorCode);
Fast486StackPush(State, ErrorCode);
}
}

View file

@ -1,5 +1,5 @@
/*
* Soft386 386/486 CPU Emulation Library
* Fast486 386/486 CPU Emulation Library
* common.h
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
@ -48,20 +48,20 @@
#define PAGE_SIZE 4096
#endif
typedef struct _SOFT386_MOD_REG_RM
typedef struct _FAST486_MOD_REG_RM
{
SOFT386_GEN_REGS Register;
FAST486_GEN_REGS Register;
BOOLEAN Memory;
union
{
SOFT386_GEN_REGS SecondRegister;
FAST486_GEN_REGS SecondRegister;
ULONG MemoryAddress;
};
} SOFT386_MOD_REG_RM, *PSOFT386_MOD_REG_RM;
} FAST486_MOD_REG_RM, *PFAST486_MOD_REG_RM;
#pragma pack(push, 1)
typedef union _SOFT386_PAGE_DIR
typedef union _FAST486_PAGE_DIR
{
struct
{
@ -77,9 +77,9 @@ typedef union _SOFT386_PAGE_DIR
ULONG TableAddress : 20;
};
ULONG Value;
} SOFT386_PAGE_DIR, *PSOFT386_PAGE_DIR;
} FAST486_PAGE_DIR, *PFAST486_PAGE_DIR;
typedef union _SOFT386_PAGE_TABLE
typedef union _FAST486_PAGE_TABLE
{
struct
{
@ -96,17 +96,17 @@ typedef union _SOFT386_PAGE_TABLE
ULONG Address : 20;
};
ULONG Value;
} SOFT386_PAGE_TABLE, *PSOFT386_PAGE_TABLE;
} FAST486_PAGE_TABLE, *PFAST486_PAGE_TABLE;
#pragma pack(pop)
/* FUNCTIONS ******************************************************************/
BOOLEAN
Soft386ReadMemory
Fast486ReadMemory
(
PSOFT386_STATE State,
SOFT386_SEG_REGS SegmentReg,
PFAST486_STATE State,
FAST486_SEG_REGS SegmentReg,
ULONG Offset,
BOOLEAN InstFetch,
PVOID Buffer,
@ -114,19 +114,19 @@ Soft386ReadMemory
);
BOOLEAN
Soft386WriteMemory
Fast486WriteMemory
(
PSOFT386_STATE State,
SOFT386_SEG_REGS SegmentReg,
PFAST486_STATE State,
FAST486_SEG_REGS SegmentReg,
ULONG Offset,
PVOID Buffer,
ULONG Size
);
BOOLEAN
Soft386InterruptInternal
Fast486InterruptInternal
(
PSOFT386_STATE State,
PFAST486_STATE State,
USHORT SegmentSelector,
ULONG Offset,
BOOLEAN InterruptGate
@ -134,10 +134,10 @@ Soft386InterruptInternal
VOID
FASTCALL
Soft386ExceptionWithErrorCode
Fast486ExceptionWithErrorCode
(
PSOFT386_STATE State,
SOFT386_EXCEPTIONS ExceptionCode,
PFAST486_STATE State,
FAST486_EXCEPTIONS ExceptionCode,
ULONG ErrorCode
);
@ -145,9 +145,9 @@ Soft386ExceptionWithErrorCode
/* static */ FORCEINLINE
INT
Soft386GetCurrentPrivLevel(PSOFT386_STATE State)
Fast486GetCurrentPrivLevel(PFAST486_STATE State)
{
return GET_SEGMENT_RPL(State->SegmentRegs[SOFT386_REG_CS].Selector);
return GET_SEGMENT_RPL(State->SegmentRegs[FAST486_REG_CS].Selector);
}
#include "common.inl"

View file

@ -1,5 +1,5 @@
/*
* Soft386 386/486 CPU Emulation Library
* Fast486 386/486 CPU Emulation Library
* common.inl
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
@ -23,42 +23,42 @@
FORCEINLINE
VOID
Soft386Exception(PSOFT386_STATE State,
SOFT386_EXCEPTIONS ExceptionCode)
Fast486Exception(PFAST486_STATE State,
FAST486_EXCEPTIONS ExceptionCode)
{
/* Call the internal function */
Soft386ExceptionWithErrorCode(State, ExceptionCode, 0);
Fast486ExceptionWithErrorCode(State, ExceptionCode, 0);
}
FORCEINLINE
BOOLEAN
Soft386StackPush(PSOFT386_STATE State,
Fast486StackPush(PFAST486_STATE State,
ULONG Value)
{
BOOLEAN Size = State->SegmentRegs[SOFT386_REG_SS].Size;
BOOLEAN Size = State->SegmentRegs[FAST486_REG_SS].Size;
/* The OPSIZE prefix toggles the size */
if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) Size = !Size;
if (State->PrefixFlags & FAST486_PREFIX_OPSIZE) Size = !Size;
if (Size)
{
/* 32-bit size */
/* Check if ESP is between 1 and 3 */
if (State->GeneralRegs[SOFT386_REG_ESP].Long >= 1
&& State->GeneralRegs[SOFT386_REG_ESP].Long <= 3)
if (State->GeneralRegs[FAST486_REG_ESP].Long >= 1
&& State->GeneralRegs[FAST486_REG_ESP].Long <= 3)
{
Soft386Exception(State, SOFT386_EXCEPTION_SS);
Fast486Exception(State, FAST486_EXCEPTION_SS);
return FALSE;
}
/* Subtract ESP by 4 */
State->GeneralRegs[SOFT386_REG_ESP].Long -= 4;
State->GeneralRegs[FAST486_REG_ESP].Long -= 4;
/* Store the value in SS:ESP */
return Soft386WriteMemory(State,
SOFT386_REG_SS,
State->GeneralRegs[SOFT386_REG_ESP].Long,
return Fast486WriteMemory(State,
FAST486_REG_SS,
State->GeneralRegs[FAST486_REG_ESP].Long,
&Value,
sizeof(ULONG));
}
@ -68,19 +68,19 @@ Soft386StackPush(PSOFT386_STATE State,
USHORT ShortValue = LOWORD(Value);
/* Check if SP is 1 */
if (State->GeneralRegs[SOFT386_REG_ESP].Long == 1)
if (State->GeneralRegs[FAST486_REG_ESP].Long == 1)
{
Soft386Exception(State, SOFT386_EXCEPTION_SS);
Fast486Exception(State, FAST486_EXCEPTION_SS);
return FALSE;
}
/* Subtract SP by 2 */
State->GeneralRegs[SOFT386_REG_ESP].LowWord -= 2;
State->GeneralRegs[FAST486_REG_ESP].LowWord -= 2;
/* Store the value in SS:SP */
return Soft386WriteMemory(State,
SOFT386_REG_SS,
State->GeneralRegs[SOFT386_REG_ESP].LowWord,
return Fast486WriteMemory(State,
FAST486_REG_SS,
State->GeneralRegs[FAST486_REG_ESP].LowWord,
&ShortValue,
sizeof(USHORT));
}
@ -88,31 +88,31 @@ Soft386StackPush(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386StackPop(PSOFT386_STATE State,
Fast486StackPop(PFAST486_STATE State,
PULONG Value)
{
ULONG LongValue;
USHORT ShortValue;
BOOLEAN Size = State->SegmentRegs[SOFT386_REG_SS].Size;
BOOLEAN Size = State->SegmentRegs[FAST486_REG_SS].Size;
/* The OPSIZE prefix toggles the size */
if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) Size = !Size;
if (State->PrefixFlags & FAST486_PREFIX_OPSIZE) Size = !Size;
if (Size)
{
/* 32-bit size */
/* Check if ESP is 0xFFFFFFFF */
if (State->GeneralRegs[SOFT386_REG_ESP].Long == 0xFFFFFFFF)
if (State->GeneralRegs[FAST486_REG_ESP].Long == 0xFFFFFFFF)
{
Soft386Exception(State, SOFT386_EXCEPTION_SS);
Fast486Exception(State, FAST486_EXCEPTION_SS);
return FALSE;
}
/* Read the value from SS:ESP */
if (!Soft386ReadMemory(State,
SOFT386_REG_SS,
State->GeneralRegs[SOFT386_REG_ESP].Long,
if (!Fast486ReadMemory(State,
FAST486_REG_SS,
State->GeneralRegs[FAST486_REG_ESP].Long,
FALSE,
&LongValue,
sizeof(LongValue)))
@ -122,7 +122,7 @@ Soft386StackPop(PSOFT386_STATE State,
}
/* Increment ESP by 4 */
State->GeneralRegs[SOFT386_REG_ESP].Long += 4;
State->GeneralRegs[FAST486_REG_ESP].Long += 4;
/* Store the value in the result */
*Value = LongValue;
@ -132,16 +132,16 @@ Soft386StackPop(PSOFT386_STATE State,
/* 16-bit size */
/* Check if SP is 0xFFFF */
if (State->GeneralRegs[SOFT386_REG_ESP].LowWord == 0xFFFF)
if (State->GeneralRegs[FAST486_REG_ESP].LowWord == 0xFFFF)
{
Soft386Exception(State, SOFT386_EXCEPTION_SS);
Fast486Exception(State, FAST486_EXCEPTION_SS);
return FALSE;
}
/* Read the value from SS:SP */
if (!Soft386ReadMemory(State,
SOFT386_REG_SS,
State->GeneralRegs[SOFT386_REG_ESP].LowWord,
if (!Fast486ReadMemory(State,
FAST486_REG_SS,
State->GeneralRegs[FAST486_REG_ESP].LowWord,
FALSE,
&ShortValue,
sizeof(ShortValue)))
@ -151,7 +151,7 @@ Soft386StackPop(PSOFT386_STATE State,
}
/* Increment SP by 2 */
State->GeneralRegs[SOFT386_REG_ESP].Long += 2;
State->GeneralRegs[FAST486_REG_ESP].Long += 2;
/* Store the value in the result */
*Value = ShortValue;
@ -162,25 +162,25 @@ Soft386StackPop(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386LoadSegment(PSOFT386_STATE State,
Fast486LoadSegment(PFAST486_STATE State,
INT Segment,
USHORT Selector)
{
PSOFT386_SEG_REG CachedDescriptor;
SOFT386_GDT_ENTRY GdtEntry;
PFAST486_SEG_REG CachedDescriptor;
FAST486_GDT_ENTRY GdtEntry;
ASSERT(Segment < SOFT386_NUM_SEG_REGS);
ASSERT(Segment < FAST486_NUM_SEG_REGS);
/* Get the cached descriptor */
CachedDescriptor = &State->SegmentRegs[Segment];
/* Check for protected mode */
if ((State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_PE) && !State->Flags.Vm)
if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) && !State->Flags.Vm)
{
/* Make sure the GDT contains the entry */
if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1))
{
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
@ -202,43 +202,43 @@ Soft386LoadSegment(PSOFT386_STATE State,
sizeof(GdtEntry));
}
if (Segment == SOFT386_REG_SS)
if (Segment == FAST486_REG_SS)
{
/* Loading the stack segment */
if (GET_SEGMENT_INDEX(Selector) == 0)
{
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
if (!GdtEntry.SystemType)
{
/* This is a special descriptor */
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
if (GdtEntry.Executable || !GdtEntry.ReadWrite)
{
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
if ((GET_SEGMENT_RPL(Selector) != Soft386GetCurrentPrivLevel(State))
if ((GET_SEGMENT_RPL(Selector) != Fast486GetCurrentPrivLevel(State))
|| (GET_SEGMENT_RPL(Selector) != GdtEntry.Dpl))
{
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
if (!GdtEntry.Present)
{
Soft386Exception(State, SOFT386_EXCEPTION_SS);
Fast486Exception(State, FAST486_EXCEPTION_SS);
return FALSE;
}
}
else if (Segment == SOFT386_REG_CS)
else if (Segment == FAST486_REG_CS)
{
/* Loading the code segment */
// TODO: NOT IMPLEMENTED
@ -250,20 +250,20 @@ Soft386LoadSegment(PSOFT386_STATE State,
if (!GdtEntry.SystemType)
{
/* This is a special descriptor */
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl)
&& (Soft386GetCurrentPrivLevel(State) > GdtEntry.Dpl))
&& (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl))
{
Soft386Exception(State, SOFT386_EXCEPTION_GP);
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
if (!GdtEntry.Present)
{
Soft386Exception(State, SOFT386_EXCEPTION_NP);
Fast486Exception(State, FAST486_EXCEPTION_NP);
return FALSE;
}
}
@ -296,17 +296,17 @@ Soft386LoadSegment(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386FetchByte(PSOFT386_STATE State,
Fast486FetchByte(PFAST486_STATE State,
PUCHAR Data)
{
PSOFT386_SEG_REG CachedDescriptor;
PFAST486_SEG_REG CachedDescriptor;
/* Get the cached descriptor of CS */
CachedDescriptor = &State->SegmentRegs[SOFT386_REG_CS];
CachedDescriptor = &State->SegmentRegs[FAST486_REG_CS];
/* Read from memory */
if (!Soft386ReadMemory(State,
SOFT386_REG_CS,
if (!Fast486ReadMemory(State,
FAST486_REG_CS,
(CachedDescriptor->Size) ? State->InstPtr.Long
: State->InstPtr.LowWord,
TRUE,
@ -326,18 +326,18 @@ Soft386FetchByte(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386FetchWord(PSOFT386_STATE State,
Fast486FetchWord(PFAST486_STATE State,
PUSHORT Data)
{
PSOFT386_SEG_REG CachedDescriptor;
PFAST486_SEG_REG CachedDescriptor;
/* Get the cached descriptor of CS */
CachedDescriptor = &State->SegmentRegs[SOFT386_REG_CS];
CachedDescriptor = &State->SegmentRegs[FAST486_REG_CS];
/* Read from memory */
// FIXME: Fix byte order on big-endian machines
if (!Soft386ReadMemory(State,
SOFT386_REG_CS,
if (!Fast486ReadMemory(State,
FAST486_REG_CS,
(CachedDescriptor->Size) ? State->InstPtr.Long
: State->InstPtr.LowWord,
TRUE,
@ -357,18 +357,18 @@ Soft386FetchWord(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386FetchDword(PSOFT386_STATE State,
Fast486FetchDword(PFAST486_STATE State,
PULONG Data)
{
PSOFT386_SEG_REG CachedDescriptor;
PFAST486_SEG_REG CachedDescriptor;
/* Get the cached descriptor of CS */
CachedDescriptor = &State->SegmentRegs[SOFT386_REG_CS];
CachedDescriptor = &State->SegmentRegs[FAST486_REG_CS];
/* Read from memory */
// FIXME: Fix byte order on big-endian machines
if (!Soft386ReadMemory(State,
SOFT386_REG_CS,
if (!Fast486ReadMemory(State,
FAST486_REG_CS,
(CachedDescriptor->Size) ? State->InstPtr.Long
: State->InstPtr.LowWord,
TRUE,
@ -388,14 +388,14 @@ Soft386FetchDword(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386GetIntVector(PSOFT386_STATE State,
Fast486GetIntVector(PFAST486_STATE State,
UCHAR Number,
PSOFT386_IDT_ENTRY IdtEntry)
PFAST486_IDT_ENTRY IdtEntry)
{
ULONG FarPointer;
/* Check for protected mode */
if (State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_PE)
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
{
/* Read from the IDT */
// FIXME: This code is only correct when paging is disabled!!!
@ -440,7 +440,7 @@ Soft386GetIntVector(PSOFT386_STATE State,
IdtEntry->Offset = LOWORD(FarPointer);
IdtEntry->Selector = HIWORD(FarPointer);
IdtEntry->Zero = 0;
IdtEntry->Type = SOFT386_IDT_INT_GATE;
IdtEntry->Type = FAST486_IDT_INT_GATE;
IdtEntry->Storage = FALSE;
IdtEntry->Dpl = 0;
IdtEntry->Present = TRUE;
@ -456,21 +456,21 @@ Soft386GetIntVector(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386CalculateParity(UCHAR Number)
Fast486CalculateParity(UCHAR Number)
{
return (0x9669 >> ((Number & 0x0F) ^ (Number >> 4))) & 1;
}
FORCEINLINE
BOOLEAN
Soft386ParseModRegRm(PSOFT386_STATE State,
Fast486ParseModRegRm(PFAST486_STATE State,
BOOLEAN AddressSize,
PSOFT386_MOD_REG_RM ModRegRm)
PFAST486_MOD_REG_RM ModRegRm)
{
UCHAR ModRmByte, Mode, RegMem;
/* Fetch the MOD REG R/M byte */
if (!Soft386FetchByte(State, &ModRmByte))
if (!Fast486FetchByte(State, &ModRmByte))
{
/* Exception occurred */
return FALSE;
@ -499,13 +499,13 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
if (AddressSize)
{
if (RegMem == SOFT386_REG_ESP)
if (RegMem == FAST486_REG_ESP)
{
UCHAR SibByte;
ULONG Scale, Index, Base;
/* Fetch the SIB byte */
if (!Soft386FetchByte(State, &SibByte))
if (!Fast486FetchByte(State, &SibByte))
{
/* Exception occurred */
return FALSE;
@ -514,16 +514,16 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
/* Unpack the scale, index and base */
Scale = 1 << (SibByte >> 6);
Index = (SibByte >> 3) & 0x07;
if (Index != SOFT386_REG_ESP) Index = State->GeneralRegs[Index].Long;
if (Index != FAST486_REG_ESP) Index = State->GeneralRegs[Index].Long;
else Index = 0;
Base = State->GeneralRegs[SibByte & 0x07].Long;
/* Calculate the address */
ModRegRm->MemoryAddress = Base + Index * Scale;
}
else if (RegMem == SOFT386_REG_EBP)
else if (RegMem == FAST486_REG_EBP)
{
if (Mode) ModRegRm->MemoryAddress = State->GeneralRegs[SOFT386_REG_EBP].Long;
if (Mode) ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EBP].Long;
else ModRegRm->MemoryAddress = 0;
}
else
@ -533,14 +533,14 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
}
/* Check if there is no segment override */
if (!(State->PrefixFlags & SOFT386_PREFIX_SEG))
if (!(State->PrefixFlags & FAST486_PREFIX_SEG))
{
/* Check if the default segment should be SS */
if ((RegMem == SOFT386_REG_EBP) && Mode)
if ((RegMem == FAST486_REG_EBP) && Mode)
{
/* Add a SS: prefix */
State->PrefixFlags |= SOFT386_PREFIX_SEG;
State->SegmentOverride = SOFT386_REG_SS;
State->PrefixFlags |= FAST486_PREFIX_SEG;
State->SegmentOverride = FAST486_REG_SS;
}
}
@ -549,7 +549,7 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
CHAR Offset;
/* Fetch the byte */
if (!Soft386FetchByte(State, (PUCHAR)&Offset))
if (!Fast486FetchByte(State, (PUCHAR)&Offset))
{
/* Exception occurred */
return FALSE;
@ -558,12 +558,12 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
/* Add the signed offset to the address */
ModRegRm->MemoryAddress += (LONG)Offset;
}
else if ((Mode == 2) || ((Mode == 0) && (RegMem == SOFT386_REG_EBP)))
else if ((Mode == 2) || ((Mode == 0) && (RegMem == FAST486_REG_EBP)))
{
LONG Offset;
/* Fetch the dword */
if (!Soft386FetchDword(State, (PULONG)&Offset))
if (!Fast486FetchDword(State, (PULONG)&Offset))
{
/* Exception occurred */
return FALSE;
@ -582,8 +582,8 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
case 2:
{
/* (SS:)[BX + SI] */
ModRegRm->MemoryAddress = State->GeneralRegs[SOFT386_REG_EBX].LowWord
+ State->GeneralRegs[SOFT386_REG_ESI].LowWord;
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EBX].LowWord
+ State->GeneralRegs[FAST486_REG_ESI].LowWord;
break;
}
@ -592,8 +592,8 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
case 3:
{
/* (SS:)[BX + DI] */
ModRegRm->MemoryAddress = State->GeneralRegs[SOFT386_REG_EBX].LowWord
+ State->GeneralRegs[SOFT386_REG_EDI].LowWord;
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EBX].LowWord
+ State->GeneralRegs[FAST486_REG_EDI].LowWord;
break;
}
@ -601,7 +601,7 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
case 4:
{
/* [SI] */
ModRegRm->MemoryAddress = State->GeneralRegs[SOFT386_REG_ESI].LowWord;
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_ESI].LowWord;
break;
}
@ -609,7 +609,7 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
case 5:
{
/* [DI] */
ModRegRm->MemoryAddress = State->GeneralRegs[SOFT386_REG_EDI].LowWord;
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EDI].LowWord;
break;
}
@ -619,7 +619,7 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
if (Mode)
{
/* [BP] */
ModRegRm->MemoryAddress = State->GeneralRegs[SOFT386_REG_EBP].LowWord;
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EBP].LowWord;
}
else
{
@ -633,21 +633,21 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
case 7:
{
/* [BX] */
ModRegRm->MemoryAddress = State->GeneralRegs[SOFT386_REG_EBX].LowWord;
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EBX].LowWord;
break;
}
}
/* Check if there is no segment override */
if (!(State->PrefixFlags & SOFT386_PREFIX_SEG))
if (!(State->PrefixFlags & FAST486_PREFIX_SEG))
{
/* Check if the default segment should be SS */
if ((RegMem == 2) || (RegMem == 3) || ((RegMem == 6) && Mode))
{
/* Add a SS: prefix */
State->PrefixFlags |= SOFT386_PREFIX_SEG;
State->SegmentOverride = SOFT386_REG_SS;
State->PrefixFlags |= FAST486_PREFIX_SEG;
State->SegmentOverride = FAST486_REG_SS;
}
}
@ -656,7 +656,7 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
CHAR Offset;
/* Fetch the byte */
if (!Soft386FetchByte(State, (PUCHAR)&Offset))
if (!Fast486FetchByte(State, (PUCHAR)&Offset))
{
/* Exception occurred */
return FALSE;
@ -670,7 +670,7 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
SHORT Offset;
/* Fetch the word */
if (!Soft386FetchWord(State, (PUSHORT)&Offset))
if (!Fast486FetchWord(State, (PUSHORT)&Offset))
{
/* Exception occurred */
return FALSE;
@ -689,12 +689,12 @@ Soft386ParseModRegRm(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386ReadModrmByteOperands(PSOFT386_STATE State,
PSOFT386_MOD_REG_RM ModRegRm,
Fast486ReadModrmByteOperands(PFAST486_STATE State,
PFAST486_MOD_REG_RM ModRegRm,
PUCHAR RegValue,
PUCHAR RmValue)
{
SOFT386_SEG_REGS Segment = SOFT386_REG_DS;
FAST486_SEG_REGS Segment = FAST486_REG_DS;
/* Get the register value */
if (ModRegRm->Register & 0x04)
@ -725,14 +725,14 @@ Soft386ReadModrmByteOperands(PSOFT386_STATE State,
else
{
/* Check for the segment override */
if (State->PrefixFlags & SOFT386_PREFIX_SEG)
if (State->PrefixFlags & FAST486_PREFIX_SEG)
{
/* Use the override segment instead */
Segment = State->SegmentOverride;
}
/* Read memory */
if (!Soft386ReadMemory(State,
if (!Fast486ReadMemory(State,
Segment,
ModRegRm->MemoryAddress,
FALSE,
@ -749,12 +749,12 @@ Soft386ReadModrmByteOperands(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386ReadModrmWordOperands(PSOFT386_STATE State,
PSOFT386_MOD_REG_RM ModRegRm,
Fast486ReadModrmWordOperands(PFAST486_STATE State,
PFAST486_MOD_REG_RM ModRegRm,
PUSHORT RegValue,
PUSHORT RmValue)
{
SOFT386_SEG_REGS Segment = SOFT386_REG_DS;
FAST486_SEG_REGS Segment = FAST486_REG_DS;
/* Get the register value */
*RegValue = State->GeneralRegs[ModRegRm->Register].LowWord;
@ -767,14 +767,14 @@ Soft386ReadModrmWordOperands(PSOFT386_STATE State,
else
{
/* Check for the segment override */
if (State->PrefixFlags & SOFT386_PREFIX_SEG)
if (State->PrefixFlags & FAST486_PREFIX_SEG)
{
/* Use the override segment instead */
Segment = State->SegmentOverride;
}
/* Read memory */
if (!Soft386ReadMemory(State,
if (!Fast486ReadMemory(State,
Segment,
ModRegRm->MemoryAddress,
FALSE,
@ -791,12 +791,12 @@ Soft386ReadModrmWordOperands(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386ReadModrmDwordOperands(PSOFT386_STATE State,
PSOFT386_MOD_REG_RM ModRegRm,
Fast486ReadModrmDwordOperands(PFAST486_STATE State,
PFAST486_MOD_REG_RM ModRegRm,
PULONG RegValue,
PULONG RmValue)
{
SOFT386_SEG_REGS Segment = SOFT386_REG_DS;
FAST486_SEG_REGS Segment = FAST486_REG_DS;
/* Get the register value */
*RegValue = State->GeneralRegs[ModRegRm->Register].Long;
@ -809,14 +809,14 @@ Soft386ReadModrmDwordOperands(PSOFT386_STATE State,
else
{
/* Check for the segment override */
if (State->PrefixFlags & SOFT386_PREFIX_SEG)
if (State->PrefixFlags & FAST486_PREFIX_SEG)
{
/* Use the override segment instead */
Segment = State->SegmentOverride;
}
/* Read memory */
if (!Soft386ReadMemory(State,
if (!Fast486ReadMemory(State,
Segment,
ModRegRm->MemoryAddress,
FALSE,
@ -833,12 +833,12 @@ Soft386ReadModrmDwordOperands(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386WriteModrmByteOperands(PSOFT386_STATE State,
PSOFT386_MOD_REG_RM ModRegRm,
Fast486WriteModrmByteOperands(PFAST486_STATE State,
PFAST486_MOD_REG_RM ModRegRm,
BOOLEAN WriteRegister,
UCHAR Value)
{
SOFT386_SEG_REGS Segment = SOFT386_REG_DS;
FAST486_SEG_REGS Segment = FAST486_REG_DS;
if (WriteRegister)
{
@ -873,14 +873,14 @@ Soft386WriteModrmByteOperands(PSOFT386_STATE State,
else
{
/* Check for the segment override */
if (State->PrefixFlags & SOFT386_PREFIX_SEG)
if (State->PrefixFlags & FAST486_PREFIX_SEG)
{
/* Use the override segment instead */
Segment = State->SegmentOverride;
}
/* Write memory */
if (!Soft386WriteMemory(State,
if (!Fast486WriteMemory(State,
Segment,
ModRegRm->MemoryAddress,
&Value,
@ -897,12 +897,12 @@ Soft386WriteModrmByteOperands(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386WriteModrmWordOperands(PSOFT386_STATE State,
PSOFT386_MOD_REG_RM ModRegRm,
Fast486WriteModrmWordOperands(PFAST486_STATE State,
PFAST486_MOD_REG_RM ModRegRm,
BOOLEAN WriteRegister,
USHORT Value)
{
SOFT386_SEG_REGS Segment = SOFT386_REG_DS;
FAST486_SEG_REGS Segment = FAST486_REG_DS;
if (WriteRegister)
{
@ -919,14 +919,14 @@ Soft386WriteModrmWordOperands(PSOFT386_STATE State,
else
{
/* Check for the segment override */
if (State->PrefixFlags & SOFT386_PREFIX_SEG)
if (State->PrefixFlags & FAST486_PREFIX_SEG)
{
/* Use the override segment instead */
Segment = State->SegmentOverride;
}
/* Write memory */
if (!Soft386WriteMemory(State,
if (!Fast486WriteMemory(State,
Segment,
ModRegRm->MemoryAddress,
&Value,
@ -943,12 +943,12 @@ Soft386WriteModrmWordOperands(PSOFT386_STATE State,
FORCEINLINE
BOOLEAN
Soft386WriteModrmDwordOperands(PSOFT386_STATE State,
PSOFT386_MOD_REG_RM ModRegRm,
Fast486WriteModrmDwordOperands(PFAST486_STATE State,
PFAST486_MOD_REG_RM ModRegRm,
BOOLEAN WriteRegister,
ULONG Value)
{
SOFT386_SEG_REGS Segment = SOFT386_REG_DS;
FAST486_SEG_REGS Segment = FAST486_REG_DS;
if (WriteRegister)
{
@ -965,14 +965,14 @@ Soft386WriteModrmDwordOperands(PSOFT386_STATE State,
else
{
/* Check for the segment override */
if (State->PrefixFlags & SOFT386_PREFIX_SEG)
if (State->PrefixFlags & FAST486_PREFIX_SEG)
{
/* Use the override segment instead */
Segment = State->SegmentOverride;
}
/* Write memory */
if (!Soft386WriteMemory(State,
if (!Fast486WriteMemory(State,
Segment,
ModRegRm->MemoryAddress,
&Value,

View file

@ -1,5 +1,5 @@
/*
* Soft386 386/486 CPU Emulation Library
* Fast486 386/486 CPU Emulation Library
* extraops.c
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
@ -28,15 +28,15 @@
// #define NDEBUG
#include <debug.h>
#include <soft386.h>
#include <fast486.h>
#include "opcodes.h"
#include "common.h"
#include "extraops.h"
/* PUBLIC VARIABLES ***********************************************************/
SOFT386_OPCODE_HANDLER_PROC
Soft386ExtendedHandlers[SOFT386_NUM_OPCODE_HANDLERS] =
FAST486_OPCODE_HANDLER_PROC
Fast486ExtendedHandlers[FAST486_NUM_OPCODE_HANDLERS] =
{
NULL, // TODO: OPCODE 0x00 NOT IMPLEMENTED
NULL, // TODO: OPCODE 0x01 NOT IMPLEMENTED
@ -166,22 +166,22 @@ Soft386ExtendedHandlers[SOFT386_NUM_OPCODE_HANDLERS] =
NULL, // TODO: OPCODE 0x7D NOT IMPLEMENTED
NULL, // TODO: OPCODE 0x7E NOT IMPLEMENTED
NULL, // TODO: OPCODE 0x7F NOT IMPLEMENTED
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Soft386ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
Fast486ExtOpcodeConditionalJmp,
NULL, // TODO: OPCODE 0x90 NOT IMPLEMENTED
NULL, // TODO: OPCODE 0x91 NOT IMPLEMENTED
NULL, // TODO: OPCODE 0x92 NOT IMPLEMENTED
@ -298,22 +298,22 @@ Soft386ExtendedHandlers[SOFT386_NUM_OPCODE_HANDLERS] =
/* PUBLIC FUNCTIONS ***********************************************************/
SOFT386_OPCODE_HANDLER(Soft386ExtOpcodeConditionalJmp)
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalJmp)
{
BOOLEAN Jump = FALSE;
LONG Offset = 0;
BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
if (State->PrefixFlags & FAST486_PREFIX_OPSIZE)
{
/* The OPSIZE prefix toggles the size */
Size = !Size;
}
if (State->PrefixFlags & SOFT386_PREFIX_LOCK)
if (State->PrefixFlags & FAST486_PREFIX_LOCK)
{
/* Invalid prefix */
Soft386Exception(State, SOFT386_EXCEPTION_UD);
Fast486Exception(State, FAST486_EXCEPTION_UD);
return FALSE;
}
@ -323,7 +323,7 @@ SOFT386_OPCODE_HANDLER(Soft386ExtOpcodeConditionalJmp)
/* Fetch the offset */
if (Size)
{
if (!Soft386FetchDword(State, (PULONG)&Offset))
if (!Fast486FetchDword(State, (PULONG)&Offset))
{
/* Exception occurred */
return FALSE;
@ -333,7 +333,7 @@ SOFT386_OPCODE_HANDLER(Soft386ExtOpcodeConditionalJmp)
{
SHORT Value;
if (!Soft386FetchWord(State, (PUSHORT)&Value))
if (!Fast486FetchWord(State, (PUSHORT)&Value))
{
/* Exception occurred */
return FALSE;
@ -419,26 +419,26 @@ SOFT386_OPCODE_HANDLER(Soft386ExtOpcodeConditionalJmp)
}
SOFT386_OPCODE_HANDLER(Soft386OpcodeExtended)
FAST486_OPCODE_HANDLER(Fast486OpcodeExtended)
{
UCHAR SecondOpcode;
/* Fetch the second operation code */
if (!Soft386FetchByte(State, &SecondOpcode))
if (!Fast486FetchByte(State, &SecondOpcode))
{
/* Exception occurred */
return FALSE;
}
if (Soft386ExtendedHandlers[SecondOpcode] != NULL)
if (Fast486ExtendedHandlers[SecondOpcode] != NULL)
{
/* Call the extended opcode handler */
return Soft386ExtendedHandlers[SecondOpcode](State, SecondOpcode);
return Fast486ExtendedHandlers[SecondOpcode](State, SecondOpcode);
}
else
{
/* This is not a valid opcode */
Soft386Exception(State, SOFT386_EXCEPTION_UD);
Fast486Exception(State, FAST486_EXCEPTION_UD);
return FALSE;
}
}

View file

@ -1,5 +1,5 @@
/*
* Soft386 386/486 CPU Emulation Library
* Fast486 386/486 CPU Emulation Library
* extraops.h
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
@ -23,8 +23,8 @@
#define _EXTRAOPS_H_
/* DEFINES ********************************************************************/
SOFT386_OPCODE_HANDLER(Soft386ExtOpcodeConditionalJmp);
SOFT386_OPCODE_HANDLER(Soft386OpcodeExtended);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalJmp);
FAST486_OPCODE_HANDLER(Fast486OpcodeExtended);
#endif // _EXTRAOPS_H_

View file

@ -1,6 +1,6 @@
/*
* Soft386 386/486 CPU Emulation Library
* soft386.c
* Fast486 386/486 CPU Emulation Library
* fast486.c
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*
@ -28,7 +28,7 @@
// #define NDEBUG
#include <debug.h>
#include <soft386.h>
#include <fast486.h>
#include "common.h"
#include "opcodes.h"
@ -36,11 +36,11 @@
typedef enum
{
SOFT386_STEP_INTO,
SOFT386_STEP_OVER,
SOFT386_STEP_OUT,
SOFT386_CONTINUE
} SOFT386_EXEC_CMD;
FAST486_STEP_INTO,
FAST486_STEP_OVER,
FAST486_STEP_OUT,
FAST486_CONTINUE
} FAST486_EXEC_CMD;
/* PRIVATE FUNCTIONS **********************************************************/
@ -48,7 +48,7 @@ static
inline
VOID
NTAPI
Soft386ExecutionControl(PSOFT386_STATE State, INT Command)
Fast486ExecutionControl(PFAST486_STATE State, INT Command)
{
UCHAR Opcode;
INT ProcedureCallCount = 0;
@ -64,13 +64,13 @@ Soft386ExecutionControl(PSOFT386_STATE State, INT Command)
/* Check if interrupts are enabled and there is an interrupt pending */
if (State->Flags.If && State->HardwareInt)
{
SOFT386_IDT_ENTRY IdtEntry;
FAST486_IDT_ENTRY IdtEntry;
/* Get the interrupt vector */
if (Soft386GetIntVector(State, State->PendingIntNum, &IdtEntry))
if (Fast486GetIntVector(State, State->PendingIntNum, &IdtEntry))
{
/* Perform the interrupt */
Soft386InterruptInternal(State,
Fast486InterruptInternal(State,
IdtEntry.Selector,
MAKELONG(IdtEntry.Offset, IdtEntry.OffsetHigh),
IdtEntry.Type);
@ -82,22 +82,22 @@ Soft386ExecutionControl(PSOFT386_STATE State, INT Command)
}
/* Perform an instruction fetch */
if (!Soft386FetchByte(State, &Opcode)) continue;
if (!Fast486FetchByte(State, &Opcode)) continue;
// TODO: Check for CALL/RET to update ProcedureCallCount.
if (Soft386OpcodeHandlers[Opcode] != NULL)
if (Fast486OpcodeHandlers[Opcode] != NULL)
{
/* Call the opcode handler */
Soft386OpcodeHandlers[Opcode](State, Opcode);
Fast486OpcodeHandlers[Opcode](State, Opcode);
}
else
{
/* This is not a valid opcode */
Soft386Exception(State, SOFT386_EXCEPTION_UD);
Fast486Exception(State, FAST486_EXCEPTION_UD);
}
if (Soft386OpcodeHandlers[Opcode] != Soft386OpcodePrefix)
if (Fast486OpcodeHandlers[Opcode] != Fast486OpcodePrefix)
{
/* A non-prefix opcode has been executed, reset the prefix flags */
State->PrefixFlags = 0;
@ -111,67 +111,67 @@ Soft386ExecutionControl(PSOFT386_STATE State, INT Command)
/* Increment the time stamp counter */
State->TimeStampCounter++;
}
while ((Command == SOFT386_CONTINUE)
|| (Command == SOFT386_STEP_OVER && ProcedureCallCount > 0)
|| (Command == SOFT386_STEP_OUT && ProcedureCallCount >= 0)
|| (Soft386OpcodeHandlers[Opcode] == Soft386OpcodePrefix));
while ((Command == FAST486_CONTINUE)
|| (Command == FAST486_STEP_OVER && ProcedureCallCount > 0)
|| (Command == FAST486_STEP_OUT && ProcedureCallCount >= 0)
|| (Fast486OpcodeHandlers[Opcode] == Fast486OpcodePrefix));
}
/* PUBLIC FUNCTIONS ***********************************************************/
VOID
NTAPI
Soft386Continue(PSOFT386_STATE State)
Fast486Continue(PFAST486_STATE State)
{
/* Call the internal function */
Soft386ExecutionControl(State, SOFT386_CONTINUE);
Fast486ExecutionControl(State, FAST486_CONTINUE);
}
VOID
NTAPI
Soft386StepInto(PSOFT386_STATE State)
Fast486StepInto(PFAST486_STATE State)
{
/* Call the internal function */
Soft386ExecutionControl(State, SOFT386_STEP_INTO);
Fast486ExecutionControl(State, FAST486_STEP_INTO);
}
VOID
NTAPI
Soft386StepOver(PSOFT386_STATE State)
Fast486StepOver(PFAST486_STATE State)
{
/* Call the internal function */
Soft386ExecutionControl(State, SOFT386_STEP_OVER);
Fast486ExecutionControl(State, FAST486_STEP_OVER);
}
VOID
NTAPI
Soft386StepOut(PSOFT386_STATE State)
Fast486StepOut(PFAST486_STATE State)
{
/* Call the internal function */
Soft386ExecutionControl(State, SOFT386_STEP_OUT);
Fast486ExecutionControl(State, FAST486_STEP_OUT);
}
VOID
NTAPI
Soft386DumpState(PSOFT386_STATE State)
Fast486DumpState(PFAST486_STATE State)
{
DPRINT1("\nCPU currently executing in %s mode at %04X:%08X\n"
"Time Stamp Counter = %016X\n",
(State->ControlRegisters[0] & SOFT386_CR0_PE) ? "protected" : "real",
State->SegmentRegs[SOFT386_REG_CS].Selector,
(State->ControlRegisters[0] & FAST486_CR0_PE) ? "protected" : "real",
State->SegmentRegs[FAST486_REG_CS].Selector,
State->InstPtr.Long,
State->TimeStampCounter);
DPRINT1("\nGeneral purpose registers:\n"
"EAX = %08X\tECX = %08X\tEDX = %08X\tEBX = %08X\n"
"ESP = %08X\tEBP = %08X\tESI = %08X\tEDI = %08X\n",
State->GeneralRegs[SOFT386_REG_EAX].Long,
State->GeneralRegs[SOFT386_REG_ECX].Long,
State->GeneralRegs[SOFT386_REG_EDX].Long,
State->GeneralRegs[SOFT386_REG_EBX].Long,
State->GeneralRegs[SOFT386_REG_ESP].Long,
State->GeneralRegs[SOFT386_REG_EBP].Long,
State->GeneralRegs[SOFT386_REG_ESI].Long,
State->GeneralRegs[SOFT386_REG_EDI].Long);
State->GeneralRegs[FAST486_REG_EAX].Long,
State->GeneralRegs[FAST486_REG_ECX].Long,
State->GeneralRegs[FAST486_REG_EDX].Long,
State->GeneralRegs[FAST486_REG_EBX].Long,
State->GeneralRegs[FAST486_REG_ESP].Long,
State->GeneralRegs[FAST486_REG_EBP].Long,
State->GeneralRegs[FAST486_REG_ESI].Long,
State->GeneralRegs[FAST486_REG_EDI].Long);
DPRINT1("\nSegment registers:\n"
"ES = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n"
"CS = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n"
@ -179,30 +179,30 @@ Soft386DumpState(PSOFT386_STATE State)
"DS = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n"
"FS = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n"
"GS = %04X (Base: %08X, Limit: %08X, Dpl: %u)\n",
State->SegmentRegs[SOFT386_REG_ES].Selector,
State->SegmentRegs[SOFT386_REG_ES].Base,
State->SegmentRegs[SOFT386_REG_ES].Limit,
State->SegmentRegs[SOFT386_REG_ES].Dpl,
State->SegmentRegs[SOFT386_REG_CS].Selector,
State->SegmentRegs[SOFT386_REG_CS].Base,
State->SegmentRegs[SOFT386_REG_CS].Limit,
State->SegmentRegs[SOFT386_REG_CS].Dpl,
State->SegmentRegs[SOFT386_REG_SS].Selector,
State->SegmentRegs[SOFT386_REG_SS].Base,
State->SegmentRegs[SOFT386_REG_SS].Limit,
State->SegmentRegs[SOFT386_REG_SS].Dpl,
State->SegmentRegs[SOFT386_REG_DS].Selector,
State->SegmentRegs[SOFT386_REG_DS].Base,
State->SegmentRegs[SOFT386_REG_DS].Limit,
State->SegmentRegs[SOFT386_REG_DS].Dpl,
State->SegmentRegs[SOFT386_REG_FS].Selector,
State->SegmentRegs[SOFT386_REG_FS].Base,
State->SegmentRegs[SOFT386_REG_FS].Limit,
State->SegmentRegs[SOFT386_REG_FS].Dpl,
State->SegmentRegs[SOFT386_REG_GS].Selector,
State->SegmentRegs[SOFT386_REG_GS].Base,
State->SegmentRegs[SOFT386_REG_GS].Limit,
State->SegmentRegs[SOFT386_REG_GS].Dpl);
State->SegmentRegs[FAST486_REG_ES].Selector,
State->SegmentRegs[FAST486_REG_ES].Base,
State->SegmentRegs[FAST486_REG_ES].Limit,
State->SegmentRegs[FAST486_REG_ES].Dpl,
State->SegmentRegs[FAST486_REG_CS].Selector,
State->SegmentRegs[FAST486_REG_CS].Base,
State->SegmentRegs[FAST486_REG_CS].Limit,
State->SegmentRegs[FAST486_REG_CS].Dpl,
State->SegmentRegs[FAST486_REG_SS].Selector,
State->SegmentRegs[FAST486_REG_SS].Base,
State->SegmentRegs[FAST486_REG_SS].Limit,
State->SegmentRegs[FAST486_REG_SS].Dpl,
State->SegmentRegs[FAST486_REG_DS].Selector,
State->SegmentRegs[FAST486_REG_DS].Base,
State->SegmentRegs[FAST486_REG_DS].Limit,
State->SegmentRegs[FAST486_REG_DS].Dpl,
State->SegmentRegs[FAST486_REG_FS].Selector,
State->SegmentRegs[FAST486_REG_FS].Base,
State->SegmentRegs[FAST486_REG_FS].Limit,
State->SegmentRegs[FAST486_REG_FS].Dpl,
State->SegmentRegs[FAST486_REG_GS].Selector,
State->SegmentRegs[FAST486_REG_GS].Base,
State->SegmentRegs[FAST486_REG_GS].Limit,
State->SegmentRegs[FAST486_REG_GS].Dpl);
DPRINT1("\nFlags: %08X (%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s) Iopl: %u\n",
State->Flags.Long,
State->Flags.Cf ? "CF" : "cf",
@ -224,38 +224,38 @@ Soft386DumpState(PSOFT386_STATE State)
DPRINT1("\nControl Registers:\n"
"CR0 = %08X\tCR1 = %08X\tCR2 = %08X\tCR3 = %08X\n"
"CR4 = %08X\tCR5 = %08X\tCR6 = %08X\tCR7 = %08X\n",
State->ControlRegisters[SOFT386_REG_CR0],
State->ControlRegisters[SOFT386_REG_CR1],
State->ControlRegisters[SOFT386_REG_CR2],
State->ControlRegisters[SOFT386_REG_CR3],
State->ControlRegisters[SOFT386_REG_CR4],
State->ControlRegisters[SOFT386_REG_CR5],
State->ControlRegisters[SOFT386_REG_CR6],
State->ControlRegisters[SOFT386_REG_CR7]);
State->ControlRegisters[FAST486_REG_CR0],
State->ControlRegisters[FAST486_REG_CR1],
State->ControlRegisters[FAST486_REG_CR2],
State->ControlRegisters[FAST486_REG_CR3],
State->ControlRegisters[FAST486_REG_CR4],
State->ControlRegisters[FAST486_REG_CR5],
State->ControlRegisters[FAST486_REG_CR6],
State->ControlRegisters[FAST486_REG_CR7]);
DPRINT1("\nDebug Registers:\n"
"DR0 = %08X\tDR1 = %08X\tDR2 = %08X\tDR3 = %08X\n"
"DR4 = %08X\tDR5 = %08X\tDR6 = %08X\tDR7 = %08X\n",
State->DebugRegisters[SOFT386_REG_DR0],
State->DebugRegisters[SOFT386_REG_DR1],
State->DebugRegisters[SOFT386_REG_DR2],
State->DebugRegisters[SOFT386_REG_DR3],
State->DebugRegisters[SOFT386_REG_DR4],
State->DebugRegisters[SOFT386_REG_DR5],
State->DebugRegisters[SOFT386_REG_DR6],
State->DebugRegisters[SOFT386_REG_DR7]);
State->DebugRegisters[FAST486_REG_DR0],
State->DebugRegisters[FAST486_REG_DR1],
State->DebugRegisters[FAST486_REG_DR2],
State->DebugRegisters[FAST486_REG_DR3],
State->DebugRegisters[FAST486_REG_DR4],
State->DebugRegisters[FAST486_REG_DR5],
State->DebugRegisters[FAST486_REG_DR6],
State->DebugRegisters[FAST486_REG_DR7]);
}
VOID
NTAPI
Soft386Reset(PSOFT386_STATE State)
Fast486Reset(PFAST486_STATE State)
{
INT i;
SOFT386_MEM_READ_PROC MemReadCallback = State->MemReadCallback;
SOFT386_MEM_WRITE_PROC MemWriteCallback = State->MemWriteCallback;
SOFT386_IO_READ_PROC IoReadCallback = State->IoReadCallback;
SOFT386_IO_WRITE_PROC IoWriteCallback = State->IoWriteCallback;
SOFT386_IDLE_PROC IdleCallback = State->IdleCallback;
SOFT386_BOP_PROC BopCallback = State->BopCallback;
FAST486_MEM_READ_PROC MemReadCallback = State->MemReadCallback;
FAST486_MEM_WRITE_PROC MemWriteCallback = State->MemWriteCallback;
FAST486_IO_READ_PROC IoReadCallback = State->IoReadCallback;
FAST486_IO_WRITE_PROC IoWriteCallback = State->IoWriteCallback;
FAST486_IDLE_PROC IdleCallback = State->IdleCallback;
FAST486_BOP_PROC BopCallback = State->BopCallback;
/* Clear the entire structure */
RtlZeroMemory(State, sizeof(*State));
@ -265,7 +265,7 @@ Soft386Reset(PSOFT386_STATE State)
State->InstPtr.LowWord = 0xFFF0;
/* Initialize segments */
for (i = 0; i < SOFT386_NUM_SEG_REGS; i++)
for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
{
/* Set the selector, base and limit, other values don't apply in real mode */
State->SegmentRegs[i].Selector = 0;
@ -274,15 +274,15 @@ Soft386Reset(PSOFT386_STATE State)
}
/* Initialize the code segment */
State->SegmentRegs[SOFT386_REG_CS].Selector = 0xF000;
State->SegmentRegs[SOFT386_REG_CS].Base = 0xFFFF0000;
State->SegmentRegs[FAST486_REG_CS].Selector = 0xF000;
State->SegmentRegs[FAST486_REG_CS].Base = 0xFFFF0000;
/* Initialize the IDT */
State->Idtr.Size = 0x3FF;
State->Idtr.Address = 0;
/* Initialize CR0 */
State->ControlRegisters[SOFT386_REG_CR0] |= SOFT386_CR0_ET;
State->ControlRegisters[FAST486_REG_CR0] |= FAST486_CR0_ET;
/* Restore the callbacks */
State->MemReadCallback = MemReadCallback;
@ -295,7 +295,7 @@ Soft386Reset(PSOFT386_STATE State)
VOID
NTAPI
Soft386Interrupt(PSOFT386_STATE State, UCHAR Number)
Fast486Interrupt(PFAST486_STATE State, UCHAR Number)
{
/* Set the hardware interrupt flag */
State->HardwareInt = TRUE;
@ -304,10 +304,10 @@ Soft386Interrupt(PSOFT386_STATE State, UCHAR Number)
VOID
NTAPI
Soft386ExecuteAt(PSOFT386_STATE State, USHORT Segment, ULONG Offset)
Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset)
{
/* Load the new CS */
if (!Soft386LoadSegment(State, SOFT386_REG_CS, Segment))
if (!Fast486LoadSegment(State, FAST486_REG_CS, Segment))
{
/* An exception occurred, let the handler execute instead */
return;
@ -319,27 +319,27 @@ Soft386ExecuteAt(PSOFT386_STATE State, USHORT Segment, ULONG Offset)
VOID
NTAPI
Soft386SetStack(PSOFT386_STATE State, USHORT Segment, ULONG Offset)
Fast486SetStack(PFAST486_STATE State, USHORT Segment, ULONG Offset)
{
/* Load the new SS */
if (!Soft386LoadSegment(State, SOFT386_REG_SS, Segment))
if (!Fast486LoadSegment(State, FAST486_REG_SS, Segment))
{
/* An exception occurred, let the handler execute instead */
return;
}
/* Set the new SP */
State->GeneralRegs[SOFT386_REG_ESP].Long = Offset;
State->GeneralRegs[FAST486_REG_ESP].Long = Offset;
}
VOID
NTAPI
Soft386SetSegment(PSOFT386_STATE State,
SOFT386_SEG_REGS Segment,
Fast486SetSegment(PFAST486_STATE State,
FAST486_SEG_REGS Segment,
USHORT Selector)
{
/* Call the internal function */
Soft386LoadSegment(State, Segment, Selector);
Fast486LoadSegment(State, Segment, Selector);
}
/* EOF */

File diff suppressed because it is too large Load diff

159
lib/fast486/opcodes.h Normal file
View file

@ -0,0 +1,159 @@
/*
* Fast486 386/486 CPU Emulation Library
* opcodes.h
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _OPCODES_H_
#define _OPCODES_H_
/* DEFINES ********************************************************************/
#ifndef FASTCALL
#define FASTCALL __fastcall
#endif
#define FAST486_NUM_OPCODE_HANDLERS 256
#define FAST486_OPCODE_WRITE_REG (1 << 1)
#define FAST486_OPCODE_HANDLER(x) \
BOOLEAN FASTCALL x(PFAST486_STATE State, UCHAR Opcode)
typedef BOOLEAN (FASTCALL *FAST486_OPCODE_HANDLER_PROC)(PFAST486_STATE, UCHAR);
extern
FAST486_OPCODE_HANDLER_PROC
Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS];
FAST486_OPCODE_HANDLER(Fast486OpcodePrefix);
FAST486_OPCODE_HANDLER(Fast486OpcodeIncrement);
FAST486_OPCODE_HANDLER(Fast486OpcodeDecrement);
FAST486_OPCODE_HANDLER(Fast486OpcodePushReg);
FAST486_OPCODE_HANDLER(Fast486OpcodePopReg);
FAST486_OPCODE_HANDLER(Fast486OpcodeNop);
FAST486_OPCODE_HANDLER(Fast486OpcodeExchangeEax);
FAST486_OPCODE_HANDLER(Fast486OpcodeShortConditionalJmp);
FAST486_OPCODE_HANDLER(Fast486OpcodeClearCarry);
FAST486_OPCODE_HANDLER(Fast486OpcodeSetCarry);
FAST486_OPCODE_HANDLER(Fast486OpcodeComplCarry);
FAST486_OPCODE_HANDLER(Fast486OpcodeClearInt);
FAST486_OPCODE_HANDLER(Fast486OpcodeSetInt);
FAST486_OPCODE_HANDLER(Fast486OpcodeClearDir);
FAST486_OPCODE_HANDLER(Fast486OpcodeSetDir);
FAST486_OPCODE_HANDLER(Fast486OpcodeHalt);
FAST486_OPCODE_HANDLER(Fast486OpcodeInByte);
FAST486_OPCODE_HANDLER(Fast486OpcodeIn);
FAST486_OPCODE_HANDLER(Fast486OpcodeOutByte);
FAST486_OPCODE_HANDLER(Fast486OpcodeOut);
FAST486_OPCODE_HANDLER(Fast486OpcodeShortJump);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovRegImm);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovByteRegImm);
FAST486_OPCODE_HANDLER(Fast486OpcodeAddByteModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeAddModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeAddAl);
FAST486_OPCODE_HANDLER(Fast486OpcodeAddEax);
FAST486_OPCODE_HANDLER(Fast486OpcodeOrByteModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeOrModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeOrAl);
FAST486_OPCODE_HANDLER(Fast486OpcodeOrEax);
FAST486_OPCODE_HANDLER(Fast486OpcodeAndByteModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeAndModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeAndAl);
FAST486_OPCODE_HANDLER(Fast486OpcodeAndEax);
FAST486_OPCODE_HANDLER(Fast486OpcodeXorByteModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeXorModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeXorAl);
FAST486_OPCODE_HANDLER(Fast486OpcodeXorEax);
FAST486_OPCODE_HANDLER(Fast486OpcodeTestByteModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeTestModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeTestAl);
FAST486_OPCODE_HANDLER(Fast486OpcodeTestEax);
FAST486_OPCODE_HANDLER(Fast486OpcodeXchgByteModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeXchgModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodePushEs);
FAST486_OPCODE_HANDLER(Fast486OpcodePopEs);
FAST486_OPCODE_HANDLER(Fast486OpcodePushCs);
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcByteModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcAl);
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcEax);
FAST486_OPCODE_HANDLER(Fast486OpcodePushSs);
FAST486_OPCODE_HANDLER(Fast486OpcodePopSs);
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbByteModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbAl);
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbEax);
FAST486_OPCODE_HANDLER(Fast486OpcodePushDs);
FAST486_OPCODE_HANDLER(Fast486OpcodePopDs);
FAST486_OPCODE_HANDLER(Fast486OpcodeDaa);
FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubByteModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubAl);
FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubEax);
FAST486_OPCODE_HANDLER(Fast486OpcodeDas);
FAST486_OPCODE_HANDLER(Fast486OpcodeAaa);
FAST486_OPCODE_HANDLER(Fast486OpcodeAas);
FAST486_OPCODE_HANDLER(Fast486OpcodePushAll);
FAST486_OPCODE_HANDLER(Fast486OpcodePopAll);
FAST486_OPCODE_HANDLER(Fast486OpcodeBound);
FAST486_OPCODE_HANDLER(Fast486OpcodeArpl);
FAST486_OPCODE_HANDLER(Fast486OpcodePushImm);
FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm);
FAST486_OPCODE_HANDLER(Fast486OpcodePushByteImm);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovByteModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovModrm);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovStoreSeg);
FAST486_OPCODE_HANDLER(Fast486OpcodeLea);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovLoadSeg);
FAST486_OPCODE_HANDLER(Fast486OpcodeCwde);
FAST486_OPCODE_HANDLER(Fast486OpcodeCdq);
FAST486_OPCODE_HANDLER(Fast486OpcodeCallAbs);
FAST486_OPCODE_HANDLER(Fast486OpcodeWait);
FAST486_OPCODE_HANDLER(Fast486OpcodePushFlags);
FAST486_OPCODE_HANDLER(Fast486OpcodePopFlags);
FAST486_OPCODE_HANDLER(Fast486OpcodeSahf);
FAST486_OPCODE_HANDLER(Fast486OpcodeLahf);
FAST486_OPCODE_HANDLER(Fast486OpcodeRet);
FAST486_OPCODE_HANDLER(Fast486OpcodeLdsLes);
FAST486_OPCODE_HANDLER(Fast486OpcodeEnter);
FAST486_OPCODE_HANDLER(Fast486OpcodeLeave);
FAST486_OPCODE_HANDLER(Fast486OpcodeRetFarImm);
FAST486_OPCODE_HANDLER(Fast486OpcodeRetFar);
FAST486_OPCODE_HANDLER(Fast486OpcodeInt);
FAST486_OPCODE_HANDLER(Fast486OpcodeIret);
FAST486_OPCODE_HANDLER(Fast486OpcodeAam);
FAST486_OPCODE_HANDLER(Fast486OpcodeAad);
FAST486_OPCODE_HANDLER(Fast486OpcodeXlat);
FAST486_OPCODE_HANDLER(Fast486OpcodeLoop);
FAST486_OPCODE_HANDLER(Fast486OpcodeJecxz);
FAST486_OPCODE_HANDLER(Fast486OpcodeCall);
FAST486_OPCODE_HANDLER(Fast486OpcodeJmp);
FAST486_OPCODE_HANDLER(Fast486OpcodeJmpAbs);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovAlOffset);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovEaxOffset);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovOffsetAl);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovOffsetEax);
FAST486_OPCODE_HANDLER(Fast486OpcodeSalc);
FAST486_OPCODE_HANDLER(Fast486OpcodeMovs);
FAST486_OPCODE_HANDLER(Fast486OpcodeCmps);
FAST486_OPCODE_HANDLER(Fast486OpcodeStos);
FAST486_OPCODE_HANDLER(Fast486OpcodeLods);
FAST486_OPCODE_HANDLER(Fast486OpcodeScas);
FAST486_OPCODE_HANDLER(Fast486OpcodeIns);
FAST486_OPCODE_HANDLER(Fast486OpcodeOuts);
#endif // _OPCODES_H_

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
* Soft386 386/486 CPU Emulation Library
* Fast486 386/486 CPU Emulation Library
* opgroups.h
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
@ -24,22 +24,22 @@
/* DEFINES ********************************************************************/
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroup8082);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroup81);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroup83);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroup8F);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupC0);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupC1);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupC6);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupC7);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupD0);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupD1);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupD2);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupD3);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupF6);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupF7);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFE);
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFF);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup8082);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup81);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup83);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup8F);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC0);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC1);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC6);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC7);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupD0);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupD1);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupD2);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupD3);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupF6);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupF7);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFE);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFF);
#endif // _OPGROUPS_H_

View file

@ -1,11 +0,0 @@
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs/soft386)
list(APPEND SOURCE
soft386.c
opcodes.c
opgroups.c
extraops.c
common.c)
add_library(soft386 ${SOURCE})

View file

@ -1,159 +0,0 @@
/*
* Soft386 386/486 CPU Emulation Library
* opcodes.h
*
* Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _OPCODES_H_
#define _OPCODES_H_
/* DEFINES ********************************************************************/
#ifndef FASTCALL
#define FASTCALL __fastcall
#endif
#define SOFT386_NUM_OPCODE_HANDLERS 256
#define SOFT386_OPCODE_WRITE_REG (1 << 1)
#define SOFT386_OPCODE_HANDLER(x) \
BOOLEAN FASTCALL x(PSOFT386_STATE State, UCHAR Opcode)
typedef BOOLEAN (FASTCALL *SOFT386_OPCODE_HANDLER_PROC)(PSOFT386_STATE, UCHAR);
extern
SOFT386_OPCODE_HANDLER_PROC
Soft386OpcodeHandlers[SOFT386_NUM_OPCODE_HANDLERS];
SOFT386_OPCODE_HANDLER(Soft386OpcodePrefix);
SOFT386_OPCODE_HANDLER(Soft386OpcodeIncrement);
SOFT386_OPCODE_HANDLER(Soft386OpcodeDecrement);
SOFT386_OPCODE_HANDLER(Soft386OpcodePushReg);
SOFT386_OPCODE_HANDLER(Soft386OpcodePopReg);
SOFT386_OPCODE_HANDLER(Soft386OpcodeNop);
SOFT386_OPCODE_HANDLER(Soft386OpcodeExchangeEax);
SOFT386_OPCODE_HANDLER(Soft386OpcodeShortConditionalJmp);
SOFT386_OPCODE_HANDLER(Soft386OpcodeClearCarry);
SOFT386_OPCODE_HANDLER(Soft386OpcodeSetCarry);
SOFT386_OPCODE_HANDLER(Soft386OpcodeComplCarry);
SOFT386_OPCODE_HANDLER(Soft386OpcodeClearInt);
SOFT386_OPCODE_HANDLER(Soft386OpcodeSetInt);
SOFT386_OPCODE_HANDLER(Soft386OpcodeClearDir);
SOFT386_OPCODE_HANDLER(Soft386OpcodeSetDir);
SOFT386_OPCODE_HANDLER(Soft386OpcodeHalt);
SOFT386_OPCODE_HANDLER(Soft386OpcodeInByte);
SOFT386_OPCODE_HANDLER(Soft386OpcodeIn);
SOFT386_OPCODE_HANDLER(Soft386OpcodeOutByte);
SOFT386_OPCODE_HANDLER(Soft386OpcodeOut);
SOFT386_OPCODE_HANDLER(Soft386OpcodeShortJump);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovRegImm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovByteRegImm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAddByteModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAddModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAddAl);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAddEax);
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrByteModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrAl);
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrEax);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndByteModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndAl);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndEax);
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorByteModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorAl);
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorEax);
SOFT386_OPCODE_HANDLER(Soft386OpcodeTestByteModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeTestModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeTestAl);
SOFT386_OPCODE_HANDLER(Soft386OpcodeTestEax);
SOFT386_OPCODE_HANDLER(Soft386OpcodeXchgByteModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeXchgModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodePushEs);
SOFT386_OPCODE_HANDLER(Soft386OpcodePopEs);
SOFT386_OPCODE_HANDLER(Soft386OpcodePushCs);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAdcByteModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAdcModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAdcAl);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAdcEax);
SOFT386_OPCODE_HANDLER(Soft386OpcodePushSs);
SOFT386_OPCODE_HANDLER(Soft386OpcodePopSs);
SOFT386_OPCODE_HANDLER(Soft386OpcodeSbbByteModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeSbbModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeSbbAl);
SOFT386_OPCODE_HANDLER(Soft386OpcodeSbbEax);
SOFT386_OPCODE_HANDLER(Soft386OpcodePushDs);
SOFT386_OPCODE_HANDLER(Soft386OpcodePopDs);
SOFT386_OPCODE_HANDLER(Soft386OpcodeDaa);
SOFT386_OPCODE_HANDLER(Soft386OpcodeCmpSubByteModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeCmpSubModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeCmpSubAl);
SOFT386_OPCODE_HANDLER(Soft386OpcodeCmpSubEax);
SOFT386_OPCODE_HANDLER(Soft386OpcodeDas);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAaa);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAas);
SOFT386_OPCODE_HANDLER(Soft386OpcodePushAll);
SOFT386_OPCODE_HANDLER(Soft386OpcodePopAll);
SOFT386_OPCODE_HANDLER(Soft386OpcodeBound);
SOFT386_OPCODE_HANDLER(Soft386OpcodeArpl);
SOFT386_OPCODE_HANDLER(Soft386OpcodePushImm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeImulModrmImm);
SOFT386_OPCODE_HANDLER(Soft386OpcodePushByteImm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovByteModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovModrm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovStoreSeg);
SOFT386_OPCODE_HANDLER(Soft386OpcodeLea);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovLoadSeg);
SOFT386_OPCODE_HANDLER(Soft386OpcodeCwde);
SOFT386_OPCODE_HANDLER(Soft386OpcodeCdq);
SOFT386_OPCODE_HANDLER(Soft386OpcodeCallAbs);
SOFT386_OPCODE_HANDLER(Soft386OpcodeWait);
SOFT386_OPCODE_HANDLER(Soft386OpcodePushFlags);
SOFT386_OPCODE_HANDLER(Soft386OpcodePopFlags);
SOFT386_OPCODE_HANDLER(Soft386OpcodeSahf);
SOFT386_OPCODE_HANDLER(Soft386OpcodeLahf);
SOFT386_OPCODE_HANDLER(Soft386OpcodeRet);
SOFT386_OPCODE_HANDLER(Soft386OpcodeLdsLes);
SOFT386_OPCODE_HANDLER(Soft386OpcodeEnter);
SOFT386_OPCODE_HANDLER(Soft386OpcodeLeave);
SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFarImm);
SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFar);
SOFT386_OPCODE_HANDLER(Soft386OpcodeInt);
SOFT386_OPCODE_HANDLER(Soft386OpcodeIret);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAam);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAad);
SOFT386_OPCODE_HANDLER(Soft386OpcodeXlat);
SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop);
SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz);
SOFT386_OPCODE_HANDLER(Soft386OpcodeCall);
SOFT386_OPCODE_HANDLER(Soft386OpcodeJmp);
SOFT386_OPCODE_HANDLER(Soft386OpcodeJmpAbs);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovAlOffset);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovEaxOffset);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovOffsetAl);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovOffsetEax);
SOFT386_OPCODE_HANDLER(Soft386OpcodeSalc);
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovs);
SOFT386_OPCODE_HANDLER(Soft386OpcodeCmps);
SOFT386_OPCODE_HANDLER(Soft386OpcodeStos);
SOFT386_OPCODE_HANDLER(Soft386OpcodeLods);
SOFT386_OPCODE_HANDLER(Soft386OpcodeScas);
SOFT386_OPCODE_HANDLER(Soft386OpcodeIns);
SOFT386_OPCODE_HANDLER(Soft386OpcodeOuts);
#endif // _OPCODES_H_

View file

@ -1,6 +1,6 @@
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs/softx86)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs/soft386)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs/fast486)
spec2def(ntvdm.exe ntvdm.spec)
@ -19,7 +19,7 @@ list(APPEND SOURCE
add_executable(ntvdm ${SOURCE})
set_module_type(ntvdm win32cui UNICODE)
target_link_libraries(ntvdm softx86 softx87 soft386)
target_link_libraries(ntvdm softx86 softx87 fast486)
add_importlibs(ntvdm msvcrt user32 gdi32 kernel32 ntdll)
add_dependencies(ntvdm softx86 softx87)
add_cd_file(TARGET ntvdm DESTINATION reactos/system32 FOR all)

View file

@ -24,7 +24,7 @@
softx86_ctx EmulatorContext;
softx87_ctx FpuEmulatorContext;
#else
SOFT386_STATE EmulatorContext;
FAST486_STATE EmulatorContext;
#endif
static BOOLEAN A20Line = FALSE;
@ -239,8 +239,8 @@ static VOID EmulatorBop(WORD Code)
StackSegment = EmulatorContext.state->segment_reg[SX86_SREG_SS].val;
StackPointer = EmulatorContext.state->general_reg[SX86_REG_SP].val;
#else
StackSegment = EmulatorContext.SegmentRegs[SOFT386_REG_SS].Selector;
StackPointer = EmulatorContext.GeneralRegs[SOFT386_REG_ESP].LowWord;
StackSegment = EmulatorContext.SegmentRegs[FAST486_REG_SS].Selector;
StackPointer = EmulatorContext.GeneralRegs[FAST486_REG_ESP].LowWord;
#endif
/* Get the stack */
@ -340,7 +340,7 @@ static VOID EmulatorBop(WORD Code)
}
#ifdef NEW_EMULATOR
static VOID WINAPI EmulatorBiosOperation(PSOFT386_STATE State, WORD Code)
static VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, WORD Code)
{
/*
* HACK: To maintain softx86 compatbility, just call the old EmulatorBop here.
@ -421,14 +421,14 @@ BOOLEAN EmulatorInitialize()
softx87_connect_to_CPU(&EmulatorContext, &FpuEmulatorContext);
#else
/* Set the callbacks */
EmulatorContext.MemReadCallback = (SOFT386_MEM_READ_PROC)EmulatorReadMemory;
EmulatorContext.MemWriteCallback = (SOFT386_MEM_WRITE_PROC)EmulatorWriteMemory;
EmulatorContext.IoReadCallback = (SOFT386_IO_READ_PROC)EmulatorReadIo;
EmulatorContext.IoWriteCallback = (SOFT386_IO_WRITE_PROC)EmulatorWriteIo;
EmulatorContext.BopCallback = (SOFT386_BOP_PROC)EmulatorBiosOperation;
EmulatorContext.MemReadCallback = (FAST486_MEM_READ_PROC)EmulatorReadMemory;
EmulatorContext.MemWriteCallback = (FAST486_MEM_WRITE_PROC)EmulatorWriteMemory;
EmulatorContext.IoReadCallback = (FAST486_IO_READ_PROC)EmulatorReadIo;
EmulatorContext.IoWriteCallback = (FAST486_IO_WRITE_PROC)EmulatorWriteIo;
EmulatorContext.BopCallback = (FAST486_BOP_PROC)EmulatorBiosOperation;
/* Reset the CPU */
Soft386Reset(&EmulatorContext);
Fast486Reset(&EmulatorContext);
#endif
/* Enable interrupts */
@ -443,7 +443,7 @@ VOID EmulatorSetStack(WORD Segment, DWORD Offset)
/* Call the softx86 API */
softx86_set_stack_ptr(&EmulatorContext, Segment, Offset);
#else
Soft386SetStack(&EmulatorContext, Segment, Offset);
Fast486SetStack(&EmulatorContext, Segment, Offset);
#endif
}
@ -454,8 +454,8 @@ VOID EmulatorExecute(WORD Segment, WORD Offset)
/* Call the softx86 API */
softx86_set_instruction_ptr(&EmulatorContext, Segment, Offset);
#else
/* Tell Soft386 to move the instruction pointer */
Soft386ExecuteAt(&EmulatorContext, Segment, Offset);
/* Tell Fast486 to move the instruction pointer */
Fast486ExecuteAt(&EmulatorContext, Segment, Offset);
#endif
}
@ -472,8 +472,8 @@ VOID EmulatorInterrupt(BYTE Number)
/* Call the softx86 API */
softx86_make_simple_interrupt_call(&EmulatorContext, &Segment, &Offset);
#else
/* Call the Soft386 API */
Soft386Interrupt(&EmulatorContext, Number);
/* Call the Fast486 API */
Fast486Interrupt(&EmulatorContext, Number);
#endif
}
@ -483,8 +483,8 @@ VOID EmulatorExternalInterrupt(BYTE Number)
/* Call the softx86 API */
softx86_ext_hw_signal(&EmulatorContext, Number);
#else
/* Call the Soft386 API */
Soft386Interrupt(&EmulatorContext, Number);
/* Call the Fast486 API */
Fast486Interrupt(&EmulatorContext, Number);
#endif
}
@ -538,7 +538,7 @@ VOID EmulatorSetRegister(ULONG Register, ULONG Value)
}
else
{
Soft386SetSegment(&EmulatorContext, Register - EMULATOR_REG_ES, (USHORT)Value);
Fast486SetSegment(&EmulatorContext, Register - EMULATOR_REG_ES, (USHORT)Value);
}
#endif
}
@ -605,10 +605,10 @@ VOID EmulatorStep(VOID)
}
#else
/* Dump the state for debugging purposes */
// Soft386DumpState(&EmulatorContext);
// Fast486DumpState(&EmulatorContext);
/* Execute the next instruction */
Soft386StepInto(&EmulatorContext);
Fast486StepInto(&EmulatorContext);
#endif
}

View file

@ -17,7 +17,7 @@
#include <softx86.h>
#include <softx87.h>
#else
#include <soft386.h>
#include <fast486.h>
#endif
/* DEFINES ********************************************************************/
@ -94,7 +94,7 @@ extern softx87_ctx FpuEmulatorContext;
#else
#define NTVDMCALL __stdcall
extern SOFT386_STATE EmulatorContext;
extern FAST486_STATE EmulatorContext;
#endif

View file

@ -27,8 +27,8 @@
#define FAR_POINTER(x) ((ULONG_PTR)BaseAddress + TO_LINEAR(HIWORD(x), LOWORD(x)))
#define STEPS_PER_CYCLE 256
// Uncomment the following to use the new Soft386 CPU emulator (EXPERIMENTAL)
// #define NEW_EMULATOR
// Uncomment the following to use the new Fast486 CPU emulator (EXPERIMENTAL)
#define NEW_EMULATOR
/* FUNCTIONS ******************************************************************/