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