1*ece92f85SJason Jin /**************************************************************************** 2*ece92f85SJason Jin * 3*ece92f85SJason Jin * Realmode X86 Emulator Library 4*ece92f85SJason Jin * 5*ece92f85SJason Jin * Copyright (C) 1991-2004 SciTech Software, Inc. 6*ece92f85SJason Jin * Copyright (C) David Mosberger-Tang 7*ece92f85SJason Jin * Copyright (C) 1999 Egbert Eich 8*ece92f85SJason Jin * 9*ece92f85SJason Jin * ======================================================================== 10*ece92f85SJason Jin * 11*ece92f85SJason Jin * Permission to use, copy, modify, distribute, and sell this software and 12*ece92f85SJason Jin * its documentation for any purpose is hereby granted without fee, 13*ece92f85SJason Jin * provided that the above copyright notice appear in all copies and that 14*ece92f85SJason Jin * both that copyright notice and this permission notice appear in 15*ece92f85SJason Jin * supporting documentation, and that the name of the authors not be used 16*ece92f85SJason Jin * in advertising or publicity pertaining to distribution of the software 17*ece92f85SJason Jin * without specific, written prior permission. The authors makes no 18*ece92f85SJason Jin * representations about the suitability of this software for any purpose. 19*ece92f85SJason Jin * It is provided "as is" without express or implied warranty. 20*ece92f85SJason Jin * 21*ece92f85SJason Jin * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 22*ece92f85SJason Jin * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 23*ece92f85SJason Jin * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 24*ece92f85SJason Jin * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 25*ece92f85SJason Jin * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 26*ece92f85SJason Jin * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 27*ece92f85SJason Jin * PERFORMANCE OF THIS SOFTWARE. 28*ece92f85SJason Jin * 29*ece92f85SJason Jin * ======================================================================== 30*ece92f85SJason Jin * 31*ece92f85SJason Jin * Language: ANSI C 32*ece92f85SJason Jin * Environment: Any 33*ece92f85SJason Jin * Developer: Kendall Bennett 34*ece92f85SJason Jin * 35*ece92f85SJason Jin * Description: This file includes subroutines which are related to 36*ece92f85SJason Jin * instruction decoding and accessess of immediate data via IP. etc. 37*ece92f85SJason Jin * 38*ece92f85SJason Jin ****************************************************************************/ 39*ece92f85SJason Jin 40*ece92f85SJason Jin #include "x86emu/x86emui.h" 41*ece92f85SJason Jin 42*ece92f85SJason Jin /*----------------------------- Implementation ----------------------------*/ 43*ece92f85SJason Jin 44*ece92f85SJason Jin /**************************************************************************** 45*ece92f85SJason Jin REMARKS: 46*ece92f85SJason Jin Handles any pending asychronous interrupts. 47*ece92f85SJason Jin ****************************************************************************/ 48*ece92f85SJason Jin static void x86emu_intr_handle(void) 49*ece92f85SJason Jin { 50*ece92f85SJason Jin u8 intno; 51*ece92f85SJason Jin 52*ece92f85SJason Jin if (M.x86.intr & INTR_SYNCH) { 53*ece92f85SJason Jin intno = M.x86.intno; 54*ece92f85SJason Jin if (_X86EMU_intrTab[intno]) { 55*ece92f85SJason Jin (*_X86EMU_intrTab[intno])(intno); 56*ece92f85SJason Jin } else { 57*ece92f85SJason Jin push_word((u16)M.x86.R_FLG); 58*ece92f85SJason Jin CLEAR_FLAG(F_IF); 59*ece92f85SJason Jin CLEAR_FLAG(F_TF); 60*ece92f85SJason Jin push_word(M.x86.R_CS); 61*ece92f85SJason Jin M.x86.R_CS = mem_access_word(intno * 4 + 2); 62*ece92f85SJason Jin push_word(M.x86.R_IP); 63*ece92f85SJason Jin M.x86.R_IP = mem_access_word(intno * 4); 64*ece92f85SJason Jin M.x86.intr = 0; 65*ece92f85SJason Jin } 66*ece92f85SJason Jin } 67*ece92f85SJason Jin } 68*ece92f85SJason Jin 69*ece92f85SJason Jin /**************************************************************************** 70*ece92f85SJason Jin PARAMETERS: 71*ece92f85SJason Jin intrnum - Interrupt number to raise 72*ece92f85SJason Jin 73*ece92f85SJason Jin REMARKS: 74*ece92f85SJason Jin Raise the specified interrupt to be handled before the execution of the 75*ece92f85SJason Jin next instruction. 76*ece92f85SJason Jin ****************************************************************************/ 77*ece92f85SJason Jin void x86emu_intr_raise( 78*ece92f85SJason Jin u8 intrnum) 79*ece92f85SJason Jin { 80*ece92f85SJason Jin M.x86.intno = intrnum; 81*ece92f85SJason Jin M.x86.intr |= INTR_SYNCH; 82*ece92f85SJason Jin } 83*ece92f85SJason Jin 84*ece92f85SJason Jin /**************************************************************************** 85*ece92f85SJason Jin REMARKS: 86*ece92f85SJason Jin Main execution loop for the emulator. We return from here when the system 87*ece92f85SJason Jin halts, which is normally caused by a stack fault when we return from the 88*ece92f85SJason Jin original real mode call. 89*ece92f85SJason Jin ****************************************************************************/ 90*ece92f85SJason Jin void X86EMU_exec(void) 91*ece92f85SJason Jin { 92*ece92f85SJason Jin u8 op1; 93*ece92f85SJason Jin 94*ece92f85SJason Jin M.x86.intr = 0; 95*ece92f85SJason Jin DB(x86emu_end_instr();) 96*ece92f85SJason Jin 97*ece92f85SJason Jin for (;;) { 98*ece92f85SJason Jin DB( if (CHECK_IP_FETCH()) 99*ece92f85SJason Jin x86emu_check_ip_access();) 100*ece92f85SJason Jin /* If debugging, save the IP and CS values. */ 101*ece92f85SJason Jin SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP); 102*ece92f85SJason Jin INC_DECODED_INST_LEN(1); 103*ece92f85SJason Jin if (M.x86.intr) { 104*ece92f85SJason Jin if (M.x86.intr & INTR_HALTED) { 105*ece92f85SJason Jin DB( if (M.x86.R_SP != 0) { 106*ece92f85SJason Jin printk("halted\n"); 107*ece92f85SJason Jin X86EMU_trace_regs(); 108*ece92f85SJason Jin } 109*ece92f85SJason Jin else { 110*ece92f85SJason Jin if (M.x86.debug) 111*ece92f85SJason Jin printk("Service completed successfully\n"); 112*ece92f85SJason Jin }) 113*ece92f85SJason Jin return; 114*ece92f85SJason Jin } 115*ece92f85SJason Jin if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) || 116*ece92f85SJason Jin !ACCESS_FLAG(F_IF)) { 117*ece92f85SJason Jin x86emu_intr_handle(); 118*ece92f85SJason Jin } 119*ece92f85SJason Jin } 120*ece92f85SJason Jin op1 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); 121*ece92f85SJason Jin (*x86emu_optab[op1])(op1); 122*ece92f85SJason Jin if (M.x86.debug & DEBUG_EXIT) { 123*ece92f85SJason Jin M.x86.debug &= ~DEBUG_EXIT; 124*ece92f85SJason Jin return; 125*ece92f85SJason Jin } 126*ece92f85SJason Jin } 127*ece92f85SJason Jin } 128*ece92f85SJason Jin 129*ece92f85SJason Jin /**************************************************************************** 130*ece92f85SJason Jin REMARKS: 131*ece92f85SJason Jin Halts the system by setting the halted system flag. 132*ece92f85SJason Jin ****************************************************************************/ 133*ece92f85SJason Jin void X86EMU_halt_sys(void) 134*ece92f85SJason Jin { 135*ece92f85SJason Jin M.x86.intr |= INTR_HALTED; 136*ece92f85SJason Jin } 137*ece92f85SJason Jin 138*ece92f85SJason Jin /**************************************************************************** 139*ece92f85SJason Jin PARAMETERS: 140*ece92f85SJason Jin mod - Mod value from decoded byte 141*ece92f85SJason Jin regh - Reg h value from decoded byte 142*ece92f85SJason Jin regl - Reg l value from decoded byte 143*ece92f85SJason Jin 144*ece92f85SJason Jin REMARKS: 145*ece92f85SJason Jin Raise the specified interrupt to be handled before the execution of the 146*ece92f85SJason Jin next instruction. 147*ece92f85SJason Jin 148*ece92f85SJason Jin NOTE: Do not inline this function, as (*sys_rdb) is already inline! 149*ece92f85SJason Jin ****************************************************************************/ 150*ece92f85SJason Jin void fetch_decode_modrm( 151*ece92f85SJason Jin int *mod, 152*ece92f85SJason Jin int *regh, 153*ece92f85SJason Jin int *regl) 154*ece92f85SJason Jin { 155*ece92f85SJason Jin int fetched; 156*ece92f85SJason Jin 157*ece92f85SJason Jin DB( if (CHECK_IP_FETCH()) 158*ece92f85SJason Jin x86emu_check_ip_access();) 159*ece92f85SJason Jin fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); 160*ece92f85SJason Jin INC_DECODED_INST_LEN(1); 161*ece92f85SJason Jin *mod = (fetched >> 6) & 0x03; 162*ece92f85SJason Jin *regh = (fetched >> 3) & 0x07; 163*ece92f85SJason Jin *regl = (fetched >> 0) & 0x07; 164*ece92f85SJason Jin } 165*ece92f85SJason Jin 166*ece92f85SJason Jin /**************************************************************************** 167*ece92f85SJason Jin RETURNS: 168*ece92f85SJason Jin Immediate byte value read from instruction queue 169*ece92f85SJason Jin 170*ece92f85SJason Jin REMARKS: 171*ece92f85SJason Jin This function returns the immediate byte from the instruction queue, and 172*ece92f85SJason Jin moves the instruction pointer to the next value. 173*ece92f85SJason Jin 174*ece92f85SJason Jin NOTE: Do not inline this function, as (*sys_rdb) is already inline! 175*ece92f85SJason Jin ****************************************************************************/ 176*ece92f85SJason Jin u8 fetch_byte_imm(void) 177*ece92f85SJason Jin { 178*ece92f85SJason Jin u8 fetched; 179*ece92f85SJason Jin 180*ece92f85SJason Jin DB( if (CHECK_IP_FETCH()) 181*ece92f85SJason Jin x86emu_check_ip_access();) 182*ece92f85SJason Jin fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); 183*ece92f85SJason Jin INC_DECODED_INST_LEN(1); 184*ece92f85SJason Jin return fetched; 185*ece92f85SJason Jin } 186*ece92f85SJason Jin 187*ece92f85SJason Jin /**************************************************************************** 188*ece92f85SJason Jin RETURNS: 189*ece92f85SJason Jin Immediate word value read from instruction queue 190*ece92f85SJason Jin 191*ece92f85SJason Jin REMARKS: 192*ece92f85SJason Jin This function returns the immediate byte from the instruction queue, and 193*ece92f85SJason Jin moves the instruction pointer to the next value. 194*ece92f85SJason Jin 195*ece92f85SJason Jin NOTE: Do not inline this function, as (*sys_rdw) is already inline! 196*ece92f85SJason Jin ****************************************************************************/ 197*ece92f85SJason Jin u16 fetch_word_imm(void) 198*ece92f85SJason Jin { 199*ece92f85SJason Jin u16 fetched; 200*ece92f85SJason Jin 201*ece92f85SJason Jin DB( if (CHECK_IP_FETCH()) 202*ece92f85SJason Jin x86emu_check_ip_access();) 203*ece92f85SJason Jin fetched = (*sys_rdw)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP)); 204*ece92f85SJason Jin M.x86.R_IP += 2; 205*ece92f85SJason Jin INC_DECODED_INST_LEN(2); 206*ece92f85SJason Jin return fetched; 207*ece92f85SJason Jin } 208*ece92f85SJason Jin 209*ece92f85SJason Jin /**************************************************************************** 210*ece92f85SJason Jin RETURNS: 211*ece92f85SJason Jin Immediate lone value read from instruction queue 212*ece92f85SJason Jin 213*ece92f85SJason Jin REMARKS: 214*ece92f85SJason Jin This function returns the immediate byte from the instruction queue, and 215*ece92f85SJason Jin moves the instruction pointer to the next value. 216*ece92f85SJason Jin 217*ece92f85SJason Jin NOTE: Do not inline this function, as (*sys_rdw) is already inline! 218*ece92f85SJason Jin ****************************************************************************/ 219*ece92f85SJason Jin u32 fetch_long_imm(void) 220*ece92f85SJason Jin { 221*ece92f85SJason Jin u32 fetched; 222*ece92f85SJason Jin 223*ece92f85SJason Jin DB( if (CHECK_IP_FETCH()) 224*ece92f85SJason Jin x86emu_check_ip_access();) 225*ece92f85SJason Jin fetched = (*sys_rdl)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP)); 226*ece92f85SJason Jin M.x86.R_IP += 4; 227*ece92f85SJason Jin INC_DECODED_INST_LEN(4); 228*ece92f85SJason Jin return fetched; 229*ece92f85SJason Jin } 230*ece92f85SJason Jin 231*ece92f85SJason Jin /**************************************************************************** 232*ece92f85SJason Jin RETURNS: 233*ece92f85SJason Jin Value of the default data segment 234*ece92f85SJason Jin 235*ece92f85SJason Jin REMARKS: 236*ece92f85SJason Jin Inline function that returns the default data segment for the current 237*ece92f85SJason Jin instruction. 238*ece92f85SJason Jin 239*ece92f85SJason Jin On the x86 processor, the default segment is not always DS if there is 240*ece92f85SJason Jin no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to 241*ece92f85SJason Jin addresses relative to SS (ie: on the stack). So, at the minimum, all 242*ece92f85SJason Jin decodings of addressing modes would have to set/clear a bit describing 243*ece92f85SJason Jin whether the access is relative to DS or SS. That is the function of the 244*ece92f85SJason Jin cpu-state-varible M.x86.mode. There are several potential states: 245*ece92f85SJason Jin 246*ece92f85SJason Jin repe prefix seen (handled elsewhere) 247*ece92f85SJason Jin repne prefix seen (ditto) 248*ece92f85SJason Jin 249*ece92f85SJason Jin cs segment override 250*ece92f85SJason Jin ds segment override 251*ece92f85SJason Jin es segment override 252*ece92f85SJason Jin fs segment override 253*ece92f85SJason Jin gs segment override 254*ece92f85SJason Jin ss segment override 255*ece92f85SJason Jin 256*ece92f85SJason Jin ds/ss select (in absense of override) 257*ece92f85SJason Jin 258*ece92f85SJason Jin Each of the above 7 items are handled with a bit in the mode field. 259*ece92f85SJason Jin ****************************************************************************/ 260*ece92f85SJason Jin _INLINE u32 get_data_segment(void) 261*ece92f85SJason Jin { 262*ece92f85SJason Jin #define GET_SEGMENT(segment) 263*ece92f85SJason Jin switch (M.x86.mode & SYSMODE_SEGMASK) { 264*ece92f85SJason Jin case 0: /* default case: use ds register */ 265*ece92f85SJason Jin case SYSMODE_SEGOVR_DS: 266*ece92f85SJason Jin case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS: 267*ece92f85SJason Jin return M.x86.R_DS; 268*ece92f85SJason Jin case SYSMODE_SEG_DS_SS: /* non-overridden, use ss register */ 269*ece92f85SJason Jin return M.x86.R_SS; 270*ece92f85SJason Jin case SYSMODE_SEGOVR_CS: 271*ece92f85SJason Jin case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS: 272*ece92f85SJason Jin return M.x86.R_CS; 273*ece92f85SJason Jin case SYSMODE_SEGOVR_ES: 274*ece92f85SJason Jin case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS: 275*ece92f85SJason Jin return M.x86.R_ES; 276*ece92f85SJason Jin case SYSMODE_SEGOVR_FS: 277*ece92f85SJason Jin case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS: 278*ece92f85SJason Jin return M.x86.R_FS; 279*ece92f85SJason Jin case SYSMODE_SEGOVR_GS: 280*ece92f85SJason Jin case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS: 281*ece92f85SJason Jin return M.x86.R_GS; 282*ece92f85SJason Jin case SYSMODE_SEGOVR_SS: 283*ece92f85SJason Jin case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS: 284*ece92f85SJason Jin return M.x86.R_SS; 285*ece92f85SJason Jin default: 286*ece92f85SJason Jin #ifdef DEBUG 287*ece92f85SJason Jin printk("error: should not happen: multiple overrides.\n"); 288*ece92f85SJason Jin #endif 289*ece92f85SJason Jin HALT_SYS(); 290*ece92f85SJason Jin return 0; 291*ece92f85SJason Jin } 292*ece92f85SJason Jin } 293*ece92f85SJason Jin 294*ece92f85SJason Jin /**************************************************************************** 295*ece92f85SJason Jin PARAMETERS: 296*ece92f85SJason Jin offset - Offset to load data from 297*ece92f85SJason Jin 298*ece92f85SJason Jin RETURNS: 299*ece92f85SJason Jin Byte value read from the absolute memory location. 300*ece92f85SJason Jin 301*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_rdX) is already inline! 302*ece92f85SJason Jin ****************************************************************************/ 303*ece92f85SJason Jin u8 fetch_data_byte( 304*ece92f85SJason Jin uint offset) 305*ece92f85SJason Jin { 306*ece92f85SJason Jin #ifdef DEBUG 307*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 308*ece92f85SJason Jin x86emu_check_data_access((u16)get_data_segment(), offset); 309*ece92f85SJason Jin #endif 310*ece92f85SJason Jin return (*sys_rdb)((get_data_segment() << 4) + offset); 311*ece92f85SJason Jin } 312*ece92f85SJason Jin 313*ece92f85SJason Jin /**************************************************************************** 314*ece92f85SJason Jin PARAMETERS: 315*ece92f85SJason Jin offset - Offset to load data from 316*ece92f85SJason Jin 317*ece92f85SJason Jin RETURNS: 318*ece92f85SJason Jin Word value read from the absolute memory location. 319*ece92f85SJason Jin 320*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_rdX) is already inline! 321*ece92f85SJason Jin ****************************************************************************/ 322*ece92f85SJason Jin u16 fetch_data_word( 323*ece92f85SJason Jin uint offset) 324*ece92f85SJason Jin { 325*ece92f85SJason Jin #ifdef DEBUG 326*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 327*ece92f85SJason Jin x86emu_check_data_access((u16)get_data_segment(), offset); 328*ece92f85SJason Jin #endif 329*ece92f85SJason Jin return (*sys_rdw)((get_data_segment() << 4) + offset); 330*ece92f85SJason Jin } 331*ece92f85SJason Jin 332*ece92f85SJason Jin /**************************************************************************** 333*ece92f85SJason Jin PARAMETERS: 334*ece92f85SJason Jin offset - Offset to load data from 335*ece92f85SJason Jin 336*ece92f85SJason Jin RETURNS: 337*ece92f85SJason Jin Long value read from the absolute memory location. 338*ece92f85SJason Jin 339*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_rdX) is already inline! 340*ece92f85SJason Jin ****************************************************************************/ 341*ece92f85SJason Jin u32 fetch_data_long( 342*ece92f85SJason Jin uint offset) 343*ece92f85SJason Jin { 344*ece92f85SJason Jin #ifdef DEBUG 345*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 346*ece92f85SJason Jin x86emu_check_data_access((u16)get_data_segment(), offset); 347*ece92f85SJason Jin #endif 348*ece92f85SJason Jin return (*sys_rdl)((get_data_segment() << 4) + offset); 349*ece92f85SJason Jin } 350*ece92f85SJason Jin 351*ece92f85SJason Jin /**************************************************************************** 352*ece92f85SJason Jin PARAMETERS: 353*ece92f85SJason Jin segment - Segment to load data from 354*ece92f85SJason Jin offset - Offset to load data from 355*ece92f85SJason Jin 356*ece92f85SJason Jin RETURNS: 357*ece92f85SJason Jin Byte value read from the absolute memory location. 358*ece92f85SJason Jin 359*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_rdX) is already inline! 360*ece92f85SJason Jin ****************************************************************************/ 361*ece92f85SJason Jin u8 fetch_data_byte_abs( 362*ece92f85SJason Jin uint segment, 363*ece92f85SJason Jin uint offset) 364*ece92f85SJason Jin { 365*ece92f85SJason Jin #ifdef DEBUG 366*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 367*ece92f85SJason Jin x86emu_check_data_access(segment, offset); 368*ece92f85SJason Jin #endif 369*ece92f85SJason Jin return (*sys_rdb)(((u32)segment << 4) + offset); 370*ece92f85SJason Jin } 371*ece92f85SJason Jin 372*ece92f85SJason Jin /**************************************************************************** 373*ece92f85SJason Jin PARAMETERS: 374*ece92f85SJason Jin segment - Segment to load data from 375*ece92f85SJason Jin offset - Offset to load data from 376*ece92f85SJason Jin 377*ece92f85SJason Jin RETURNS: 378*ece92f85SJason Jin Word value read from the absolute memory location. 379*ece92f85SJason Jin 380*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_rdX) is already inline! 381*ece92f85SJason Jin ****************************************************************************/ 382*ece92f85SJason Jin u16 fetch_data_word_abs( 383*ece92f85SJason Jin uint segment, 384*ece92f85SJason Jin uint offset) 385*ece92f85SJason Jin { 386*ece92f85SJason Jin #ifdef DEBUG 387*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 388*ece92f85SJason Jin x86emu_check_data_access(segment, offset); 389*ece92f85SJason Jin #endif 390*ece92f85SJason Jin return (*sys_rdw)(((u32)segment << 4) + offset); 391*ece92f85SJason Jin } 392*ece92f85SJason Jin 393*ece92f85SJason Jin /**************************************************************************** 394*ece92f85SJason Jin PARAMETERS: 395*ece92f85SJason Jin segment - Segment to load data from 396*ece92f85SJason Jin offset - Offset to load data from 397*ece92f85SJason Jin 398*ece92f85SJason Jin RETURNS: 399*ece92f85SJason Jin Long value read from the absolute memory location. 400*ece92f85SJason Jin 401*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_rdX) is already inline! 402*ece92f85SJason Jin ****************************************************************************/ 403*ece92f85SJason Jin u32 fetch_data_long_abs( 404*ece92f85SJason Jin uint segment, 405*ece92f85SJason Jin uint offset) 406*ece92f85SJason Jin { 407*ece92f85SJason Jin #ifdef DEBUG 408*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 409*ece92f85SJason Jin x86emu_check_data_access(segment, offset); 410*ece92f85SJason Jin #endif 411*ece92f85SJason Jin return (*sys_rdl)(((u32)segment << 4) + offset); 412*ece92f85SJason Jin } 413*ece92f85SJason Jin 414*ece92f85SJason Jin /**************************************************************************** 415*ece92f85SJason Jin PARAMETERS: 416*ece92f85SJason Jin offset - Offset to store data at 417*ece92f85SJason Jin val - Value to store 418*ece92f85SJason Jin 419*ece92f85SJason Jin REMARKS: 420*ece92f85SJason Jin Writes a word value to an segmented memory location. The segment used is 421*ece92f85SJason Jin the current 'default' segment, which may have been overridden. 422*ece92f85SJason Jin 423*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_wrX) is already inline! 424*ece92f85SJason Jin ****************************************************************************/ 425*ece92f85SJason Jin void store_data_byte( 426*ece92f85SJason Jin uint offset, 427*ece92f85SJason Jin u8 val) 428*ece92f85SJason Jin { 429*ece92f85SJason Jin #ifdef DEBUG 430*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 431*ece92f85SJason Jin x86emu_check_data_access((u16)get_data_segment(), offset); 432*ece92f85SJason Jin #endif 433*ece92f85SJason Jin (*sys_wrb)((get_data_segment() << 4) + offset, val); 434*ece92f85SJason Jin } 435*ece92f85SJason Jin 436*ece92f85SJason Jin /**************************************************************************** 437*ece92f85SJason Jin PARAMETERS: 438*ece92f85SJason Jin offset - Offset to store data at 439*ece92f85SJason Jin val - Value to store 440*ece92f85SJason Jin 441*ece92f85SJason Jin REMARKS: 442*ece92f85SJason Jin Writes a word value to an segmented memory location. The segment used is 443*ece92f85SJason Jin the current 'default' segment, which may have been overridden. 444*ece92f85SJason Jin 445*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_wrX) is already inline! 446*ece92f85SJason Jin ****************************************************************************/ 447*ece92f85SJason Jin void store_data_word( 448*ece92f85SJason Jin uint offset, 449*ece92f85SJason Jin u16 val) 450*ece92f85SJason Jin { 451*ece92f85SJason Jin #ifdef DEBUG 452*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 453*ece92f85SJason Jin x86emu_check_data_access((u16)get_data_segment(), offset); 454*ece92f85SJason Jin #endif 455*ece92f85SJason Jin (*sys_wrw)((get_data_segment() << 4) + offset, val); 456*ece92f85SJason Jin } 457*ece92f85SJason Jin 458*ece92f85SJason Jin /**************************************************************************** 459*ece92f85SJason Jin PARAMETERS: 460*ece92f85SJason Jin offset - Offset to store data at 461*ece92f85SJason Jin val - Value to store 462*ece92f85SJason Jin 463*ece92f85SJason Jin REMARKS: 464*ece92f85SJason Jin Writes a long value to an segmented memory location. The segment used is 465*ece92f85SJason Jin the current 'default' segment, which may have been overridden. 466*ece92f85SJason Jin 467*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_wrX) is already inline! 468*ece92f85SJason Jin ****************************************************************************/ 469*ece92f85SJason Jin void store_data_long( 470*ece92f85SJason Jin uint offset, 471*ece92f85SJason Jin u32 val) 472*ece92f85SJason Jin { 473*ece92f85SJason Jin #ifdef DEBUG 474*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 475*ece92f85SJason Jin x86emu_check_data_access((u16)get_data_segment(), offset); 476*ece92f85SJason Jin #endif 477*ece92f85SJason Jin (*sys_wrl)((get_data_segment() << 4) + offset, val); 478*ece92f85SJason Jin } 479*ece92f85SJason Jin 480*ece92f85SJason Jin /**************************************************************************** 481*ece92f85SJason Jin PARAMETERS: 482*ece92f85SJason Jin segment - Segment to store data at 483*ece92f85SJason Jin offset - Offset to store data at 484*ece92f85SJason Jin val - Value to store 485*ece92f85SJason Jin 486*ece92f85SJason Jin REMARKS: 487*ece92f85SJason Jin Writes a byte value to an absolute memory location. 488*ece92f85SJason Jin 489*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_wrX) is already inline! 490*ece92f85SJason Jin ****************************************************************************/ 491*ece92f85SJason Jin void store_data_byte_abs( 492*ece92f85SJason Jin uint segment, 493*ece92f85SJason Jin uint offset, 494*ece92f85SJason Jin u8 val) 495*ece92f85SJason Jin { 496*ece92f85SJason Jin #ifdef DEBUG 497*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 498*ece92f85SJason Jin x86emu_check_data_access(segment, offset); 499*ece92f85SJason Jin #endif 500*ece92f85SJason Jin (*sys_wrb)(((u32)segment << 4) + offset, val); 501*ece92f85SJason Jin } 502*ece92f85SJason Jin 503*ece92f85SJason Jin /**************************************************************************** 504*ece92f85SJason Jin PARAMETERS: 505*ece92f85SJason Jin segment - Segment to store data at 506*ece92f85SJason Jin offset - Offset to store data at 507*ece92f85SJason Jin val - Value to store 508*ece92f85SJason Jin 509*ece92f85SJason Jin REMARKS: 510*ece92f85SJason Jin Writes a word value to an absolute memory location. 511*ece92f85SJason Jin 512*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_wrX) is already inline! 513*ece92f85SJason Jin ****************************************************************************/ 514*ece92f85SJason Jin void store_data_word_abs( 515*ece92f85SJason Jin uint segment, 516*ece92f85SJason Jin uint offset, 517*ece92f85SJason Jin u16 val) 518*ece92f85SJason Jin { 519*ece92f85SJason Jin #ifdef DEBUG 520*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 521*ece92f85SJason Jin x86emu_check_data_access(segment, offset); 522*ece92f85SJason Jin #endif 523*ece92f85SJason Jin (*sys_wrw)(((u32)segment << 4) + offset, val); 524*ece92f85SJason Jin } 525*ece92f85SJason Jin 526*ece92f85SJason Jin /**************************************************************************** 527*ece92f85SJason Jin PARAMETERS: 528*ece92f85SJason Jin segment - Segment to store data at 529*ece92f85SJason Jin offset - Offset to store data at 530*ece92f85SJason Jin val - Value to store 531*ece92f85SJason Jin 532*ece92f85SJason Jin REMARKS: 533*ece92f85SJason Jin Writes a long value to an absolute memory location. 534*ece92f85SJason Jin 535*ece92f85SJason Jin NOTE: Do not inline this function as (*sys_wrX) is already inline! 536*ece92f85SJason Jin ****************************************************************************/ 537*ece92f85SJason Jin void store_data_long_abs( 538*ece92f85SJason Jin uint segment, 539*ece92f85SJason Jin uint offset, 540*ece92f85SJason Jin u32 val) 541*ece92f85SJason Jin { 542*ece92f85SJason Jin #ifdef DEBUG 543*ece92f85SJason Jin if (CHECK_DATA_ACCESS()) 544*ece92f85SJason Jin x86emu_check_data_access(segment, offset); 545*ece92f85SJason Jin #endif 546*ece92f85SJason Jin (*sys_wrl)(((u32)segment << 4) + offset, val); 547*ece92f85SJason Jin } 548*ece92f85SJason Jin 549*ece92f85SJason Jin /**************************************************************************** 550*ece92f85SJason Jin PARAMETERS: 551*ece92f85SJason Jin reg - Register to decode 552*ece92f85SJason Jin 553*ece92f85SJason Jin RETURNS: 554*ece92f85SJason Jin Pointer to the appropriate register 555*ece92f85SJason Jin 556*ece92f85SJason Jin REMARKS: 557*ece92f85SJason Jin Return a pointer to the register given by the R/RM field of the 558*ece92f85SJason Jin modrm byte, for byte operands. Also enables the decoding of instructions. 559*ece92f85SJason Jin ****************************************************************************/ 560*ece92f85SJason Jin u8* decode_rm_byte_register( 561*ece92f85SJason Jin int reg) 562*ece92f85SJason Jin { 563*ece92f85SJason Jin switch (reg) { 564*ece92f85SJason Jin case 0: 565*ece92f85SJason Jin DECODE_PRINTF("AL"); 566*ece92f85SJason Jin return &M.x86.R_AL; 567*ece92f85SJason Jin case 1: 568*ece92f85SJason Jin DECODE_PRINTF("CL"); 569*ece92f85SJason Jin return &M.x86.R_CL; 570*ece92f85SJason Jin case 2: 571*ece92f85SJason Jin DECODE_PRINTF("DL"); 572*ece92f85SJason Jin return &M.x86.R_DL; 573*ece92f85SJason Jin case 3: 574*ece92f85SJason Jin DECODE_PRINTF("BL"); 575*ece92f85SJason Jin return &M.x86.R_BL; 576*ece92f85SJason Jin case 4: 577*ece92f85SJason Jin DECODE_PRINTF("AH"); 578*ece92f85SJason Jin return &M.x86.R_AH; 579*ece92f85SJason Jin case 5: 580*ece92f85SJason Jin DECODE_PRINTF("CH"); 581*ece92f85SJason Jin return &M.x86.R_CH; 582*ece92f85SJason Jin case 6: 583*ece92f85SJason Jin DECODE_PRINTF("DH"); 584*ece92f85SJason Jin return &M.x86.R_DH; 585*ece92f85SJason Jin case 7: 586*ece92f85SJason Jin DECODE_PRINTF("BH"); 587*ece92f85SJason Jin return &M.x86.R_BH; 588*ece92f85SJason Jin } 589*ece92f85SJason Jin HALT_SYS(); 590*ece92f85SJason Jin return NULL; /* NOT REACHED OR REACHED ON ERROR */ 591*ece92f85SJason Jin } 592*ece92f85SJason Jin 593*ece92f85SJason Jin /**************************************************************************** 594*ece92f85SJason Jin PARAMETERS: 595*ece92f85SJason Jin reg - Register to decode 596*ece92f85SJason Jin 597*ece92f85SJason Jin RETURNS: 598*ece92f85SJason Jin Pointer to the appropriate register 599*ece92f85SJason Jin 600*ece92f85SJason Jin REMARKS: 601*ece92f85SJason Jin Return a pointer to the register given by the R/RM field of the 602*ece92f85SJason Jin modrm byte, for word operands. Also enables the decoding of instructions. 603*ece92f85SJason Jin ****************************************************************************/ 604*ece92f85SJason Jin u16* decode_rm_word_register( 605*ece92f85SJason Jin int reg) 606*ece92f85SJason Jin { 607*ece92f85SJason Jin switch (reg) { 608*ece92f85SJason Jin case 0: 609*ece92f85SJason Jin DECODE_PRINTF("AX"); 610*ece92f85SJason Jin return &M.x86.R_AX; 611*ece92f85SJason Jin case 1: 612*ece92f85SJason Jin DECODE_PRINTF("CX"); 613*ece92f85SJason Jin return &M.x86.R_CX; 614*ece92f85SJason Jin case 2: 615*ece92f85SJason Jin DECODE_PRINTF("DX"); 616*ece92f85SJason Jin return &M.x86.R_DX; 617*ece92f85SJason Jin case 3: 618*ece92f85SJason Jin DECODE_PRINTF("BX"); 619*ece92f85SJason Jin return &M.x86.R_BX; 620*ece92f85SJason Jin case 4: 621*ece92f85SJason Jin DECODE_PRINTF("SP"); 622*ece92f85SJason Jin return &M.x86.R_SP; 623*ece92f85SJason Jin case 5: 624*ece92f85SJason Jin DECODE_PRINTF("BP"); 625*ece92f85SJason Jin return &M.x86.R_BP; 626*ece92f85SJason Jin case 6: 627*ece92f85SJason Jin DECODE_PRINTF("SI"); 628*ece92f85SJason Jin return &M.x86.R_SI; 629*ece92f85SJason Jin case 7: 630*ece92f85SJason Jin DECODE_PRINTF("DI"); 631*ece92f85SJason Jin return &M.x86.R_DI; 632*ece92f85SJason Jin } 633*ece92f85SJason Jin HALT_SYS(); 634*ece92f85SJason Jin return NULL; /* NOTREACHED OR REACHED ON ERROR */ 635*ece92f85SJason Jin } 636*ece92f85SJason Jin 637*ece92f85SJason Jin /**************************************************************************** 638*ece92f85SJason Jin PARAMETERS: 639*ece92f85SJason Jin reg - Register to decode 640*ece92f85SJason Jin 641*ece92f85SJason Jin RETURNS: 642*ece92f85SJason Jin Pointer to the appropriate register 643*ece92f85SJason Jin 644*ece92f85SJason Jin REMARKS: 645*ece92f85SJason Jin Return a pointer to the register given by the R/RM field of the 646*ece92f85SJason Jin modrm byte, for dword operands. Also enables the decoding of instructions. 647*ece92f85SJason Jin ****************************************************************************/ 648*ece92f85SJason Jin u32* decode_rm_long_register( 649*ece92f85SJason Jin int reg) 650*ece92f85SJason Jin { 651*ece92f85SJason Jin switch (reg) { 652*ece92f85SJason Jin case 0: 653*ece92f85SJason Jin DECODE_PRINTF("EAX"); 654*ece92f85SJason Jin return &M.x86.R_EAX; 655*ece92f85SJason Jin case 1: 656*ece92f85SJason Jin DECODE_PRINTF("ECX"); 657*ece92f85SJason Jin return &M.x86.R_ECX; 658*ece92f85SJason Jin case 2: 659*ece92f85SJason Jin DECODE_PRINTF("EDX"); 660*ece92f85SJason Jin return &M.x86.R_EDX; 661*ece92f85SJason Jin case 3: 662*ece92f85SJason Jin DECODE_PRINTF("EBX"); 663*ece92f85SJason Jin return &M.x86.R_EBX; 664*ece92f85SJason Jin case 4: 665*ece92f85SJason Jin DECODE_PRINTF("ESP"); 666*ece92f85SJason Jin return &M.x86.R_ESP; 667*ece92f85SJason Jin case 5: 668*ece92f85SJason Jin DECODE_PRINTF("EBP"); 669*ece92f85SJason Jin return &M.x86.R_EBP; 670*ece92f85SJason Jin case 6: 671*ece92f85SJason Jin DECODE_PRINTF("ESI"); 672*ece92f85SJason Jin return &M.x86.R_ESI; 673*ece92f85SJason Jin case 7: 674*ece92f85SJason Jin DECODE_PRINTF("EDI"); 675*ece92f85SJason Jin return &M.x86.R_EDI; 676*ece92f85SJason Jin } 677*ece92f85SJason Jin HALT_SYS(); 678*ece92f85SJason Jin return NULL; /* NOTREACHED OR REACHED ON ERROR */ 679*ece92f85SJason Jin } 680*ece92f85SJason Jin 681*ece92f85SJason Jin /**************************************************************************** 682*ece92f85SJason Jin PARAMETERS: 683*ece92f85SJason Jin reg - Register to decode 684*ece92f85SJason Jin 685*ece92f85SJason Jin RETURNS: 686*ece92f85SJason Jin Pointer to the appropriate register 687*ece92f85SJason Jin 688*ece92f85SJason Jin REMARKS: 689*ece92f85SJason Jin Return a pointer to the register given by the R/RM field of the 690*ece92f85SJason Jin modrm byte, for word operands, modified from above for the weirdo 691*ece92f85SJason Jin special case of segreg operands. Also enables the decoding of instructions. 692*ece92f85SJason Jin ****************************************************************************/ 693*ece92f85SJason Jin u16* decode_rm_seg_register( 694*ece92f85SJason Jin int reg) 695*ece92f85SJason Jin { 696*ece92f85SJason Jin switch (reg) { 697*ece92f85SJason Jin case 0: 698*ece92f85SJason Jin DECODE_PRINTF("ES"); 699*ece92f85SJason Jin return &M.x86.R_ES; 700*ece92f85SJason Jin case 1: 701*ece92f85SJason Jin DECODE_PRINTF("CS"); 702*ece92f85SJason Jin return &M.x86.R_CS; 703*ece92f85SJason Jin case 2: 704*ece92f85SJason Jin DECODE_PRINTF("SS"); 705*ece92f85SJason Jin return &M.x86.R_SS; 706*ece92f85SJason Jin case 3: 707*ece92f85SJason Jin DECODE_PRINTF("DS"); 708*ece92f85SJason Jin return &M.x86.R_DS; 709*ece92f85SJason Jin case 4: 710*ece92f85SJason Jin DECODE_PRINTF("FS"); 711*ece92f85SJason Jin return &M.x86.R_FS; 712*ece92f85SJason Jin case 5: 713*ece92f85SJason Jin DECODE_PRINTF("GS"); 714*ece92f85SJason Jin return &M.x86.R_GS; 715*ece92f85SJason Jin case 6: 716*ece92f85SJason Jin case 7: 717*ece92f85SJason Jin DECODE_PRINTF("ILLEGAL SEGREG"); 718*ece92f85SJason Jin break; 719*ece92f85SJason Jin } 720*ece92f85SJason Jin HALT_SYS(); 721*ece92f85SJason Jin return NULL; /* NOT REACHED OR REACHED ON ERROR */ 722*ece92f85SJason Jin } 723*ece92f85SJason Jin 724*ece92f85SJason Jin /**************************************************************************** 725*ece92f85SJason Jin PARAMETERS: 726*ece92f85SJason Jin scale - scale value of SIB byte 727*ece92f85SJason Jin index - index value of SIB byte 728*ece92f85SJason Jin 729*ece92f85SJason Jin RETURNS: 730*ece92f85SJason Jin Value of scale * index 731*ece92f85SJason Jin 732*ece92f85SJason Jin REMARKS: 733*ece92f85SJason Jin Decodes scale/index of SIB byte and returns relevant offset part of 734*ece92f85SJason Jin effective address. 735*ece92f85SJason Jin ****************************************************************************/ 736*ece92f85SJason Jin unsigned decode_sib_si( 737*ece92f85SJason Jin int scale, 738*ece92f85SJason Jin int index) 739*ece92f85SJason Jin { 740*ece92f85SJason Jin scale = 1 << scale; 741*ece92f85SJason Jin if (scale > 1) { 742*ece92f85SJason Jin DECODE_PRINTF2("[%d*", scale); 743*ece92f85SJason Jin } else { 744*ece92f85SJason Jin DECODE_PRINTF("["); 745*ece92f85SJason Jin } 746*ece92f85SJason Jin switch (index) { 747*ece92f85SJason Jin case 0: 748*ece92f85SJason Jin DECODE_PRINTF("EAX]"); 749*ece92f85SJason Jin return M.x86.R_EAX * index; 750*ece92f85SJason Jin case 1: 751*ece92f85SJason Jin DECODE_PRINTF("ECX]"); 752*ece92f85SJason Jin return M.x86.R_ECX * index; 753*ece92f85SJason Jin case 2: 754*ece92f85SJason Jin DECODE_PRINTF("EDX]"); 755*ece92f85SJason Jin return M.x86.R_EDX * index; 756*ece92f85SJason Jin case 3: 757*ece92f85SJason Jin DECODE_PRINTF("EBX]"); 758*ece92f85SJason Jin return M.x86.R_EBX * index; 759*ece92f85SJason Jin case 4: 760*ece92f85SJason Jin DECODE_PRINTF("0]"); 761*ece92f85SJason Jin return 0; 762*ece92f85SJason Jin case 5: 763*ece92f85SJason Jin DECODE_PRINTF("EBP]"); 764*ece92f85SJason Jin return M.x86.R_EBP * index; 765*ece92f85SJason Jin case 6: 766*ece92f85SJason Jin DECODE_PRINTF("ESI]"); 767*ece92f85SJason Jin return M.x86.R_ESI * index; 768*ece92f85SJason Jin case 7: 769*ece92f85SJason Jin DECODE_PRINTF("EDI]"); 770*ece92f85SJason Jin return M.x86.R_EDI * index; 771*ece92f85SJason Jin } 772*ece92f85SJason Jin HALT_SYS(); 773*ece92f85SJason Jin return 0; /* NOT REACHED OR REACHED ON ERROR */ 774*ece92f85SJason Jin } 775*ece92f85SJason Jin 776*ece92f85SJason Jin /**************************************************************************** 777*ece92f85SJason Jin PARAMETERS: 778*ece92f85SJason Jin mod - MOD value of preceding ModR/M byte 779*ece92f85SJason Jin 780*ece92f85SJason Jin RETURNS: 781*ece92f85SJason Jin Offset in memory for the address decoding 782*ece92f85SJason Jin 783*ece92f85SJason Jin REMARKS: 784*ece92f85SJason Jin Decodes SIB addressing byte and returns calculated effective address. 785*ece92f85SJason Jin ****************************************************************************/ 786*ece92f85SJason Jin unsigned decode_sib_address( 787*ece92f85SJason Jin int mod) 788*ece92f85SJason Jin { 789*ece92f85SJason Jin int sib = fetch_byte_imm(); 790*ece92f85SJason Jin int ss = (sib >> 6) & 0x03; 791*ece92f85SJason Jin int index = (sib >> 3) & 0x07; 792*ece92f85SJason Jin int base = sib & 0x07; 793*ece92f85SJason Jin int offset = 0; 794*ece92f85SJason Jin int displacement; 795*ece92f85SJason Jin 796*ece92f85SJason Jin switch (base) { 797*ece92f85SJason Jin case 0: 798*ece92f85SJason Jin DECODE_PRINTF("[EAX]"); 799*ece92f85SJason Jin offset = M.x86.R_EAX; 800*ece92f85SJason Jin break; 801*ece92f85SJason Jin case 1: 802*ece92f85SJason Jin DECODE_PRINTF("[ECX]"); 803*ece92f85SJason Jin offset = M.x86.R_ECX; 804*ece92f85SJason Jin break; 805*ece92f85SJason Jin case 2: 806*ece92f85SJason Jin DECODE_PRINTF("[EDX]"); 807*ece92f85SJason Jin offset = M.x86.R_EDX; 808*ece92f85SJason Jin break; 809*ece92f85SJason Jin case 3: 810*ece92f85SJason Jin DECODE_PRINTF("[EBX]"); 811*ece92f85SJason Jin offset = M.x86.R_EBX; 812*ece92f85SJason Jin break; 813*ece92f85SJason Jin case 4: 814*ece92f85SJason Jin DECODE_PRINTF("[ESP]"); 815*ece92f85SJason Jin offset = M.x86.R_ESP; 816*ece92f85SJason Jin break; 817*ece92f85SJason Jin case 5: 818*ece92f85SJason Jin switch (mod) { 819*ece92f85SJason Jin case 0: 820*ece92f85SJason Jin displacement = (s32)fetch_long_imm(); 821*ece92f85SJason Jin DECODE_PRINTF2("[%d]", displacement); 822*ece92f85SJason Jin offset = displacement; 823*ece92f85SJason Jin break; 824*ece92f85SJason Jin case 1: 825*ece92f85SJason Jin displacement = (s8)fetch_byte_imm(); 826*ece92f85SJason Jin DECODE_PRINTF2("[%d][EBP]", displacement); 827*ece92f85SJason Jin offset = M.x86.R_EBP + displacement; 828*ece92f85SJason Jin break; 829*ece92f85SJason Jin case 2: 830*ece92f85SJason Jin displacement = (s32)fetch_long_imm(); 831*ece92f85SJason Jin DECODE_PRINTF2("[%d][EBP]", displacement); 832*ece92f85SJason Jin offset = M.x86.R_EBP + displacement; 833*ece92f85SJason Jin break; 834*ece92f85SJason Jin default: 835*ece92f85SJason Jin HALT_SYS(); 836*ece92f85SJason Jin } 837*ece92f85SJason Jin DECODE_PRINTF("[EAX]"); 838*ece92f85SJason Jin offset = M.x86.R_EAX; 839*ece92f85SJason Jin break; 840*ece92f85SJason Jin case 6: 841*ece92f85SJason Jin DECODE_PRINTF("[ESI]"); 842*ece92f85SJason Jin offset = M.x86.R_ESI; 843*ece92f85SJason Jin break; 844*ece92f85SJason Jin case 7: 845*ece92f85SJason Jin DECODE_PRINTF("[EDI]"); 846*ece92f85SJason Jin offset = M.x86.R_EDI; 847*ece92f85SJason Jin break; 848*ece92f85SJason Jin default: 849*ece92f85SJason Jin HALT_SYS(); 850*ece92f85SJason Jin } 851*ece92f85SJason Jin offset += decode_sib_si(ss, index); 852*ece92f85SJason Jin return offset; 853*ece92f85SJason Jin 854*ece92f85SJason Jin } 855*ece92f85SJason Jin 856*ece92f85SJason Jin /**************************************************************************** 857*ece92f85SJason Jin PARAMETERS: 858*ece92f85SJason Jin rm - RM value to decode 859*ece92f85SJason Jin 860*ece92f85SJason Jin RETURNS: 861*ece92f85SJason Jin Offset in memory for the address decoding 862*ece92f85SJason Jin 863*ece92f85SJason Jin REMARKS: 864*ece92f85SJason Jin Return the offset given by mod=00 addressing. Also enables the 865*ece92f85SJason Jin decoding of instructions. 866*ece92f85SJason Jin 867*ece92f85SJason Jin NOTE: The code which specifies the corresponding segment (ds vs ss) 868*ece92f85SJason Jin below in the case of [BP+..]. The assumption here is that at the 869*ece92f85SJason Jin point that this subroutine is called, the bit corresponding to 870*ece92f85SJason Jin SYSMODE_SEG_DS_SS will be zero. After every instruction 871*ece92f85SJason Jin except the segment override instructions, this bit (as well 872*ece92f85SJason Jin as any bits indicating segment overrides) will be clear. So 873*ece92f85SJason Jin if a SS access is needed, set this bit. Otherwise, DS access 874*ece92f85SJason Jin occurs (unless any of the segment override bits are set). 875*ece92f85SJason Jin ****************************************************************************/ 876*ece92f85SJason Jin unsigned decode_rm00_address( 877*ece92f85SJason Jin int rm) 878*ece92f85SJason Jin { 879*ece92f85SJason Jin unsigned offset; 880*ece92f85SJason Jin 881*ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_ADDR) { 882*ece92f85SJason Jin /* 32-bit addressing */ 883*ece92f85SJason Jin switch (rm) { 884*ece92f85SJason Jin case 0: 885*ece92f85SJason Jin DECODE_PRINTF("[EAX]"); 886*ece92f85SJason Jin return M.x86.R_EAX; 887*ece92f85SJason Jin case 1: 888*ece92f85SJason Jin DECODE_PRINTF("[ECX]"); 889*ece92f85SJason Jin return M.x86.R_ECX; 890*ece92f85SJason Jin case 2: 891*ece92f85SJason Jin DECODE_PRINTF("[EDX]"); 892*ece92f85SJason Jin return M.x86.R_EDX; 893*ece92f85SJason Jin case 3: 894*ece92f85SJason Jin DECODE_PRINTF("[EBX]"); 895*ece92f85SJason Jin return M.x86.R_EBX; 896*ece92f85SJason Jin case 4: 897*ece92f85SJason Jin return decode_sib_address(0); 898*ece92f85SJason Jin case 5: 899*ece92f85SJason Jin offset = fetch_long_imm(); 900*ece92f85SJason Jin DECODE_PRINTF2("[%08x]", offset); 901*ece92f85SJason Jin return offset; 902*ece92f85SJason Jin case 6: 903*ece92f85SJason Jin DECODE_PRINTF("[ESI]"); 904*ece92f85SJason Jin return M.x86.R_ESI; 905*ece92f85SJason Jin case 7: 906*ece92f85SJason Jin DECODE_PRINTF("[EDI]"); 907*ece92f85SJason Jin return M.x86.R_EDI; 908*ece92f85SJason Jin } 909*ece92f85SJason Jin } else { 910*ece92f85SJason Jin /* 16-bit addressing */ 911*ece92f85SJason Jin switch (rm) { 912*ece92f85SJason Jin case 0: 913*ece92f85SJason Jin DECODE_PRINTF("[BX+SI]"); 914*ece92f85SJason Jin return (M.x86.R_BX + M.x86.R_SI) & 0xffff; 915*ece92f85SJason Jin case 1: 916*ece92f85SJason Jin DECODE_PRINTF("[BX+DI]"); 917*ece92f85SJason Jin return (M.x86.R_BX + M.x86.R_DI) & 0xffff; 918*ece92f85SJason Jin case 2: 919*ece92f85SJason Jin DECODE_PRINTF("[BP+SI]"); 920*ece92f85SJason Jin M.x86.mode |= SYSMODE_SEG_DS_SS; 921*ece92f85SJason Jin return (M.x86.R_BP + M.x86.R_SI) & 0xffff; 922*ece92f85SJason Jin case 3: 923*ece92f85SJason Jin DECODE_PRINTF("[BP+DI]"); 924*ece92f85SJason Jin M.x86.mode |= SYSMODE_SEG_DS_SS; 925*ece92f85SJason Jin return (M.x86.R_BP + M.x86.R_DI) & 0xffff; 926*ece92f85SJason Jin case 4: 927*ece92f85SJason Jin DECODE_PRINTF("[SI]"); 928*ece92f85SJason Jin return M.x86.R_SI; 929*ece92f85SJason Jin case 5: 930*ece92f85SJason Jin DECODE_PRINTF("[DI]"); 931*ece92f85SJason Jin return M.x86.R_DI; 932*ece92f85SJason Jin case 6: 933*ece92f85SJason Jin offset = fetch_word_imm(); 934*ece92f85SJason Jin DECODE_PRINTF2("[%04x]", offset); 935*ece92f85SJason Jin return offset; 936*ece92f85SJason Jin case 7: 937*ece92f85SJason Jin DECODE_PRINTF("[BX]"); 938*ece92f85SJason Jin return M.x86.R_BX; 939*ece92f85SJason Jin } 940*ece92f85SJason Jin } 941*ece92f85SJason Jin HALT_SYS(); 942*ece92f85SJason Jin return 0; 943*ece92f85SJason Jin } 944*ece92f85SJason Jin 945*ece92f85SJason Jin /**************************************************************************** 946*ece92f85SJason Jin PARAMETERS: 947*ece92f85SJason Jin rm - RM value to decode 948*ece92f85SJason Jin 949*ece92f85SJason Jin RETURNS: 950*ece92f85SJason Jin Offset in memory for the address decoding 951*ece92f85SJason Jin 952*ece92f85SJason Jin REMARKS: 953*ece92f85SJason Jin Return the offset given by mod=01 addressing. Also enables the 954*ece92f85SJason Jin decoding of instructions. 955*ece92f85SJason Jin ****************************************************************************/ 956*ece92f85SJason Jin unsigned decode_rm01_address( 957*ece92f85SJason Jin int rm) 958*ece92f85SJason Jin { 959*ece92f85SJason Jin int displacement; 960*ece92f85SJason Jin 961*ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_ADDR) { 962*ece92f85SJason Jin /* 32-bit addressing */ 963*ece92f85SJason Jin if (rm != 4) 964*ece92f85SJason Jin displacement = (s8)fetch_byte_imm(); 965*ece92f85SJason Jin else 966*ece92f85SJason Jin displacement = 0; 967*ece92f85SJason Jin 968*ece92f85SJason Jin switch (rm) { 969*ece92f85SJason Jin case 0: 970*ece92f85SJason Jin DECODE_PRINTF2("%d[EAX]", displacement); 971*ece92f85SJason Jin return M.x86.R_EAX + displacement; 972*ece92f85SJason Jin case 1: 973*ece92f85SJason Jin DECODE_PRINTF2("%d[ECX]", displacement); 974*ece92f85SJason Jin return M.x86.R_ECX + displacement; 975*ece92f85SJason Jin case 2: 976*ece92f85SJason Jin DECODE_PRINTF2("%d[EDX]", displacement); 977*ece92f85SJason Jin return M.x86.R_EDX + displacement; 978*ece92f85SJason Jin case 3: 979*ece92f85SJason Jin DECODE_PRINTF2("%d[EBX]", displacement); 980*ece92f85SJason Jin return M.x86.R_EBX + displacement; 981*ece92f85SJason Jin case 4: { 982*ece92f85SJason Jin int offset = decode_sib_address(1); 983*ece92f85SJason Jin displacement = (s8)fetch_byte_imm(); 984*ece92f85SJason Jin DECODE_PRINTF2("[%d]", displacement); 985*ece92f85SJason Jin return offset + displacement; 986*ece92f85SJason Jin } 987*ece92f85SJason Jin case 5: 988*ece92f85SJason Jin DECODE_PRINTF2("%d[EBP]", displacement); 989*ece92f85SJason Jin return M.x86.R_EBP + displacement; 990*ece92f85SJason Jin case 6: 991*ece92f85SJason Jin DECODE_PRINTF2("%d[ESI]", displacement); 992*ece92f85SJason Jin return M.x86.R_ESI + displacement; 993*ece92f85SJason Jin case 7: 994*ece92f85SJason Jin DECODE_PRINTF2("%d[EDI]", displacement); 995*ece92f85SJason Jin return M.x86.R_EDI + displacement; 996*ece92f85SJason Jin } 997*ece92f85SJason Jin } else { 998*ece92f85SJason Jin /* 16-bit addressing */ 999*ece92f85SJason Jin displacement = (s8)fetch_byte_imm(); 1000*ece92f85SJason Jin switch (rm) { 1001*ece92f85SJason Jin case 0: 1002*ece92f85SJason Jin DECODE_PRINTF2("%d[BX+SI]", displacement); 1003*ece92f85SJason Jin return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; 1004*ece92f85SJason Jin case 1: 1005*ece92f85SJason Jin DECODE_PRINTF2("%d[BX+DI]", displacement); 1006*ece92f85SJason Jin return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; 1007*ece92f85SJason Jin case 2: 1008*ece92f85SJason Jin DECODE_PRINTF2("%d[BP+SI]", displacement); 1009*ece92f85SJason Jin M.x86.mode |= SYSMODE_SEG_DS_SS; 1010*ece92f85SJason Jin return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; 1011*ece92f85SJason Jin case 3: 1012*ece92f85SJason Jin DECODE_PRINTF2("%d[BP+DI]", displacement); 1013*ece92f85SJason Jin M.x86.mode |= SYSMODE_SEG_DS_SS; 1014*ece92f85SJason Jin return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; 1015*ece92f85SJason Jin case 4: 1016*ece92f85SJason Jin DECODE_PRINTF2("%d[SI]", displacement); 1017*ece92f85SJason Jin return (M.x86.R_SI + displacement) & 0xffff; 1018*ece92f85SJason Jin case 5: 1019*ece92f85SJason Jin DECODE_PRINTF2("%d[DI]", displacement); 1020*ece92f85SJason Jin return (M.x86.R_DI + displacement) & 0xffff; 1021*ece92f85SJason Jin case 6: 1022*ece92f85SJason Jin DECODE_PRINTF2("%d[BP]", displacement); 1023*ece92f85SJason Jin M.x86.mode |= SYSMODE_SEG_DS_SS; 1024*ece92f85SJason Jin return (M.x86.R_BP + displacement) & 0xffff; 1025*ece92f85SJason Jin case 7: 1026*ece92f85SJason Jin DECODE_PRINTF2("%d[BX]", displacement); 1027*ece92f85SJason Jin return (M.x86.R_BX + displacement) & 0xffff; 1028*ece92f85SJason Jin } 1029*ece92f85SJason Jin } 1030*ece92f85SJason Jin HALT_SYS(); 1031*ece92f85SJason Jin return 0; /* SHOULD NOT HAPPEN */ 1032*ece92f85SJason Jin } 1033*ece92f85SJason Jin 1034*ece92f85SJason Jin /**************************************************************************** 1035*ece92f85SJason Jin PARAMETERS: 1036*ece92f85SJason Jin rm - RM value to decode 1037*ece92f85SJason Jin 1038*ece92f85SJason Jin RETURNS: 1039*ece92f85SJason Jin Offset in memory for the address decoding 1040*ece92f85SJason Jin 1041*ece92f85SJason Jin REMARKS: 1042*ece92f85SJason Jin Return the offset given by mod=10 addressing. Also enables the 1043*ece92f85SJason Jin decoding of instructions. 1044*ece92f85SJason Jin ****************************************************************************/ 1045*ece92f85SJason Jin unsigned decode_rm10_address( 1046*ece92f85SJason Jin int rm) 1047*ece92f85SJason Jin { 1048*ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_ADDR) { 1049*ece92f85SJason Jin int displacement; 1050*ece92f85SJason Jin 1051*ece92f85SJason Jin /* 32-bit addressing */ 1052*ece92f85SJason Jin if (rm != 4) 1053*ece92f85SJason Jin displacement = (s32)fetch_long_imm(); 1054*ece92f85SJason Jin else 1055*ece92f85SJason Jin displacement = 0; 1056*ece92f85SJason Jin 1057*ece92f85SJason Jin switch (rm) { 1058*ece92f85SJason Jin case 0: 1059*ece92f85SJason Jin DECODE_PRINTF2("%d[EAX]", displacement); 1060*ece92f85SJason Jin return M.x86.R_EAX + displacement; 1061*ece92f85SJason Jin case 1: 1062*ece92f85SJason Jin DECODE_PRINTF2("%d[ECX]", displacement); 1063*ece92f85SJason Jin return M.x86.R_ECX + displacement; 1064*ece92f85SJason Jin case 2: 1065*ece92f85SJason Jin DECODE_PRINTF2("%d[EDX]", displacement); 1066*ece92f85SJason Jin return M.x86.R_EDX + displacement; 1067*ece92f85SJason Jin case 3: 1068*ece92f85SJason Jin DECODE_PRINTF2("%d[EBX]", displacement); 1069*ece92f85SJason Jin return M.x86.R_EBX + displacement; 1070*ece92f85SJason Jin case 4: { 1071*ece92f85SJason Jin int offset = decode_sib_address(2); 1072*ece92f85SJason Jin displacement = (s32)fetch_long_imm(); 1073*ece92f85SJason Jin DECODE_PRINTF2("[%d]", displacement); 1074*ece92f85SJason Jin return offset + displacement; 1075*ece92f85SJason Jin } 1076*ece92f85SJason Jin case 5: 1077*ece92f85SJason Jin DECODE_PRINTF2("%d[EBP]", displacement); 1078*ece92f85SJason Jin return M.x86.R_EBP + displacement; 1079*ece92f85SJason Jin case 6: 1080*ece92f85SJason Jin DECODE_PRINTF2("%d[ESI]", displacement); 1081*ece92f85SJason Jin return M.x86.R_ESI + displacement; 1082*ece92f85SJason Jin case 7: 1083*ece92f85SJason Jin DECODE_PRINTF2("%d[EDI]", displacement); 1084*ece92f85SJason Jin return M.x86.R_EDI + displacement; 1085*ece92f85SJason Jin } 1086*ece92f85SJason Jin } else { 1087*ece92f85SJason Jin int displacement = (s16)fetch_word_imm(); 1088*ece92f85SJason Jin 1089*ece92f85SJason Jin /* 16-bit addressing */ 1090*ece92f85SJason Jin switch (rm) { 1091*ece92f85SJason Jin case 0: 1092*ece92f85SJason Jin DECODE_PRINTF2("%d[BX+SI]", displacement); 1093*ece92f85SJason Jin return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; 1094*ece92f85SJason Jin case 1: 1095*ece92f85SJason Jin DECODE_PRINTF2("%d[BX+DI]", displacement); 1096*ece92f85SJason Jin return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; 1097*ece92f85SJason Jin case 2: 1098*ece92f85SJason Jin DECODE_PRINTF2("%d[BP+SI]", displacement); 1099*ece92f85SJason Jin M.x86.mode |= SYSMODE_SEG_DS_SS; 1100*ece92f85SJason Jin return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; 1101*ece92f85SJason Jin case 3: 1102*ece92f85SJason Jin DECODE_PRINTF2("%d[BP+DI]", displacement); 1103*ece92f85SJason Jin M.x86.mode |= SYSMODE_SEG_DS_SS; 1104*ece92f85SJason Jin return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; 1105*ece92f85SJason Jin case 4: 1106*ece92f85SJason Jin DECODE_PRINTF2("%d[SI]", displacement); 1107*ece92f85SJason Jin return (M.x86.R_SI + displacement) & 0xffff; 1108*ece92f85SJason Jin case 5: 1109*ece92f85SJason Jin DECODE_PRINTF2("%d[DI]", displacement); 1110*ece92f85SJason Jin return (M.x86.R_DI + displacement) & 0xffff; 1111*ece92f85SJason Jin case 6: 1112*ece92f85SJason Jin DECODE_PRINTF2("%d[BP]", displacement); 1113*ece92f85SJason Jin M.x86.mode |= SYSMODE_SEG_DS_SS; 1114*ece92f85SJason Jin return (M.x86.R_BP + displacement) & 0xffff; 1115*ece92f85SJason Jin case 7: 1116*ece92f85SJason Jin DECODE_PRINTF2("%d[BX]", displacement); 1117*ece92f85SJason Jin return (M.x86.R_BX + displacement) & 0xffff; 1118*ece92f85SJason Jin } 1119*ece92f85SJason Jin } 1120*ece92f85SJason Jin HALT_SYS(); 1121*ece92f85SJason Jin return 0; /* SHOULD NOT HAPPEN */ 1122*ece92f85SJason Jin } 1123*ece92f85SJason Jin 1124*ece92f85SJason Jin 1125*ece92f85SJason Jin /**************************************************************************** 1126*ece92f85SJason Jin PARAMETERS: 1127*ece92f85SJason Jin mod - modifier 1128*ece92f85SJason Jin rm - RM value to decode 1129*ece92f85SJason Jin 1130*ece92f85SJason Jin RETURNS: 1131*ece92f85SJason Jin Offset in memory for the address decoding, multiplexing calls to 1132*ece92f85SJason Jin the decode_rmXX_address functions 1133*ece92f85SJason Jin 1134*ece92f85SJason Jin REMARKS: 1135*ece92f85SJason Jin Return the offset given by "mod" addressing. 1136*ece92f85SJason Jin ****************************************************************************/ 1137*ece92f85SJason Jin 1138*ece92f85SJason Jin unsigned decode_rmXX_address(int mod, int rm) 1139*ece92f85SJason Jin { 1140*ece92f85SJason Jin if(mod == 0) 1141*ece92f85SJason Jin return decode_rm00_address(rm); 1142*ece92f85SJason Jin if(mod == 1) 1143*ece92f85SJason Jin return decode_rm01_address(rm); 1144*ece92f85SJason Jin return decode_rm10_address(rm); 1145*ece92f85SJason Jin } 1146*ece92f85SJason Jin 1147*ece92f85SJason Jin 1148*ece92f85SJason Jin 1149