c660a25c7bd2d37b9ed29cab502095afe62be9b2
[reactos.git] / include / reactos / libs / fast486 / fast486.h
1 /*
2 * Fast486 386/486 CPU Emulation Library
3 * fast486.h
4 *
5 * Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
6 *
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.
11 *
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.
16 *
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.
20 */
21
22 #ifndef _FAST486_H_
23 #define _FAST486_H_
24
25 #pragma once
26
27 /* DEFINES ********************************************************************/
28
29 #ifndef FASTCALL
30 #define FASTCALL __fastcall
31 #endif
32
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
38
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)
50
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)
58
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)
70
71 #define FAST486_DBG_BREAK_EXEC 0
72 #define FAST486_DBG_BREAK_WRITE 1
73 #define FAST486_DBG_BREAK_READWRITE 3
74
75 #define FAST486_DR4_RESERVED 0xFFFF1FF0
76 #define FAST486_DR5_RESERVED 0x0000DC00
77
78 #define FAST486_IDT_TASK_GATE 0x5
79 #define FAST486_IDT_INT_GATE 0x6
80 #define FAST486_IDT_TRAP_GATE 0x7
81 #define FAST486_IDT_INT_GATE_32 0xE
82 #define FAST486_IDT_TRAP_GATE_32 0xF
83
84 #define FAST486_LDT_SIGNATURE 0x02
85 #define FAST486_TSS_SIGNATURE 0x09
86
87 #define FAST486_PREFIX_SEG (1 << 0)
88 #define FAST486_PREFIX_OPSIZE (1 << 1)
89 #define FAST486_PREFIX_ADSIZE (1 << 2)
90 #define FAST486_PREFIX_LOCK (1 << 3)
91 #define FAST486_PREFIX_REPNZ (1 << 4)
92 #define FAST486_PREFIX_REP (1 << 5)
93
94 struct _FAST486_STATE;
95 typedef struct _FAST486_STATE FAST486_STATE, *PFAST486_STATE;
96
97 typedef enum _FAST486_GEN_REGS
98 {
99 FAST486_REG_EAX,
100 FAST486_REG_ECX,
101 FAST486_REG_EDX,
102 FAST486_REG_EBX,
103 FAST486_REG_ESP,
104 FAST486_REG_EBP,
105 FAST486_REG_ESI,
106 FAST486_REG_EDI
107 } FAST486_GEN_REGS, *PFAST486_GEN_REGS;
108
109 typedef enum _FAST486_SEG_REGS
110 {
111 FAST486_REG_ES,
112 FAST486_REG_CS,
113 FAST486_REG_SS,
114 FAST486_REG_DS,
115 FAST486_REG_FS,
116 FAST486_REG_GS
117 } FAST486_SEG_REGS, *PFAST486_SEG_REGS;
118
119 typedef enum _FAST486_CTRL_REGS
120 {
121 FAST486_REG_CR0 = 0,
122 FAST486_REG_CR2 = 1,
123 FAST486_REG_CR3 = 2,
124 } FAST486_CTRL_REGS, *PFAST486_CTRL_REGS;
125
126 typedef enum _FAST486_DBG_REGS
127 {
128 FAST486_REG_DR0 = 0,
129 FAST486_REG_DR1 = 1,
130 FAST486_REG_DR2 = 2,
131 FAST486_REG_DR3 = 3,
132 FAST486_REG_DR4 = 4,
133 FAST486_REG_DR5 = 5,
134 FAST486_REG_DR6 = 4, // alias to DR4
135 FAST486_REG_DR7 = 5 // alias to DR5
136 } FAST486_DBG_REGS, *PFAST486_DBG_REGS;
137
138 typedef enum _FAST486_EXCEPTIONS
139 {
140 FAST486_EXCEPTION_DE = 0x00,
141 FAST486_EXCEPTION_DB = 0x01,
142 FAST486_EXCEPTION_BP = 0x03,
143 FAST486_EXCEPTION_OF = 0x04,
144 FAST486_EXCEPTION_BR = 0x05,
145 FAST486_EXCEPTION_UD = 0x06,
146 FAST486_EXCEPTION_NM = 0x07,
147 FAST486_EXCEPTION_DF = 0x08,
148 FAST486_EXCEPTION_TS = 0x0A,
149 FAST486_EXCEPTION_NP = 0x0B,
150 FAST486_EXCEPTION_SS = 0x0C,
151 FAST486_EXCEPTION_GP = 0x0D,
152 FAST486_EXCEPTION_PF = 0x0E,
153 FAST486_EXCEPTION_MF = 0x10,
154 FAST486_EXCEPTION_AC = 0x11,
155 FAST486_EXCEPTION_MC = 0x12
156 } FAST486_EXCEPTIONS, *PFAST486_EXCEPTIONS;
157
158 typedef enum _FAST486_INT_STATUS
159 {
160 FAST486_INT_NONE = 0,
161 FAST486_INT_EXECUTE = 1,
162 FAST486_INT_SIGNAL = 2
163 } FAST486_INT_STATUS, *PFAST486_INT_STATUS;
164
165 typedef
166 VOID
167 (NTAPI *FAST486_MEM_READ_PROC)
168 (
169 PFAST486_STATE State,
170 ULONG Address,
171 PVOID Buffer,
172 ULONG Size
173 );
174
175 typedef
176 VOID
177 (NTAPI *FAST486_MEM_WRITE_PROC)
178 (
179 PFAST486_STATE State,
180 ULONG Address,
181 PVOID Buffer,
182 ULONG Size
183 );
184
185 typedef
186 VOID
187 (NTAPI *FAST486_IO_READ_PROC)
188 (
189 PFAST486_STATE State,
190 ULONG Port,
191 PVOID Buffer,
192 ULONG DataCount,
193 UCHAR DataSize
194 );
195
196 typedef
197 VOID
198 (NTAPI *FAST486_IO_WRITE_PROC)
199 (
200 PFAST486_STATE State,
201 ULONG Port,
202 PVOID Buffer,
203 ULONG DataCount,
204 UCHAR DataSize
205 );
206
207 typedef
208 VOID
209 (NTAPI *FAST486_IDLE_PROC)
210 (
211 PFAST486_STATE State
212 );
213
214 typedef
215 VOID
216 (NTAPI *FAST486_BOP_PROC)
217 (
218 PFAST486_STATE State,
219 UCHAR BopCode
220 );
221
222 typedef
223 UCHAR
224 (NTAPI *FAST486_INT_ACK_PROC)
225 (
226 PFAST486_STATE State
227 );
228
229 typedef union _FAST486_REG
230 {
231 union
232 {
233 struct
234 {
235 UCHAR LowByte;
236 UCHAR HighByte;
237 };
238 USHORT LowWord;
239 };
240 ULONG Long;
241 } FAST486_REG, *PFAST486_REG;
242
243 typedef struct _FAST486_SEG_REG
244 {
245 USHORT Selector;
246
247 /* Descriptor cache */
248 ULONG Accessed : 1;
249 ULONG ReadWrite : 1;
250 ULONG DirConf : 1;
251 ULONG Executable : 1;
252 ULONG SystemType : 1;
253 ULONG Dpl : 2;
254 ULONG Present : 1;
255 ULONG Size : 1;
256 ULONG Limit;
257 ULONG Base;
258 } FAST486_SEG_REG, *PFAST486_SEG_REG;
259
260 typedef struct
261 {
262 USHORT Selector;
263 ULONG Base;
264 ULONG Limit;
265 } FAST486_LDT_REG;
266
267 typedef struct
268 {
269 USHORT Selector;
270 ULONG Base;
271 ULONG Limit;
272 BOOLEAN Busy;
273 } FAST486_TASK_REG, *PFAST486_TASK_REG;
274
275 #pragma pack(push, 1)
276
277 typedef struct
278 {
279 ULONG Limit : 16;
280 ULONG Base : 16;
281 ULONG BaseMid : 8;
282 ULONG Accessed : 1;
283 ULONG ReadWrite : 1;
284 ULONG DirConf : 1;
285 ULONG Executable : 1;
286 ULONG SystemType : 1;
287 ULONG Dpl : 2;
288 ULONG Present : 1;
289 ULONG LimitHigh : 4;
290 ULONG Avl : 1;
291 ULONG Reserved : 1;
292 ULONG Size : 1;
293 ULONG Granularity : 1;
294 ULONG BaseHigh : 8;
295 } FAST486_GDT_ENTRY, *PFAST486_GDT_ENTRY;
296
297 /* Verify the structure size */
298 C_ASSERT(sizeof(FAST486_GDT_ENTRY) == sizeof(ULONGLONG));
299
300 typedef struct
301 {
302 ULONG Limit : 16;
303 ULONG Base : 16;
304 ULONG BaseMid : 8;
305 ULONG Signature : 5;
306 ULONG Dpl : 2;
307 ULONG Present : 1;
308 ULONG LimitHigh : 4;
309 ULONG Avl : 1;
310 ULONG Reserved : 2;
311 ULONG Granularity : 1;
312 ULONG BaseHigh : 8;
313 } FAST486_SYSTEM_DESCRIPTOR, *PFAST486_SYSTEM_DESCRIPTOR;
314
315 /* Verify the structure size */
316 C_ASSERT(sizeof(FAST486_SYSTEM_DESCRIPTOR) == sizeof(ULONGLONG));
317
318 typedef struct
319 {
320 ULONG Offset : 16;
321 ULONG Selector : 16;
322 ULONG ParamCount : 5;
323 ULONG Reserved : 3;
324 ULONG Type : 4;
325 ULONG SystemType : 1;
326 ULONG Dpl : 2;
327 ULONG Present : 1;
328 ULONG OffsetHigh : 16;
329 } FAST486_CALL_GATE, *PFAST486_CALL_GATE;
330
331 /* Verify the structure size */
332 C_ASSERT(sizeof(FAST486_CALL_GATE) == sizeof(ULONGLONG));
333
334 typedef struct
335 {
336 ULONG Offset : 16;
337 ULONG Selector : 16;
338 ULONG Zero : 8;
339 ULONG Type : 4;
340 ULONG Storage : 1;
341 ULONG Dpl : 2;
342 ULONG Present : 1;
343 ULONG OffsetHigh : 16;
344 } FAST486_IDT_ENTRY, *PFAST486_IDT_ENTRY;
345
346 /* Verify the structure size */
347 C_ASSERT(sizeof(FAST486_IDT_ENTRY) == sizeof(ULONGLONG));
348
349 #pragma pack(pop)
350
351 typedef struct _FAST486_TABLE_REG
352 {
353 USHORT Size;
354 ULONG Address;
355 } FAST486_TABLE_REG, *PFAST486_TABLE_REG;
356
357 typedef union _FAST486_FLAGS_REG
358 {
359 USHORT LowWord;
360 ULONG Long;
361
362 struct
363 {
364 ULONG Cf : 1;
365 ULONG AlwaysSet : 1;
366 ULONG Pf : 1;
367 ULONG Reserved0 : 1;
368 ULONG Af : 1;
369 ULONG Reserved1 : 1;
370 ULONG Zf : 1;
371 ULONG Sf : 1;
372 ULONG Tf : 1;
373 ULONG If : 1;
374 ULONG Df : 1;
375 ULONG Of : 1;
376 ULONG Iopl : 2;
377 ULONG Nt : 1;
378 ULONG Reserved2 : 1;
379 ULONG Rf : 1;
380 ULONG Vm : 1;
381
382 // ULONG Reserved : 14;
383 };
384 } FAST486_FLAGS_REG, *PFAST486_FLAGS_REG;
385
386 typedef struct _FAST486_TSS
387 {
388 ULONG Link;
389 ULONG Esp0;
390 ULONG Ss0;
391 ULONG Esp1;
392 ULONG Ss1;
393 ULONG Esp2;
394 ULONG Ss2;
395 ULONG Cr3;
396 ULONG Eip;
397 ULONG Eflags;
398 ULONG Eax;
399 ULONG Ecx;
400 ULONG Edx;
401 ULONG Ebx;
402 ULONG Esp;
403 ULONG Ebp;
404 ULONG Esi;
405 ULONG Edi;
406 ULONG Es;
407 ULONG Cs;
408 ULONG Ss;
409 ULONG Ds;
410 ULONG Fs;
411 ULONG Gs;
412 ULONG Ldtr;
413 ULONG IopbOffset;
414 } FAST486_TSS, *PFAST486_TSS;
415
416 typedef struct _FAST486_FPU_DATA_REG
417 {
418 ULONGLONG Mantissa;
419 USHORT Exponent;
420 } FAST486_FPU_DATA_REG, *PFAST486_FPU_DATA_REG;
421
422 typedef union _FAST486_FPU_STATUS_REG
423 {
424 USHORT Value;
425
426 struct
427 {
428 ULONG Ie : 1;
429 ULONG De : 1;
430 ULONG Ze : 1;
431 ULONG Oe : 1;
432 ULONG Ue : 1;
433 ULONG Pe : 1;
434 ULONG Sf : 1;
435 ULONG Es : 1;
436 ULONG Code0 : 1;
437 ULONG Code1 : 1;
438 ULONG Code2 : 1;
439 ULONG Top : 3;
440 ULONG Code3 : 1;
441 ULONG Busy : 1;
442 };
443 } FAST486_FPU_STATUS_REG, *PFAST486_FPU_STATUS_REG;
444
445 typedef union _FAST486_FPU_CONTROL_REG
446 {
447 USHORT Value;
448
449 struct
450 {
451 ULONG Im : 1;
452 ULONG Dm : 1;
453 ULONG Zm : 1;
454 ULONG Om : 1;
455 ULONG Um : 1;
456 ULONG Pm : 1;
457 ULONG Reserved : 2;
458 ULONG Pc : 2;
459 ULONG Rc : 2;
460 ULONG Inf : 1;
461 // ULONG Reserved1 : 3;
462 };
463 } FAST486_FPU_CONTROL_REG, *PFAST486_FPU_CONTROL_REG;
464
465 struct _FAST486_STATE
466 {
467 FAST486_MEM_READ_PROC MemReadCallback;
468 FAST486_MEM_WRITE_PROC MemWriteCallback;
469 FAST486_IO_READ_PROC IoReadCallback;
470 FAST486_IO_WRITE_PROC IoWriteCallback;
471 FAST486_IDLE_PROC IdleCallback;
472 FAST486_BOP_PROC BopCallback;
473 FAST486_INT_ACK_PROC IntAckCallback;
474 FAST486_REG GeneralRegs[FAST486_NUM_GEN_REGS];
475 FAST486_SEG_REG SegmentRegs[FAST486_NUM_SEG_REGS];
476 FAST486_REG InstPtr, SavedInstPtr;
477 FAST486_FLAGS_REG Flags;
478 FAST486_TABLE_REG Gdtr, Idtr;
479 FAST486_LDT_REG Ldtr;
480 FAST486_TASK_REG TaskReg;
481 UCHAR Cpl;
482 ULONG ControlRegisters[FAST486_NUM_CTRL_REGS];
483 ULONG DebugRegisters[FAST486_NUM_DBG_REGS];
484 ULONG ExceptionCount;
485 ULONG PrefixFlags;
486 FAST486_SEG_REGS SegmentOverride;
487 FAST486_INT_STATUS IntStatus;
488 UCHAR PendingIntNum;
489 PULONG Tlb;
490 FAST486_FPU_DATA_REG FpuRegisters[FAST486_NUM_FPU_REGS];
491 FAST486_FPU_STATUS_REG FpuStatus;
492 FAST486_FPU_CONTROL_REG FpuControl;
493 USHORT FpuTag;
494 };
495
496 /* FUNCTIONS ******************************************************************/
497
498 VOID
499 NTAPI
500 Fast486Initialize(PFAST486_STATE State,
501 FAST486_MEM_READ_PROC MemReadCallback,
502 FAST486_MEM_WRITE_PROC MemWriteCallback,
503 FAST486_IO_READ_PROC IoReadCallback,
504 FAST486_IO_WRITE_PROC IoWriteCallback,
505 FAST486_IDLE_PROC IdleCallback,
506 FAST486_BOP_PROC BopCallback,
507 FAST486_INT_ACK_PROC IntAckCallback,
508 PULONG Tlb);
509
510 VOID
511 NTAPI
512 Fast486Reset(PFAST486_STATE State);
513
514 VOID
515 NTAPI
516 Fast486Continue(PFAST486_STATE State);
517
518 VOID
519 NTAPI
520 Fast486StepInto(PFAST486_STATE State);
521
522 VOID
523 NTAPI
524 Fast486StepOver(PFAST486_STATE State);
525
526 VOID
527 NTAPI
528 Fast486StepOut(PFAST486_STATE State);
529
530 VOID
531 NTAPI
532 Fast486DumpState(PFAST486_STATE State);
533
534 VOID
535 NTAPI
536 Fast486Interrupt(PFAST486_STATE State, UCHAR Number);
537
538 VOID
539 NTAPI
540 Fast486InterruptSignal(PFAST486_STATE State);
541
542 VOID
543 NTAPI
544 Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset);
545
546 VOID
547 NTAPI
548 Fast486SetStack(PFAST486_STATE State, USHORT Segment, ULONG Offset);
549
550 VOID
551 NTAPI
552 Fast486SetSegment
553 (
554 PFAST486_STATE State,
555 FAST486_SEG_REGS Segment,
556 USHORT Selector
557 );
558
559 #endif // _FAST486_H_
560
561 /* EOF */