2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: 386/486 CPU Emulation Library
5 * PURPOSE: Opcode handlers.
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
9 /* INCLUDES *******************************************************************/
11 // #define WIN32_NO_STATUS
12 // #define _INC_WINDOWS
22 /* PUBLIC VARIABLES ***********************************************************/
24 SOFT386_OPCODE_HANDLER_PROC
25 Soft386OpcodeHandlers
[SOFT386_NUM_OPCODE_HANDLERS
] =
27 NULL
, // TODO: OPCODE 0x00 NOT SUPPORTED
28 NULL
, // TODO: OPCODE 0x01 NOT SUPPORTED
29 NULL
, // TODO: OPCODE 0x02 NOT SUPPORTED
30 NULL
, // TODO: OPCODE 0x03 NOT SUPPORTED
31 NULL
, // TODO: OPCODE 0x04 NOT SUPPORTED
32 NULL
, // TODO: OPCODE 0x05 NOT SUPPORTED
33 NULL
, // TODO: OPCODE 0x06 NOT SUPPORTED
34 NULL
, // TODO: OPCODE 0x07 NOT SUPPORTED
35 NULL
, // TODO: OPCODE 0x08 NOT SUPPORTED
36 NULL
, // TODO: OPCODE 0x09 NOT SUPPORTED
37 NULL
, // TODO: OPCODE 0x0A NOT SUPPORTED
38 NULL
, // TODO: OPCODE 0x0B NOT SUPPORTED
39 NULL
, // TODO: OPCODE 0x0C NOT SUPPORTED
40 NULL
, // TODO: OPCODE 0x0D NOT SUPPORTED
41 NULL
, // TODO: OPCODE 0x0E NOT SUPPORTED
42 NULL
, // TODO: OPCODE 0x0F NOT SUPPORTED
43 NULL
, // TODO: OPCODE 0x10 NOT SUPPORTED
44 NULL
, // TODO: OPCODE 0x11 NOT SUPPORTED
45 NULL
, // TODO: OPCODE 0x12 NOT SUPPORTED
46 NULL
, // TODO: OPCODE 0x13 NOT SUPPORTED
47 NULL
, // TODO: OPCODE 0x14 NOT SUPPORTED
48 NULL
, // TODO: OPCODE 0x15 NOT SUPPORTED
49 NULL
, // TODO: OPCODE 0x16 NOT SUPPORTED
50 NULL
, // TODO: OPCODE 0x17 NOT SUPPORTED
51 NULL
, // TODO: OPCODE 0x18 NOT SUPPORTED
52 NULL
, // TODO: OPCODE 0x19 NOT SUPPORTED
53 NULL
, // TODO: OPCODE 0x1A NOT SUPPORTED
54 NULL
, // TODO: OPCODE 0x1B NOT SUPPORTED
55 NULL
, // TODO: OPCODE 0x1C NOT SUPPORTED
56 NULL
, // TODO: OPCODE 0x1D NOT SUPPORTED
57 NULL
, // TODO: OPCODE 0x1E NOT SUPPORTED
58 NULL
, // TODO: OPCODE 0x1F NOT SUPPORTED
59 NULL
, // TODO: OPCODE 0x20 NOT SUPPORTED
60 NULL
, // TODO: OPCODE 0x21 NOT SUPPORTED
61 NULL
, // TODO: OPCODE 0x22 NOT SUPPORTED
62 NULL
, // TODO: OPCODE 0x23 NOT SUPPORTED
63 NULL
, // TODO: OPCODE 0x24 NOT SUPPORTED
64 NULL
, // TODO: OPCODE 0x25 NOT SUPPORTED
66 NULL
, // TODO: OPCODE 0x27 NOT SUPPORTED
67 NULL
, // TODO: OPCODE 0x28 NOT SUPPORTED
68 NULL
, // TODO: OPCODE 0x29 NOT SUPPORTED
69 NULL
, // TODO: OPCODE 0x2A NOT SUPPORTED
70 NULL
, // TODO: OPCODE 0x2B NOT SUPPORTED
71 NULL
, // TODO: OPCODE 0x2C NOT SUPPORTED
72 NULL
, // TODO: OPCODE 0x2D NOT SUPPORTED
74 NULL
, // TODO: OPCODE 0x2F NOT SUPPORTED
75 NULL
, // TODO: OPCODE 0x30 NOT SUPPORTED
76 NULL
, // TODO: OPCODE 0x31 NOT SUPPORTED
77 NULL
, // TODO: OPCODE 0x32 NOT SUPPORTED
78 NULL
, // TODO: OPCODE 0x33 NOT SUPPORTED
79 NULL
, // TODO: OPCODE 0x34 NOT SUPPORTED
80 NULL
, // TODO: OPCODE 0x35 NOT SUPPORTED
82 NULL
, // TODO: OPCODE 0x37 NOT SUPPORTED
83 NULL
, // TODO: OPCODE 0x38 NOT SUPPORTED
84 NULL
, // TODO: OPCODE 0x39 NOT SUPPORTED
85 NULL
, // TODO: OPCODE 0x3A NOT SUPPORTED
86 NULL
, // TODO: OPCODE 0x3B NOT SUPPORTED
87 NULL
, // TODO: OPCODE 0x3C NOT SUPPORTED
88 NULL
, // TODO: OPCODE 0x3D NOT SUPPORTED
90 NULL
, // TODO: OPCODE 0x3F NOT SUPPORTED
91 Soft386OpcodeIncrement
,
92 Soft386OpcodeIncrement
,
93 Soft386OpcodeIncrement
,
94 Soft386OpcodeIncrement
,
95 Soft386OpcodeIncrement
,
96 Soft386OpcodeIncrement
,
97 Soft386OpcodeIncrement
,
98 Soft386OpcodeIncrement
,
99 Soft386OpcodeDecrement
,
100 Soft386OpcodeDecrement
,
101 Soft386OpcodeDecrement
,
102 Soft386OpcodeDecrement
,
103 Soft386OpcodeDecrement
,
104 Soft386OpcodeDecrement
,
105 Soft386OpcodeDecrement
,
106 Soft386OpcodeDecrement
,
107 Soft386OpcodePushReg
,
108 Soft386OpcodePushReg
,
109 Soft386OpcodePushReg
,
110 Soft386OpcodePushReg
,
111 Soft386OpcodePushReg
,
112 Soft386OpcodePushReg
,
113 Soft386OpcodePushReg
,
114 Soft386OpcodePushReg
,
123 NULL
, // TODO: OPCODE 0x60 NOT SUPPORTED
124 NULL
, // TODO: OPCODE 0x61 NOT SUPPORTED
125 NULL
, // TODO: OPCODE 0x62 NOT SUPPORTED
126 NULL
, // TODO: OPCODE 0x63 NOT SUPPORTED
131 NULL
, // TODO: OPCODE 0x68 NOT SUPPORTED
132 NULL
, // TODO: OPCODE 0x69 NOT SUPPORTED
133 NULL
, // TODO: OPCODE 0x6A NOT SUPPORTED
134 NULL
, // TODO: OPCODE 0x6B NOT SUPPORTED
135 NULL
, // TODO: OPCODE 0x6C NOT SUPPORTED
136 NULL
, // TODO: OPCODE 0x6D NOT SUPPORTED
137 NULL
, // TODO: OPCODE 0x6E NOT SUPPORTED
138 NULL
, // TODO: OPCODE 0x6F NOT SUPPORTED
139 Soft386OpcodeShortConditionalJmp
,
140 Soft386OpcodeShortConditionalJmp
,
141 Soft386OpcodeShortConditionalJmp
,
142 Soft386OpcodeShortConditionalJmp
,
143 Soft386OpcodeShortConditionalJmp
,
144 Soft386OpcodeShortConditionalJmp
,
145 Soft386OpcodeShortConditionalJmp
,
146 Soft386OpcodeShortConditionalJmp
,
147 Soft386OpcodeShortConditionalJmp
,
148 Soft386OpcodeShortConditionalJmp
,
149 Soft386OpcodeShortConditionalJmp
,
150 Soft386OpcodeShortConditionalJmp
,
151 Soft386OpcodeShortConditionalJmp
,
152 Soft386OpcodeShortConditionalJmp
,
153 Soft386OpcodeShortConditionalJmp
,
154 Soft386OpcodeShortConditionalJmp
,
155 NULL
, // TODO: OPCODE 0x80 NOT SUPPORTED
156 NULL
, // TODO: OPCODE 0x81 NOT SUPPORTED
157 NULL
, // TODO: OPCODE 0x82 NOT SUPPORTED
158 NULL
, // TODO: OPCODE 0x83 NOT SUPPORTED
159 NULL
, // TODO: OPCODE 0x84 NOT SUPPORTED
160 NULL
, // TODO: OPCODE 0x85 NOT SUPPORTED
161 NULL
, // TODO: OPCODE 0x86 NOT SUPPORTED
162 NULL
, // TODO: OPCODE 0x87 NOT SUPPORTED
163 NULL
, // TODO: OPCODE 0x88 NOT SUPPORTED
164 NULL
, // TODO: OPCODE 0x89 NOT SUPPORTED
165 NULL
, // TODO: OPCODE 0x8A NOT SUPPORTED
166 NULL
, // TODO: OPCODE 0x8B NOT SUPPORTED
167 NULL
, // TODO: OPCODE 0x8C NOT SUPPORTED
168 NULL
, // TODO: OPCODE 0x8D NOT SUPPORTED
169 NULL
, // TODO: OPCODE 0x8E NOT SUPPORTED
170 NULL
, // TODO: OPCODE 0x8F NOT SUPPORTED
172 Soft386OpcodeExchangeEax
,
173 Soft386OpcodeExchangeEax
,
174 Soft386OpcodeExchangeEax
,
175 Soft386OpcodeExchangeEax
,
176 Soft386OpcodeExchangeEax
,
177 Soft386OpcodeExchangeEax
,
178 Soft386OpcodeExchangeEax
,
179 NULL
, // TODO: OPCODE 0x98 NOT SUPPORTED
180 NULL
, // TODO: OPCODE 0x99 NOT SUPPORTED
181 NULL
, // TODO: OPCODE 0x9A NOT SUPPORTED
182 NULL
, // TODO: OPCODE 0x9B NOT SUPPORTED
183 NULL
, // TODO: OPCODE 0x9C NOT SUPPORTED
184 NULL
, // TODO: OPCODE 0x9D NOT SUPPORTED
185 NULL
, // TODO: OPCODE 0x9E NOT SUPPORTED
186 NULL
, // TODO: OPCODE 0x9F NOT SUPPORTED
187 NULL
, // TODO: OPCODE 0xA0 NOT SUPPORTED
188 NULL
, // TODO: OPCODE 0xA1 NOT SUPPORTED
189 NULL
, // TODO: OPCODE 0xA2 NOT SUPPORTED
190 NULL
, // TODO: OPCODE 0xA3 NOT SUPPORTED
191 NULL
, // TODO: OPCODE 0xA4 NOT SUPPORTED
192 NULL
, // TODO: OPCODE 0xA5 NOT SUPPORTED
193 NULL
, // TODO: OPCODE 0xA6 NOT SUPPORTED
194 NULL
, // TODO: OPCODE 0xA7 NOT SUPPORTED
195 NULL
, // TODO: OPCODE 0xA8 NOT SUPPORTED
196 NULL
, // TODO: OPCODE 0xA9 NOT SUPPORTED
197 NULL
, // TODO: OPCODE 0xAA NOT SUPPORTED
198 NULL
, // TODO: OPCODE 0xAB NOT SUPPORTED
199 NULL
, // TODO: OPCODE 0xAC NOT SUPPORTED
200 NULL
, // TODO: OPCODE 0xAD NOT SUPPORTED
201 NULL
, // TODO: OPCODE 0xAE NOT SUPPORTED
202 NULL
, // TODO: OPCODE 0xAF NOT SUPPORTED
203 NULL
, // TODO: OPCODE 0xB0 NOT SUPPORTED
204 NULL
, // TODO: OPCODE 0xB1 NOT SUPPORTED
205 NULL
, // TODO: OPCODE 0xB2 NOT SUPPORTED
206 NULL
, // TODO: OPCODE 0xB3 NOT SUPPORTED
207 NULL
, // TODO: OPCODE 0xB4 NOT SUPPORTED
208 NULL
, // TODO: OPCODE 0xB5 NOT SUPPORTED
209 NULL
, // TODO: OPCODE 0xB6 NOT SUPPORTED
210 NULL
, // TODO: OPCODE 0xB7 NOT SUPPORTED
211 NULL
, // TODO: OPCODE 0xB8 NOT SUPPORTED
212 NULL
, // TODO: OPCODE 0xB9 NOT SUPPORTED
213 NULL
, // TODO: OPCODE 0xBA NOT SUPPORTED
214 NULL
, // TODO: OPCODE 0xBB NOT SUPPORTED
215 NULL
, // TODO: OPCODE 0xBC NOT SUPPORTED
216 NULL
, // TODO: OPCODE 0xBD NOT SUPPORTED
217 NULL
, // TODO: OPCODE 0xBE NOT SUPPORTED
218 NULL
, // TODO: OPCODE 0xBF NOT SUPPORTED
219 NULL
, // TODO: OPCODE 0xC0 NOT SUPPORTED
220 NULL
, // TODO: OPCODE 0xC1 NOT SUPPORTED
221 NULL
, // TODO: OPCODE 0xC2 NOT SUPPORTED
222 NULL
, // TODO: OPCODE 0xC3 NOT SUPPORTED
223 NULL
, // TODO: OPCODE 0xC4 NOT SUPPORTED
224 NULL
, // TODO: OPCODE 0xC5 NOT SUPPORTED
225 NULL
, // TODO: OPCODE 0xC6 NOT SUPPORTED
226 NULL
, // TODO: OPCODE 0xC7 NOT SUPPORTED
227 NULL
, // TODO: OPCODE 0xC8 NOT SUPPORTED
228 NULL
, // TODO: OPCODE 0xC9 NOT SUPPORTED
229 NULL
, // TODO: OPCODE 0xCA NOT SUPPORTED
230 NULL
, // TODO: OPCODE 0xCB NOT SUPPORTED
231 NULL
, // TODO: OPCODE 0xCC NOT SUPPORTED
232 NULL
, // TODO: OPCODE 0xCD NOT SUPPORTED
233 NULL
, // TODO: OPCODE 0xCE NOT SUPPORTED
234 NULL
, // TODO: OPCODE 0xCF NOT SUPPORTED
235 NULL
, // TODO: OPCODE 0xD0 NOT SUPPORTED
236 NULL
, // TODO: OPCODE 0xD1 NOT SUPPORTED
237 NULL
, // TODO: OPCODE 0xD2 NOT SUPPORTED
238 NULL
, // TODO: OPCODE 0xD3 NOT SUPPORTED
239 NULL
, // TODO: OPCODE 0xD4 NOT SUPPORTED
240 NULL
, // TODO: OPCODE 0xD5 NOT SUPPORTED
241 NULL
, // TODO: OPCODE 0xD6 NOT SUPPORTED
242 NULL
, // TODO: OPCODE 0xD7 NOT SUPPORTED
243 NULL
, // TODO: OPCODE 0xD8 NOT SUPPORTED
244 NULL
, // TODO: OPCODE 0xD9 NOT SUPPORTED
245 NULL
, // TODO: OPCODE 0xDA NOT SUPPORTED
246 NULL
, // TODO: OPCODE 0xDB NOT SUPPORTED
247 NULL
, // TODO: OPCODE 0xDC NOT SUPPORTED
248 NULL
, // TODO: OPCODE 0xDD NOT SUPPORTED
249 NULL
, // TODO: OPCODE 0xDE NOT SUPPORTED
250 NULL
, // TODO: OPCODE 0xDF NOT SUPPORTED
251 NULL
, // TODO: OPCODE 0xE0 NOT SUPPORTED
252 NULL
, // TODO: OPCODE 0xE1 NOT SUPPORTED
253 NULL
, // TODO: OPCODE 0xE2 NOT SUPPORTED
254 NULL
, // TODO: OPCODE 0xE3 NOT SUPPORTED
255 NULL
, // TODO: OPCODE 0xE4 NOT SUPPORTED
256 NULL
, // TODO: OPCODE 0xE5 NOT SUPPORTED
257 NULL
, // TODO: OPCODE 0xE6 NOT SUPPORTED
258 NULL
, // TODO: OPCODE 0xE7 NOT SUPPORTED
259 NULL
, // TODO: OPCODE 0xE8 NOT SUPPORTED
260 NULL
, // TODO: OPCODE 0xE9 NOT SUPPORTED
261 NULL
, // TODO: OPCODE 0xEA NOT SUPPORTED
262 NULL
, // TODO: OPCODE 0xEB NOT SUPPORTED
263 NULL
, // TODO: OPCODE 0xEC NOT SUPPORTED
264 NULL
, // TODO: OPCODE 0xED NOT SUPPORTED
265 NULL
, // TODO: OPCODE 0xEE NOT SUPPORTED
266 NULL
, // TODO: OPCODE 0xEF NOT SUPPORTED
271 NULL
, // TODO: OPCODE 0xF4 NOT SUPPORTED
272 NULL
, // TODO: OPCODE 0xF5 NOT SUPPORTED
273 NULL
, // TODO: OPCODE 0xF6 NOT SUPPORTED
274 NULL
, // TODO: OPCODE 0xF7 NOT SUPPORTED
275 Soft386OpcodeClearCarry
,
276 Soft386OpcodeSetCarry
,
277 Soft386OpcodeClearInt
,
279 Soft386OpcodeClearDir
,
281 NULL
, // TODO: OPCODE 0xFE NOT SUPPORTED
282 NULL
, // TODO: OPCODE 0xFF NOT SUPPORTED
287 Soft386OpcodePrefix(PSOFT386_STATE State
, UCHAR Opcode
)
289 BOOLEAN Valid
= FALSE
;
296 if (!(State
->PrefixFlags
& SOFT386_PREFIX_SEG
))
298 State
->PrefixFlags
|= SOFT386_PREFIX_SEG
;
299 State
->SegmentOverride
= SOFT386_REG_ES
;
309 if (!(State
->PrefixFlags
& SOFT386_PREFIX_SEG
))
311 State
->PrefixFlags
|= SOFT386_PREFIX_SEG
;
312 State
->SegmentOverride
= SOFT386_REG_CS
;
322 if (!(State
->PrefixFlags
& SOFT386_PREFIX_SEG
))
324 State
->PrefixFlags
|= SOFT386_PREFIX_SEG
;
325 State
->SegmentOverride
= SOFT386_REG_SS
;
335 if (!(State
->PrefixFlags
& SOFT386_PREFIX_SEG
))
337 State
->PrefixFlags
|= SOFT386_PREFIX_SEG
;
338 State
->SegmentOverride
= SOFT386_REG_DS
;
348 if (!(State
->PrefixFlags
& SOFT386_PREFIX_SEG
))
350 State
->PrefixFlags
|= SOFT386_PREFIX_SEG
;
351 State
->SegmentOverride
= SOFT386_REG_FS
;
361 if (!(State
->PrefixFlags
& SOFT386_PREFIX_SEG
))
363 State
->PrefixFlags
|= SOFT386_PREFIX_SEG
;
364 State
->SegmentOverride
= SOFT386_REG_GS
;
374 if (!(State
->PrefixFlags
& SOFT386_PREFIX_OPSIZE
))
376 State
->PrefixFlags
|= SOFT386_PREFIX_OPSIZE
;
386 if (!(State
->PrefixFlags
& SOFT386_PREFIX_ADSIZE
))
388 State
->PrefixFlags
|= SOFT386_PREFIX_ADSIZE
;
397 if (!(State
->PrefixFlags
& SOFT386_PREFIX_LOCK
))
399 State
->PrefixFlags
|= SOFT386_PREFIX_LOCK
;
409 /* Mutually exclusive with REP */
410 if (!(State
->PrefixFlags
411 & (SOFT386_PREFIX_REPNZ
| SOFT386_PREFIX_REP
)))
413 State
->PrefixFlags
|= SOFT386_PREFIX_REPNZ
;
423 /* Mutually exclusive with REPNZ */
424 if (!(State
->PrefixFlags
425 & (SOFT386_PREFIX_REPNZ
| SOFT386_PREFIX_REP
)))
427 State
->PrefixFlags
|= SOFT386_PREFIX_REP
;
437 /* Clear all prefixes */
438 State
->PrefixFlags
= 0;
440 /* Throw an exception */
441 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
450 Soft386OpcodeIncrement(PSOFT386_STATE State
, UCHAR Opcode
)
453 BOOLEAN Size
= State
->SegmentRegs
[SOFT386_REG_CS
].Size
;
455 if (State
->PrefixFlags
== SOFT386_PREFIX_OPSIZE
)
457 /* The OPSIZE prefix toggles the size */
460 else if (State
->PrefixFlags
!= 0)
463 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
467 /* Make sure this is the right instruction */
468 ASSERT((Opcode
& 0xF8) == 0x40);
472 Value
= ++State
->GeneralRegs
[Opcode
& 0x07].Long
;
474 State
->Flags
.Of
= (Value
== SIGN_FLAG_LONG
) ? TRUE
: FALSE
;
475 State
->Flags
.Sf
= (Value
& SIGN_FLAG_LONG
) ? TRUE
: FALSE
;
479 Value
= ++State
->GeneralRegs
[Opcode
& 0x07].LowWord
;
481 State
->Flags
.Of
= (Value
== SIGN_FLAG_WORD
) ? TRUE
: FALSE
;
482 State
->Flags
.Sf
= (Value
& SIGN_FLAG_WORD
) ? TRUE
: FALSE
;
485 State
->Flags
.Zf
= (Value
== 0) ? TRUE
: FALSE
;
486 State
->Flags
.Af
= ((Value
& 0x0F) == 0) ? TRUE
: FALSE
;
487 State
->Flags
.Pf
= Soft386CalculateParity(LOBYTE(Value
));
495 Soft386OpcodeDecrement(PSOFT386_STATE State
, UCHAR Opcode
)
498 BOOLEAN Size
= State
->SegmentRegs
[SOFT386_REG_CS
].Size
;
500 if (State
->PrefixFlags
== SOFT386_PREFIX_OPSIZE
)
502 /* The OPSIZE prefix toggles the size */
505 else if (State
->PrefixFlags
!= 0)
508 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
512 /* Make sure this is the right instruction */
513 ASSERT((Opcode
& 0xF8) == 0x48);
517 Value
= --State
->GeneralRegs
[Opcode
& 0x07].Long
;
519 State
->Flags
.Of
= (Value
== (SIGN_FLAG_LONG
- 1)) ? TRUE
: FALSE
;
520 State
->Flags
.Sf
= (Value
& SIGN_FLAG_LONG
) ? TRUE
: FALSE
;
524 Value
= --State
->GeneralRegs
[Opcode
& 0x07].LowWord
;
526 State
->Flags
.Of
= (Value
== (SIGN_FLAG_WORD
- 1)) ? TRUE
: FALSE
;
527 State
->Flags
.Sf
= (Value
& SIGN_FLAG_WORD
) ? TRUE
: FALSE
;
530 State
->Flags
.Zf
= (Value
== 0) ? TRUE
: FALSE
;
531 State
->Flags
.Af
= ((Value
& 0x0F) == 0x0F) ? TRUE
: FALSE
;
532 State
->Flags
.Pf
= Soft386CalculateParity(LOBYTE(Value
));
540 Soft386OpcodePushReg(PSOFT386_STATE State
, UCHAR Opcode
)
542 if ((State
->PrefixFlags
!= SOFT386_PREFIX_OPSIZE
)
543 && (State
->PrefixFlags
!= 0))
546 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
550 /* Make sure this is the right instruction */
551 ASSERT((Opcode
& 0xF8) == 0x50);
553 /* Call the internal function */
554 return Soft386StackPush(State
, State
->GeneralRegs
[Opcode
& 0x07].Long
);
559 Soft386OpcodePopReg(PSOFT386_STATE State
, UCHAR Opcode
)
562 BOOLEAN Size
= State
->SegmentRegs
[SOFT386_REG_SS
].Size
;
564 if (State
->PrefixFlags
== SOFT386_PREFIX_OPSIZE
)
566 /* The OPSIZE prefix toggles the size */
569 else if (State
->PrefixFlags
!= 0)
572 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
576 /* Make sure this is the right instruction */
577 ASSERT((Opcode
& 0xF8) == 0x58);
579 /* Call the internal function */
580 if (!Soft386StackPop(State
, &Value
)) return FALSE
;
582 /* Store the value */
583 if (Size
) State
->GeneralRegs
[Opcode
& 0x07].Long
= Value
;
584 else State
->GeneralRegs
[Opcode
& 0x07].LowWord
= Value
;
592 Soft386OpcodeNop(PSOFT386_STATE State
, UCHAR Opcode
)
594 if (State
->PrefixFlags
& ~(SOFT386_PREFIX_OPSIZE
| SOFT386_PREFIX_REP
))
596 /* Allowed prefixes are REP and OPSIZE */
597 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
601 if (State
->PrefixFlags
& SOFT386_PREFIX_REP
)
604 State
->IdleCallback(State
);
612 Soft386OpcodeExchangeEax(PSOFT386_STATE State
, UCHAR Opcode
)
614 INT Reg
= Opcode
& 0x07;
615 BOOLEAN Size
= State
->SegmentRegs
[SOFT386_REG_CS
].Size
;
617 if (State
->PrefixFlags
== SOFT386_PREFIX_OPSIZE
)
619 /* The OPSIZE prefix toggles the size */
622 else if (State
->PrefixFlags
!= 0)
625 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
629 /* Make sure this is the right instruction */
630 ASSERT((Opcode
& 0xF8) == 0x90);
632 /* Exchange the values */
637 Value
= State
->GeneralRegs
[Reg
].Long
;
638 State
->GeneralRegs
[Reg
].Long
= State
->GeneralRegs
[SOFT386_REG_EAX
].Long
;
639 State
->GeneralRegs
[SOFT386_REG_EAX
].Long
= Value
;
645 Value
= State
->GeneralRegs
[Reg
].LowWord
;
646 State
->GeneralRegs
[Reg
].LowWord
= State
->GeneralRegs
[SOFT386_REG_EAX
].LowWord
;
647 State
->GeneralRegs
[SOFT386_REG_EAX
].LowWord
= Value
;
655 Soft386OpcodeShortConditionalJmp(PSOFT386_STATE State
, UCHAR Opcode
)
657 BOOLEAN Jump
= FALSE
;
660 /* Make sure this is the right instruction */
661 ASSERT((Opcode
& 0xF0) == 0x70);
663 /* Fetch the offset */
664 if (!Soft386FetchByte(State
, (PUCHAR
)&Offset
))
666 /* An exception occurred */
670 switch ((Opcode
& 0x0F) >> 1)
675 Jump
= State
->Flags
.Of
;
682 Jump
= State
->Flags
.Cf
;
689 Jump
= State
->Flags
.Zf
;
696 Jump
= State
->Flags
.Cf
|| State
->Flags
.Zf
;
703 Jump
= State
->Flags
.Sf
;
710 Jump
= State
->Flags
.Pf
;
717 Jump
= State
->Flags
.Sf
!= State
->Flags
.Of
;
724 Jump
= (State
->Flags
.Sf
!= State
->Flags
.Of
) || State
->Flags
.Zf
;
729 if ((Opcode
& 0xF0) & 1)
731 /* Invert the result */
737 /* Move the instruction pointer */
738 State
->InstPtr
.Long
+= Offset
;
747 Soft386OpcodeClearCarry(PSOFT386_STATE State
, UCHAR Opcode
)
749 /* Make sure this is the right instruction */
750 ASSERT(Opcode
== 0xF8);
752 /* No prefixes allowed */
753 if (State
->PrefixFlags
)
755 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
759 /* Clear CF and return success */
760 State
->Flags
.Cf
= FALSE
;
766 Soft386OpcodeSetCarry(PSOFT386_STATE State
, UCHAR Opcode
)
768 /* Make sure this is the right instruction */
769 ASSERT(Opcode
== 0xF9);
771 /* No prefixes allowed */
772 if (State
->PrefixFlags
)
774 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
778 /* Set CF and return success*/
779 State
->Flags
.Cf
= TRUE
;
785 Soft386OpcodeClearInt(PSOFT386_STATE State
, UCHAR Opcode
)
787 /* Make sure this is the right instruction */
788 ASSERT(Opcode
== 0xFA);
790 /* No prefixes allowed */
791 if (State
->PrefixFlags
)
793 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
797 /* Check for protected mode */
798 if (State
->ControlRegisters
[SOFT386_REG_CR0
] & SOFT386_CR0_PE
)
801 if (State
->Flags
.Iopl
>= State
->SegmentRegs
[SOFT386_REG_CS
].Dpl
)
803 /* Clear the interrupt flag */
804 State
->Flags
.If
= FALSE
;
808 /* General Protection Fault */
809 Soft386Exception(State
, SOFT386_EXCEPTION_GP
);
815 /* Just clear the interrupt flag */
816 State
->Flags
.If
= FALSE
;
825 Soft386OpcodeSetInt(PSOFT386_STATE State
, UCHAR Opcode
)
827 /* Make sure this is the right instruction */
828 ASSERT(Opcode
== 0xFB);
830 /* No prefixes allowed */
831 if (State
->PrefixFlags
)
833 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
837 /* Check for protected mode */
838 if (State
->ControlRegisters
[SOFT386_REG_CR0
] & SOFT386_CR0_PE
)
841 if (State
->Flags
.Iopl
>= State
->SegmentRegs
[SOFT386_REG_CS
].Dpl
)
843 /* Set the interrupt flag */
844 State
->Flags
.If
= TRUE
;
848 /* General Protection Fault */
849 Soft386Exception(State
, SOFT386_EXCEPTION_GP
);
855 /* Just set the interrupt flag */
856 State
->Flags
.If
= TRUE
;
865 Soft386OpcodeClearDir(PSOFT386_STATE State
, UCHAR Opcode
)
867 /* Make sure this is the right instruction */
868 ASSERT(Opcode
== 0xFC);
870 /* No prefixes allowed */
871 if (State
->PrefixFlags
)
873 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
877 /* Clear DF and return success */
878 State
->Flags
.Df
= FALSE
;
884 Soft386OpcodeSetDir(PSOFT386_STATE State
, UCHAR Opcode
)
886 /* Make sure this is the right instruction */
887 ASSERT(Opcode
== 0xFD);
889 /* No prefixes allowed */
890 if (State
->PrefixFlags
)
892 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
896 /* Set DF and return success*/
897 State
->Flags
.Df
= TRUE
;
903 Soft386OpcodeHalt(PSOFT386_STATE State
, UCHAR Opcode
)
905 /* Make sure this is the right instruction */
906 ASSERT(Opcode
== 0xF4);
908 /* No prefixes allowed */
909 if (State
->PrefixFlags
)
911 Soft386Exception(State
, SOFT386_EXCEPTION_UD
);
915 /* Privileged instructions can only be executed under CPL = 0 */
916 if (State
->SegmentRegs
[SOFT386_REG_CS
].Dpl
!= 0)
918 Soft386Exception(State
, SOFT386_EXCEPTION_GP
);
923 while (!State
->HardwareInt
) State
->IdleCallback(State
);