2 * Fast486 386/486 CPU Emulation Library
5 * Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
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.
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.
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.
22 /* INCLUDES *******************************************************************/
24 // #define WIN32_NO_STATUS
25 // #define _INC_WINDOWS
36 /* PUBLIC VARIABLES ***********************************************************/
38 FAST486_OPCODE_HANDLER_PROC
39 Fast486ExtendedHandlers
[FAST486_NUM_OPCODE_HANDLERS
] =
41 NULL
, // TODO: OPCODE 0x00 NOT IMPLEMENTED
42 NULL
, // TODO: OPCODE 0x01 NOT IMPLEMENTED
43 NULL
, // TODO: OPCODE 0x02 NOT IMPLEMENTED
44 NULL
, // TODO: OPCODE 0x03 NOT IMPLEMENTED
45 NULL
, // TODO: OPCODE 0x04 NOT IMPLEMENTED
46 NULL
, // TODO: OPCODE 0x05 NOT IMPLEMENTED
47 NULL
, // TODO: OPCODE 0x06 NOT IMPLEMENTED
48 NULL
, // TODO: OPCODE 0x07 NOT IMPLEMENTED
49 NULL
, // TODO: OPCODE 0x08 NOT IMPLEMENTED
50 NULL
, // TODO: OPCODE 0x09 NOT IMPLEMENTED
52 NULL
, // Reserved (UD1)
57 NULL
, // TODO: OPCODE 0x10 NOT IMPLEMENTED
58 NULL
, // TODO: OPCODE 0x11 NOT IMPLEMENTED
59 NULL
, // TODO: OPCODE 0x12 NOT IMPLEMENTED
60 NULL
, // TODO: OPCODE 0x13 NOT IMPLEMENTED
73 NULL
, // TODO: OPCODE 0x20 NOT IMPLEMENTED
74 NULL
, // TODO: OPCODE 0x21 NOT IMPLEMENTED
75 NULL
, // TODO: OPCODE 0x22 NOT IMPLEMENTED
76 NULL
, // TODO: OPCODE 0x23 NOT IMPLEMENTED
77 NULL
, // TODO: OPCODE 0x24 NOT IMPLEMENTED
79 NULL
, // TODO: OPCODE 0x26 NOT IMPLEMENTED
169 Fast486ExtOpcodeConditionalJmp
,
170 Fast486ExtOpcodeConditionalJmp
,
171 Fast486ExtOpcodeConditionalJmp
,
172 Fast486ExtOpcodeConditionalJmp
,
173 Fast486ExtOpcodeConditionalJmp
,
174 Fast486ExtOpcodeConditionalJmp
,
175 Fast486ExtOpcodeConditionalJmp
,
176 Fast486ExtOpcodeConditionalJmp
,
177 Fast486ExtOpcodeConditionalJmp
,
178 Fast486ExtOpcodeConditionalJmp
,
179 Fast486ExtOpcodeConditionalJmp
,
180 Fast486ExtOpcodeConditionalJmp
,
181 Fast486ExtOpcodeConditionalJmp
,
182 Fast486ExtOpcodeConditionalJmp
,
183 Fast486ExtOpcodeConditionalJmp
,
184 Fast486ExtOpcodeConditionalJmp
,
185 Fast486ExtOpcodeConditionalSet
,
186 Fast486ExtOpcodeConditionalSet
,
187 Fast486ExtOpcodeConditionalSet
,
188 Fast486ExtOpcodeConditionalSet
,
189 Fast486ExtOpcodeConditionalSet
,
190 Fast486ExtOpcodeConditionalSet
,
191 Fast486ExtOpcodeConditionalSet
,
192 Fast486ExtOpcodeConditionalSet
,
193 Fast486ExtOpcodeConditionalSet
,
194 Fast486ExtOpcodeConditionalSet
,
195 Fast486ExtOpcodeConditionalSet
,
196 Fast486ExtOpcodeConditionalSet
,
197 Fast486ExtOpcodeConditionalSet
,
198 Fast486ExtOpcodeConditionalSet
,
199 Fast486ExtOpcodeConditionalSet
,
200 Fast486ExtOpcodeConditionalSet
,
201 Fast486ExtOpcodePushFs
,
202 Fast486ExtOpcodePopFs
,
204 Fast486ExtOpcodeBitTest
,
205 NULL
, // TODO: OPCODE 0xA4 NOT IMPLEMENTED
206 NULL
, // TODO: OPCODE 0xA5 NOT IMPLEMENTED
209 Fast486ExtOpcodePushGs
,
210 Fast486ExtOpcodePopGs
,
211 NULL
, // TODO: OPCODE 0xAA NOT IMPLEMENTED
213 NULL
, // TODO: OPCODE 0xAC NOT IMPLEMENTED
214 NULL
, // TODO: OPCODE 0xAD NOT IMPLEMENTED
215 NULL
, // TODO: OPCODE 0xAE NOT IMPLEMENTED
216 NULL
, // TODO: OPCODE 0xAF NOT IMPLEMENTED
217 Fast486ExtOpcodeCmpXchgByte
,
218 Fast486ExtOpcodeCmpXchg
,
219 NULL
, // TODO: OPCODE 0xB2 NOT IMPLEMENTED
221 NULL
, // TODO: OPCODE 0xB4 NOT IMPLEMENTED
222 NULL
, // TODO: OPCODE 0xB5 NOT IMPLEMENTED
223 NULL
, // TODO: OPCODE 0xB6 NOT IMPLEMENTED
224 NULL
, // TODO: OPCODE 0xB7 NOT IMPLEMENTED
225 NULL
, // TODO: OPCODE 0xB8 NOT IMPLEMENTED
226 NULL
, // TODO: OPCODE 0xB9 NOT IMPLEMENTED
227 NULL
, // TODO: OPCODE 0xBA NOT IMPLEMENTED
229 NULL
, // TODO: OPCODE 0xBC NOT IMPLEMENTED
230 NULL
, // TODO: OPCODE 0xBD NOT IMPLEMENTED
231 NULL
, // TODO: OPCODE 0xBE NOT IMPLEMENTED
232 NULL
, // TODO: OPCODE 0xBF NOT IMPLEMENTED
233 NULL
, // TODO: OPCODE 0xC0 NOT IMPLEMENTED
234 NULL
, // TODO: OPCODE 0xC1 NOT IMPLEMENTED
241 Fast486ExtOpcodeBswap
,
242 Fast486ExtOpcodeBswap
,
243 Fast486ExtOpcodeBswap
,
244 Fast486ExtOpcodeBswap
,
245 Fast486ExtOpcodeBswap
,
246 Fast486ExtOpcodeBswap
,
247 Fast486ExtOpcodeBswap
,
248 Fast486ExtOpcodeBswap
,
299 /* PUBLIC FUNCTIONS ***********************************************************/
301 FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushFs
)
303 /* Call the internal API */
304 return Fast486StackPush(State
, State
->SegmentRegs
[FAST486_REG_FS
].Selector
);
307 FAST486_OPCODE_HANDLER(Fast486ExtOpcodePopFs
)
311 if (!Fast486StackPop(State
, &NewSelector
))
313 /* Exception occurred */
317 /* Call the internal API */
318 return Fast486LoadSegment(State
, FAST486_REG_FS
, LOWORD(NewSelector
));
321 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBitTest
)
323 BOOLEAN OperandSize
, AddressSize
;
324 FAST486_MOD_REG_RM ModRegRm
;
328 OperandSize
= AddressSize
= State
->SegmentRegs
[FAST486_REG_CS
].Size
;
329 TOGGLE_OPSIZE(OperandSize
);
330 TOGGLE_ADSIZE(AddressSize
);
332 /* Get the number of bits */
333 if (OperandSize
) DataSize
= 32;
336 /* Get the operands */
337 if (!Fast486ParseModRegRm(State
, AddressSize
, &ModRegRm
))
339 /* Exception occurred */
343 /* Get the bit number */
344 BitNumber
= OperandSize
? State
->GeneralRegs
[ModRegRm
.Register
].Long
345 : (ULONG
)State
->GeneralRegs
[ModRegRm
.Register
].LowWord
;
350 * For memory operands, add the bit offset divided by
351 * the data size to the address
353 ModRegRm
.MemoryAddress
+= BitNumber
/ DataSize
;
356 /* Normalize the bit number */
357 BitNumber
&= (1 << DataSize
) - 1;
364 if (!Fast486ReadModrmDwordOperands(State
, &ModRegRm
, &Dummy
, &Value
))
366 /* Exception occurred */
370 /* Set CF to the bit value */
371 State
->Flags
.Cf
= (Value
>> BitNumber
) & 1;
378 if (!Fast486ReadModrmWordOperands(State
, &ModRegRm
, &Dummy
, &Value
))
380 /* Exception occurred */
384 /* Set CF to the bit value */
385 State
->Flags
.Cf
= (Value
>> BitNumber
) & 1;
392 FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushGs
)
394 /* Call the internal API */
395 return Fast486StackPush(State
, State
->SegmentRegs
[FAST486_REG_GS
].Selector
);
398 FAST486_OPCODE_HANDLER(Fast486ExtOpcodePopGs
)
402 if (!Fast486StackPop(State
, &NewSelector
))
404 /* Exception occurred */
408 /* Call the internal API */
409 return Fast486LoadSegment(State
, FAST486_REG_GS
, LOWORD(NewSelector
));
412 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBts
)
414 BOOLEAN OperandSize
, AddressSize
;
415 FAST486_MOD_REG_RM ModRegRm
;
419 OperandSize
= AddressSize
= State
->SegmentRegs
[FAST486_REG_CS
].Size
;
420 TOGGLE_OPSIZE(OperandSize
);
421 TOGGLE_ADSIZE(AddressSize
);
423 /* Get the number of bits */
424 if (OperandSize
) DataSize
= 32;
427 /* Get the operands */
428 if (!Fast486ParseModRegRm(State
, AddressSize
, &ModRegRm
))
430 /* Exception occurred */
434 /* Get the bit number */
435 BitNumber
= OperandSize
? State
->GeneralRegs
[ModRegRm
.Register
].Long
436 : (ULONG
)State
->GeneralRegs
[ModRegRm
.Register
].LowWord
;
441 * For memory operands, add the bit offset divided by
442 * the data size to the address
444 ModRegRm
.MemoryAddress
+= BitNumber
/ DataSize
;
447 /* Normalize the bit number */
448 BitNumber
&= (1 << DataSize
) - 1;
455 if (!Fast486ReadModrmDwordOperands(State
, &ModRegRm
, &Dummy
, &Value
))
457 /* Exception occurred */
461 /* Set CF to the bit value */
462 State
->Flags
.Cf
= (Value
>> BitNumber
) & 1;
465 Value
|= 1 << BitNumber
;
467 /* Write back the result */
468 if (!Fast486WriteModrmDwordOperands(State
, &ModRegRm
, FALSE
, Value
))
470 /* Exception occurred */
479 if (!Fast486ReadModrmWordOperands(State
, &ModRegRm
, &Dummy
, &Value
))
481 /* Exception occurred */
485 /* Set CF to the bit value */
486 State
->Flags
.Cf
= (Value
>> BitNumber
) & 1;
489 Value
|= 1 << BitNumber
;
491 /* Write back the result */
492 if (!Fast486WriteModrmWordOperands(State
, &ModRegRm
, FALSE
, Value
))
494 /* Exception occurred */
503 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchgByte
)
505 FAST486_MOD_REG_RM ModRegRm
;
506 UCHAR Accumulator
= State
->GeneralRegs
[FAST486_REG_EAX
].LowByte
;
507 UCHAR Source
, Destination
, Result
;
508 BOOLEAN AddressSize
= State
->SegmentRegs
[FAST486_REG_CS
].Size
;
510 TOGGLE_ADSIZE(AddressSize
);
512 /* Get the operands */
513 if (!Fast486ParseModRegRm(State
, AddressSize
, &ModRegRm
))
515 /* Exception occurred */
519 /* Read the operands */
520 if (!Fast486ReadModrmByteOperands(State
, &ModRegRm
, &Source
, &Destination
))
522 /* Exception occurred */
526 /* Compare AL with the destination */
527 Result
= Accumulator
- Destination
;
529 /* Update the flags */
530 State
->Flags
.Cf
= Accumulator
< Destination
;
531 State
->Flags
.Of
= ((Accumulator
& SIGN_FLAG_BYTE
) != (Destination
& SIGN_FLAG_BYTE
))
532 && ((Accumulator
& SIGN_FLAG_BYTE
) != (Result
& SIGN_FLAG_BYTE
));
533 State
->Flags
.Af
= (Accumulator
& 0x0F) < (Destination
& 0x0F);
534 State
->Flags
.Zf
= (Result
== 0) ? TRUE
: FALSE
;
535 State
->Flags
.Sf
= (Result
& SIGN_FLAG_BYTE
) ? TRUE
: FALSE
;
536 State
->Flags
.Pf
= Fast486CalculateParity(Result
);
540 /* Load the source operand into the destination */
541 return Fast486WriteModrmByteOperands(State
, &ModRegRm
, FALSE
, Source
);
545 /* Load the destination into AL */
546 State
->GeneralRegs
[FAST486_REG_EAX
].LowByte
= Destination
;
553 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchg
)
555 FAST486_MOD_REG_RM ModRegRm
;
556 BOOLEAN OperandSize
, AddressSize
;
558 OperandSize
= AddressSize
= State
->SegmentRegs
[FAST486_REG_CS
].Size
;
560 TOGGLE_OPSIZE(OperandSize
);
561 TOGGLE_ADSIZE(AddressSize
);
563 /* Get the operands */
564 if (!Fast486ParseModRegRm(State
, AddressSize
, &ModRegRm
))
566 /* Exception occurred */
572 ULONG Source
, Destination
, Result
;
573 ULONG Accumulator
= State
->GeneralRegs
[FAST486_REG_EAX
].Long
;
575 /* Read the operands */
576 if (!Fast486ReadModrmDwordOperands(State
, &ModRegRm
, &Source
, &Destination
))
578 /* Exception occurred */
582 /* Compare EAX with the destination */
583 Result
= Accumulator
- Destination
;
585 /* Update the flags */
586 State
->Flags
.Cf
= Accumulator
< Destination
;
587 State
->Flags
.Of
= ((Accumulator
& SIGN_FLAG_LONG
) != (Destination
& SIGN_FLAG_LONG
))
588 && ((Accumulator
& SIGN_FLAG_LONG
) != (Result
& SIGN_FLAG_LONG
));
589 State
->Flags
.Af
= (Accumulator
& 0x0F) < (Destination
& 0x0F);
590 State
->Flags
.Zf
= (Result
== 0) ? TRUE
: FALSE
;
591 State
->Flags
.Sf
= (Result
& SIGN_FLAG_LONG
) ? TRUE
: FALSE
;
592 State
->Flags
.Pf
= Fast486CalculateParity(Result
);
596 /* Load the source operand into the destination */
597 return Fast486WriteModrmDwordOperands(State
, &ModRegRm
, FALSE
, Source
);
601 /* Load the destination into EAX */
602 State
->GeneralRegs
[FAST486_REG_EAX
].Long
= Destination
;
607 USHORT Source
, Destination
, Result
;
608 USHORT Accumulator
= State
->GeneralRegs
[FAST486_REG_EAX
].LowWord
;
610 /* Read the operands */
611 if (!Fast486ReadModrmWordOperands(State
, &ModRegRm
, &Source
, &Destination
))
613 /* Exception occurred */
617 /* Compare AX with the destination */
618 Result
= Accumulator
- Destination
;
620 /* Update the flags */
621 State
->Flags
.Cf
= Accumulator
< Destination
;
622 State
->Flags
.Of
= ((Accumulator
& SIGN_FLAG_WORD
) != (Destination
& SIGN_FLAG_WORD
))
623 && ((Accumulator
& SIGN_FLAG_WORD
) != (Result
& SIGN_FLAG_WORD
));
624 State
->Flags
.Af
= (Accumulator
& 0x0F) < (Destination
& 0x0F);
625 State
->Flags
.Zf
= (Result
== 0) ? TRUE
: FALSE
;
626 State
->Flags
.Sf
= (Result
& SIGN_FLAG_WORD
) ? TRUE
: FALSE
;
627 State
->Flags
.Pf
= Fast486CalculateParity(Result
);
631 /* Load the source operand into the destination */
632 return Fast486WriteModrmWordOperands(State
, &ModRegRm
, FALSE
, Source
);
636 /* Load the destination into AX */
637 State
->GeneralRegs
[FAST486_REG_EAX
].LowWord
= Destination
;
645 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtr
)
647 BOOLEAN OperandSize
, AddressSize
;
648 FAST486_MOD_REG_RM ModRegRm
;
652 OperandSize
= AddressSize
= State
->SegmentRegs
[FAST486_REG_CS
].Size
;
653 TOGGLE_OPSIZE(OperandSize
);
654 TOGGLE_ADSIZE(AddressSize
);
656 /* Get the number of bits */
657 if (OperandSize
) DataSize
= 32;
660 /* Get the operands */
661 if (!Fast486ParseModRegRm(State
, AddressSize
, &ModRegRm
))
663 /* Exception occurred */
667 /* Get the bit number */
668 BitNumber
= OperandSize
? State
->GeneralRegs
[ModRegRm
.Register
].Long
669 : (ULONG
)State
->GeneralRegs
[ModRegRm
.Register
].LowWord
;
674 * For memory operands, add the bit offset divided by
675 * the data size to the address
677 ModRegRm
.MemoryAddress
+= BitNumber
/ DataSize
;
680 /* Normalize the bit number */
681 BitNumber
&= (1 << DataSize
) - 1;
688 if (!Fast486ReadModrmDwordOperands(State
, &ModRegRm
, &Dummy
, &Value
))
690 /* Exception occurred */
694 /* Set CF to the bit value */
695 State
->Flags
.Cf
= (Value
>> BitNumber
) & 1;
698 Value
&= ~(1 << BitNumber
);
700 /* Write back the result */
701 if (!Fast486WriteModrmDwordOperands(State
, &ModRegRm
, FALSE
, Value
))
703 /* Exception occurred */
712 if (!Fast486ReadModrmWordOperands(State
, &ModRegRm
, &Dummy
, &Value
))
714 /* Exception occurred */
718 /* Set CF to the bit value */
719 State
->Flags
.Cf
= (Value
>> BitNumber
) & 1;
722 Value
&= ~(1 << BitNumber
);
724 /* Write back the result */
725 if (!Fast486WriteModrmWordOperands(State
, &ModRegRm
, FALSE
, Value
))
727 /* Exception occurred */
736 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtc
)
738 BOOLEAN OperandSize
, AddressSize
;
739 FAST486_MOD_REG_RM ModRegRm
;
743 OperandSize
= AddressSize
= State
->SegmentRegs
[FAST486_REG_CS
].Size
;
744 TOGGLE_OPSIZE(OperandSize
);
745 TOGGLE_ADSIZE(AddressSize
);
747 /* Get the number of bits */
748 if (OperandSize
) DataSize
= 32;
751 /* Get the operands */
752 if (!Fast486ParseModRegRm(State
, AddressSize
, &ModRegRm
))
754 /* Exception occurred */
758 /* Get the bit number */
759 BitNumber
= OperandSize
? State
->GeneralRegs
[ModRegRm
.Register
].Long
760 : (ULONG
)State
->GeneralRegs
[ModRegRm
.Register
].LowWord
;
765 * For memory operands, add the bit offset divided by
766 * the data size to the address
768 ModRegRm
.MemoryAddress
+= BitNumber
/ DataSize
;
771 /* Normalize the bit number */
772 BitNumber
&= (1 << DataSize
) - 1;
779 if (!Fast486ReadModrmDwordOperands(State
, &ModRegRm
, &Dummy
, &Value
))
781 /* Exception occurred */
785 /* Set CF to the bit value */
786 State
->Flags
.Cf
= (Value
>> BitNumber
) & 1;
789 Value
^= 1 << BitNumber
;
791 /* Write back the result */
792 if (!Fast486WriteModrmDwordOperands(State
, &ModRegRm
, FALSE
, Value
))
794 /* Exception occurred */
803 if (!Fast486ReadModrmWordOperands(State
, &ModRegRm
, &Dummy
, &Value
))
805 /* Exception occurred */
809 /* Set CF to the bit value */
810 State
->Flags
.Cf
= (Value
>> BitNumber
) & 1;
813 Value
^= 1 << BitNumber
;
815 /* Write back the result */
816 if (!Fast486WriteModrmWordOperands(State
, &ModRegRm
, FALSE
, Value
))
818 /* Exception occurred */
827 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalJmp
)
829 BOOLEAN Jump
= FALSE
;
831 BOOLEAN Size
= State
->SegmentRegs
[FAST486_REG_CS
].Size
;
836 /* Make sure this is the right instruction */
837 ASSERT((Opcode
& 0xF0) == 0x80);
839 /* Fetch the offset */
842 if (!Fast486FetchDword(State
, (PULONG
)&Offset
))
844 /* Exception occurred */
852 if (!Fast486FetchWord(State
, (PUSHORT
)&Value
))
854 /* Exception occurred */
859 Offset
= (LONG
)Value
;
862 switch ((Opcode
& 0x0F) >> 1)
867 Jump
= State
->Flags
.Of
;
874 Jump
= State
->Flags
.Cf
;
881 Jump
= State
->Flags
.Zf
;
888 Jump
= State
->Flags
.Cf
|| State
->Flags
.Zf
;
895 Jump
= State
->Flags
.Sf
;
902 Jump
= State
->Flags
.Pf
;
909 Jump
= State
->Flags
.Sf
!= State
->Flags
.Of
;
916 Jump
= (State
->Flags
.Sf
!= State
->Flags
.Of
) || State
->Flags
.Zf
;
923 /* Invert the result */
929 /* Move the instruction pointer */
930 State
->InstPtr
.Long
+= Offset
;
937 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalSet
)
939 BOOLEAN Value
= FALSE
;
940 BOOLEAN AddressSize
= State
->SegmentRegs
[FAST486_REG_CS
].Size
;
941 FAST486_MOD_REG_RM ModRegRm
;
943 TOGGLE_ADSIZE(AddressSize
);
945 /* Get the operands */
946 if (!Fast486ParseModRegRm(State
, AddressSize
, &ModRegRm
))
948 /* Exception occurred */
952 /* Make sure this is the right instruction */
953 ASSERT((Opcode
& 0xF0) == 0x90);
955 switch ((Opcode
& 0x0F) >> 1)
960 Value
= State
->Flags
.Of
;
967 Value
= State
->Flags
.Cf
;
974 Value
= State
->Flags
.Zf
;
981 Value
= State
->Flags
.Cf
|| State
->Flags
.Zf
;
988 Value
= State
->Flags
.Sf
;
995 Value
= State
->Flags
.Pf
;
1002 Value
= State
->Flags
.Sf
!= State
->Flags
.Of
;
1006 /* SETLE / SETNLE */
1009 Value
= (State
->Flags
.Sf
!= State
->Flags
.Of
) || State
->Flags
.Zf
;
1016 /* Invert the result */
1020 /* Write back the result */
1021 return Fast486WriteModrmByteOperands(State
, &ModRegRm
, FALSE
, Value
);
1024 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBswap
)
1030 /* Get a pointer to the value */
1031 Pointer
= (PUCHAR
)&State
->GeneralRegs
[Opcode
& 0x07].Long
;
1033 /* Swap the byte order */
1034 SWAP(Pointer
[0], Pointer
[3]);
1035 SWAP(Pointer
[1], Pointer
[2]);
1037 /* Return success */
1041 FAST486_OPCODE_HANDLER(Fast486OpcodeExtended
)
1045 /* Fetch the second operation code */
1046 if (!Fast486FetchByte(State
, &SecondOpcode
))
1048 /* Exception occurred */
1052 if (Fast486ExtendedHandlers
[SecondOpcode
] != NULL
)
1054 /* Call the extended opcode handler */
1055 return Fast486ExtendedHandlers
[SecondOpcode
](State
, SecondOpcode
);
1059 /* This is not a valid opcode */
1060 Fast486Exception(State
, FAST486_EXCEPTION_UD
);