587f7e7dcb240d056b6460a6cd31ef9976034146
[reactos.git] / include / reactos / libs / softx86 / softx86.h
1
2 #ifndef SOFTX86_H
3 #define SOFTX86_H
4
5 /* get the Softx86 configuration defines */
6 #include <softx86cfg.h>
7
8 #ifdef __cplusplus
9 extern "C" {
10 #endif //__cplusplus
11
12 /// version composed as follows: H.LL.SSSS
13 // where: H = major version number (any length)
14 // L = minor version number (2 digits)
15 // S = sub-minor version number (4 digits)
16 //
17 // The context structure is only allowed to change if the major (high)
18 // version number changes.
19 //
20 // This is v0.00.0033
21 #define SOFTX86_VERSION_HI 0
22 #define SOFTX86_VERSION_LO 0
23 #define SOFTX86_VERSION_SUBLO 33
24
25 #ifdef __MINGW32__ // MINGW
26
27 typedef unsigned char sx86_ubyte;
28 typedef signed char sx86_sbyte;
29 typedef unsigned short int sx86_uword;
30 typedef signed short int sx86_sword;
31 typedef unsigned int sx86_udword;
32 typedef signed int sx86_sdword;
33 typedef unsigned long long int sx86_uldword;
34 typedef signed long long int sx86_sldword;
35
36 #elif WIN32 // MSVC
37
38 typedef unsigned char sx86_ubyte;
39 typedef signed char sx86_sbyte;
40 typedef unsigned short int sx86_uword;
41 typedef signed short int sx86_sword;
42 typedef unsigned int sx86_udword;
43 typedef signed int sx86_sdword;
44 typedef unsigned __int64 sx86_uldword;
45 typedef signed __int64 sx86_sldword;
46
47 #else // GCC 3.xx.xx
48
49 typedef unsigned char sx86_ubyte;
50 typedef signed char sx86_sbyte;
51 typedef unsigned short int sx86_uword;
52 typedef signed short int sx86_sword;
53 typedef unsigned int sx86_udword;
54 typedef signed int sx86_sdword;
55 typedef unsigned long long int sx86_uldword;
56 typedef signed long long int sx86_sldword;
57
58 #endif
59
60 /* NOTE: All registers contain the CPU values in native byte order NOT little
61 Endian byte order! When loading values from RAM always use
62 the SWAP_WORD_FROM_LE() macro! */
63 typedef union {
64 sx86_udword val; /* the entire 32-bit register as a whole (i.e. EAX) */
65
66 #if SX86_BYTE_ORDER == LE
67
68 struct __dummy_w {
69 sx86_uword lo; /* lower 16 bits of register (i.e. AX) */
70 sx86_uword hi; /* upper 16 bits of register */
71 } w;
72
73 struct __dummy_b {
74 sx86_ubyte lo; /* lower 8 bits of register (i.e. AL) */
75 sx86_ubyte hi; /* bits 8-15 of register (i.e. AH) */
76 sx86_ubyte extra[2];
77 } b;
78
79 #elif SX86_BYTE_ORDER == BE /* member order reversed from LE because byte order reversed */
80
81 struct __dummy_w {
82 sx86_uword hi; /* upper 16 bits of register */
83 sx86_uword lo; /* lower 16 bits of register (i.e. AX) */
84 } w;
85
86 struct __dummy_b {
87 sx86_ubyte extra[2];
88 sx86_ubyte hi; /* bits 8-15 of register (i.e. AH) */
89 sx86_ubyte lo; /* lower 8 bits of register (i.e. AL) */
90 } b;
91
92 #endif
93
94 } softx86_regval;
95
96 typedef struct {
97 sx86_uword val; /* visible to program---the value */
98 sx86_udword cached_linear; /* hidden---linear address of segment */
99 sx86_udword cached_limit; /* hidden---limit of segment */
100 } softx86_segregval;
101
102 /*============================================================================
103 CPU state variables.
104
105 All segment register values are handled in little endian order.
106
107 WARNING: Also this structure will change over time to accomodate the
108 "hidden portions" of registers that, like the real thing,
109 are used to avoid recalculating values that hardly change
110 anyway (such as the segment register to linear address conversions).
111
112 WARNING: This structure is likely to change constantly over time, do not
113 rely on this structure staying the same from version to version.
114 THE VERSION NUMBERS ARE THERE TO HELP YOU WITH THIS.
115
116 04-21-2003: Jonathan Campbell <jcampbell@mdjk.com>
117 Registers are now represented by a C union rather than a word
118 value. This makes referring to upper and lower parts (i.e.
119 AL or AH in AX or AX in EAX) easier to code because the members
120 can be reordered based on the byte order of the platform we are
121 running on. Thanks to Paul Muller for this idea!
122
123 All general-purpose registers are now stowed in one big array.
124 Use the constants SX86_REG_AX, SX86_REG_BX... to refer to it.
125 */
126
127 /* This enumeration refers to indices within softx86_ctx.state.general_reg[] */
128 enum softx86_genregidx16 {
129 SX86_REG_AX=0,
130 SX86_REG_CX,
131 SX86_REG_DX,
132 SX86_REG_BX,
133 SX86_REG_SP,
134 SX86_REG_BP,
135 SX86_REG_SI,
136 SX86_REG_DI,
137 };
138
139 /* This enumeration refers to indices within softx86_ctx.ptr_regs_8reg[],
140 which are set at run time to point to the representative portion of
141 softx86_ctx.state.general_reg[] */
142 enum softx86_genregidx8 {
143 SX86_REG_AL=0,
144 SX86_REG_CL,
145 SX86_REG_DL,
146 SX86_REG_BL,
147 SX86_REG_AH,
148 SX86_REG_CH,
149 SX86_REG_DH,
150 SX86_REG_BH,
151 };
152
153 /* seg-reg IDs used in this library to refer to softx86_ctx.state.segment_reg[] */
154 enum softx86_segregidx {
155 SX86_SREG_ES=0,
156 SX86_SREG_CS,
157 SX86_SREG_SS,
158 SX86_SREG_DS,
159 };
160
161 typedef struct {
162 /************************ VISIBLE REGISTERS ****************************/
163 /*--------------------general purpose registers------------------------*/
164 softx86_regval general_reg[8];
165 /*-------------------------segment registers---------------------------*/
166 softx86_segregval segment_reg[8];
167 /*-----------------instruction and FLAGS registers---------------------*/
168 softx86_regval reg_flags;
169 sx86_udword reg_ip;
170 /*-----------------control/machine state registers---------------------*/
171 sx86_udword reg_cr0;
172 /************* INVISIBLE REGISTERS (FOR CACHING PURPOSES) **************/
173 /*------------instruction pointer saved before execution---------------*/
174 sx86_uword reg_cs_exec_initial; /* these are copied from CS:IP before executing an instruction */
175 sx86_udword reg_ip_exec_initial; /* <------' */
176 /*----------------instruction pointer for decompiler-------------------*/
177 sx86_uword reg_cs_decompiler;
178 sx86_udword reg_ip_decompiler;
179 /*-------------------interrupt flags-----------------------------------*/
180 sx86_ubyte int_hw_flag; /* flag to indicate hardware (external) interrupt pending */
181 sx86_ubyte int_hw; /* if int_hw_flag==1, which interrupt is being signalled */
182 sx86_ubyte int_nmi; /* flag to indicate NMI hardware (external) interrupt pending */
183 /*-------------------other internal flags------------------------------*/
184 sx86_ubyte rep_flag; /* 0=no REP loop, 1=REPNZ, 2=REPZ */
185 sx86_ubyte is_segment_override; /* 1=segment override was encountered */
186 sx86_uword segment_override; /* value of segment that overrides the default */
187 } softx86_cpustate;
188
189 typedef struct {
190 /* I/O */
191 void (*on_read_memory) (/* softx86_ctx */ void* _ctx,sx86_udword address,sx86_ubyte *buf,int size); /* called to fetch from memory <size> bytes from address <address> */
192 void (*on_read_io) (/* softx86_ctx */ void* _ctx,sx86_udword address,sx86_ubyte *buf,int size); /* called to fetch from I/O <size> bytes from address <address> */
193 void (*on_write_memory) (/* softx86_ctx */ void* _ctx,sx86_udword address,sx86_ubyte *buf,int size); /* called to write to memory <size> bytes from address <address> */
194 void (*on_write_io) (/* softx86_ctx */ void* _ctx,sx86_udword address,sx86_ubyte *buf,int size); /* called to write to I/O <size> bytes from address <address> */
195 /* interrupts */
196 void (*on_hw_int) (/* softx86_ctx */ void* _ctx,sx86_ubyte i); /* called when an external (to this library) interrupt occurs */
197 void (*on_sw_int) (/* softx86_ctx */ void* _ctx,sx86_ubyte i); /* called when an internal (emulated software) interrupt occurs */
198 void (*on_hw_int_ack) (/* softx86_ctx */ void* _ctx,sx86_ubyte i); /* called when the CPU (this library) acknowledges the interrupt */
199 void (*on_nmi_int) (/* softx86_ctx */ void* _ctx); /* called when an external (to this library) NMI interrupt occurs */
200 void (*on_nmi_int_ack) (/* softx86_ctx */ void* _ctx); /* called when the CPU (this library) acknowledges the NMI interrupt */
201 /* host-to-CPU interaction */
202 void (*on_idle_cycle) (/* softx86_ctx */ void* _ctx); /* called so host application can do finer-grained things during the execution of one instruction */
203 void (*on_reset) (/* softx86_ctx */ void* _ctx); /* informs host application if CPU reset itself or has been reset */
204 /* CPU-to-FPU interaction */
205 int (*on_fpu_opcode_exec) (/* softx86_ctx */ void* _ctx86,/* softx87_ctx */ void* _ctx87,sx86_ubyte opcode); /* called when an FPU opcode is encountered during execution */
206 int (*on_fpu_opcode_dec) (/* softx86_ctx */ void* _ctx86,/* softx87_ctx */ void* _ctx87,sx86_ubyte opcode,char buf[128]); /* called when an FPU opcode is encountered during decompile */
207 } softx86_callbacks;
208
209 #ifndef bswap16
210 #define bswap16(x) (((x&0xFF)<<8) | ((x>>8)&0xFF))
211 #endif //bswap16
212
213 /* segment to linear conversion routines */
214 #define SEGMENT_TO_LINEAR(x) (x<<4)
215 #define SEGMENT_OFFSET_TO_LINEAR(s,o) (SEGMENT_TO_LINEAR(x)+o)
216
217 /* force a given value to fit within the specified size */
218 #define MASK_BYTE_SIZE(x) (x &= 0xFF)
219 #define MASK_WORD_SIZE(x) (x &= 0xFFFF)
220 #define MASK_DWORD_SIZE(x) (x &= 0xFFFFFFFFL)
221 #define FORCE_BYTE_SIZE(x) (x & 0xFF)
222 #define FORCE_WORD_SIZE(x) (x & 0xFFFF)
223 #define FORCE_DWORD_SIZE(x) (x & 0xFFFFFFFFL)
224
225 /* sign-extending macros */
226 #define SGNEXT8(x) (x | ((x & 0x80) ? 0xFFFFFF00 : 0))
227 #define SGNEXT16(x) (x | ((x & 0x8000) ? 0xFFFF0000 : 0))
228
229 /*=====================================================================================
230 Softx86 bug structure
231
232 This structure is used to contain variables related to the emulation of various
233 flaws and bugs in the CPU.
234
235 Please do not modify these directly.
236 */
237 typedef struct {
238 sx86_ubyte preemptible_after_prefix; // 1=interrupts can occur between the prefix and the opcode (8088/8086 behavior)
239 sx86_ubyte decrement_sp_before_store; // 1=(E)SP is decremented before storing
240 sx86_ubyte mask_5bit_shiftcount; // 1=mask shift count to 5 bits (286+ behavior)
241 } softx86_bugs;
242
243 /*=====================================================================================
244 Softx86 internal context structure
245
246 This structure is used internally by softx86
247 */
248 typedef struct {
249 #ifdef SX86_INSIDER
250 /* ------------------ if compiling softx86 library source code ---------------- */
251 void* opcode_table; // main opcode table
252 void* opcode_table_sub_0Fh; // alternate opcode table for instructions that start with 0Fh
253 sx86_udword addr_mask; // used to limit addressing based on CPU level
254 int level; // which CPU are we emulating?
255 sx86_ubyte* ptr_regs_8reg[8]; // pointer table to 8-bit regs given reg value in opcode
256 #else
257 /* ----------------------- if compiling outsider source code ------------------- */
258 void* nothing;
259 #endif
260 } softx86_internal;
261
262 /*=====================================================================================
263 Softx86 context structure
264
265 This structure is used to interact with the host application.
266 */
267 typedef struct {
268 // version
269 sx86_ubyte version_hi;
270 sx86_ubyte version_lo;
271 sx86_uword version_sublo;
272 // publicly viewable/modifiable standard vars
273 softx86_cpustate* state;
274 softx86_callbacks* callbacks;
275 softx86_bugs* bugs;
276 // private vars
277 softx86_internal* __private;
278 // linkage vars
279 void* ref_softx87_ctx; // link to context structure of softx87
280 // "user-defined" vars (whatever the host application wants to carry with this context structure)
281 void* user;
282 } softx86_ctx;
283
284 /* CPU emulation levels */
285 #define SX86_CPULEVEL_8088 0 // 8088
286 #define SX86_CPULEVEL_8086 1 // 8086
287 #define SX86_CPULEVEL_80186 2 // 80186
288 #define SX86_CPULEVEL_80286 3 // 80286
289
290 #define sx86_far_to_linear(ctx,seg,ofs) ((seg<<4)+ofs)
291
292 void sx86_exec_full_modregrm_rw(softx86_ctx* ctx,sx86_ubyte w16,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte reg,sx86_ubyte rm,sx86_ubyte opswap,sx86_ubyte (*op8)(softx86_ctx* ctx,sx86_ubyte src,sx86_ubyte val),sx86_uword (*op16)(softx86_ctx* ctx,sx86_uword src,sx86_uword val),sx86_udword (*op32)(softx86_ctx* ctx,sx86_udword src,sx86_udword val));
293 void sx86_exec_full_modregrm_ro(softx86_ctx* ctx,sx86_ubyte w16,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte reg,sx86_ubyte rm,sx86_ubyte opswap,sx86_ubyte (*op8)(softx86_ctx* ctx,sx86_ubyte src,sx86_ubyte val),sx86_uword (*op16)(softx86_ctx* ctx,sx86_uword src,sx86_uword val),sx86_udword (*op32)(softx86_ctx* ctx,sx86_udword src,sx86_udword val));
294 void sx86_exec_full_modsregrm_rw(softx86_ctx* ctx,sx86_ubyte mod,sx86_ubyte reg,sx86_ubyte rm,sx86_ubyte opswap,sx86_uword (*op16)(softx86_ctx* ctx,sx86_uword src,sx86_uword val));
295 void sx86_exec_full_modrmonly_rw(softx86_ctx* ctx,sx86_ubyte w16,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte rm,sx86_ubyte (*op8)(softx86_ctx* ctx,sx86_ubyte src),sx86_uword (*op16)(softx86_ctx* ctx,sx86_uword src),sx86_udword (*op32)(softx86_ctx* ctx,sx86_udword src));
296 void sx86_exec_full_modrmonly_rw_imm(softx86_ctx* ctx,sx86_ubyte w16,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte rm,sx86_ubyte (*op8)(softx86_ctx* ctx,sx86_ubyte src,sx86_ubyte val),sx86_uword (*op16)(softx86_ctx* ctx,sx86_uword src,sx86_uword val),sx86_udword (*op32)(softx86_ctx* ctx,sx86_udword src,sx86_udword val),int sx);
297 void sx86_exec_full_modrmonly_rw_imm8(softx86_ctx* ctx,sx86_ubyte w16,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte rm,sx86_ubyte (*op8)(softx86_ctx* ctx,sx86_ubyte src,sx86_ubyte val),sx86_uword (*op16)(softx86_ctx* ctx,sx86_uword src,sx86_uword val),sx86_udword (*op32)(softx86_ctx* ctx,sx86_udword src,sx86_udword val));
298 void sx86_exec_full_modrmonly_ro_imm(softx86_ctx* ctx,sx86_ubyte w16,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte rm,sx86_ubyte (*op8)(softx86_ctx* ctx,sx86_ubyte src,sx86_ubyte val),sx86_uword (*op16)(softx86_ctx* ctx,sx86_uword src,sx86_uword val),sx86_udword (*op32)(softx86_ctx* ctx,sx86_udword src,sx86_udword val),int sx);
299 void sx86_exec_full_modregrm_xchg(softx86_ctx* ctx,sx86_ubyte w16,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte reg,sx86_ubyte rm);
300 void sx86_exec_full_modregrm_lea(softx86_ctx* ctx,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte reg,sx86_ubyte rm);
301 void sx86_exec_full_modrw_memx(softx86_ctx* ctx,sx86_ubyte mod,sx86_ubyte rm,int sz,void (*op64)(softx86_ctx* ctx,char *datz,int sz));
302 void sx86_exec_full_modrmonly_memx(softx86_ctx* ctx,sx86_ubyte mod,sx86_ubyte rm,int sz,void (*op64)(softx86_ctx* ctx,char *datz,int sz));
303 void sx86_exec_full_modrmonly_callfar(softx86_ctx* ctx,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte rm,void (*op16)(softx86_ctx* ctx,sx86_uword seg,sx86_uword ofs),void (*op32)(softx86_ctx* ctx,sx86_udword seg,sx86_udword ofs));
304 void sx86_exec_full_modrmonly_ro(softx86_ctx* ctx,sx86_ubyte w16,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte rm,sx86_ubyte (*op8)(softx86_ctx* ctx,sx86_ubyte src),sx86_uword (*op16)(softx86_ctx* ctx,sx86_uword src),sx86_udword (*op32)(softx86_ctx* ctx,sx86_udword src));
305 void sx86_exec_full_modrmonly_wo(softx86_ctx* ctx,sx86_ubyte w16,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte rm,sx86_ubyte (*op8)(softx86_ctx* ctx),sx86_uword (*op16)(softx86_ctx* ctx),sx86_udword (*op32)(softx86_ctx* ctx));
306 void sx86_exec_full_modregrm_far(softx86_ctx* ctx,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte reg,sx86_ubyte rm,sx86_uword (*op16)(softx86_ctx* ctx,sx86_uword seg,sx86_uword ofs),sx86_udword (*op32)(softx86_ctx* ctx,sx86_udword seg,sx86_udword ofs));
307 void sx86_exec_full_modregrm_far_ro3(softx86_ctx* ctx,sx86_ubyte d32,sx86_ubyte mod,sx86_ubyte reg,sx86_ubyte rm,sx86_sword (*op16)(softx86_ctx* ctx,sx86_sword idx,sx86_sword upper,sx86_sword lower),sx86_sdword (*op32)(softx86_ctx* ctx,sx86_sdword idx,sx86_sdword upper,sx86_sdword lower));
308
309 void sx86_dec_full_modrmonly(softx86_ctx* ctx,sx86_ubyte is_word,sx86_ubyte dat32,sx86_ubyte mod,sx86_ubyte rm,char* op1);
310 void sx86_dec_full_modregrm(softx86_ctx* cpu,sx86_ubyte is_word,sx86_ubyte dat32,sx86_ubyte mod,sx86_ubyte reg,sx86_ubyte rm,char* op1,char* op2);
311 void sx86_dec_full_modsregrm(softx86_ctx* cpu,sx86_ubyte mod,sx86_ubyte reg,sx86_ubyte rm,char* op1,char* op2);
312
313 void softx86_bswap2(sx86_ubyte *x);
314 void softx86_bswap4(sx86_ubyte *x);
315
316 #if SX86_BYTE_ORDER == LE
317 #define SWAP_WORD_FROM_LE(x)
318 #define SWAP_DWORD_FROM_LE(x)
319 #else
320 #define SWAP_WORD_FROM_LE(x) softx86_bswap2((sx86_ubyte*)(&x));
321 #define SWAP_DWORD_FROM_LE(x) softx86_bswap4((sx86_ubyte*)(&x));
322 #endif
323
324 #define SWAP_WORD_TO_LE(x) SWAP_WORD_FROM_LE(x)
325 #define SWAP_DWORD_TO_LE(x) SWAP_DWORD_FROM_LE(x)
326
327 /* API */
328 int softx86_getversion(int *major,int *minor,int *subminor);
329 int softx86_init(softx86_ctx* ctx,int level);
330 int softx86_reset(softx86_ctx* ctx);
331 int softx86_free(softx86_ctx* ctx);
332 int softx86_step(softx86_ctx* ctx);
333 int softx86_decompile(softx86_ctx* ctx,char asmbuf[256]);
334 int softx86_decompile_exec_cs_ip(softx86_ctx* ctx);
335 /* API for stack */
336 sx86_uword softx86_stack_popw(softx86_ctx* ctx);
337 void softx86_stack_discard_n(softx86_ctx* ctx,int bytez);
338 void softx86_stack_add_n(softx86_ctx* ctx,int bytez);
339 void softx86_stack_pushw(softx86_ctx* ctx,sx86_uword data);
340 /* API for CPU itself in terms of fetching data properly */
341 int softx86_fetch(softx86_ctx* ctx,void *reserved,sx86_udword addr,void *buf,int sz);
342 int softx86_write(softx86_ctx* ctx,void *reserved,sx86_udword addr,void *buf,int sz);
343 sx86_ubyte softx86_fetch_exec_byte(softx86_ctx* ctx);
344 sx86_ubyte softx86_fetch_dec_byte(softx86_ctx* ctx);
345 /* API for setting segment register values */
346 int softx86_setsegval(softx86_ctx* ctx,int sreg_id,sx86_udword x);
347 /* API for setting important pointers (NOTE: use these instead of directly
348 * modifying the register values please, as it will make future development
349 * of instruction queues, caches, and pipelines much easier to manage in
350 * terms of CS:IP and SS:SP) */
351 int softx86_set_instruction_ptr(softx86_ctx* ctx,sx86_udword cs,sx86_udword ip);
352 int softx86_set_instruction_dec_ptr(softx86_ctx* ctx,sx86_udword cs,sx86_udword ip);
353 int softx86_set_stack_ptr(softx86_ctx* ctx,sx86_udword ss,sx86_udword sp);
354 int softx86_set_near_instruction_ptr(softx86_ctx* ctx,sx86_udword ip);
355 /* get an interrupt vector */
356 int softx86_get_intvect(softx86_ctx* ctx,sx86_ubyte i,sx86_uword *seg,sx86_uword *ofs);
357 int softx86_set_intvect(softx86_ctx* ctx,sx86_ubyte i,sx86_uword seg,sx86_uword ofs);
358 /* save instruction pointer on stack, get int vector, set instruction pointer there */
359 void softx86_go_int_frame(softx86_ctx* ctx,sx86_ubyte i);
360 /* generate stack frame and (optionally) set the instruction pointer */
361 int softx86_make_simple_near_call(softx86_ctx* ctx,sx86_udword* ip);
362 int softx86_make_simple_far_call(softx86_ctx* ctx,sx86_udword* cs,sx86_udword* ip);
363 int softx86_make_simple_interrupt_call(softx86_ctx* ctx,sx86_udword* cs,sx86_udword* ip);
364 /* macros for more advanced versions of the above functions (param1, param2, etc...
365 refers to the number of parameters passed to the function). */
366 /*---------------------- "typical" refers to the fact that most
367 ---------------------- C/C++ compilers for DOS and Win16 (ignoring
368 ---------------------- those that use the CPU registers) use
369 ---------------------- a simple calling convention where the
370 ---------------------- parameters are pushed onto the stack
371 ---------------------- in the opposite of the order they
372 ---------------------- appear in the parameter list. __pascal, __stdcall,
373 ---------------------- __cdecl, and the like all share this
374 ---------------------- apparently (the difference is how the
375 ---------------------- stack is cleaned up) */
376 #define softx86_make_typical_near_call_param1(ctx,ip,p1)\
377 softx86_stack_pushw(ctx,p1);\
378 softx86_make_simple_near_call(ctx,ip);
379
380 #define softx86_make_typical_near_call_param2(ctx,ip,p1,p2)\
381 softx86_stack_pushw(ctx,p2);\
382 softx86_stack_pushw(ctx,p1);\
383 softx86_make_simple_near_call(ctx,ip);
384
385 #define softx86_make_typical_near_call_param3(ctx,ip,p1,p2,p3)\
386 softx86_stack_pushw(ctx,p3);\
387 softx86_stack_pushw(ctx,p2);\
388 softx86_stack_pushw(ctx,p1);\
389 softx86_make_simple_near_call(ctx,ip);
390
391 #define softx86_make_typical_near_call_param4(ctx,ip,p1,p2,p3,p4)\
392 softx86_stack_pushw(ctx,p4);\
393 softx86_stack_pushw(ctx,p3);\
394 softx86_stack_pushw(ctx,p2);\
395 softx86_stack_pushw(ctx,p1);\
396 softx86_make_simple_near_call(ctx,ip);
397
398
399 #define softx86_make_typical_far_call_param1(ctx,cs,ip,p1)\
400 softx86_stack_pushw(ctx,p1);\
401 softx86_make_simple_far_call(ctx,cs,ip);
402
403 #define softx86_make_typical_far_call_param2(ctx,cs,ip,p1,p2)\
404 softx86_stack_pushw(ctx,p2);\
405 softx86_stack_pushw(ctx,p1);\
406 softx86_make_simple_far_call(ctx,cs,ip);
407
408 #define softx86_make_typical_far_call_param3(ctx,cs,ip,p1,p2,p3)\
409 softx86_stack_pushw(ctx,p3);\
410 softx86_stack_pushw(ctx,p2);\
411 softx86_stack_pushw(ctx,p1);\
412 softx86_make_simple_far_call(ctx,cs,ip);
413
414 #define softx86_make_typical_far_call_param4(ctx,cs,ip,p1,p2,p3,p4)\
415 softx86_stack_pushw(ctx,p4);\
416 softx86_stack_pushw(ctx,p3);\
417 softx86_stack_pushw(ctx,p2);\
418 softx86_stack_pushw(ctx,p1);\
419 softx86_make_simple_far_call(ctx,cs,ip);
420
421
422 /* mask constants for CR0 (286+ compatible) */
423 #define SX86_CR0_LMSW_MASK 0x0000000E
424 #define SX86_CR0FLAG_PE 0x00000001
425 #define SX86_CR0FLAG_MP 0x00000002
426 #define SX86_CR0FLAG_EM 0x00000004
427 #define SX86_CR0FLAG_TS 0x00000008
428 /* mask constants for CR0 (386+ compatible) */
429 #define SX86_CR0FLAG_ET 0x00000010
430 #define SX86_CR0FLAG_NE 0x00000020
431 #define SX86_CR0FLAG_WP 0x00010000
432 #define SX86_CR0FLAG_AM 0x00040000
433 #define SX86_CR0FLAG_NW 0x20000000
434 #define SX86_CR0FLAG_CD 0x40000000
435 #define SX86_CR0FLAG_PG 0x80000000
436
437 /* mask constants for CPU flags */
438 #define SX86_CPUFLAG_CARRY 0x00000001
439 #define SX86_CPUFLAG_RESERVED_01 0x00000002
440 #define SX86_CPUFLAG_PARITY 0x00000004
441 #define SX86_CPUFLAG_RESERVED_03 0x00000008
442 #define SX86_CPUFLAG_AUX 0x00000010
443 #define SX86_CPUFLAG_RESERVED_05 0x00000020
444 #define SX86_CPUFLAG_ZERO 0x00000040
445 #define SX86_CPUFLAG_SIGN 0x00000080
446 #define SX86_CPUFLAG_TRAP 0x00000100
447 #define SX86_CPUFLAG_INTENABLE 0x00000200
448 #define SX86_CPUFLAG_DIRECTIONREV 0x00000400
449 #define SX86_CPUFLAG_OVERFLOW 0x00000800
450 #define SX86_CPUFLAG_IOPL 0x00003000
451 #define SX86_CPUFLAG_IOPLSET(x) (((x&3))<<12)
452 #define SX86_CPUFLAG_IOPLGET(x) ((x>>12)&3)
453 #define SX86_CPUFLAG_NESTEDTASK 0x00004000
454 #define SX86_CPUFLAG_RESERVED_15 0x00008000
455 #define SX86_CPUFLAG_RESUME 0x00010000
456 #define SX86_CPUFLAG_V86 0x00020000
457 #define SX86_CPUFLAG_ALIGNMENTCHK 0x00040000
458 #define SX86_CPUFLAG_RESERVED_19 0x00080000
459 #define SX86_CPUFLAG_RESERVED_20 0x00100000
460 #define SX86_CPUFLAG_RESERVED_21 0x00200000
461 #define SX86_CPUFLAG_RESERVED_22 0x00400000
462 #define SX86_CPUFLAG_RESERVED_23 0x00800000
463 #define SX86_CPUFLAG_RESERVED_24 0x01000000
464 #define SX86_CPUFLAG_RESERVED_25 0x02000000
465 #define SX86_CPUFLAG_RESERVED_26 0x04000000
466 #define SX86_CPUFLAG_RESERVED_27 0x08000000
467 #define SX86_CPUFLAG_RESERVED_28 0x10000000
468 #define SX86_CPUFLAG_RESERVED_29 0x20000000
469 #define SX86_CPUFLAG_RESERVED_30 0x40000000
470 #define SX86_CPUFLAG_RESERVED_31 0x80000000
471
472 #define SX86_CPUFLAGBO_CARRY 0
473 #define SX86_CPUFLAGBO_RESERVED_01 1
474 #define SX86_CPUFLAGBO_PARITY 2
475 #define SX86_CPUFLAGBO_RESERVED_03 3
476 #define SX86_CPUFLAGBO_AUX 4
477 #define SX86_CPUFLAGBO_RESERVED_05 5
478 #define SX86_CPUFLAGBO_ZERO 6
479 #define SX86_CPUFLAGBO_SIGN 7
480 #define SX86_CPUFLAGBO_TRAP 8
481 #define SX86_CPUFLAGBO_INTENABLE 9
482 #define SX86_CPUFLAGBO_DIRECTIONREV 10
483 #define SX86_CPUFLAGBO_OVERFLOW 11
484 #define SX86_CPUFLAGBO_IOPL 12
485 #define SX86_CPUFLAGBO_NESTEDTASK 14
486 #define SX86_CPUFLAGBO_RESERVED_15 15
487 #define SX86_CPUFLAGBO_RESUME 16
488 #define SX86_CPUFLAGBO_V86 17
489 #define SX86_CPUFLAGBO_ALIGNMENTCHK 18
490 #define SX86_CPUFLAGBO_RESERVED_19 19
491 #define SX86_CPUFLAGBO_RESERVED_20 20
492 #define SX86_CPUFLAGBO_RESERVED_21 21
493 #define SX86_CPUFLAGBO_RESERVED_22 22
494 #define SX86_CPUFLAGBO_RESERVED_23 23
495 #define SX86_CPUFLAGBO_RESERVED_24 24
496 #define SX86_CPUFLAGBO_RESERVED_25 25
497 #define SX86_CPUFLAGBO_RESERVED_26 26
498 #define SX86_CPUFLAGBO_RESERVED_27 27
499 #define SX86_CPUFLAGBO_RESERVED_28 28
500 #define SX86_CPUFLAGBO_RESERVED_29 29
501 #define SX86_CPUFLAGBO_RESERVED_30 30
502 #define SX86_CPUFLAGBO_RESERVED_31 31
503
504 /* default callback functions within the library */
505 void softx86_step_def_on_read_memory(void* _ctx,sx86_udword address,sx86_ubyte *buf,int size);
506 void softx86_step_def_on_read_io(void* _ctx,sx86_udword address,sx86_ubyte *buf,int size);
507 void softx86_step_def_on_write_memory(void* _ctx,sx86_udword address,sx86_ubyte *buf,int size);
508 void softx86_step_def_on_write_io(void* _ctx,sx86_udword address,sx86_ubyte *buf,int size);
509 void softx86_step_def_on_hw_int(void* _ctx,sx86_ubyte i);
510 void softx86_step_def_on_sw_int(void* _ctx,sx86_ubyte i);
511 void softx86_step_def_on_hw_int_ack(void* _ctx,sx86_ubyte i);
512 void softx86_step_def_on_idle_cycle(void* _ctx);
513 void softx86_step_def_on_nmi_int(void* _ctx);
514 void softx86_step_def_on_nmi_int_ack(void* _ctx);
515 int softx86_step_def_on_fpu_opcode_exec(void* _ctx86,void* _ctx87,sx86_ubyte opcode);
516 int softx86_step_def_on_fpu_opcode_dec(void* _ctx86,void* _ctx87,sx86_ubyte opcode,char buf[128]);
517 void softx86_step_def_on_reset(void* _ctx);
518
519 /* external/internal/NMI interrupt generation and acknowledgement */
520 int softx86_ext_hw_signal(softx86_ctx* ctx,sx86_ubyte i);
521 int softx86_ext_hw_ack(softx86_ctx* ctx);
522 int softx86_int_sw_signal(softx86_ctx* ctx,sx86_ubyte i);
523 int softx86_ext_hw_nmi_signal(softx86_ctx* ctx);
524 int softx86_ext_hw_nmi_ack(softx86_ctx* ctx);
525
526 /* parity flag computation routines */
527 int softx86_parity8(sx86_ubyte ret);
528 int softx86_parity16(sx86_uword ret);
529 int softx86_parity32(sx86_udword ret);
530 int softx86_parity64(sx86_uldword ret);
531
532 /* bug emulation constants. each is meant to be unique. */
533 #define SX86_BUG_PREEMPTIBLE_AFTER_PREFIX 0x12340500
534 #define SX86_BUG_SP_DECREMENT_BEFORE_STORE 0x12340600 // specific to all prior to 286
535 #define SX86_BUG_5BIT_SHIFTMASK 0x12340700 // 286+ behavior of masking shift count to 5 bits
536
537 /* use this to change values in the bug emulation structure */
538 int softx86_setbug(softx86_ctx* ctx,sx86_udword bug_id,sx86_ubyte on_off);
539
540 /* mod/reg/rm unpacking */
541 #define sx86_modregrm_unpack(mrr,mod,reg,rm) mod = (mrr>>6);\
542 reg = (mrr>>3)&7;\
543 rm = mrr&7;
544
545 #ifdef __cplusplus
546 }
547 #endif //__cplusplus
548
549 #endif //SOFTX86_H
550