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