d4f3cf18a9620097c678a030ca5b2e8019e02709
[reactos.git] / reactos / include / reactos / libs / fast486 / fast486.h
1 /*
2 * Fast486 386/486 CPU Emulation Library
3 * fast486.h
4 *
5 * Copyright (C) 2015 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_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
90
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)
97
98 #define FAST486_FPU_DEFAULT_CONTROL 0x037F
99
100 #define FAST486_PAGE_SIZE 4096
101 #define FAST486_CACHE_SIZE 32
102
103 /*
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.
108 */
109 C_ASSERT((FAST486_CACHE_SIZE >= sizeof(DWORD))
110 && (FAST486_CACHE_SIZE <= FAST486_PAGE_SIZE));
111
112 struct _FAST486_STATE;
113 typedef struct _FAST486_STATE FAST486_STATE, *PFAST486_STATE;
114
115 typedef enum _FAST486_GEN_REGS
116 {
117 FAST486_REG_EAX,
118 FAST486_REG_ECX,
119 FAST486_REG_EDX,
120 FAST486_REG_EBX,
121 FAST486_REG_ESP,
122 FAST486_REG_EBP,
123 FAST486_REG_ESI,
124 FAST486_REG_EDI
125 } FAST486_GEN_REGS, *PFAST486_GEN_REGS;
126
127 typedef enum _FAST486_SEG_REGS
128 {
129 FAST486_REG_ES,
130 FAST486_REG_CS,
131 FAST486_REG_SS,
132 FAST486_REG_DS,
133 FAST486_REG_FS,
134 FAST486_REG_GS
135 } FAST486_SEG_REGS, *PFAST486_SEG_REGS;
136
137 typedef enum _FAST486_CTRL_REGS
138 {
139 FAST486_REG_CR0 = 0,
140 FAST486_REG_CR2 = 1,
141 FAST486_REG_CR3 = 2,
142 } FAST486_CTRL_REGS, *PFAST486_CTRL_REGS;
143
144 typedef enum _FAST486_DBG_REGS
145 {
146 FAST486_REG_DR0 = 0,
147 FAST486_REG_DR1 = 1,
148 FAST486_REG_DR2 = 2,
149 FAST486_REG_DR3 = 3,
150 FAST486_REG_DR4 = 4,
151 FAST486_REG_DR5 = 5,
152 FAST486_REG_DR6 = 4, // alias to DR4
153 FAST486_REG_DR7 = 5 // alias to DR5
154 } FAST486_DBG_REGS, *PFAST486_DBG_REGS;
155
156 typedef enum _FAST486_EXCEPTIONS
157 {
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;
175
176 typedef
177 VOID
178 (NTAPI *FAST486_MEM_READ_PROC)
179 (
180 PFAST486_STATE State,
181 ULONG Address,
182 PVOID Buffer,
183 ULONG Size
184 );
185
186 typedef
187 VOID
188 (NTAPI *FAST486_MEM_WRITE_PROC)
189 (
190 PFAST486_STATE State,
191 ULONG Address,
192 PVOID Buffer,
193 ULONG Size
194 );
195
196 typedef
197 VOID
198 (NTAPI *FAST486_IO_READ_PROC)
199 (
200 PFAST486_STATE State,
201 USHORT Port,
202 PVOID Buffer,
203 ULONG DataCount,
204 UCHAR DataSize
205 );
206
207 typedef
208 VOID
209 (NTAPI *FAST486_IO_WRITE_PROC)
210 (
211 PFAST486_STATE State,
212 USHORT Port,
213 PVOID Buffer,
214 ULONG DataCount,
215 UCHAR DataSize
216 );
217
218 typedef
219 VOID
220 (NTAPI *FAST486_BOP_PROC)
221 (
222 PFAST486_STATE State,
223 UCHAR BopCode
224 );
225
226 typedef
227 UCHAR
228 (NTAPI *FAST486_INT_ACK_PROC)
229 (
230 PFAST486_STATE State
231 );
232
233 typedef
234 VOID
235 (NTAPI *FAST486_FPU_PROC)
236 (
237 PFAST486_STATE State
238 );
239
240 typedef union _FAST486_REG
241 {
242 union
243 {
244 struct
245 {
246 UCHAR LowByte;
247 UCHAR HighByte;
248 };
249 USHORT LowWord;
250 };
251 ULONG Long;
252 } FAST486_REG, *PFAST486_REG;
253
254 typedef struct _FAST486_SEG_REG
255 {
256 USHORT Selector;
257
258 /* Descriptor cache */
259 ULONG Accessed : 1;
260 ULONG ReadWrite : 1;
261 ULONG DirConf : 1;
262 ULONG Executable : 1;
263 ULONG SystemType : 1;
264 ULONG Rpl : 2;
265 ULONG Dpl : 2;
266 ULONG Present : 1;
267 ULONG Size : 1;
268 ULONG Limit;
269 ULONG Base;
270 } FAST486_SEG_REG, *PFAST486_SEG_REG;
271
272 typedef struct _FAST486_LDT_REG
273 {
274 USHORT Selector;
275 ULONG Base;
276 ULONG Limit;
277 } FAST486_LDT_REG, *PFAST486_LDT_REG;
278
279 typedef struct _FAST486_TASK_REG
280 {
281 USHORT Selector;
282 ULONG Base;
283 ULONG Limit;
284 } FAST486_TASK_REG, *PFAST486_TASK_REG;
285
286 #include <pshpack1.h>
287
288 typedef struct
289 {
290 ULONG Limit : 16;
291 ULONG Base : 16;
292 ULONG BaseMid : 8;
293 ULONG Accessed : 1;
294 ULONG ReadWrite : 1;
295 ULONG DirConf : 1;
296 ULONG Executable : 1;
297 ULONG SystemType : 1;
298 ULONG Dpl : 2;
299 ULONG Present : 1;
300 ULONG LimitHigh : 4;
301 ULONG Avl : 1;
302 ULONG Reserved : 1;
303 ULONG Size : 1;
304 ULONG Granularity : 1;
305 ULONG BaseHigh : 8;
306 } FAST486_GDT_ENTRY, *PFAST486_GDT_ENTRY;
307
308 /* Verify the structure size */
309 C_ASSERT(sizeof(FAST486_GDT_ENTRY) == sizeof(ULONGLONG));
310
311 typedef struct
312 {
313 ULONG Limit : 16;
314 ULONG Base : 16;
315 ULONG BaseMid : 8;
316 ULONG Signature : 5;
317 ULONG Dpl : 2;
318 ULONG Present : 1;
319 ULONG LimitHigh : 4;
320 ULONG Avl : 1;
321 ULONG Reserved : 2;
322 ULONG Granularity : 1;
323 ULONG BaseHigh : 8;
324 } FAST486_SYSTEM_DESCRIPTOR, *PFAST486_SYSTEM_DESCRIPTOR;
325
326 /* Verify the structure size */
327 C_ASSERT(sizeof(FAST486_SYSTEM_DESCRIPTOR) == sizeof(ULONGLONG));
328
329 typedef struct
330 {
331 ULONG Offset : 16;
332 ULONG Selector : 16;
333 ULONG ParamCount : 5;
334 ULONG Reserved : 3;
335 ULONG Type : 4;
336 ULONG SystemType : 1;
337 ULONG Dpl : 2;
338 ULONG Present : 1;
339 ULONG OffsetHigh : 16;
340 } FAST486_CALL_GATE, *PFAST486_CALL_GATE;
341
342 /* Verify the structure size */
343 C_ASSERT(sizeof(FAST486_CALL_GATE) == sizeof(ULONGLONG));
344
345 typedef struct
346 {
347 ULONG Offset : 16;
348 ULONG Selector : 16;
349 ULONG Zero : 8;
350 ULONG Type : 4;
351 ULONG Storage : 1;
352 ULONG Dpl : 2;
353 ULONG Present : 1;
354 ULONG OffsetHigh : 16;
355 } FAST486_IDT_ENTRY, *PFAST486_IDT_ENTRY;
356
357 /* Verify the structure size */
358 C_ASSERT(sizeof(FAST486_IDT_ENTRY) == sizeof(ULONGLONG));
359
360 typedef struct _FAST486_TSS
361 {
362 ULONG Link;
363 ULONG Esp0;
364 ULONG Ss0;
365 ULONG Esp1;
366 ULONG Ss1;
367 ULONG Esp2;
368 ULONG Ss2;
369 ULONG Cr3;
370 ULONG Eip;
371 ULONG Eflags;
372 ULONG Eax;
373 ULONG Ecx;
374 ULONG Edx;
375 ULONG Ebx;
376 ULONG Esp;
377 ULONG Ebp;
378 ULONG Esi;
379 ULONG Edi;
380 ULONG Es;
381 ULONG Cs;
382 ULONG Ss;
383 ULONG Ds;
384 ULONG Fs;
385 ULONG Gs;
386 ULONG Ldtr;
387 ULONG IopbOffset;
388 } FAST486_TSS, *PFAST486_TSS;
389
390 typedef struct _FAST486_LEGACY_TSS
391 {
392 USHORT Link;
393 USHORT Sp0;
394 USHORT Ss0;
395 USHORT Sp1;
396 USHORT Ss1;
397 USHORT Sp2;
398 USHORT Ss2;
399 USHORT Ip;
400 USHORT Flags;
401 USHORT Ax;
402 USHORT Cx;
403 USHORT Dx;
404 USHORT Bx;
405 USHORT Sp;
406 USHORT Bp;
407 USHORT Si;
408 USHORT Di;
409 USHORT Es;
410 USHORT Cs;
411 USHORT Ss;
412 USHORT Ds;
413 USHORT Ldtr;
414 } FAST486_LEGACY_TSS, *PFAST486_LEGACY_TSS;
415
416 #include <poppack.h>
417
418 typedef struct _FAST486_TABLE_REG
419 {
420 USHORT Size;
421 ULONG Address;
422 } FAST486_TABLE_REG, *PFAST486_TABLE_REG;
423
424 typedef union _FAST486_FLAGS_REG
425 {
426 USHORT LowWord;
427 ULONG Long;
428
429 struct
430 {
431 ULONG Cf : 1;
432 ULONG AlwaysSet : 1;
433 ULONG Pf : 1;
434 ULONG Reserved0 : 1;
435 ULONG Af : 1;
436 ULONG Reserved1 : 1;
437 ULONG Zf : 1;
438 ULONG Sf : 1;
439 ULONG Tf : 1;
440 ULONG If : 1;
441 ULONG Df : 1;
442 ULONG Of : 1;
443 ULONG Iopl : 2;
444 ULONG Nt : 1;
445 ULONG Reserved2 : 1;
446 ULONG Rf : 1;
447 ULONG Vm : 1;
448 ULONG Ac : 1;
449
450 // ULONG Reserved : 13;
451 };
452 } FAST486_FLAGS_REG, *PFAST486_FLAGS_REG;
453
454 typedef struct _FAST486_FPU_DATA_REG
455 {
456 ULONGLONG Mantissa;
457 USHORT Exponent;
458 UCHAR Sign;
459 } FAST486_FPU_DATA_REG, *PFAST486_FPU_DATA_REG;
460
461 typedef const FAST486_FPU_DATA_REG *PCFAST486_FPU_DATA_REG;
462
463 typedef union _FAST486_FPU_STATUS_REG
464 {
465 USHORT Value;
466
467 struct
468 {
469 ULONG Ie : 1;
470 ULONG De : 1;
471 ULONG Ze : 1;
472 ULONG Oe : 1;
473 ULONG Ue : 1;
474 ULONG Pe : 1;
475 ULONG Sf : 1;
476 ULONG Es : 1;
477 ULONG Code0 : 1;
478 ULONG Code1 : 1;
479 ULONG Code2 : 1;
480 ULONG Top : 3;
481 ULONG Code3 : 1;
482 ULONG Busy : 1;
483 };
484 } FAST486_FPU_STATUS_REG, *PFAST486_FPU_STATUS_REG;
485
486 typedef union _FAST486_FPU_CONTROL_REG
487 {
488 USHORT Value;
489
490 struct
491 {
492 ULONG Im : 1;
493 ULONG Dm : 1;
494 ULONG Zm : 1;
495 ULONG Om : 1;
496 ULONG Um : 1;
497 ULONG Pm : 1;
498 ULONG Reserved : 2;
499 ULONG Pc : 2;
500 ULONG Rc : 2;
501 ULONG Inf : 1;
502 // ULONG Reserved1 : 3;
503 };
504 } FAST486_FPU_CONTROL_REG, *PFAST486_FPU_CONTROL_REG;
505
506 struct _FAST486_STATE
507 {
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;
522 UCHAR Cpl;
523 ULONG ControlRegisters[FAST486_NUM_CTRL_REGS];
524 ULONG DebugRegisters[FAST486_NUM_DBG_REGS];
525 ULONG ExceptionCount;
526 ULONG PrefixFlags;
527 FAST486_SEG_REGS SegmentOverride;
528 BOOLEAN Halted;
529 BOOLEAN IntSignaled;
530 BOOLEAN DoNotInterrupt;
531 PULONG Tlb;
532 BOOLEAN TlbEmpty;
533 #ifndef FAST486_NO_PREFETCH
534 BOOLEAN PrefetchValid;
535 ULONG PrefetchAddress;
536 UCHAR PrefetchCache[FAST486_CACHE_SIZE];
537 #endif
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;
542 USHORT FpuTag;
543 FAST486_REG FpuLastInstPtr;
544 USHORT FpuLastCodeSel;
545 FAST486_REG FpuLastOpPtr;
546 USHORT FpuLastDataSel;
547 #endif
548 };
549
550 /* FUNCTIONS ******************************************************************/
551
552 VOID
553 NTAPI
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,
562 PULONG Tlb);
563
564 VOID
565 NTAPI
566 Fast486Reset(PFAST486_STATE State);
567
568 VOID
569 NTAPI
570 Fast486Continue(PFAST486_STATE State);
571
572 VOID
573 NTAPI
574 Fast486StepInto(PFAST486_STATE State);
575
576 VOID
577 NTAPI
578 Fast486StepOver(PFAST486_STATE State);
579
580 VOID
581 NTAPI
582 Fast486StepOut(PFAST486_STATE State);
583
584 VOID
585 NTAPI
586 Fast486DumpState(PFAST486_STATE State);
587
588 VOID
589 NTAPI
590 Fast486InterruptSignal(PFAST486_STATE State);
591
592 VOID
593 NTAPI
594 Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset);
595
596 VOID
597 NTAPI
598 Fast486SetStack(PFAST486_STATE State, USHORT Segment, ULONG Offset);
599
600 VOID
601 NTAPI
602 Fast486SetSegment
603 (
604 PFAST486_STATE State,
605 FAST486_SEG_REGS Segment,
606 USHORT Selector
607 );
608
609 VOID
610 NTAPI
611 Fast486Rewind(PFAST486_STATE State);
612
613 #endif // _FAST486_H_
614
615 /* EOF */