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