1
/****************************************************************************
3
* Realmode X86 Emulator Library
5
* Copyright (C) 1996-1999 SciTech Software, Inc.
6
* Copyright (C) David Mosberger-Tang
7
* Copyright (C) 1999 Egbert Eich
9
* ========================================================================
11
* Permission to use, copy, modify, distribute, and sell this software and
12
* its documentation for any purpose is hereby granted without fee,
13
* provided that the above copyright notice appear in all copies and that
14
* both that copyright notice and this permission notice appear in
15
* supporting documentation, and that the name of the authors not be used
16
* in advertising or publicity pertaining to distribution of the software
17
* without specific, written prior permission. The authors makes no
18
* representations about the suitability of this software for any purpose.
19
* It is provided "as is" without express or implied warranty.
21
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27
* PERFORMANCE OF THIS SOFTWARE.
29
* ========================================================================
33
* Developer: Kendall Bennett
35
* Description: This file includes subroutines which are related to
36
* instruction decoding and accessess of immediate data via IP. etc.
38
****************************************************************************/
41
#include "x86emu/x86emui.h"
43
/*----------------------------- Implementation ----------------------------*/
45
/****************************************************************************
47
Handles any pending asychronous interrupts.
48
****************************************************************************/
49
static void x86emu_intr_handle(void)
53
if (M.x86.intr & INTR_SYNCH) {
55
if (_X86EMU_intrTab[intno]) {
56
(*_X86EMU_intrTab[intno])(intno);
58
push_word((u16)M.x86.R_FLG);
61
push_word(M.x86.R_CS);
62
M.x86.R_CS = mem_access_word(intno * 4 + 2);
63
push_word(M.x86.R_IP);
64
M.x86.R_IP = mem_access_word(intno * 4);
70
/****************************************************************************
72
intrnum - Interrupt number to raise
75
Raise the specified interrupt to be handled before the execution of the
77
****************************************************************************/
78
void x86emu_intr_raise(
81
M.x86.intno = intrnum;
82
M.x86.intr |= INTR_SYNCH;
85
/****************************************************************************
87
Main execution loop for the emulator. We return from here when the system
88
halts, which is normally caused by a stack fault when we return from the
89
original real mode call.
90
****************************************************************************/
91
void X86EMU_exec(void)
96
DB(x86emu_end_instr();)
99
DB( if (CHECK_IP_FETCH())
100
x86emu_check_ip_access();)
101
/* If debugging, save the IP and CS values. */
102
SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
103
INC_DECODED_INST_LEN(1);
105
if (M.x86.intr & INTR_HALTED) {
106
DB( if (M.x86.R_SP != 0) {
112
printk("Service completed successfully\n");
116
if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) ||
117
!ACCESS_FLAG(F_IF)) {
118
x86emu_intr_handle();
121
op1 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
122
(*x86emu_optab[op1])(op1);
123
if (M.x86.debug & DEBUG_EXIT) {
124
M.x86.debug &= ~DEBUG_EXIT;
130
/****************************************************************************
132
Halts the system by setting the halted system flag.
133
****************************************************************************/
134
void X86EMU_halt_sys(void)
136
M.x86.intr |= INTR_HALTED;
139
/****************************************************************************
141
mod - Mod value from decoded byte
142
regh - Reg h value from decoded byte
143
regl - Reg l value from decoded byte
146
Raise the specified interrupt to be handled before the execution of the
149
NOTE: Do not inline this function, as (*sys_rdb) is already inline!
150
****************************************************************************/
151
void fetch_decode_modrm(
158
DB( if (CHECK_IP_FETCH())
159
x86emu_check_ip_access();)
160
fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
161
INC_DECODED_INST_LEN(1);
162
*mod = (fetched >> 6) & 0x03;
163
*regh = (fetched >> 3) & 0x07;
164
*regl = (fetched >> 0) & 0x07;
167
/****************************************************************************
169
Immediate byte value read from instruction queue
172
This function returns the immediate byte from the instruction queue, and
173
moves the instruction pointer to the next value.
175
NOTE: Do not inline this function, as (*sys_rdb) is already inline!
176
****************************************************************************/
177
u8 fetch_byte_imm(void)
181
DB( if (CHECK_IP_FETCH())
182
x86emu_check_ip_access();)
183
fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
184
INC_DECODED_INST_LEN(1);
188
/****************************************************************************
190
Immediate word value read from instruction queue
193
This function returns the immediate byte from the instruction queue, and
194
moves the instruction pointer to the next value.
196
NOTE: Do not inline this function, as (*sys_rdw) is already inline!
197
****************************************************************************/
198
u16 fetch_word_imm(void)
202
DB( if (CHECK_IP_FETCH())
203
x86emu_check_ip_access();)
204
fetched = (*sys_rdw)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP));
206
INC_DECODED_INST_LEN(2);
210
/****************************************************************************
212
Immediate lone value read from instruction queue
215
This function returns the immediate byte from the instruction queue, and
216
moves the instruction pointer to the next value.
218
NOTE: Do not inline this function, as (*sys_rdw) is already inline!
219
****************************************************************************/
220
u32 fetch_long_imm(void)
224
DB( if (CHECK_IP_FETCH())
225
x86emu_check_ip_access();)
226
fetched = (*sys_rdl)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP));
228
INC_DECODED_INST_LEN(4);
232
/****************************************************************************
234
Value of the default data segment
237
Inline function that returns the default data segment for the current
240
On the x86 processor, the default segment is not always DS if there is
241
no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
242
addresses relative to SS (ie: on the stack). So, at the minimum, all
243
decodings of addressing modes would have to set/clear a bit describing
244
whether the access is relative to DS or SS. That is the function of the
245
cpu-state-varible M.x86.mode. There are several potential states:
247
repe prefix seen (handled elsewhere)
248
repne prefix seen (ditto)
257
ds/ss select (in absense of override)
259
Each of the above 7 items are handled with a bit in the mode field.
260
****************************************************************************/
261
_INLINE u32 get_data_segment(void)
263
#define GET_SEGMENT(segment)
264
switch (M.x86.mode & SYSMODE_SEGMASK) {
265
case 0: /* default case: use ds register */
266
case SYSMODE_SEGOVR_DS:
267
case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
269
case SYSMODE_SEG_DS_SS: /* non-overridden, use ss register */
271
case SYSMODE_SEGOVR_CS:
272
case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
274
case SYSMODE_SEGOVR_ES:
275
case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
277
case SYSMODE_SEGOVR_FS:
278
case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
280
case SYSMODE_SEGOVR_GS:
281
case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
283
case SYSMODE_SEGOVR_SS:
284
case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
288
printk("error: should not happen: multiple overrides.\n");
295
/****************************************************************************
297
offset - Offset to load data from
300
Byte value read from the absolute memory location.
302
NOTE: Do not inline this function as (*sys_rdX) is already inline!
303
****************************************************************************/
308
if (CHECK_DATA_ACCESS())
309
x86emu_check_data_access((u16)get_data_segment(), offset);
311
return (*sys_rdb)((get_data_segment() << 4) + offset);
314
/****************************************************************************
316
offset - Offset to load data from
319
Word value read from the absolute memory location.
321
NOTE: Do not inline this function as (*sys_rdX) is already inline!
322
****************************************************************************/
327
if (CHECK_DATA_ACCESS())
328
x86emu_check_data_access((u16)get_data_segment(), offset);
330
return (*sys_rdw)((get_data_segment() << 4) + offset);
333
/****************************************************************************
335
offset - Offset to load data from
338
Long value read from the absolute memory location.
340
NOTE: Do not inline this function as (*sys_rdX) is already inline!
341
****************************************************************************/
346
if (CHECK_DATA_ACCESS())
347
x86emu_check_data_access((u16)get_data_segment(), offset);
349
return (*sys_rdl)((get_data_segment() << 4) + offset);
352
/****************************************************************************
354
segment - Segment to load data from
355
offset - Offset to load data from
358
Byte value read from the absolute memory location.
360
NOTE: Do not inline this function as (*sys_rdX) is already inline!
361
****************************************************************************/
362
u8 fetch_data_byte_abs(
367
if (CHECK_DATA_ACCESS())
368
x86emu_check_data_access(segment, offset);
370
return (*sys_rdb)(((u32)segment << 4) + offset);
373
/****************************************************************************
375
segment - Segment to load data from
376
offset - Offset to load data from
379
Word value read from the absolute memory location.
381
NOTE: Do not inline this function as (*sys_rdX) is already inline!
382
****************************************************************************/
383
u16 fetch_data_word_abs(
388
if (CHECK_DATA_ACCESS())
389
x86emu_check_data_access(segment, offset);
391
return (*sys_rdw)(((u32)segment << 4) + offset);
394
/****************************************************************************
396
segment - Segment to load data from
397
offset - Offset to load data from
400
Long value read from the absolute memory location.
402
NOTE: Do not inline this function as (*sys_rdX) is already inline!
403
****************************************************************************/
404
u32 fetch_data_long_abs(
409
if (CHECK_DATA_ACCESS())
410
x86emu_check_data_access(segment, offset);
412
return (*sys_rdl)(((u32)segment << 4) + offset);
415
/****************************************************************************
417
offset - Offset to store data at
421
Writes a word value to an segmented memory location. The segment used is
422
the current 'default' segment, which may have been overridden.
424
NOTE: Do not inline this function as (*sys_wrX) is already inline!
425
****************************************************************************/
426
void store_data_byte(
431
if (CHECK_DATA_ACCESS())
432
x86emu_check_data_access((u16)get_data_segment(), offset);
434
(*sys_wrb)((get_data_segment() << 4) + offset, val);
437
/****************************************************************************
439
offset - Offset to store data at
443
Writes a word value to an segmented memory location. The segment used is
444
the current 'default' segment, which may have been overridden.
446
NOTE: Do not inline this function as (*sys_wrX) is already inline!
447
****************************************************************************/
448
void store_data_word(
453
if (CHECK_DATA_ACCESS())
454
x86emu_check_data_access((u16)get_data_segment(), offset);
456
(*sys_wrw)((get_data_segment() << 4) + offset, val);
459
/****************************************************************************
461
offset - Offset to store data at
465
Writes a long value to an segmented memory location. The segment used is
466
the current 'default' segment, which may have been overridden.
468
NOTE: Do not inline this function as (*sys_wrX) is already inline!
469
****************************************************************************/
470
void store_data_long(
475
if (CHECK_DATA_ACCESS())
476
x86emu_check_data_access((u16)get_data_segment(), offset);
478
(*sys_wrl)((get_data_segment() << 4) + offset, val);
481
/****************************************************************************
483
segment - Segment to store data at
484
offset - Offset to store data at
488
Writes a byte value to an absolute memory location.
490
NOTE: Do not inline this function as (*sys_wrX) is already inline!
491
****************************************************************************/
492
void store_data_byte_abs(
498
if (CHECK_DATA_ACCESS())
499
x86emu_check_data_access(segment, offset);
501
(*sys_wrb)(((u32)segment << 4) + offset, val);
504
/****************************************************************************
506
segment - Segment to store data at
507
offset - Offset to store data at
511
Writes a word value to an absolute memory location.
513
NOTE: Do not inline this function as (*sys_wrX) is already inline!
514
****************************************************************************/
515
void store_data_word_abs(
521
if (CHECK_DATA_ACCESS())
522
x86emu_check_data_access(segment, offset);
524
(*sys_wrw)(((u32)segment << 4) + offset, val);
527
/****************************************************************************
529
segment - Segment to store data at
530
offset - Offset to store data at
534
Writes a long value to an absolute memory location.
536
NOTE: Do not inline this function as (*sys_wrX) is already inline!
537
****************************************************************************/
538
void store_data_long_abs(
544
if (CHECK_DATA_ACCESS())
545
x86emu_check_data_access(segment, offset);
547
(*sys_wrl)(((u32)segment << 4) + offset, val);
550
/****************************************************************************
552
reg - Register to decode
555
Pointer to the appropriate register
558
Return a pointer to the register given by the R/RM field of the
559
modrm byte, for byte operands. Also enables the decoding of instructions.
560
****************************************************************************/
561
u8* decode_rm_byte_register(
591
return NULL; /* NOT REACHED OR REACHED ON ERROR */
594
/****************************************************************************
596
reg - Register to decode
599
Pointer to the appropriate register
602
Return a pointer to the register given by the R/RM field of the
603
modrm byte, for word operands. Also enables the decoding of instructions.
604
****************************************************************************/
605
u16* decode_rm_word_register(
635
return NULL; /* NOTREACHED OR REACHED ON ERROR */
638
/****************************************************************************
640
reg - Register to decode
643
Pointer to the appropriate register
646
Return a pointer to the register given by the R/RM field of the
647
modrm byte, for dword operands. Also enables the decoding of instructions.
648
****************************************************************************/
649
u32* decode_rm_long_register(
654
DECODE_PRINTF("EAX");
657
DECODE_PRINTF("ECX");
660
DECODE_PRINTF("EDX");
663
DECODE_PRINTF("EBX");
666
DECODE_PRINTF("ESP");
669
DECODE_PRINTF("EBP");
672
DECODE_PRINTF("ESI");
675
DECODE_PRINTF("EDI");
679
return NULL; /* NOTREACHED OR REACHED ON ERROR */
682
/****************************************************************************
684
reg - Register to decode
687
Pointer to the appropriate register
690
Return a pointer to the register given by the R/RM field of the
691
modrm byte, for word operands, modified from above for the weirdo
692
special case of segreg operands. Also enables the decoding of instructions.
693
****************************************************************************/
694
u16* decode_rm_seg_register(
718
DECODE_PRINTF("ILLEGAL SEGREG");
722
return NULL; /* NOT REACHED OR REACHED ON ERROR */
727
* return offset from the SIB Byte
729
u32 decode_sib_address(int sib, int mod)
731
u32 base = 0, i = 0, scale = 1;
735
DECODE_PRINTF("[EAX]");
739
DECODE_PRINTF("[ECX]");
743
DECODE_PRINTF("[EDX]");
747
DECODE_PRINTF("[EBX]");
751
DECODE_PRINTF("[ESP]");
753
M.x86.mode |= SYSMODE_SEG_DS_SS;
757
base = fetch_long_imm();
758
DECODE_PRINTF2("%08x", base);
760
DECODE_PRINTF("[EBP]");
762
M.x86.mode |= SYSMODE_SEG_DS_SS;
766
DECODE_PRINTF("[ESI]");
770
DECODE_PRINTF("[EDI]");
774
switch ((sib >> 3) & 0x07) {
776
DECODE_PRINTF("[EAX");
780
DECODE_PRINTF("[ECX");
784
DECODE_PRINTF("[EDX");
788
DECODE_PRINTF("[EBX");
795
DECODE_PRINTF("[EBP");
799
DECODE_PRINTF("[ESI");
803
DECODE_PRINTF("[EDI");
807
scale = 1 << ((sib >> 6) & 0x03);
808
if (((sib >> 3) & 0x07) != 4) {
812
DECODE_PRINTF2("*%d]", scale);
815
return base + (i * scale);
818
/****************************************************************************
820
rm - RM value to decode
823
Offset in memory for the address decoding
826
Return the offset given by mod=00 addressing. Also enables the
827
decoding of instructions.
829
NOTE: The code which specifies the corresponding segment (ds vs ss)
830
below in the case of [BP+..]. The assumption here is that at the
831
point that this subroutine is called, the bit corresponding to
832
SYSMODE_SEG_DS_SS will be zero. After every instruction
833
except the segment override instructions, this bit (as well
834
as any bits indicating segment overrides) will be clear. So
835
if a SS access is needed, set this bit. Otherwise, DS access
836
occurs (unless any of the segment override bits are set).
837
****************************************************************************/
838
u32 decode_rm00_address(
844
if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
845
/* 32-bit addressing */
848
DECODE_PRINTF("[EAX]");
851
DECODE_PRINTF("[ECX]");
854
DECODE_PRINTF("[EDX]");
857
DECODE_PRINTF("[EBX]");
860
sib = fetch_byte_imm();
861
return decode_sib_address(sib, 0);
863
offset = fetch_long_imm();
864
DECODE_PRINTF2("[%08x]", offset);
867
DECODE_PRINTF("[ESI]");
870
DECODE_PRINTF("[EDI]");
875
/* 16-bit addressing */
878
DECODE_PRINTF("[BX+SI]");
879
return (M.x86.R_BX + M.x86.R_SI) & 0xffff;
881
DECODE_PRINTF("[BX+DI]");
882
return (M.x86.R_BX + M.x86.R_DI) & 0xffff;
884
DECODE_PRINTF("[BP+SI]");
885
M.x86.mode |= SYSMODE_SEG_DS_SS;
886
return (M.x86.R_BP + M.x86.R_SI) & 0xffff;
888
DECODE_PRINTF("[BP+DI]");
889
M.x86.mode |= SYSMODE_SEG_DS_SS;
890
return (M.x86.R_BP + M.x86.R_DI) & 0xffff;
892
DECODE_PRINTF("[SI]");
895
DECODE_PRINTF("[DI]");
898
offset = fetch_word_imm();
899
DECODE_PRINTF2("[%04x]", offset);
902
DECODE_PRINTF("[BX]");
910
/****************************************************************************
912
rm - RM value to decode
915
Offset in memory for the address decoding
918
Return the offset given by mod=01 addressing. Also enables the
919
decoding of instructions.
920
****************************************************************************/
921
u32 decode_rm01_address(
924
int displacement = 0;
927
/* Fetch disp8 if no SIB byte */
928
if (!((M.x86.mode & SYSMODE_PREFIX_ADDR) && (rm == 4)))
929
displacement = (s8)fetch_byte_imm();
931
if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
932
/* 32-bit addressing */
935
DECODE_PRINTF2("%d[EAX]", displacement);
936
return M.x86.R_EAX + displacement;
938
DECODE_PRINTF2("%d[ECX]", displacement);
939
return M.x86.R_ECX + displacement;
941
DECODE_PRINTF2("%d[EDX]", displacement);
942
return M.x86.R_EDX + displacement;
944
DECODE_PRINTF2("%d[EBX]", displacement);
945
return M.x86.R_EBX + displacement;
947
sib = fetch_byte_imm();
948
displacement = (s8)fetch_byte_imm();
949
DECODE_PRINTF2("%d", displacement);
950
return decode_sib_address(sib, 1) + displacement;
952
DECODE_PRINTF2("%d[EBP]", displacement);
953
return M.x86.R_EBP + displacement;
955
DECODE_PRINTF2("%d[ESI]", displacement);
956
return M.x86.R_ESI + displacement;
958
DECODE_PRINTF2("%d[EDI]", displacement);
959
return M.x86.R_EDI + displacement;
963
/* 16-bit addressing */
966
DECODE_PRINTF2("%d[BX+SI]", displacement);
967
return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
969
DECODE_PRINTF2("%d[BX+DI]", displacement);
970
return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
972
DECODE_PRINTF2("%d[BP+SI]", displacement);
973
M.x86.mode |= SYSMODE_SEG_DS_SS;
974
return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
976
DECODE_PRINTF2("%d[BP+DI]", displacement);
977
M.x86.mode |= SYSMODE_SEG_DS_SS;
978
return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
980
DECODE_PRINTF2("%d[SI]", displacement);
981
return (M.x86.R_SI + displacement) & 0xffff;
983
DECODE_PRINTF2("%d[DI]", displacement);
984
return (M.x86.R_DI + displacement) & 0xffff;
986
DECODE_PRINTF2("%d[BP]", displacement);
987
M.x86.mode |= SYSMODE_SEG_DS_SS;
988
return (M.x86.R_BP + displacement) & 0xffff;
990
DECODE_PRINTF2("%d[BX]", displacement);
991
return (M.x86.R_BX + displacement) & 0xffff;
995
return 0; /* SHOULD NOT HAPPEN */
998
/****************************************************************************
1000
rm - RM value to decode
1003
Offset in memory for the address decoding
1006
Return the offset given by mod=10 addressing. Also enables the
1007
decoding of instructions.
1008
****************************************************************************/
1009
u32 decode_rm10_address(
1012
u32 displacement = 0;
1015
/* Fetch disp16 if 16-bit addr mode */
1016
if (!(M.x86.mode & SYSMODE_PREFIX_ADDR))
1017
displacement = (u16)fetch_word_imm();
1019
/* Fetch disp32 if no SIB byte */
1021
displacement = (u32)fetch_long_imm();
1024
if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
1025
/* 32-bit addressing */
1028
DECODE_PRINTF2("%08x[EAX]", displacement);
1029
return M.x86.R_EAX + displacement;
1031
DECODE_PRINTF2("%08x[ECX]", displacement);
1032
return M.x86.R_ECX + displacement;
1034
DECODE_PRINTF2("%08x[EDX]", displacement);
1035
M.x86.mode |= SYSMODE_SEG_DS_SS;
1036
return M.x86.R_EDX + displacement;
1038
DECODE_PRINTF2("%08x[EBX]", displacement);
1039
return M.x86.R_EBX + displacement;
1041
sib = fetch_byte_imm();
1042
displacement = (u32)fetch_long_imm();
1043
DECODE_PRINTF2("%08x", displacement);
1044
return decode_sib_address(sib, 2) + displacement;
1047
DECODE_PRINTF2("%08x[EBP]", displacement);
1048
return M.x86.R_EBP + displacement;
1050
DECODE_PRINTF2("%08x[ESI]", displacement);
1051
return M.x86.R_ESI + displacement;
1053
DECODE_PRINTF2("%08x[EDI]", displacement);
1054
return M.x86.R_EDI + displacement;
1058
/* 16-bit addressing */
1061
DECODE_PRINTF2("%04x[BX+SI]", displacement);
1062
return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
1064
DECODE_PRINTF2("%04x[BX+DI]", displacement);
1065
return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
1067
DECODE_PRINTF2("%04x[BP+SI]", displacement);
1068
M.x86.mode |= SYSMODE_SEG_DS_SS;
1069
return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
1071
DECODE_PRINTF2("%04x[BP+DI]", displacement);
1072
M.x86.mode |= SYSMODE_SEG_DS_SS;
1073
return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
1075
DECODE_PRINTF2("%04x[SI]", displacement);
1076
return (M.x86.R_SI + displacement) & 0xffff;
1078
DECODE_PRINTF2("%04x[DI]", displacement);
1079
return (M.x86.R_DI + displacement) & 0xffff;
1081
DECODE_PRINTF2("%04x[BP]", displacement);
1082
M.x86.mode |= SYSMODE_SEG_DS_SS;
1083
return (M.x86.R_BP + displacement) & 0xffff;
1085
DECODE_PRINTF2("%04x[BX]", displacement);
1086
return (M.x86.R_BX + displacement) & 0xffff;