682f3e159c959c608b561af31cbd0559d4d51643
[reactos.git] / lib / fast486 / extraops.c
1 /*
2 * Fast486 386/486 CPU Emulation Library
3 * extraops.c
4 *
5 * Copyright (C) 2013 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 /* INCLUDES *******************************************************************/
23
24 // #define WIN32_NO_STATUS
25 // #define _INC_WINDOWS
26 #include <windef.h>
27
28 // #define NDEBUG
29 #include <debug.h>
30
31 #include <fast486.h>
32 #include "opcodes.h"
33 #include "common.h"
34 #include "extraops.h"
35
36 /* PUBLIC VARIABLES ***********************************************************/
37
38 FAST486_OPCODE_HANDLER_PROC
39 Fast486ExtendedHandlers[FAST486_NUM_OPCODE_HANDLERS] =
40 {
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
51 NULL, // Invalid
52 NULL, // Reserved (UD1)
53 NULL, // Invalid
54 NULL, // Invalid
55 NULL, // Invalid
56 NULL, // Invalid
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
61 NULL, // Invalid
62 NULL, // Invalid
63 NULL, // Invalid
64 NULL, // Invalid
65 NULL, // Invalid
66 NULL, // Invalid
67 NULL, // Invalid
68 NULL, // Invalid
69 NULL, // Invalid
70 NULL, // Invalid
71 NULL, // Invalid
72 NULL, // Invalid
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
78 NULL, // Invalid
79 NULL, // TODO: OPCODE 0x26 NOT IMPLEMENTED
80 NULL, // Invalid
81 NULL, // Invalid
82 NULL, // Invalid
83 NULL, // Invalid
84 NULL, // Invalid
85 NULL, // Invalid
86 NULL, // Invalid
87 NULL, // Invalid
88 NULL, // Invalid
89 NULL, // Invalid
90 NULL, // Invalid
91 NULL, // Invalid
92 NULL, // Invalid
93 NULL, // Invalid
94 NULL, // Invalid
95 NULL, // Invalid
96 NULL, // Invalid
97 NULL, // Invalid
98 NULL, // Invalid
99 NULL, // Invalid
100 NULL, // Invalid
101 NULL, // Invalid
102 NULL, // Invalid
103 NULL, // Invalid
104 NULL, // Invalid
105 NULL, // Invalid
106 NULL, // Invalid
107 NULL, // Invalid
108 NULL, // Invalid
109 NULL, // Invalid
110 NULL, // Invalid
111 NULL, // Invalid
112 NULL, // Invalid
113 NULL, // Invalid
114 NULL, // Invalid
115 NULL, // Invalid
116 NULL, // Invalid
117 NULL, // Invalid
118 NULL, // Invalid
119 NULL, // Invalid
120 NULL, // Invalid
121 NULL, // Invalid
122 NULL, // Invalid
123 NULL, // Invalid
124 NULL, // Invalid
125 NULL, // Invalid
126 NULL, // Invalid
127 NULL, // Invalid
128 NULL, // Invalid
129 NULL, // Invalid
130 NULL, // Invalid
131 NULL, // Invalid
132 NULL, // Invalid
133 NULL, // Invalid
134 NULL, // Invalid
135 NULL, // Invalid
136 NULL, // Invalid
137 NULL, // Invalid
138 NULL, // Invalid
139 NULL, // Invalid
140 NULL, // Invalid
141 NULL, // Invalid
142 NULL, // Invalid
143 NULL, // Invalid
144 NULL, // Invalid
145 NULL, // Invalid
146 NULL, // Invalid
147 NULL, // Invalid
148 NULL, // Invalid
149 NULL, // Invalid
150 NULL, // Invalid
151 NULL, // Invalid
152 NULL, // Invalid
153 NULL, // Invalid
154 NULL, // Invalid
155 NULL, // Invalid
156 NULL, // Invalid
157 NULL, // Invalid
158 NULL, // Invalid
159 NULL, // Invalid
160 NULL, // Invalid
161 NULL, // Invalid
162 NULL, // Invalid
163 NULL, // Invalid
164 NULL, // Invalid
165 NULL, // Invalid
166 NULL, // Invalid
167 NULL, // Invalid
168 NULL, // Invalid
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,
203 NULL, // Invalid
204 NULL, // TODO: OPCODE 0xA3 NOT IMPLEMENTED
205 NULL, // TODO: OPCODE 0xA4 NOT IMPLEMENTED
206 NULL, // TODO: OPCODE 0xA5 NOT IMPLEMENTED
207 NULL, // Invalid
208 NULL, // Invalid
209 Fast486ExtOpcodePushGs,
210 Fast486ExtOpcodePopGs,
211 NULL, // TODO: OPCODE 0xAA NOT IMPLEMENTED
212 NULL, // TODO: OPCODE 0xAB 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
220 NULL, // TODO: OPCODE 0xB3 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
228 NULL, // TODO: OPCODE 0xBB 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
235 NULL, // Invalid
236 NULL, // Invalid
237 NULL, // Invalid
238 NULL, // Invalid
239 NULL, // Invalid
240 NULL, // Invalid
241 NULL, // TODO: OPCODE 0xC8 NOT IMPLEMENTED
242 NULL, // TODO: OPCODE 0xC9 NOT IMPLEMENTED
243 NULL, // TODO: OPCODE 0xCA NOT IMPLEMENTED
244 NULL, // TODO: OPCODE 0xCB NOT IMPLEMENTED
245 NULL, // TODO: OPCODE 0xCC NOT IMPLEMENTED
246 NULL, // TODO: OPCODE 0xCD NOT IMPLEMENTED
247 NULL, // TODO: OPCODE 0xCE NOT IMPLEMENTED
248 NULL, // TODO: OPCODE 0xCF NOT IMPLEMENTED
249 NULL, // Invalid
250 NULL, // Invalid
251 NULL, // Invalid
252 NULL, // Invalid
253 NULL, // Invalid
254 NULL, // Invalid
255 NULL, // Invalid
256 NULL, // Invalid
257 NULL, // Invalid
258 NULL, // Invalid
259 NULL, // Invalid
260 NULL, // Invalid
261 NULL, // Invalid
262 NULL, // Invalid
263 NULL, // Invalid
264 NULL, // Invalid
265 NULL, // Invalid
266 NULL, // Invalid
267 NULL, // Invalid
268 NULL, // Invalid
269 NULL, // Invalid
270 NULL, // Invalid
271 NULL, // Invalid
272 NULL, // Invalid
273 NULL, // Invalid
274 NULL, // Invalid
275 NULL, // Invalid
276 NULL, // Invalid
277 NULL, // Invalid
278 NULL, // Invalid
279 NULL, // Invalid
280 NULL, // Invalid
281 NULL, // Invalid
282 NULL, // Invalid
283 NULL, // Invalid
284 NULL, // Invalid
285 NULL, // Invalid
286 NULL, // Invalid
287 NULL, // Invalid
288 NULL, // Invalid
289 NULL, // Invalid
290 NULL, // Invalid
291 NULL, // Invalid
292 NULL, // Invalid
293 NULL, // Invalid
294 NULL, // Invalid
295 NULL, // Invalid
296 NULL, // Invalid
297 };
298
299 /* PUBLIC FUNCTIONS ***********************************************************/
300
301 FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushFs)
302 {
303 /* Call the internal API */
304 return Fast486StackPush(State, State->SegmentRegs[FAST486_REG_FS].Selector);
305 }
306
307 FAST486_OPCODE_HANDLER(Fast486ExtOpcodePopFs)
308 {
309 ULONG NewSelector;
310
311 if (!Fast486StackPop(State, &NewSelector))
312 {
313 /* Exception occurred */
314 return FALSE;
315 }
316
317 /* Call the internal API */
318 return Fast486LoadSegment(State, FAST486_REG_FS, LOWORD(NewSelector));
319 }
320
321 FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushGs)
322 {
323 /* Call the internal API */
324 return Fast486StackPush(State, State->SegmentRegs[FAST486_REG_GS].Selector);
325 }
326
327 FAST486_OPCODE_HANDLER(Fast486ExtOpcodePopGs)
328 {
329 ULONG NewSelector;
330
331 if (!Fast486StackPop(State, &NewSelector))
332 {
333 /* Exception occurred */
334 return FALSE;
335 }
336
337 /* Call the internal API */
338 return Fast486LoadSegment(State, FAST486_REG_GS, LOWORD(NewSelector));
339 }
340
341 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchgByte)
342 {
343 FAST486_MOD_REG_RM ModRegRm;
344 UCHAR Accumulator = State->GeneralRegs[FAST486_REG_EAX].LowByte;
345 UCHAR Source, Destination, Result;
346 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;;
347
348 TOGGLE_ADSIZE(AddressSize);
349
350 /* Get the operands */
351 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
352 {
353 /* Exception occurred */
354 return FALSE;
355 }
356
357 /* Read the operands */
358 if (!Fast486ReadModrmByteOperands(State, &ModRegRm, &Source, &Destination))
359 {
360 /* Exception occurred */
361 return FALSE;
362 }
363
364 /* Compare AL with the destination */
365 Result = Accumulator - Destination;
366
367 /* Update the flags */
368 State->Flags.Cf = Accumulator < Destination;
369 State->Flags.Of = ((Accumulator & SIGN_FLAG_BYTE) != (Destination & SIGN_FLAG_BYTE))
370 && ((Accumulator & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE));
371 State->Flags.Af = (Accumulator & 0x0F) < (Destination & 0x0F);
372 State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
373 State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
374 State->Flags.Pf = Fast486CalculateParity(Result);
375
376 if (State->Flags.Zf)
377 {
378 /* Load the source operand into the destination */
379 return Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Source);
380 }
381 else
382 {
383 /* Load the destination into AL */
384 State->GeneralRegs[FAST486_REG_EAX].LowByte = Destination;
385 }
386
387 /* Return success */
388 return TRUE;
389 }
390
391 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchg)
392 {
393 FAST486_MOD_REG_RM ModRegRm;
394 BOOLEAN OperandSize, AddressSize;
395
396 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
397
398 TOGGLE_OPSIZE(OperandSize);
399 TOGGLE_ADSIZE(AddressSize);
400
401 /* Get the operands */
402 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
403 {
404 /* Exception occurred */
405 return FALSE;
406 }
407
408 if (OperandSize)
409 {
410 ULONG Source, Destination, Result;
411 ULONG Accumulator = State->GeneralRegs[FAST486_REG_EAX].Long;
412
413 /* Read the operands */
414 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Source, &Destination))
415 {
416 /* Exception occurred */
417 return FALSE;
418 }
419
420 /* Compare EAX with the destination */
421 Result = Accumulator - Destination;
422
423 /* Update the flags */
424 State->Flags.Cf = Accumulator < Destination;
425 State->Flags.Of = ((Accumulator & SIGN_FLAG_LONG) != (Destination & SIGN_FLAG_LONG))
426 && ((Accumulator & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG));
427 State->Flags.Af = (Accumulator & 0x0F) < (Destination & 0x0F);
428 State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
429 State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
430 State->Flags.Pf = Fast486CalculateParity(Result);
431
432 if (State->Flags.Zf)
433 {
434 /* Load the source operand into the destination */
435 return Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Source);
436 }
437 else
438 {
439 /* Load the destination into EAX */
440 State->GeneralRegs[FAST486_REG_EAX].Long = Destination;
441 }
442 }
443 else
444 {
445 USHORT Source, Destination, Result;
446 USHORT Accumulator = State->GeneralRegs[FAST486_REG_EAX].LowWord;
447
448 /* Read the operands */
449 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Source, &Destination))
450 {
451 /* Exception occurred */
452 return FALSE;
453 }
454
455 /* Compare AX with the destination */
456 Result = Accumulator - Destination;
457
458 /* Update the flags */
459 State->Flags.Cf = Accumulator < Destination;
460 State->Flags.Of = ((Accumulator & SIGN_FLAG_WORD) != (Destination & SIGN_FLAG_WORD))
461 && ((Accumulator & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD));
462 State->Flags.Af = (Accumulator & 0x0F) < (Destination & 0x0F);
463 State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
464 State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
465 State->Flags.Pf = Fast486CalculateParity(Result);
466
467 if (State->Flags.Zf)
468 {
469 /* Load the source operand into the destination */
470 return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Source);
471 }
472 else
473 {
474 /* Load the destination into AX */
475 State->GeneralRegs[FAST486_REG_EAX].LowWord = Destination;
476 }
477 }
478
479 /* Return success */
480 return TRUE;
481
482 }
483
484 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalJmp)
485 {
486 BOOLEAN Jump = FALSE;
487 LONG Offset = 0;
488 BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
489
490 TOGGLE_OPSIZE(Size);
491 NO_LOCK_PREFIX();
492
493 /* Make sure this is the right instruction */
494 ASSERT((Opcode & 0xF0) == 0x80);
495
496 /* Fetch the offset */
497 if (Size)
498 {
499 if (!Fast486FetchDword(State, (PULONG)&Offset))
500 {
501 /* Exception occurred */
502 return FALSE;
503 }
504 }
505 else
506 {
507 SHORT Value;
508
509 if (!Fast486FetchWord(State, (PUSHORT)&Value))
510 {
511 /* Exception occurred */
512 return FALSE;
513 }
514
515 /* Sign-extend */
516 Offset = (LONG)Value;
517 }
518
519 switch ((Opcode & 0x0F) >> 1)
520 {
521 /* JO / JNO */
522 case 0:
523 {
524 Jump = State->Flags.Of;
525 break;
526 }
527
528 /* JC / JNC */
529 case 1:
530 {
531 Jump = State->Flags.Cf;
532 break;
533 }
534
535 /* JZ / JNZ */
536 case 2:
537 {
538 Jump = State->Flags.Zf;
539 break;
540 }
541
542 /* JBE / JNBE */
543 case 3:
544 {
545 Jump = State->Flags.Cf || State->Flags.Zf;
546 break;
547 }
548
549 /* JS / JNS */
550 case 4:
551 {
552 Jump = State->Flags.Sf;
553 break;
554 }
555
556 /* JP / JNP */
557 case 5:
558 {
559 Jump = State->Flags.Pf;
560 break;
561 }
562
563 /* JL / JNL */
564 case 6:
565 {
566 Jump = State->Flags.Sf != State->Flags.Of;
567 break;
568 }
569
570 /* JLE / JNLE */
571 case 7:
572 {
573 Jump = (State->Flags.Sf != State->Flags.Of) || State->Flags.Zf;
574 break;
575 }
576 }
577
578 if (Opcode & 1)
579 {
580 /* Invert the result */
581 Jump = !Jump;
582 }
583
584 if (Jump)
585 {
586 /* Move the instruction pointer */
587 State->InstPtr.Long += Offset;
588 }
589
590 /* Return success */
591 return TRUE;
592 }
593
594 FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalSet)
595 {
596 BOOLEAN Value = FALSE;
597 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
598 FAST486_MOD_REG_RM ModRegRm;
599
600 TOGGLE_ADSIZE(AddressSize);
601
602 /* Get the operands */
603 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
604 {
605 /* Exception occurred */
606 return FALSE;
607 }
608
609 /* Make sure this is the right instruction */
610 ASSERT((Opcode & 0xF0) == 0x90);
611
612 switch ((Opcode & 0x0F) >> 1)
613 {
614 /* SETO / SETNO */
615 case 0:
616 {
617 Value = State->Flags.Of;
618 break;
619 }
620
621 /* SETC / SETNC */
622 case 1:
623 {
624 Value = State->Flags.Cf;
625 break;
626 }
627
628 /* SETZ / SETNZ */
629 case 2:
630 {
631 Value = State->Flags.Zf;
632 break;
633 }
634
635 /* SETBE / SETNBE */
636 case 3:
637 {
638 Value = State->Flags.Cf || State->Flags.Zf;
639 break;
640 }
641
642 /* SETS / SETNS */
643 case 4:
644 {
645 Value = State->Flags.Sf;
646 break;
647 }
648
649 /* SETP / SETNP */
650 case 5:
651 {
652 Value = State->Flags.Pf;
653 break;
654 }
655
656 /* SETL / SETNL */
657 case 6:
658 {
659 Value = State->Flags.Sf != State->Flags.Of;
660 break;
661 }
662
663 /* SETLE / SETNLE */
664 case 7:
665 {
666 Value = (State->Flags.Sf != State->Flags.Of) || State->Flags.Zf;
667 break;
668 }
669 }
670
671 if (Opcode & 1)
672 {
673 /* Invert the result */
674 Value = !Value;
675 }
676
677 /* Write back the result */
678 return Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
679 }
680
681 FAST486_OPCODE_HANDLER(Fast486OpcodeExtended)
682 {
683 UCHAR SecondOpcode;
684
685 /* Fetch the second operation code */
686 if (!Fast486FetchByte(State, &SecondOpcode))
687 {
688 /* Exception occurred */
689 return FALSE;
690 }
691
692 if (Fast486ExtendedHandlers[SecondOpcode] != NULL)
693 {
694 /* Call the extended opcode handler */
695 return Fast486ExtendedHandlers[SecondOpcode](State, SecondOpcode);
696 }
697 else
698 {
699 /* This is not a valid opcode */
700 Fast486Exception(State, FAST486_EXCEPTION_UD);
701 return FALSE;
702 }
703 }