mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
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:
parent
9b02129308
commit
51040fc61e
21 changed files with 2662 additions and 2662 deletions
397
include/reactos/libs/fast486/fast486.h
Normal file
397
include/reactos/libs/fast486/fast486.h
Normal 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 */
|
|
@ -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 */
|
|
@ -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()
|
||||
|
||||
|
|
11
lib/fast486/CMakeLists.txt
Normal file
11
lib/fast486/CMakeLists.txt
Normal 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})
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
|
@ -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,
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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_
|
||||
|
|
@ -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
159
lib/fast486/opcodes.h
Normal 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
|
@ -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_
|
||||
|
|
@ -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})
|
|
@ -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_
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 ******************************************************************/
|
||||
|
||||
|
|
Loading…
Reference in a new issue