2 * Fast486 386/486 CPU Emulation Library
5 * Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27 /* DEFINES ********************************************************************/
30 #define FASTCALL __fastcall
33 #define FAST486_NUM_GEN_REGS 8
34 #define FAST486_NUM_SEG_REGS 6
35 #define FAST486_NUM_CTRL_REGS 3
36 #define FAST486_NUM_DBG_REGS 6
37 #define FAST486_NUM_FPU_REGS 8
39 #define FAST486_CR0_PE (1 << 0)
40 #define FAST486_CR0_MP (1 << 1)
41 #define FAST486_CR0_EM (1 << 2)
42 #define FAST486_CR0_TS (1 << 3)
43 #define FAST486_CR0_ET (1 << 4)
44 #define FAST486_CR0_NE (1 << 5)
45 #define FAST486_CR0_WP (1 << 16)
46 #define FAST486_CR0_AM (1 << 18)
47 #define FAST486_CR0_NW (1 << 29)
48 #define FAST486_CR0_CD (1 << 30)
49 #define FAST486_CR0_PG (1 << 31)
51 #define FAST486_DR4_B0 (1 << 0)
52 #define FAST486_DR4_B1 (1 << 1)
53 #define FAST486_DR4_B2 (1 << 2)
54 #define FAST486_DR4_B3 (1 << 3)
55 #define FAST486_DR4_BD (1 << 13)
56 #define FAST486_DR4_BS (1 << 14)
57 #define FAST486_DR4_BT (1 << 15)
59 #define FAST486_DR5_L0 (1 << 0)
60 #define FAST486_DR5_G0 (1 << 1)
61 #define FAST486_DR5_L1 (1 << 2)
62 #define FAST486_DR5_G1 (1 << 3)
63 #define FAST486_DR5_L2 (1 << 4)
64 #define FAST486_DR5_G2 (1 << 5)
65 #define FAST486_DR5_L3 (1 << 6)
66 #define FAST486_DR5_G3 (1 << 7)
67 #define FAST486_DR5_LE (1 << 8)
68 #define FAST486_DR5_GE (1 << 9)
69 #define FAST486_DR5_GD (1 << 13)
71 #define FAST486_DBG_BREAK_EXEC 0
72 #define FAST486_DBG_BREAK_WRITE 1
73 #define FAST486_DBG_BREAK_READWRITE 3
75 #define FAST486_DR4_RESERVED 0xFFFF1FF0
76 #define FAST486_DR5_RESERVED 0x0000DC00
78 #define FAST486_TSS_16_SIGNATURE 0x01
79 #define FAST486_LDT_SIGNATURE 0x02
80 #define FAST486_BUSY_TSS_16_SIGNATURE 0x03
81 #define FAST486_CALL_GATE_16_SIGNATURE 0x04
82 #define FAST486_TASK_GATE_SIGNATURE 0x05
83 #define FAST486_IDT_INT_GATE 0x06
84 #define FAST486_IDT_TRAP_GATE 0x07
85 #define FAST486_TSS_SIGNATURE 0x09
86 #define FAST486_BUSY_TSS_SIGNATURE 0x0B
87 #define FAST486_CALL_GATE_SIGNATURE 0x0C
88 #define FAST486_IDT_INT_GATE_32 0x0E
89 #define FAST486_IDT_TRAP_GATE_32 0x0F
91 #define FAST486_PREFIX_SEG (1 << 0)
92 #define FAST486_PREFIX_OPSIZE (1 << 1)
93 #define FAST486_PREFIX_ADSIZE (1 << 2)
94 #define FAST486_PREFIX_LOCK (1 << 3)
95 #define FAST486_PREFIX_REPNZ (1 << 4)
96 #define FAST486_PREFIX_REP (1 << 5)
98 #define FAST486_FPU_DEFAULT_CONTROL 0x037F
100 #define FAST486_PAGE_SIZE 4096
101 #define FAST486_CACHE_SIZE 32
104 * These are condiciones sine quibus non that should be respected, because
105 * otherwise when fetching DWORDs you would read extra garbage bytes
106 * (by reading outside of the prefetch buffer). The prefetch cache must
107 * also not cross a page boundary.
109 C_ASSERT((FAST486_CACHE_SIZE
>= sizeof(DWORD
))
110 && (FAST486_CACHE_SIZE
<= FAST486_PAGE_SIZE
));
112 struct _FAST486_STATE
;
113 typedef struct _FAST486_STATE FAST486_STATE
, *PFAST486_STATE
;
115 typedef enum _FAST486_GEN_REGS
125 } FAST486_GEN_REGS
, *PFAST486_GEN_REGS
;
127 typedef enum _FAST486_SEG_REGS
135 } FAST486_SEG_REGS
, *PFAST486_SEG_REGS
;
137 typedef enum _FAST486_CTRL_REGS
142 } FAST486_CTRL_REGS
, *PFAST486_CTRL_REGS
;
144 typedef enum _FAST486_DBG_REGS
152 FAST486_REG_DR6
= 4, // alias to DR4
153 FAST486_REG_DR7
= 5 // alias to DR5
154 } FAST486_DBG_REGS
, *PFAST486_DBG_REGS
;
156 typedef enum _FAST486_EXCEPTIONS
158 FAST486_EXCEPTION_DE
= 0x00,
159 FAST486_EXCEPTION_DB
= 0x01,
160 FAST486_EXCEPTION_BP
= 0x03,
161 FAST486_EXCEPTION_OF
= 0x04,
162 FAST486_EXCEPTION_BR
= 0x05,
163 FAST486_EXCEPTION_UD
= 0x06,
164 FAST486_EXCEPTION_NM
= 0x07,
165 FAST486_EXCEPTION_DF
= 0x08,
166 FAST486_EXCEPTION_TS
= 0x0A,
167 FAST486_EXCEPTION_NP
= 0x0B,
168 FAST486_EXCEPTION_SS
= 0x0C,
169 FAST486_EXCEPTION_GP
= 0x0D,
170 FAST486_EXCEPTION_PF
= 0x0E,
171 FAST486_EXCEPTION_MF
= 0x10,
172 FAST486_EXCEPTION_AC
= 0x11,
173 FAST486_EXCEPTION_MC
= 0x12
174 } FAST486_EXCEPTIONS
, *PFAST486_EXCEPTIONS
;
178 (NTAPI
*FAST486_MEM_READ_PROC
)
180 PFAST486_STATE State
,
188 (NTAPI
*FAST486_MEM_WRITE_PROC
)
190 PFAST486_STATE State
,
198 (NTAPI
*FAST486_IO_READ_PROC
)
200 PFAST486_STATE State
,
209 (NTAPI
*FAST486_IO_WRITE_PROC
)
211 PFAST486_STATE State
,
220 (NTAPI
*FAST486_BOP_PROC
)
222 PFAST486_STATE State
,
228 (NTAPI
*FAST486_INT_ACK_PROC
)
235 (NTAPI
*FAST486_FPU_PROC
)
240 typedef union _FAST486_REG
252 } FAST486_REG
, *PFAST486_REG
;
254 typedef struct _FAST486_SEG_REG
258 /* Descriptor cache */
262 ULONG Executable
: 1;
263 ULONG SystemType
: 1;
270 } FAST486_SEG_REG
, *PFAST486_SEG_REG
;
272 typedef struct _FAST486_LDT_REG
277 } FAST486_LDT_REG
, *PFAST486_LDT_REG
;
279 typedef struct _FAST486_TASK_REG
284 } FAST486_TASK_REG
, *PFAST486_TASK_REG
;
286 #include <pshpack1.h>
296 ULONG Executable
: 1;
297 ULONG SystemType
: 1;
304 ULONG Granularity
: 1;
306 } FAST486_GDT_ENTRY
, *PFAST486_GDT_ENTRY
;
308 /* Verify the structure size */
309 C_ASSERT(sizeof(FAST486_GDT_ENTRY
) == sizeof(ULONGLONG
));
322 ULONG Granularity
: 1;
324 } FAST486_SYSTEM_DESCRIPTOR
, *PFAST486_SYSTEM_DESCRIPTOR
;
326 /* Verify the structure size */
327 C_ASSERT(sizeof(FAST486_SYSTEM_DESCRIPTOR
) == sizeof(ULONGLONG
));
333 ULONG ParamCount
: 5;
336 ULONG SystemType
: 1;
339 ULONG OffsetHigh
: 16;
340 } FAST486_CALL_GATE
, *PFAST486_CALL_GATE
;
342 /* Verify the structure size */
343 C_ASSERT(sizeof(FAST486_CALL_GATE
) == sizeof(ULONGLONG
));
354 ULONG OffsetHigh
: 16;
355 } FAST486_IDT_ENTRY
, *PFAST486_IDT_ENTRY
;
357 /* Verify the structure size */
358 C_ASSERT(sizeof(FAST486_IDT_ENTRY
) == sizeof(ULONGLONG
));
360 typedef struct _FAST486_TSS
388 } FAST486_TSS
, *PFAST486_TSS
;
390 typedef struct _FAST486_LEGACY_TSS
414 } FAST486_LEGACY_TSS
, *PFAST486_LEGACY_TSS
;
418 typedef struct _FAST486_TABLE_REG
422 } FAST486_TABLE_REG
, *PFAST486_TABLE_REG
;
424 typedef union _FAST486_FLAGS_REG
450 // ULONG Reserved : 13;
452 } FAST486_FLAGS_REG
, *PFAST486_FLAGS_REG
;
454 typedef struct _FAST486_FPU_DATA_REG
459 } FAST486_FPU_DATA_REG
, *PFAST486_FPU_DATA_REG
;
461 typedef const FAST486_FPU_DATA_REG
*PCFAST486_FPU_DATA_REG
;
463 typedef union _FAST486_FPU_STATUS_REG
484 } FAST486_FPU_STATUS_REG
, *PFAST486_FPU_STATUS_REG
;
486 typedef union _FAST486_FPU_CONTROL_REG
502 // ULONG Reserved1 : 3;
504 } FAST486_FPU_CONTROL_REG
, *PFAST486_FPU_CONTROL_REG
;
506 struct _FAST486_STATE
508 FAST486_MEM_READ_PROC MemReadCallback
;
509 FAST486_MEM_WRITE_PROC MemWriteCallback
;
510 FAST486_IO_READ_PROC IoReadCallback
;
511 FAST486_IO_WRITE_PROC IoWriteCallback
;
512 FAST486_BOP_PROC BopCallback
;
513 FAST486_INT_ACK_PROC IntAckCallback
;
514 FAST486_FPU_PROC FpuCallback
;
515 FAST486_REG GeneralRegs
[FAST486_NUM_GEN_REGS
];
516 FAST486_SEG_REG SegmentRegs
[FAST486_NUM_SEG_REGS
];
517 FAST486_REG InstPtr
, SavedInstPtr
;
518 FAST486_FLAGS_REG Flags
;
519 FAST486_TABLE_REG Gdtr
, Idtr
;
520 FAST486_LDT_REG Ldtr
;
521 FAST486_TASK_REG TaskReg
;
523 ULONG ControlRegisters
[FAST486_NUM_CTRL_REGS
];
524 ULONG DebugRegisters
[FAST486_NUM_DBG_REGS
];
525 ULONG ExceptionCount
;
527 FAST486_SEG_REGS SegmentOverride
;
530 BOOLEAN DoNotInterrupt
;
533 #ifndef FAST486_NO_PREFETCH
534 BOOLEAN PrefetchValid
;
535 ULONG PrefetchAddress
;
536 UCHAR PrefetchCache
[FAST486_CACHE_SIZE
];
538 #ifndef FAST486_NO_FPU
539 FAST486_FPU_DATA_REG FpuRegisters
[FAST486_NUM_FPU_REGS
];
540 FAST486_FPU_STATUS_REG FpuStatus
;
541 FAST486_FPU_CONTROL_REG FpuControl
;
543 FAST486_REG FpuLastInstPtr
;
544 USHORT FpuLastCodeSel
;
545 FAST486_REG FpuLastOpPtr
;
546 USHORT FpuLastDataSel
;
550 /* FUNCTIONS ******************************************************************/
554 Fast486Initialize(PFAST486_STATE State
,
555 FAST486_MEM_READ_PROC MemReadCallback
,
556 FAST486_MEM_WRITE_PROC MemWriteCallback
,
557 FAST486_IO_READ_PROC IoReadCallback
,
558 FAST486_IO_WRITE_PROC IoWriteCallback
,
559 FAST486_BOP_PROC BopCallback
,
560 FAST486_INT_ACK_PROC IntAckCallback
,
561 FAST486_FPU_PROC FpuCallback
,
566 Fast486Reset(PFAST486_STATE State
);
570 Fast486Continue(PFAST486_STATE State
);
574 Fast486StepInto(PFAST486_STATE State
);
578 Fast486StepOver(PFAST486_STATE State
);
582 Fast486StepOut(PFAST486_STATE State
);
586 Fast486DumpState(PFAST486_STATE State
);
590 Fast486InterruptSignal(PFAST486_STATE State
);
594 Fast486ExecuteAt(PFAST486_STATE State
, USHORT Segment
, ULONG Offset
);
598 Fast486SetStack(PFAST486_STATE State
, USHORT Segment
, ULONG Offset
);
604 PFAST486_STATE State
,
605 FAST486_SEG_REGS Segment
,
611 Fast486Rewind(PFAST486_STATE State
);
613 #endif // _FAST486_H_