1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#include <common.h>
40#include "x86emu/x86emui.h"
41
42
43
44
45
46
47
48static void x86emu_intr_handle(void)
49{
50 u8 intno;
51
52 if (M.x86.intr & INTR_SYNCH) {
53 intno = M.x86.intno;
54 if (_X86EMU_intrTab[intno]) {
55 (*_X86EMU_intrTab[intno])(intno);
56 } else {
57 push_word((u16)M.x86.R_FLG);
58 CLEAR_FLAG(F_IF);
59 CLEAR_FLAG(F_TF);
60 push_word(M.x86.R_CS);
61 M.x86.R_CS = mem_access_word(intno * 4 + 2);
62 push_word(M.x86.R_IP);
63 M.x86.R_IP = mem_access_word(intno * 4);
64 M.x86.intr = 0;
65 }
66 }
67}
68
69
70
71
72
73
74
75
76
77void x86emu_intr_raise(
78 u8 intrnum)
79{
80 M.x86.intno = intrnum;
81 M.x86.intr |= INTR_SYNCH;
82}
83
84
85
86
87
88
89
90void X86EMU_exec(void)
91{
92 u8 op1;
93
94 M.x86.intr = 0;
95 DB(x86emu_end_instr();)
96
97 for (;;) {
98DB( if (CHECK_IP_FETCH())
99 x86emu_check_ip_access();)
100
101 SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
102 INC_DECODED_INST_LEN(1);
103 if (M.x86.intr) {
104 if (M.x86.intr & INTR_HALTED) {
105DB( if (M.x86.R_SP != 0) {
106 printk("halted\n");
107 X86EMU_trace_regs();
108 }
109 else {
110 if (M.x86.debug)
111 printk("Service completed successfully\n");
112 })
113 return;
114 }
115 if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) ||
116 !ACCESS_FLAG(F_IF)) {
117 x86emu_intr_handle();
118 }
119 }
120 op1 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
121 (*x86emu_optab[op1])(op1);
122 if (M.x86.debug & DEBUG_EXIT) {
123 M.x86.debug &= ~DEBUG_EXIT;
124 return;
125 }
126 }
127}
128
129
130
131
132
133void X86EMU_halt_sys(void)
134{
135 M.x86.intr |= INTR_HALTED;
136}
137
138
139
140
141
142
143
144
145
146
147
148
149
150void fetch_decode_modrm(
151 int *mod,
152 int *regh,
153 int *regl)
154{
155 int fetched;
156
157DB( if (CHECK_IP_FETCH())
158 x86emu_check_ip_access();)
159 fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
160 INC_DECODED_INST_LEN(1);
161 *mod = (fetched >> 6) & 0x03;
162 *regh = (fetched >> 3) & 0x07;
163 *regl = (fetched >> 0) & 0x07;
164}
165
166
167
168
169
170
171
172
173
174
175
176u8 fetch_byte_imm(void)
177{
178 u8 fetched;
179
180DB( if (CHECK_IP_FETCH())
181 x86emu_check_ip_access();)
182 fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
183 INC_DECODED_INST_LEN(1);
184 return fetched;
185}
186
187
188
189
190
191
192
193
194
195
196
197u16 fetch_word_imm(void)
198{
199 u16 fetched;
200
201DB( if (CHECK_IP_FETCH())
202 x86emu_check_ip_access();)
203 fetched = (*sys_rdw)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP));
204 M.x86.R_IP += 2;
205 INC_DECODED_INST_LEN(2);
206 return fetched;
207}
208
209
210
211
212
213
214
215
216
217
218
219u32 fetch_long_imm(void)
220{
221 u32 fetched;
222
223DB( if (CHECK_IP_FETCH())
224 x86emu_check_ip_access();)
225 fetched = (*sys_rdl)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP));
226 M.x86.R_IP += 4;
227 INC_DECODED_INST_LEN(4);
228 return fetched;
229}
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260_INLINE u32 get_data_segment(void)
261{
262#define GET_SEGMENT(segment)
263 switch (M.x86.mode & SYSMODE_SEGMASK) {
264 case 0:
265 case SYSMODE_SEGOVR_DS:
266 case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
267 return M.x86.R_DS;
268 case SYSMODE_SEG_DS_SS:
269 return M.x86.R_SS;
270 case SYSMODE_SEGOVR_CS:
271 case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
272 return M.x86.R_CS;
273 case SYSMODE_SEGOVR_ES:
274 case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
275 return M.x86.R_ES;
276 case SYSMODE_SEGOVR_FS:
277 case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
278 return M.x86.R_FS;
279 case SYSMODE_SEGOVR_GS:
280 case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
281 return M.x86.R_GS;
282 case SYSMODE_SEGOVR_SS:
283 case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
284 return M.x86.R_SS;
285 default:
286#ifdef DEBUG
287 printk("error: should not happen: multiple overrides.\n");
288#endif
289 HALT_SYS();
290 return 0;
291 }
292}
293
294
295
296
297
298
299
300
301
302
303u8 fetch_data_byte(
304 uint offset)
305{
306#ifdef CONFIG_X86EMU_DEBUG
307 if (CHECK_DATA_ACCESS())
308 x86emu_check_data_access((u16)get_data_segment(), offset);
309#endif
310 return (*sys_rdb)((get_data_segment() << 4) + offset);
311}
312
313
314
315
316
317
318
319
320
321
322u16 fetch_data_word(
323 uint offset)
324{
325#ifdef CONFIG_X86EMU_DEBUG
326 if (CHECK_DATA_ACCESS())
327 x86emu_check_data_access((u16)get_data_segment(), offset);
328#endif
329 return (*sys_rdw)((get_data_segment() << 4) + offset);
330}
331
332
333
334
335
336
337
338
339
340
341u32 fetch_data_long(
342 uint offset)
343{
344#ifdef CONFIG_X86EMU_DEBUG
345 if (CHECK_DATA_ACCESS())
346 x86emu_check_data_access((u16)get_data_segment(), offset);
347#endif
348 return (*sys_rdl)((get_data_segment() << 4) + offset);
349}
350
351
352
353
354
355
356
357
358
359
360
361u8 fetch_data_byte_abs(
362 uint segment,
363 uint offset)
364{
365#ifdef CONFIG_X86EMU_DEBUG
366 if (CHECK_DATA_ACCESS())
367 x86emu_check_data_access(segment, offset);
368#endif
369 return (*sys_rdb)(((u32)segment << 4) + offset);
370}
371
372
373
374
375
376
377
378
379
380
381
382u16 fetch_data_word_abs(
383 uint segment,
384 uint offset)
385{
386#ifdef CONFIG_X86EMU_DEBUG
387 if (CHECK_DATA_ACCESS())
388 x86emu_check_data_access(segment, offset);
389#endif
390 return (*sys_rdw)(((u32)segment << 4) + offset);
391}
392
393
394
395
396
397
398
399
400
401
402
403u32 fetch_data_long_abs(
404 uint segment,
405 uint offset)
406{
407#ifdef CONFIG_X86EMU_DEBUG
408 if (CHECK_DATA_ACCESS())
409 x86emu_check_data_access(segment, offset);
410#endif
411 return (*sys_rdl)(((u32)segment << 4) + offset);
412}
413
414
415
416
417
418
419
420
421
422
423
424
425void store_data_byte(
426 uint offset,
427 u8 val)
428{
429#ifdef CONFIG_X86EMU_DEBUG
430 if (CHECK_DATA_ACCESS())
431 x86emu_check_data_access((u16)get_data_segment(), offset);
432#endif
433 (*sys_wrb)((get_data_segment() << 4) + offset, val);
434}
435
436
437
438
439
440
441
442
443
444
445
446
447void store_data_word(
448 uint offset,
449 u16 val)
450{
451#ifdef CONFIG_X86EMU_DEBUG
452 if (CHECK_DATA_ACCESS())
453 x86emu_check_data_access((u16)get_data_segment(), offset);
454#endif
455 (*sys_wrw)((get_data_segment() << 4) + offset, val);
456}
457
458
459
460
461
462
463
464
465
466
467
468
469void store_data_long(
470 uint offset,
471 u32 val)
472{
473#ifdef CONFIG_X86EMU_DEBUG
474 if (CHECK_DATA_ACCESS())
475 x86emu_check_data_access((u16)get_data_segment(), offset);
476#endif
477 (*sys_wrl)((get_data_segment() << 4) + offset, val);
478}
479
480
481
482
483
484
485
486
487
488
489
490
491void store_data_byte_abs(
492 uint segment,
493 uint offset,
494 u8 val)
495{
496#ifdef CONFIG_X86EMU_DEBUG
497 if (CHECK_DATA_ACCESS())
498 x86emu_check_data_access(segment, offset);
499#endif
500 (*sys_wrb)(((u32)segment << 4) + offset, val);
501}
502
503
504
505
506
507
508
509
510
511
512
513
514void store_data_word_abs(
515 uint segment,
516 uint offset,
517 u16 val)
518{
519#ifdef CONFIG_X86EMU_DEBUG
520 if (CHECK_DATA_ACCESS())
521 x86emu_check_data_access(segment, offset);
522#endif
523 (*sys_wrw)(((u32)segment << 4) + offset, val);
524}
525
526
527
528
529
530
531
532
533
534
535
536
537void store_data_long_abs(
538 uint segment,
539 uint offset,
540 u32 val)
541{
542#ifdef CONFIG_X86EMU_DEBUG
543 if (CHECK_DATA_ACCESS())
544 x86emu_check_data_access(segment, offset);
545#endif
546 (*sys_wrl)(((u32)segment << 4) + offset, val);
547}
548
549
550
551
552
553
554
555
556
557
558
559
560u8* decode_rm_byte_register(
561 int reg)
562{
563 switch (reg) {
564 case 0:
565 DECODE_PRINTF("AL");
566 return &M.x86.R_AL;
567 case 1:
568 DECODE_PRINTF("CL");
569 return &M.x86.R_CL;
570 case 2:
571 DECODE_PRINTF("DL");
572 return &M.x86.R_DL;
573 case 3:
574 DECODE_PRINTF("BL");
575 return &M.x86.R_BL;
576 case 4:
577 DECODE_PRINTF("AH");
578 return &M.x86.R_AH;
579 case 5:
580 DECODE_PRINTF("CH");
581 return &M.x86.R_CH;
582 case 6:
583 DECODE_PRINTF("DH");
584 return &M.x86.R_DH;
585 case 7:
586 DECODE_PRINTF("BH");
587 return &M.x86.R_BH;
588 }
589 HALT_SYS();
590 return NULL;
591}
592
593
594
595
596
597
598
599
600
601
602
603
604u16* decode_rm_word_register(
605 int reg)
606{
607 switch (reg) {
608 case 0:
609 DECODE_PRINTF("AX");
610 return &M.x86.R_AX;
611 case 1:
612 DECODE_PRINTF("CX");
613 return &M.x86.R_CX;
614 case 2:
615 DECODE_PRINTF("DX");
616 return &M.x86.R_DX;
617 case 3:
618 DECODE_PRINTF("BX");
619 return &M.x86.R_BX;
620 case 4:
621 DECODE_PRINTF("SP");
622 return &M.x86.R_SP;
623 case 5:
624 DECODE_PRINTF("BP");
625 return &M.x86.R_BP;
626 case 6:
627 DECODE_PRINTF("SI");
628 return &M.x86.R_SI;
629 case 7:
630 DECODE_PRINTF("DI");
631 return &M.x86.R_DI;
632 }
633 HALT_SYS();
634 return NULL;
635}
636
637
638
639
640
641
642
643
644
645
646
647
648u32* decode_rm_long_register(
649 int reg)
650{
651 switch (reg) {
652 case 0:
653 DECODE_PRINTF("EAX");
654 return &M.x86.R_EAX;
655 case 1:
656 DECODE_PRINTF("ECX");
657 return &M.x86.R_ECX;
658 case 2:
659 DECODE_PRINTF("EDX");
660 return &M.x86.R_EDX;
661 case 3:
662 DECODE_PRINTF("EBX");
663 return &M.x86.R_EBX;
664 case 4:
665 DECODE_PRINTF("ESP");
666 return &M.x86.R_ESP;
667 case 5:
668 DECODE_PRINTF("EBP");
669 return &M.x86.R_EBP;
670 case 6:
671 DECODE_PRINTF("ESI");
672 return &M.x86.R_ESI;
673 case 7:
674 DECODE_PRINTF("EDI");
675 return &M.x86.R_EDI;
676 }
677 HALT_SYS();
678 return NULL;
679}
680
681
682
683
684
685
686
687
688
689
690
691
692
693u16* decode_rm_seg_register(
694 int reg)
695{
696 switch (reg) {
697 case 0:
698 DECODE_PRINTF("ES");
699 return &M.x86.R_ES;
700 case 1:
701 DECODE_PRINTF("CS");
702 return &M.x86.R_CS;
703 case 2:
704 DECODE_PRINTF("SS");
705 return &M.x86.R_SS;
706 case 3:
707 DECODE_PRINTF("DS");
708 return &M.x86.R_DS;
709 case 4:
710 DECODE_PRINTF("FS");
711 return &M.x86.R_FS;
712 case 5:
713 DECODE_PRINTF("GS");
714 return &M.x86.R_GS;
715 case 6:
716 case 7:
717 DECODE_PRINTF("ILLEGAL SEGREG");
718 break;
719 }
720 HALT_SYS();
721 return NULL;
722}
723
724
725
726
727
728
729
730
731
732
733
734
735
736unsigned decode_sib_si(
737 int scale,
738 int index)
739{
740 scale = 1 << scale;
741 if (scale > 1) {
742 DECODE_PRINTF2("[%d*", scale);
743 } else {
744 DECODE_PRINTF("[");
745 }
746 switch (index) {
747 case 0:
748 DECODE_PRINTF("EAX]");
749 return M.x86.R_EAX * index;
750 case 1:
751 DECODE_PRINTF("ECX]");
752 return M.x86.R_ECX * index;
753 case 2:
754 DECODE_PRINTF("EDX]");
755 return M.x86.R_EDX * index;
756 case 3:
757 DECODE_PRINTF("EBX]");
758 return M.x86.R_EBX * index;
759 case 4:
760 DECODE_PRINTF("0]");
761 return 0;
762 case 5:
763 DECODE_PRINTF("EBP]");
764 return M.x86.R_EBP * index;
765 case 6:
766 DECODE_PRINTF("ESI]");
767 return M.x86.R_ESI * index;
768 case 7:
769 DECODE_PRINTF("EDI]");
770 return M.x86.R_EDI * index;
771 }
772 HALT_SYS();
773 return 0;
774}
775
776
777
778
779
780
781
782
783
784
785
786unsigned decode_sib_address(
787 int mod)
788{
789 int sib = fetch_byte_imm();
790 int ss = (sib >> 6) & 0x03;
791 int index = (sib >> 3) & 0x07;
792 int base = sib & 0x07;
793 int offset = 0;
794 int displacement;
795
796 switch (base) {
797 case 0:
798 DECODE_PRINTF("[EAX]");
799 offset = M.x86.R_EAX;
800 break;
801 case 1:
802 DECODE_PRINTF("[ECX]");
803 offset = M.x86.R_ECX;
804 break;
805 case 2:
806 DECODE_PRINTF("[EDX]");
807 offset = M.x86.R_EDX;
808 break;
809 case 3:
810 DECODE_PRINTF("[EBX]");
811 offset = M.x86.R_EBX;
812 break;
813 case 4:
814 DECODE_PRINTF("[ESP]");
815 offset = M.x86.R_ESP;
816 break;
817 case 5:
818 switch (mod) {
819 case 0:
820 displacement = (s32)fetch_long_imm();
821 DECODE_PRINTF2("[%d]", displacement);
822 offset = displacement;
823 break;
824 case 1:
825 displacement = (s8)fetch_byte_imm();
826 DECODE_PRINTF2("[%d][EBP]", displacement);
827 offset = M.x86.R_EBP + displacement;
828 break;
829 case 2:
830 displacement = (s32)fetch_long_imm();
831 DECODE_PRINTF2("[%d][EBP]", displacement);
832 offset = M.x86.R_EBP + displacement;
833 break;
834 default:
835 HALT_SYS();
836 }
837 DECODE_PRINTF("[EAX]");
838 offset = M.x86.R_EAX;
839 break;
840 case 6:
841 DECODE_PRINTF("[ESI]");
842 offset = M.x86.R_ESI;
843 break;
844 case 7:
845 DECODE_PRINTF("[EDI]");
846 offset = M.x86.R_EDI;
847 break;
848 default:
849 HALT_SYS();
850 }
851 offset += decode_sib_si(ss, index);
852 return offset;
853
854}
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876unsigned decode_rm00_address(
877 int rm)
878{
879 unsigned offset;
880
881 if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
882
883 switch (rm) {
884 case 0:
885 DECODE_PRINTF("[EAX]");
886 return M.x86.R_EAX;
887 case 1:
888 DECODE_PRINTF("[ECX]");
889 return M.x86.R_ECX;
890 case 2:
891 DECODE_PRINTF("[EDX]");
892 return M.x86.R_EDX;
893 case 3:
894 DECODE_PRINTF("[EBX]");
895 return M.x86.R_EBX;
896 case 4:
897 return decode_sib_address(0);
898 case 5:
899 offset = fetch_long_imm();
900 DECODE_PRINTF2("[%08x]", offset);
901 return offset;
902 case 6:
903 DECODE_PRINTF("[ESI]");
904 return M.x86.R_ESI;
905 case 7:
906 DECODE_PRINTF("[EDI]");
907 return M.x86.R_EDI;
908 }
909 } else {
910
911 switch (rm) {
912 case 0:
913 DECODE_PRINTF("[BX+SI]");
914 return (M.x86.R_BX + M.x86.R_SI) & 0xffff;
915 case 1:
916 DECODE_PRINTF("[BX+DI]");
917 return (M.x86.R_BX + M.x86.R_DI) & 0xffff;
918 case 2:
919 DECODE_PRINTF("[BP+SI]");
920 M.x86.mode |= SYSMODE_SEG_DS_SS;
921 return (M.x86.R_BP + M.x86.R_SI) & 0xffff;
922 case 3:
923 DECODE_PRINTF("[BP+DI]");
924 M.x86.mode |= SYSMODE_SEG_DS_SS;
925 return (M.x86.R_BP + M.x86.R_DI) & 0xffff;
926 case 4:
927 DECODE_PRINTF("[SI]");
928 return M.x86.R_SI;
929 case 5:
930 DECODE_PRINTF("[DI]");
931 return M.x86.R_DI;
932 case 6:
933 offset = fetch_word_imm();
934 DECODE_PRINTF2("[%04x]", offset);
935 return offset;
936 case 7:
937 DECODE_PRINTF("[BX]");
938 return M.x86.R_BX;
939 }
940 }
941 HALT_SYS();
942 return 0;
943}
944
945
946
947
948
949
950
951
952
953
954
955
956unsigned decode_rm01_address(
957 int rm)
958{
959 int displacement;
960
961 if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
962
963 if (rm != 4)
964 displacement = (s8)fetch_byte_imm();
965 else
966 displacement = 0;
967
968 switch (rm) {
969 case 0:
970 DECODE_PRINTF2("%d[EAX]", displacement);
971 return M.x86.R_EAX + displacement;
972 case 1:
973 DECODE_PRINTF2("%d[ECX]", displacement);
974 return M.x86.R_ECX + displacement;
975 case 2:
976 DECODE_PRINTF2("%d[EDX]", displacement);
977 return M.x86.R_EDX + displacement;
978 case 3:
979 DECODE_PRINTF2("%d[EBX]", displacement);
980 return M.x86.R_EBX + displacement;
981 case 4: {
982 int offset = decode_sib_address(1);
983 displacement = (s8)fetch_byte_imm();
984 DECODE_PRINTF2("[%d]", displacement);
985 return offset + displacement;
986 }
987 case 5:
988 DECODE_PRINTF2("%d[EBP]", displacement);
989 return M.x86.R_EBP + displacement;
990 case 6:
991 DECODE_PRINTF2("%d[ESI]", displacement);
992 return M.x86.R_ESI + displacement;
993 case 7:
994 DECODE_PRINTF2("%d[EDI]", displacement);
995 return M.x86.R_EDI + displacement;
996 }
997 } else {
998
999 displacement = (s8)fetch_byte_imm();
1000 switch (rm) {
1001 case 0:
1002 DECODE_PRINTF2("%d[BX+SI]", displacement);
1003 return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
1004 case 1:
1005 DECODE_PRINTF2("%d[BX+DI]", displacement);
1006 return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
1007 case 2:
1008 DECODE_PRINTF2("%d[BP+SI]", displacement);
1009 M.x86.mode |= SYSMODE_SEG_DS_SS;
1010 return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
1011 case 3:
1012 DECODE_PRINTF2("%d[BP+DI]", displacement);
1013 M.x86.mode |= SYSMODE_SEG_DS_SS;
1014 return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
1015 case 4:
1016 DECODE_PRINTF2("%d[SI]", displacement);
1017 return (M.x86.R_SI + displacement) & 0xffff;
1018 case 5:
1019 DECODE_PRINTF2("%d[DI]", displacement);
1020 return (M.x86.R_DI + displacement) & 0xffff;
1021 case 6:
1022 DECODE_PRINTF2("%d[BP]", displacement);
1023 M.x86.mode |= SYSMODE_SEG_DS_SS;
1024 return (M.x86.R_BP + displacement) & 0xffff;
1025 case 7:
1026 DECODE_PRINTF2("%d[BX]", displacement);
1027 return (M.x86.R_BX + displacement) & 0xffff;
1028 }
1029 }
1030 HALT_SYS();
1031 return 0;
1032}
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045unsigned decode_rm10_address(
1046 int rm)
1047{
1048 if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
1049 int displacement;
1050
1051
1052 if (rm != 4)
1053 displacement = (s32)fetch_long_imm();
1054 else
1055 displacement = 0;
1056
1057 switch (rm) {
1058 case 0:
1059 DECODE_PRINTF2("%d[EAX]", displacement);
1060 return M.x86.R_EAX + displacement;
1061 case 1:
1062 DECODE_PRINTF2("%d[ECX]", displacement);
1063 return M.x86.R_ECX + displacement;
1064 case 2:
1065 DECODE_PRINTF2("%d[EDX]", displacement);
1066 return M.x86.R_EDX + displacement;
1067 case 3:
1068 DECODE_PRINTF2("%d[EBX]", displacement);
1069 return M.x86.R_EBX + displacement;
1070 case 4: {
1071 int offset = decode_sib_address(2);
1072 displacement = (s32)fetch_long_imm();
1073 DECODE_PRINTF2("[%d]", displacement);
1074 return offset + displacement;
1075 }
1076 case 5:
1077 DECODE_PRINTF2("%d[EBP]", displacement);
1078 return M.x86.R_EBP + displacement;
1079 case 6:
1080 DECODE_PRINTF2("%d[ESI]", displacement);
1081 return M.x86.R_ESI + displacement;
1082 case 7:
1083 DECODE_PRINTF2("%d[EDI]", displacement);
1084 return M.x86.R_EDI + displacement;
1085 }
1086 } else {
1087 int displacement = (s16)fetch_word_imm();
1088
1089
1090 switch (rm) {
1091 case 0:
1092 DECODE_PRINTF2("%d[BX+SI]", displacement);
1093 return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
1094 case 1:
1095 DECODE_PRINTF2("%d[BX+DI]", displacement);
1096 return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
1097 case 2:
1098 DECODE_PRINTF2("%d[BP+SI]", displacement);
1099 M.x86.mode |= SYSMODE_SEG_DS_SS;
1100 return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
1101 case 3:
1102 DECODE_PRINTF2("%d[BP+DI]", displacement);
1103 M.x86.mode |= SYSMODE_SEG_DS_SS;
1104 return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
1105 case 4:
1106 DECODE_PRINTF2("%d[SI]", displacement);
1107 return (M.x86.R_SI + displacement) & 0xffff;
1108 case 5:
1109 DECODE_PRINTF2("%d[DI]", displacement);
1110 return (M.x86.R_DI + displacement) & 0xffff;
1111 case 6:
1112 DECODE_PRINTF2("%d[BP]", displacement);
1113 M.x86.mode |= SYSMODE_SEG_DS_SS;
1114 return (M.x86.R_BP + displacement) & 0xffff;
1115 case 7:
1116 DECODE_PRINTF2("%d[BX]", displacement);
1117 return (M.x86.R_BX + displacement) & 0xffff;
1118 }
1119 }
1120 HALT_SYS();
1121 return 0;
1122}
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137unsigned decode_rmXX_address(int mod, int rm)
1138{
1139 if(mod == 0)
1140 return decode_rm00_address(rm);
1141 if(mod == 1)
1142 return decode_rm01_address(rm);
1143 return decode_rm10_address(rm);
1144}
1145