Sync with trunk r63935.
[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_DELAYED = 3
164 } FAST486_INT_STATUS, *PFAST486_INT_STATUS;
165
166 typedef
167 VOID
168 (NTAPI *FAST486_MEM_READ_PROC)
169 (
170 PFAST486_STATE State,
171 ULONG Address,
172 PVOID Buffer,
173 ULONG Size
174 );
175
176 typedef
177 VOID
178 (NTAPI *FAST486_MEM_WRITE_PROC)
179 (
180 PFAST486_STATE State,
181 ULONG Address,
182 PVOID Buffer,
183 ULONG Size
184 );
185
186 typedef
187 VOID
188 (NTAPI *FAST486_IO_READ_PROC)
189 (
190 PFAST486_STATE State,
191 ULONG Port,
192 PVOID Buffer,
193 ULONG DataCount,
194 UCHAR DataSize
195 );
196
197 typedef
198 VOID
199 (NTAPI *FAST486_IO_WRITE_PROC)
200 (
201 PFAST486_STATE State,
202 ULONG Port,
203 PVOID Buffer,
204 ULONG DataCount,
205 UCHAR DataSize
206 );
207
208 typedef
209 VOID
210 (NTAPI *FAST486_IDLE_PROC)
211 (
212 PFAST486_STATE State
213 );
214
215 typedef
216 VOID
217 (NTAPI *FAST486_BOP_PROC)
218 (
219 PFAST486_STATE State,
220 UCHAR BopCode
221 );
222
223 typedef
224 UCHAR
225 (NTAPI *FAST486_INT_ACK_PROC)
226 (
227 PFAST486_STATE State
228 );
229
230 typedef union _FAST486_REG
231 {
232 union
233 {
234 struct
235 {
236 UCHAR LowByte;
237 UCHAR HighByte;
238 };
239 USHORT LowWord;
240 };
241 ULONG Long;
242 } FAST486_REG, *PFAST486_REG;
243
244 typedef struct _FAST486_SEG_REG
245 {
246 USHORT Selector;
247
248 /* Descriptor cache */
249 ULONG Accessed : 1;
250 ULONG ReadWrite : 1;
251 ULONG DirConf : 1;
252 ULONG Executable : 1;
253 ULONG SystemType : 1;
254 ULONG Rpl : 2;
255 ULONG Dpl : 2;
256 ULONG Present : 1;
257 ULONG Size : 1;
258 ULONG Limit;
259 ULONG Base;
260 } FAST486_SEG_REG, *PFAST486_SEG_REG;
261
262 typedef struct
263 {
264 USHORT Selector;
265 ULONG Base;
266 ULONG Limit;
267 } FAST486_LDT_REG;
268
269 typedef struct
270 {
271 USHORT Selector;
272 ULONG Base;
273 ULONG Limit;
274 BOOLEAN Busy;
275 } FAST486_TASK_REG, *PFAST486_TASK_REG;
276
277 #pragma pack(push, 1)
278
279 typedef struct
280 {
281 ULONG Limit : 16;
282 ULONG Base : 16;
283 ULONG BaseMid : 8;
284 ULONG Accessed : 1;
285 ULONG ReadWrite : 1;
286 ULONG DirConf : 1;
287 ULONG Executable : 1;
288 ULONG SystemType : 1;
289 ULONG Dpl : 2;
290 ULONG Present : 1;
291 ULONG LimitHigh : 4;
292 ULONG Avl : 1;
293 ULONG Reserved : 1;
294 ULONG Size : 1;
295 ULONG Granularity : 1;
296 ULONG BaseHigh : 8;
297 } FAST486_GDT_ENTRY, *PFAST486_GDT_ENTRY;
298
299 /* Verify the structure size */
300 C_ASSERT(sizeof(FAST486_GDT_ENTRY) == sizeof(ULONGLONG));
301
302 typedef struct
303 {
304 ULONG Limit : 16;
305 ULONG Base : 16;
306 ULONG BaseMid : 8;
307 ULONG Signature : 5;
308 ULONG Dpl : 2;
309 ULONG Present : 1;
310 ULONG LimitHigh : 4;
311 ULONG Avl : 1;
312 ULONG Reserved : 2;
313 ULONG Granularity : 1;
314 ULONG BaseHigh : 8;
315 } FAST486_SYSTEM_DESCRIPTOR, *PFAST486_SYSTEM_DESCRIPTOR;
316
317 /* Verify the structure size */
318 C_ASSERT(sizeof(FAST486_SYSTEM_DESCRIPTOR) == sizeof(ULONGLONG));
319
320 typedef struct
321 {
322 ULONG Offset : 16;
323 ULONG Selector : 16;
324 ULONG ParamCount : 5;
325 ULONG Reserved : 3;
326 ULONG Type : 4;
327 ULONG SystemType : 1;
328 ULONG Dpl : 2;
329 ULONG Present : 1;
330 ULONG OffsetHigh : 16;
331 } FAST486_CALL_GATE, *PFAST486_CALL_GATE;
332
333 /* Verify the structure size */
334 C_ASSERT(sizeof(FAST486_CALL_GATE) == sizeof(ULONGLONG));
335
336 typedef struct
337 {
338 ULONG Offset : 16;
339 ULONG Selector : 16;
340 ULONG Zero : 8;
341 ULONG Type : 4;
342 ULONG Storage : 1;
343 ULONG Dpl : 2;
344 ULONG Present : 1;
345 ULONG OffsetHigh : 16;
346 } FAST486_IDT_ENTRY, *PFAST486_IDT_ENTRY;
347
348 /* Verify the structure size */
349 C_ASSERT(sizeof(FAST486_IDT_ENTRY) == sizeof(ULONGLONG));
350
351 #pragma pack(pop)
352
353 typedef struct _FAST486_TABLE_REG
354 {
355 USHORT Size;
356 ULONG Address;
357 } FAST486_TABLE_REG, *PFAST486_TABLE_REG;
358
359 typedef union _FAST486_FLAGS_REG
360 {
361 USHORT LowWord;
362 ULONG Long;
363
364 struct
365 {
366 ULONG Cf : 1;
367 ULONG AlwaysSet : 1;
368 ULONG Pf : 1;
369 ULONG Reserved0 : 1;
370 ULONG Af : 1;
371 ULONG Reserved1 : 1;
372 ULONG Zf : 1;
373 ULONG Sf : 1;
374 ULONG Tf : 1;
375 ULONG If : 1;
376 ULONG Df : 1;
377 ULONG Of : 1;
378 ULONG Iopl : 2;
379 ULONG Nt : 1;
380 ULONG Reserved2 : 1;
381 ULONG Rf : 1;
382 ULONG Vm : 1;
383 ULONG Ac : 1;
384
385 // ULONG Reserved : 13;
386 };
387 } FAST486_FLAGS_REG, *PFAST486_FLAGS_REG;
388
389 typedef struct _FAST486_TSS
390 {
391 ULONG Link;
392 ULONG Esp0;
393 ULONG Ss0;
394 ULONG Esp1;
395 ULONG Ss1;
396 ULONG Esp2;
397 ULONG Ss2;
398 ULONG Cr3;
399 ULONG Eip;
400 ULONG Eflags;
401 ULONG Eax;
402 ULONG Ecx;
403 ULONG Edx;
404 ULONG Ebx;
405 ULONG Esp;
406 ULONG Ebp;
407 ULONG Esi;
408 ULONG Edi;
409 ULONG Es;
410 ULONG Cs;
411 ULONG Ss;
412 ULONG Ds;
413 ULONG Fs;
414 ULONG Gs;
415 ULONG Ldtr;
416 ULONG IopbOffset;
417 } FAST486_TSS, *PFAST486_TSS;
418
419 typedef struct _FAST486_FPU_DATA_REG
420 {
421 ULONGLONG Mantissa;
422 USHORT Exponent;
423 } FAST486_FPU_DATA_REG, *PFAST486_FPU_DATA_REG;
424
425 typedef union _FAST486_FPU_STATUS_REG
426 {
427 USHORT Value;
428
429 struct
430 {
431 ULONG Ie : 1;
432 ULONG De : 1;
433 ULONG Ze : 1;
434 ULONG Oe : 1;
435 ULONG Ue : 1;
436 ULONG Pe : 1;
437 ULONG Sf : 1;
438 ULONG Es : 1;
439 ULONG Code0 : 1;
440 ULONG Code1 : 1;
441 ULONG Code2 : 1;
442 ULONG Top : 3;
443 ULONG Code3 : 1;
444 ULONG Busy : 1;
445 };
446 } FAST486_FPU_STATUS_REG, *PFAST486_FPU_STATUS_REG;
447
448 typedef union _FAST486_FPU_CONTROL_REG
449 {
450 USHORT Value;
451
452 struct
453 {
454 ULONG Im : 1;
455 ULONG Dm : 1;
456 ULONG Zm : 1;
457 ULONG Om : 1;
458 ULONG Um : 1;
459 ULONG Pm : 1;
460 ULONG Reserved : 2;
461 ULONG Pc : 2;
462 ULONG Rc : 2;
463 ULONG Inf : 1;
464 // ULONG Reserved1 : 3;
465 };
466 } FAST486_FPU_CONTROL_REG, *PFAST486_FPU_CONTROL_REG;
467
468 struct _FAST486_STATE
469 {
470 FAST486_MEM_READ_PROC MemReadCallback;
471 FAST486_MEM_WRITE_PROC MemWriteCallback;
472 FAST486_IO_READ_PROC IoReadCallback;
473 FAST486_IO_WRITE_PROC IoWriteCallback;
474 FAST486_IDLE_PROC IdleCallback;
475 FAST486_BOP_PROC BopCallback;
476 FAST486_INT_ACK_PROC IntAckCallback;
477 FAST486_REG GeneralRegs[FAST486_NUM_GEN_REGS];
478 FAST486_SEG_REG SegmentRegs[FAST486_NUM_SEG_REGS];
479 FAST486_REG InstPtr, SavedInstPtr;
480 FAST486_FLAGS_REG Flags;
481 FAST486_TABLE_REG Gdtr, Idtr;
482 FAST486_LDT_REG Ldtr;
483 FAST486_TASK_REG TaskReg;
484 UCHAR Cpl;
485 ULONG ControlRegisters[FAST486_NUM_CTRL_REGS];
486 ULONG DebugRegisters[FAST486_NUM_DBG_REGS];
487 ULONG ExceptionCount;
488 ULONG PrefixFlags;
489 FAST486_SEG_REGS SegmentOverride;
490 FAST486_INT_STATUS IntStatus;
491 UCHAR PendingIntNum;
492 PULONG Tlb;
493 FAST486_FPU_DATA_REG FpuRegisters[FAST486_NUM_FPU_REGS];
494 FAST486_FPU_STATUS_REG FpuStatus;
495 FAST486_FPU_CONTROL_REG FpuControl;
496 USHORT FpuTag;
497 };
498
499 /* FUNCTIONS ******************************************************************/
500
501 VOID
502 NTAPI
503 Fast486Initialize(PFAST486_STATE State,
504 FAST486_MEM_READ_PROC MemReadCallback,
505 FAST486_MEM_WRITE_PROC MemWriteCallback,
506 FAST486_IO_READ_PROC IoReadCallback,
507 FAST486_IO_WRITE_PROC IoWriteCallback,
508 FAST486_IDLE_PROC IdleCallback,
509 FAST486_BOP_PROC BopCallback,
510 FAST486_INT_ACK_PROC IntAckCallback,
511 PULONG Tlb);
512
513 VOID
514 NTAPI
515 Fast486Reset(PFAST486_STATE State);
516
517 VOID
518 NTAPI
519 Fast486Continue(PFAST486_STATE State);
520
521 VOID
522 NTAPI
523 Fast486StepInto(PFAST486_STATE State);
524
525 VOID
526 NTAPI
527 Fast486StepOver(PFAST486_STATE State);
528
529 VOID
530 NTAPI
531 Fast486StepOut(PFAST486_STATE State);
532
533 VOID
534 NTAPI
535 Fast486DumpState(PFAST486_STATE State);
536
537 VOID
538 NTAPI
539 Fast486Interrupt(PFAST486_STATE State, UCHAR Number);
540
541 VOID
542 NTAPI
543 Fast486InterruptSignal(PFAST486_STATE State);
544
545 VOID
546 NTAPI
547 Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset);
548
549 VOID
550 NTAPI
551 Fast486SetStack(PFAST486_STATE State, USHORT Segment, ULONG Offset);
552
553 VOID
554 NTAPI
555 Fast486SetSegment
556 (
557 PFAST486_STATE State,
558 FAST486_SEG_REGS Segment,
559 USHORT Selector
560 );
561
562 #endif // _FAST486_H_
563
564 /* EOF */