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