#ifndef _FAST486_H_
#define _FAST486_H_
+#pragma once
+
/* DEFINES ********************************************************************/
+#ifndef FASTCALL
+#define FASTCALL __fastcall
+#endif
+
#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_NUM_CTRL_REGS 3
+#define FAST486_NUM_DBG_REGS 6
+#define FAST486_NUM_FPU_REGS 8
#define FAST486_CR0_PE (1 << 0)
#define FAST486_CR0_MP (1 << 1)
#define FAST486_CR0_CD (1 << 30)
#define FAST486_CR0_PG (1 << 31)
+#define FAST486_DR4_B0 (1 << 0)
+#define FAST486_DR4_B1 (1 << 1)
+#define FAST486_DR4_B2 (1 << 2)
+#define FAST486_DR4_B3 (1 << 3)
+#define FAST486_DR4_BD (1 << 13)
+#define FAST486_DR4_BS (1 << 14)
+#define FAST486_DR4_BT (1 << 15)
+
+#define FAST486_DR5_L0 (1 << 0)
+#define FAST486_DR5_G0 (1 << 1)
+#define FAST486_DR5_L1 (1 << 2)
+#define FAST486_DR5_G1 (1 << 3)
+#define FAST486_DR5_L2 (1 << 4)
+#define FAST486_DR5_G2 (1 << 5)
+#define FAST486_DR5_L3 (1 << 6)
+#define FAST486_DR5_G3 (1 << 7)
+#define FAST486_DR5_LE (1 << 8)
+#define FAST486_DR5_GE (1 << 9)
+#define FAST486_DR5_GD (1 << 13)
+
+#define FAST486_DBG_BREAK_EXEC 0
+#define FAST486_DBG_BREAK_WRITE 1
+#define FAST486_DBG_BREAK_READWRITE 3
+
+#define FAST486_DR4_RESERVED 0xFFFF1FF0
+#define FAST486_DR5_RESERVED 0x0000DC00
+
#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_LDT_SIGNATURE 0x02
+#define FAST486_TSS_SIGNATURE 0x09
+
#define FAST486_PREFIX_SEG (1 << 0)
#define FAST486_PREFIX_OPSIZE (1 << 1)
#define FAST486_PREFIX_ADSIZE (1 << 2)
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_REG_CR0 = 0,
+ FAST486_REG_CR2 = 1,
+ FAST486_REG_CR3 = 2,
} 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_REG_DR0 = 0,
+ FAST486_REG_DR1 = 1,
+ FAST486_REG_DR2 = 2,
+ FAST486_REG_DR3 = 3,
+ FAST486_REG_DR4 = 4,
+ FAST486_REG_DR5 = 5,
+ FAST486_REG_DR6 = 4, // alias to DR4
+ FAST486_REG_DR7 = 5 // alias to DR5
} FAST486_DBG_REGS, *PFAST486_DBG_REGS;
typedef enum _FAST486_EXCEPTIONS
FAST486_EXCEPTION_MC = 0x12
} FAST486_EXCEPTIONS, *PFAST486_EXCEPTIONS;
+typedef enum _FAST486_INT_STATUS
+{
+ FAST486_INT_NONE = 0,
+ FAST486_INT_EXECUTE = 1,
+ FAST486_INT_SIGNAL = 2
+} FAST486_INT_STATUS, *PFAST486_INT_STATUS;
+
typedef
-BOOLEAN
+VOID
(NTAPI *FAST486_MEM_READ_PROC)
(
PFAST486_STATE State,
);
typedef
-BOOLEAN
+VOID
(NTAPI *FAST486_MEM_WRITE_PROC)
(
PFAST486_STATE State,
PFAST486_STATE State,
ULONG Port,
PVOID Buffer,
- ULONG Size
+ ULONG DataCount,
+ UCHAR DataSize
);
typedef
PFAST486_STATE State,
ULONG Port,
PVOID Buffer,
- ULONG Size
+ ULONG DataCount,
+ UCHAR DataSize
);
typedef
(NTAPI *FAST486_BOP_PROC)
(
PFAST486_STATE State,
- USHORT BopCode
+ UCHAR BopCode
+);
+
+typedef
+UCHAR
+(NTAPI *FAST486_INT_ACK_PROC)
+(
+ PFAST486_STATE State
);
typedef union _FAST486_REG
ULONG Base;
} FAST486_SEG_REG, *PFAST486_SEG_REG;
+typedef struct
+{
+ USHORT Selector;
+ ULONG Base;
+ ULONG Limit;
+} FAST486_LDT_REG;
+
+typedef struct
+{
+ USHORT Selector;
+ ULONG Base;
+ ULONG Limit;
+ BOOLEAN Busy;
+} FAST486_TASK_REG, *PFAST486_TASK_REG;
+
+#pragma pack(push, 1)
+
typedef struct
{
ULONG Limit : 16;
- ULONG Base : 24;
+ ULONG Base : 16;
+ ULONG BaseMid : 8;
ULONG Accessed : 1;
ULONG ReadWrite : 1;
ULONG DirConf : 1;
ULONG BaseHigh : 8;
} FAST486_GDT_ENTRY, *PFAST486_GDT_ENTRY;
+/* Verify the structure size */
+C_ASSERT(sizeof(FAST486_GDT_ENTRY) == sizeof(ULONGLONG));
+
+typedef struct
+{
+ ULONG Limit : 16;
+ ULONG Base : 16;
+ ULONG BaseMid : 8;
+ ULONG Signature : 5;
+ ULONG Dpl : 2;
+ ULONG Present : 1;
+ ULONG LimitHigh : 4;
+ ULONG Avl : 1;
+ ULONG Reserved : 2;
+ ULONG Granularity : 1;
+ ULONG BaseHigh : 8;
+} FAST486_SYSTEM_DESCRIPTOR, *PFAST486_SYSTEM_DESCRIPTOR;
+
+/* Verify the structure size */
+C_ASSERT(sizeof(FAST486_SYSTEM_DESCRIPTOR) == sizeof(ULONGLONG));
+
typedef struct
{
ULONG Offset : 16;
ULONG OffsetHigh : 16;
} FAST486_CALL_GATE, *PFAST486_CALL_GATE;
+/* Verify the structure size */
+C_ASSERT(sizeof(FAST486_CALL_GATE) == sizeof(ULONGLONG));
+
typedef struct
{
ULONG Offset : 16;
ULONG OffsetHigh : 16;
} FAST486_IDT_ENTRY, *PFAST486_IDT_ENTRY;
+/* Verify the structure size */
+C_ASSERT(sizeof(FAST486_IDT_ENTRY) == sizeof(ULONGLONG));
+
+#pragma pack(pop)
+
typedef struct _FAST486_TABLE_REG
{
USHORT Size;
ULONG Reserved2 : 1;
ULONG Rf : 1;
ULONG Vm : 1;
- ULONG Ac : 1;
- ULONG Vif : 1;
- ULONG Vip : 1;
- ULONG Id : 1;
- // ULONG Reserved : 10;
+ // ULONG Reserved : 14;
};
} FAST486_FLAGS_REG, *PFAST486_FLAGS_REG;
ULONG IopbOffset;
} FAST486_TSS, *PFAST486_TSS;
+typedef struct _FAST486_FPU_DATA_REG
+{
+ ULONGLONG Mantissa;
+ USHORT Exponent;
+} FAST486_FPU_DATA_REG, *PFAST486_FPU_DATA_REG;
+
+typedef union _FAST486_FPU_STATUS_REG
+{
+ USHORT Value;
+
+ struct
+ {
+ ULONG Ie : 1;
+ ULONG De : 1;
+ ULONG Ze : 1;
+ ULONG Oe : 1;
+ ULONG Ue : 1;
+ ULONG Pe : 1;
+ ULONG Sf : 1;
+ ULONG Es : 1;
+ ULONG Code0 : 1;
+ ULONG Code1 : 1;
+ ULONG Code2 : 1;
+ ULONG Top : 3;
+ ULONG Code3 : 1;
+ ULONG Busy : 1;
+ };
+} FAST486_FPU_STATUS_REG, *PFAST486_FPU_STATUS_REG;
+
+typedef union _FAST486_FPU_CONTROL_REG
+{
+ USHORT Value;
+
+ struct
+ {
+ ULONG Im : 1;
+ ULONG Dm : 1;
+ ULONG Zm : 1;
+ ULONG Om : 1;
+ ULONG Um : 1;
+ ULONG Pm : 1;
+ ULONG Reserved : 2;
+ ULONG Pc : 2;
+ ULONG Rc : 2;
+ ULONG Inf : 1;
+ // ULONG Reserved1 : 3;
+ };
+} FAST486_FPU_CONTROL_REG, *PFAST486_FPU_CONTROL_REG;
+
struct _FAST486_STATE
{
FAST486_MEM_READ_PROC MemReadCallback;
FAST486_IO_WRITE_PROC IoWriteCallback;
FAST486_IDLE_PROC IdleCallback;
FAST486_BOP_PROC BopCallback;
+ FAST486_INT_ACK_PROC IntAckCallback;
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;
+ FAST486_TABLE_REG Gdtr, Idtr;
+ FAST486_LDT_REG Ldtr;
+ FAST486_TASK_REG TaskReg;
+ UCHAR Cpl;
ULONG ControlRegisters[FAST486_NUM_CTRL_REGS];
ULONG DebugRegisters[FAST486_NUM_DBG_REGS];
ULONG ExceptionCount;
ULONG PrefixFlags;
FAST486_SEG_REGS SegmentOverride;
- BOOLEAN HardwareInt;
+ FAST486_INT_STATUS IntStatus;
UCHAR PendingIntNum;
+ PULONG Tlb;
+ FAST486_FPU_DATA_REG FpuRegisters[FAST486_NUM_FPU_REGS];
+ FAST486_FPU_STATUS_REG FpuStatus;
+ FAST486_FPU_CONTROL_REG FpuControl;
+ USHORT FpuTag;
};
/* FUNCTIONS ******************************************************************/
+VOID
+NTAPI
+Fast486Initialize(PFAST486_STATE 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_INT_ACK_PROC IntAckCallback,
+ PULONG Tlb);
+
+VOID
+NTAPI
+Fast486Reset(PFAST486_STATE State);
+
VOID
NTAPI
Fast486Continue(PFAST486_STATE State);
VOID
NTAPI
-Fast486Reset(PFAST486_STATE State);
+Fast486Interrupt(PFAST486_STATE State, UCHAR Number);
VOID
NTAPI
-Fast486Interrupt(PFAST486_STATE State, UCHAR Number);
+Fast486InterruptSignal(PFAST486_STATE State);
VOID
NTAPI