diff options
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/x86emu/decode.c')
| -rw-r--r-- | board/MAI/bios_emulator/scitech/src/x86emu/decode.c | 970 | 
1 files changed, 0 insertions, 970 deletions
| diff --git a/board/MAI/bios_emulator/scitech/src/x86emu/decode.c b/board/MAI/bios_emulator/scitech/src/x86emu/decode.c deleted file mode 100644 index 832b1f5f2..000000000 --- a/board/MAI/bios_emulator/scitech/src/x86emu/decode.c +++ /dev/null @@ -1,970 +0,0 @@ -/**************************************************************************** -* -*						Realmode X86 Emulator Library -* -*            	Copyright (C) 1996-1999 SciTech Software, Inc. -* 				     Copyright (C) David Mosberger-Tang -* 					   Copyright (C) 1999 Egbert Eich -* -*  ======================================================================== -* -*  Permission to use, copy, modify, distribute, and sell this software and -*  its documentation for any purpose is hereby granted without fee, -*  provided that the above copyright notice appear in all copies and that -*  both that copyright notice and this permission notice appear in -*  supporting documentation, and that the name of the authors not be used -*  in advertising or publicity pertaining to distribution of the software -*  without specific, written prior permission.  The authors makes no -*  representations about the suitability of this software for any purpose. -*  It is provided "as is" without express or implied warranty. -* -*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF -*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -*  PERFORMANCE OF THIS SOFTWARE. -* -*  ======================================================================== -* -* Language:		ANSI C -* Environment:	Any -* Developer:    Kendall Bennett -* -* Description:  This file includes subroutines which are related to -*				instruction decoding and accessess of immediate data via IP.  etc. -* -****************************************************************************/ - -#include "x86emu/x86emui.h" - -/*----------------------------- Implementation ----------------------------*/ - -/**************************************************************************** -REMARKS: -Handles any pending asychronous interrupts. -****************************************************************************/ -static void x86emu_intr_handle(void) -{ -	u8	intno; - -	if (M.x86.intr & INTR_SYNCH) { -		intno = M.x86.intno; -		if (_X86EMU_intrTab[intno]) { -			(*_X86EMU_intrTab[intno])(intno); -		} else { -			push_word((u16)M.x86.R_FLG); -			CLEAR_FLAG(F_IF); -			CLEAR_FLAG(F_TF); -			push_word(M.x86.R_CS); -			M.x86.R_CS = mem_access_word(intno * 4 + 2); -			push_word(M.x86.R_IP); -			M.x86.R_IP = mem_access_word(intno * 4); -			M.x86.intr = 0; -		} -	} -} - -/**************************************************************************** -PARAMETERS: -intrnum - Interrupt number to raise - -REMARKS: -Raise the specified interrupt to be handled before the execution of the -next instruction. -****************************************************************************/ -void x86emu_intr_raise( -	u8 intrnum) -{ -	M.x86.intno = intrnum; -	M.x86.intr |= INTR_SYNCH; -} - -/**************************************************************************** -REMARKS: -Main execution loop for the emulator. We return from here when the system -halts, which is normally caused by a stack fault when we return from the -original real mode call. -****************************************************************************/ -void X86EMU_exec(void) -{ -    u8 op1; - -    M.x86.intr = 0; -    DB(x86emu_end_instr();) - -    for (;;) { -	DB(if (CHECK_IP_FETCH()) x86emu_check_ip_access();) -	/* If debugging, save the IP and CS values. */ -	SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP); -	INC_DECODED_INST_LEN(1); -	if (M.x86.intr) { -	    if (M.x86.intr & INTR_HALTED) { -		DB(	printk("halted\n"); X86EMU_trace_regs();) -		    return; -	    } -	    if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) || -		!ACCESS_FLAG(F_IF)) { -		x86emu_intr_handle(); -	    } -	} -	op1 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); -	(*x86emu_optab[op1])(op1); -	if (M.x86.debug & DEBUG_EXIT) { -	    M.x86.debug &= ~DEBUG_EXIT; -	    return; -	} -    } -} - -/**************************************************************************** -REMARKS: -Halts the system by setting the halted system flag. -****************************************************************************/ -void X86EMU_halt_sys(void) -{ -	M.x86.intr |= INTR_HALTED; -} - -/**************************************************************************** -PARAMETERS: -mod		- Mod value from decoded byte -regh	- Reg h value from decoded byte -regl	- Reg l value from decoded byte - -REMARKS: -Raise the specified interrupt to be handled before the execution of the -next instruction. - -NOTE: Do not inline this function, as (*sys_rdb) is already inline! -****************************************************************************/ -void fetch_decode_modrm( -	int *mod, -	int *regh, -	int *regl) -{ -	int fetched; - -DB(	if (CHECK_IP_FETCH()) -	  x86emu_check_ip_access();) -	fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); -	INC_DECODED_INST_LEN(1); -	*mod  = (fetched >> 6) & 0x03; -	*regh = (fetched >> 3) & 0x07; -    *regl = (fetched >> 0) & 0x07; -} - -/**************************************************************************** -RETURNS: -Immediate byte value read from instruction queue - -REMARKS: -This function returns the immediate byte from the instruction queue, and -moves the instruction pointer to the next value. - -NOTE: Do not inline this function, as (*sys_rdb) is already inline! -****************************************************************************/ -u8 fetch_byte_imm(void) -{ -	u8 fetched; - -DB(	if (CHECK_IP_FETCH()) -		x86emu_check_ip_access();) -	fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); -	INC_DECODED_INST_LEN(1); -	return fetched; -} - -/**************************************************************************** -RETURNS: -Immediate word value read from instruction queue - -REMARKS: -This function returns the immediate byte from the instruction queue, and -moves the instruction pointer to the next value. - -NOTE: Do not inline this function, as (*sys_rdw) is already inline! -****************************************************************************/ -u16 fetch_word_imm(void) -{ -	u16	fetched; - -DB(	if (CHECK_IP_FETCH()) -		x86emu_check_ip_access();) -	fetched = (*sys_rdw)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP)); -	M.x86.R_IP += 2; -	INC_DECODED_INST_LEN(2); -	return fetched; -} - -/**************************************************************************** -RETURNS: -Immediate lone value read from instruction queue - -REMARKS: -This function returns the immediate byte from the instruction queue, and -moves the instruction pointer to the next value. - -NOTE: Do not inline this function, as (*sys_rdw) is already inline! -****************************************************************************/ -u32 fetch_long_imm(void) -{ -	u32 fetched; - -DB(	if (CHECK_IP_FETCH()) -	  x86emu_check_ip_access();) -	fetched = (*sys_rdl)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP)); -	M.x86.R_IP += 4; -	INC_DECODED_INST_LEN(4); -	return fetched; -} - -/**************************************************************************** -RETURNS: -Value of the default data segment - -REMARKS: -Inline function that returns the default data segment for the current -instruction. - -On the x86 processor, the default segment is not always DS if there is -no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to -addresses relative to SS (ie: on the stack). So, at the minimum, all -decodings of addressing modes would have to set/clear a bit describing -whether the access is relative to DS or SS.  That is the function of the -cpu-state-varible M.x86.mode. There are several potential states: - -	repe prefix seen  (handled elsewhere) -	repne prefix seen  (ditto) - -	cs segment override -	ds segment override -	es segment override -	fs segment override -	gs segment override -	ss segment override - -	ds/ss select (in absense of override) - -Each of the above 7 items are handled with a bit in the mode field. -****************************************************************************/ -_INLINE u32 get_data_segment(void) -{ -#define	GET_SEGMENT(segment) -	switch (M.x86.mode & SYSMODE_SEGMASK) { -	  case 0:					/* default case: use ds register */ -	  case SYSMODE_SEGOVR_DS: -	  case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS: -		return  M.x86.R_DS; -	  case SYSMODE_SEG_DS_SS:	/* non-overridden, use ss register */ -		return  M.x86.R_SS; -	  case SYSMODE_SEGOVR_CS: -	  case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS: -		return  M.x86.R_CS; -	  case SYSMODE_SEGOVR_ES: -	  case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS: -		return  M.x86.R_ES; -	  case SYSMODE_SEGOVR_FS: -	  case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS: -		return  M.x86.R_FS; -	  case SYSMODE_SEGOVR_GS: -	  case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS: -		return  M.x86.R_GS; -	  case SYSMODE_SEGOVR_SS: -	  case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS: -		return  M.x86.R_SS; -	  default: -#ifdef	DEBUG -		printk("error: should not happen:  multiple overrides.\n"); -#endif -		HALT_SYS(); -		return 0; -	} -} - -/**************************************************************************** -PARAMETERS: -offset	- Offset to load data from - -RETURNS: -Byte value read from the absolute memory location. - -NOTE: Do not inline this function as (*sys_rdX) is already inline! -****************************************************************************/ -u8 fetch_data_byte( -	uint offset) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access((u16)get_data_segment(), offset); -#endif -	return (*sys_rdb)((get_data_segment() << 4) + offset); -} - -/**************************************************************************** -PARAMETERS: -offset	- Offset to load data from - -RETURNS: -Word value read from the absolute memory location. - -NOTE: Do not inline this function as (*sys_rdX) is already inline! -****************************************************************************/ -u16 fetch_data_word( -	uint offset) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access((u16)get_data_segment(), offset); -#endif -	return (*sys_rdw)((get_data_segment() << 4) + offset); -} - -/**************************************************************************** -PARAMETERS: -offset	- Offset to load data from - -RETURNS: -Long value read from the absolute memory location. - -NOTE: Do not inline this function as (*sys_rdX) is already inline! -****************************************************************************/ -u32 fetch_data_long( -	uint offset) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access((u16)get_data_segment(), offset); -#endif -	return (*sys_rdl)((get_data_segment() << 4) + offset); -} - -/**************************************************************************** -PARAMETERS: -segment	- Segment to load data from -offset	- Offset to load data from - -RETURNS: -Byte value read from the absolute memory location. - -NOTE: Do not inline this function as (*sys_rdX) is already inline! -****************************************************************************/ -u8 fetch_data_byte_abs( -	uint segment, -	uint offset) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access(segment, offset); -#endif -	return (*sys_rdb)(((u32)segment << 4) + offset); -} - -/**************************************************************************** -PARAMETERS: -segment	- Segment to load data from -offset	- Offset to load data from - -RETURNS: -Word value read from the absolute memory location. - -NOTE: Do not inline this function as (*sys_rdX) is already inline! -****************************************************************************/ -u16 fetch_data_word_abs( -	uint segment, -	uint offset) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access(segment, offset); -#endif -	return (*sys_rdw)(((u32)segment << 4) + offset); -} - -/**************************************************************************** -PARAMETERS: -segment	- Segment to load data from -offset	- Offset to load data from - -RETURNS: -Long value read from the absolute memory location. - -NOTE: Do not inline this function as (*sys_rdX) is already inline! -****************************************************************************/ -u32 fetch_data_long_abs( -	uint segment, -	uint offset) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access(segment, offset); -#endif -	return (*sys_rdl)(((u32)segment << 4) + offset); -} - -/**************************************************************************** -PARAMETERS: -offset	- Offset to store data at -val		- Value to store - -REMARKS: -Writes a word value to an segmented memory location. The segment used is -the current 'default' segment, which may have been overridden. - -NOTE: Do not inline this function as (*sys_wrX) is already inline! -****************************************************************************/ -void store_data_byte( -	uint offset, -	u8 val) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access((u16)get_data_segment(), offset); -#endif -	(*sys_wrb)((get_data_segment() << 4) + offset, val); -} - -/**************************************************************************** -PARAMETERS: -offset	- Offset to store data at -val		- Value to store - -REMARKS: -Writes a word value to an segmented memory location. The segment used is -the current 'default' segment, which may have been overridden. - -NOTE: Do not inline this function as (*sys_wrX) is already inline! -****************************************************************************/ -void store_data_word( -	uint offset, -	u16 val) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access((u16)get_data_segment(), offset); -#endif -	(*sys_wrw)((get_data_segment() << 4) + offset, val); -} - -/**************************************************************************** -PARAMETERS: -offset	- Offset to store data at -val		- Value to store - -REMARKS: -Writes a long value to an segmented memory location. The segment used is -the current 'default' segment, which may have been overridden. - -NOTE: Do not inline this function as (*sys_wrX) is already inline! -****************************************************************************/ -void store_data_long( -	uint offset, -	u32 val) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access((u16)get_data_segment(), offset); -#endif -	(*sys_wrl)((get_data_segment() << 4) + offset, val); -} - -/**************************************************************************** -PARAMETERS: -segment	- Segment to store data at -offset	- Offset to store data at -val		- Value to store - -REMARKS: -Writes a byte value to an absolute memory location. - -NOTE: Do not inline this function as (*sys_wrX) is already inline! -****************************************************************************/ -void store_data_byte_abs( -	uint segment, -	uint offset, -	u8 val) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access(segment, offset); -#endif -	(*sys_wrb)(((u32)segment << 4) + offset, val); -} - -/**************************************************************************** -PARAMETERS: -segment	- Segment to store data at -offset	- Offset to store data at -val		- Value to store - -REMARKS: -Writes a word value to an absolute memory location. - -NOTE: Do not inline this function as (*sys_wrX) is already inline! -****************************************************************************/ -void store_data_word_abs( -	uint segment, -	uint offset, -	u16 val) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access(segment, offset); -#endif -	(*sys_wrw)(((u32)segment << 4) + offset, val); -} - -/**************************************************************************** -PARAMETERS: -segment	- Segment to store data at -offset	- Offset to store data at -val		- Value to store - -REMARKS: -Writes a long value to an absolute memory location. - -NOTE: Do not inline this function as (*sys_wrX) is already inline! -****************************************************************************/ -void store_data_long_abs( -	uint segment, -	uint offset, -	u32 val) -{ -#ifdef DEBUG -	if (CHECK_DATA_ACCESS()) -		x86emu_check_data_access(segment, offset); -#endif -	(*sys_wrl)(((u32)segment << 4) + offset, val); -} - -/**************************************************************************** -PARAMETERS: -reg	- Register to decode - -RETURNS: -Pointer to the appropriate register - -REMARKS: -Return a pointer to the register given by the R/RM field of the -modrm byte, for byte operands. Also enables the decoding of instructions. -****************************************************************************/ -u8* decode_rm_byte_register( -	int reg) -{ -	switch (reg) { -      case 0: -		DECODE_PRINTF("AL"); -		return &M.x86.R_AL; -	  case 1: -		DECODE_PRINTF("CL"); -		return &M.x86.R_CL; -	  case 2: -		DECODE_PRINTF("DL"); -		return &M.x86.R_DL; -	  case 3: -		DECODE_PRINTF("BL"); -		return &M.x86.R_BL; -	  case 4: -		DECODE_PRINTF("AH"); -		return &M.x86.R_AH; -	  case 5: -		DECODE_PRINTF("CH"); -		return &M.x86.R_CH; -	  case 6: -		DECODE_PRINTF("DH"); -		return &M.x86.R_DH; -	  case 7: -		DECODE_PRINTF("BH"); -		return &M.x86.R_BH; -	} -	HALT_SYS(); -	return NULL;                /* NOT REACHED OR REACHED ON ERROR */ -} - -/**************************************************************************** -PARAMETERS: -reg	- Register to decode - -RETURNS: -Pointer to the appropriate register - -REMARKS: -Return a pointer to the register given by the R/RM field of the -modrm byte, for word operands.  Also enables the decoding of instructions. -****************************************************************************/ -u16* decode_rm_word_register( -	int reg) -{ -	switch (reg) { -	  case 0: -		DECODE_PRINTF("AX"); -		return &M.x86.R_AX; -	  case 1: -		DECODE_PRINTF("CX"); -		return &M.x86.R_CX; -	  case 2: -		DECODE_PRINTF("DX"); -		return &M.x86.R_DX; -	  case 3: -		DECODE_PRINTF("BX"); -		return &M.x86.R_BX; -	  case 4: -		DECODE_PRINTF("SP"); -		return &M.x86.R_SP; -	  case 5: -		DECODE_PRINTF("BP"); -		return &M.x86.R_BP; -	  case 6: -		DECODE_PRINTF("SI"); -		return &M.x86.R_SI; -	  case 7: -		DECODE_PRINTF("DI"); -		return &M.x86.R_DI; -	} -	HALT_SYS(); -    return NULL;                /* NOTREACHED OR REACHED ON ERROR */ -} - -/**************************************************************************** -PARAMETERS: -reg	- Register to decode - -RETURNS: -Pointer to the appropriate register - -REMARKS: -Return a pointer to the register given by the R/RM field of the -modrm byte, for dword operands.  Also enables the decoding of instructions. -****************************************************************************/ -u32* decode_rm_long_register( -	int reg) -{ -    switch (reg) { -      case 0: -		DECODE_PRINTF("EAX"); -		return &M.x86.R_EAX; -	  case 1: -		DECODE_PRINTF("ECX"); -		return &M.x86.R_ECX; -	  case 2: -		DECODE_PRINTF("EDX"); -		return &M.x86.R_EDX; -	  case 3: -		DECODE_PRINTF("EBX"); -		return &M.x86.R_EBX; -	  case 4: -		DECODE_PRINTF("ESP"); -		return &M.x86.R_ESP; -	  case 5: -		DECODE_PRINTF("EBP"); -		return &M.x86.R_EBP; -	  case 6: -		DECODE_PRINTF("ESI"); -		return &M.x86.R_ESI; -	  case 7: -		DECODE_PRINTF("EDI"); -		return &M.x86.R_EDI; -	} -	HALT_SYS(); -    return NULL;                /* NOTREACHED OR REACHED ON ERROR */ -} - -/**************************************************************************** -PARAMETERS: -reg	- Register to decode - -RETURNS: -Pointer to the appropriate register - -REMARKS: -Return a pointer to the register given by the R/RM field of the -modrm byte, for word operands, modified from above for the weirdo -special case of segreg operands.  Also enables the decoding of instructions. -****************************************************************************/ -u16* decode_rm_seg_register( -	int reg) -{ -	switch (reg) { -	  case 0: -		DECODE_PRINTF("ES"); -		return &M.x86.R_ES; -	  case 1: -		DECODE_PRINTF("CS"); -		return &M.x86.R_CS; -	  case 2: -		DECODE_PRINTF("SS"); -		return &M.x86.R_SS; -	  case 3: -		DECODE_PRINTF("DS"); -		return &M.x86.R_DS; -	  case 4: -	  case 5: -	  case 6: -	  case 7: -		DECODE_PRINTF("ILLEGAL SEGREG"); -		break; -	} -	HALT_SYS(); -	return NULL;                /* NOT REACHED OR REACHED ON ERROR */ -} - -/**************************************************************************** -PARAMETERS: -rm	- RM value to decode - -RETURNS: -Offset in memory for the address decoding - -REMARKS: -Return the offset given by mod=00 addressing.  Also enables the -decoding of instructions. - -NOTE: 	The code which specifies the corresponding segment (ds vs ss) -		below in the case of [BP+..].  The assumption here is that at the -		point that this subroutine is called, the bit corresponding to -		SYSMODE_SEG_DS_SS will be zero.  After every instruction -		except the segment override instructions, this bit (as well -		as any bits indicating segment overrides) will be clear.  So -		if a SS access is needed, set this bit.  Otherwise, DS access -		occurs (unless any of the segment override bits are set). -****************************************************************************/ -unsigned decode_rm00_address( -	int rm) -{ -	unsigned offset; - -	if (M.x86.mode & SYSMODE_PREFIX_ADDR) -	{ -	    switch (rm) { -	    case 0: -		DECODE_PRINTF("[EAX]"); -		return M.x86.R_EAX; -	    case 1: -		DECODE_PRINTF("[ECX]"); -		return M.x86.R_ECX; -	    case 2: -		DECODE_PRINTF("[EDX]"); -/*		M.x86.mode |= SYSMODE_SEG_DS_SS; */ -		return M.x86.R_EDX; -	    case 3: -		DECODE_PRINTF("[EBX]"); -/*		M.x86.mode |= SYSMODE_SEG_DS_SS; */ -		return M.x86.R_EBX; -	    case 4: -		printk("Unsupported SIB encoding\n"); -		HALT_SYS(); -		return 0; -	    case 5: -		offset = fetch_long_imm(); -		DECODE_PRINTF2("[%08x]", offset); -		return offset; -	    case 6: -		DECODE_PRINTF("[ESI]"); -		return M.x86.R_ESI; -	    case 7: -		DECODE_PRINTF("[EDI]"); -		return M.x86.R_EDI; -	    } -	} -	else -	{ -	    switch (rm) { -	    case 0: -		DECODE_PRINTF("[BX+SI]"); -		return M.x86.R_BX + M.x86.R_SI; -	    case 1: -		DECODE_PRINTF("[BX+DI]"); -		return M.x86.R_BX + M.x86.R_DI; -	    case 2: -		DECODE_PRINTF("[BP+SI]"); -		M.x86.mode |= SYSMODE_SEG_DS_SS; -		return M.x86.R_BP + M.x86.R_SI; -	    case 3: -		DECODE_PRINTF("[BP+DI]"); -		M.x86.mode |= SYSMODE_SEG_DS_SS; -		return M.x86.R_BP + M.x86.R_DI; -	    case 4: -		DECODE_PRINTF("[SI]"); -		return M.x86.R_SI; -	    case 5: -		DECODE_PRINTF("[DI]"); -		return M.x86.R_DI; -	    case 6: -		offset = fetch_word_imm(); -		DECODE_PRINTF2("[%04x]", offset); -		return offset; -	    case 7: -		DECODE_PRINTF("[BX]"); -		return M.x86.R_BX; -	    } -	} -	HALT_SYS(); -    return 0; -} - -/**************************************************************************** -PARAMETERS: -rm	- RM value to decode - -RETURNS: -Offset in memory for the address decoding - -REMARKS: -Return the offset given by mod=01 addressing.  Also enables the -decoding of instructions. -****************************************************************************/ -unsigned decode_rm01_address( -	int rm) -{ -    int displacement = (s8)fetch_byte_imm(); -    if (M.x86.mode & SYSMODE_PREFIX_ADDR) -    { -	switch (rm) -	{ -	case 0: -	    DECODE_PRINTF2("%d[EAX}", displacement); -	    return M.x86.R_EAX + displacement; -	case 1: -	    DECODE_PRINTF2("%d[ECX]", displacement); -	    return M.x86.R_ECX + displacement; -	case 2: -	    DECODE_PRINTF2("%d[EDX]", displacement); -	    return M.x86.R_EDX + displacement; -	case 3: -	    DECODE_PRINTF2("%d[EBX]", displacement); -	    return M.x86.R_EBX + displacement; -	case 4: -	    printk("Unsupported SIB addressing mode\n"); -	    HALT_SYS(); -	    return 0; -	case 5: -	    DECODE_PRINTF2("%d[EBP]", displacement); -	    return M.x86.R_EBP + displacement; -	case 6: -	    DECODE_PRINTF2("%d[ESI]", displacement); -	    return M.x86.R_ESI + displacement; -	case 7: -	    DECODE_PRINTF2("%d[EDI]", displacement); -	    return M.x86.R_EDI + displacement; -	} -    } -    else -    { -	switch (rm) { -	case 0: -	    DECODE_PRINTF2("%d[BX+SI]", displacement); -	    return M.x86.R_BX + M.x86.R_SI + displacement; -	case 1: -	    DECODE_PRINTF2("%d[BX+DI]", displacement); -	    return M.x86.R_BX + M.x86.R_DI + displacement; -	case 2: -	    DECODE_PRINTF2("%d[BP+SI]", displacement); -	    M.x86.mode |= SYSMODE_SEG_DS_SS; -	    return M.x86.R_BP + M.x86.R_SI + displacement; -	case 3: -	    DECODE_PRINTF2("%d[BP+DI]", displacement); -	    M.x86.mode |= SYSMODE_SEG_DS_SS; -	    return M.x86.R_BP + M.x86.R_DI + displacement; -	case 4: -	    DECODE_PRINTF2("%d[SI]", displacement); -	    return M.x86.R_SI + displacement; -	case 5: -	    DECODE_PRINTF2("%d[DI]", displacement); -	    return M.x86.R_DI + displacement; -	case 6: -	    DECODE_PRINTF2("%d[BP]", displacement); -	    M.x86.mode |= SYSMODE_SEG_DS_SS; -	    return M.x86.R_BP + displacement; -	case 7: -	    DECODE_PRINTF2("%d[BX]", displacement); -	    return M.x86.R_BX + displacement; -	} -	HALT_SYS(); -    } -    return 0;                   /* SHOULD NOT HAPPEN */ -} - -/**************************************************************************** -PARAMETERS: -rm	- RM value to decode - -RETURNS: -Offset in memory for the address decoding - -REMARKS: -Return the offset given by mod=10 addressing.  Also enables the -decoding of instructions. -****************************************************************************/ -unsigned decode_rm10_address( -	int rm) -{ -    if (M.x86.mode & SYSMODE_PREFIX_ADDR) -    { -	int displacement = (s32)fetch_long_imm(); -	switch (rm) -	{ -	case 0: -	    DECODE_PRINTF2("%d[EAX}", displacement); -	    return M.x86.R_EAX + displacement; -	case 1: -	    DECODE_PRINTF2("%d[ECX]", displacement); -	    return M.x86.R_ECX + displacement; -	case 2: -	    DECODE_PRINTF2("%d[EDX]", displacement); -	    return M.x86.R_EDX + displacement; -	case 3: -	    DECODE_PRINTF2("%d[EBX]", displacement); -	    return M.x86.R_EBX + displacement; -	case 4: -	    printk("Unsupported SIB addressing mode\n"); -	    HALT_SYS(); -	    return 0; -	case 5: -	    DECODE_PRINTF2("%d[EBP]", displacement); -	    return M.x86.R_EBP + displacement; -	case 6: -	    DECODE_PRINTF2("%d[ESI]", displacement); -	    return M.x86.R_ESI + displacement; -	case 7: -	    DECODE_PRINTF2("%d[EDI]", displacement); -	    return M.x86.R_EDI + displacement; -	} -    } -    else -    { -	int displacement = (s16)fetch_word_imm(); -	switch (rm) { -	case 0: -	    DECODE_PRINTF2("%d[BX+SI]", displacement); -	    return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; -	case 1: -	    DECODE_PRINTF2("%d[BX+DI]", displacement); -	    return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; -	case 2: -	    DECODE_PRINTF2("%d[BP+SI]", displacement); -	    M.x86.mode |= SYSMODE_SEG_DS_SS; -	    return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; -	case 3: -	    DECODE_PRINTF2("%d[BP+DI]", displacement); -	    M.x86.mode |= SYSMODE_SEG_DS_SS; -	    return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; -	case 4: -	    DECODE_PRINTF2("%d[SI]", displacement); -	    return (M.x86.R_SI + displacement) & 0xffff; -	case 5: -	    DECODE_PRINTF2("%d[DI]", displacement); -	    return (M.x86.R_DI + displacement) & 0xffff; -	case 6: -	    DECODE_PRINTF2("%d[BP]", displacement); -	    M.x86.mode |= SYSMODE_SEG_DS_SS; -	    return (M.x86.R_BP + displacement) & 0xffff; -	case 7: -	    DECODE_PRINTF2("%d[BX]", displacement); -	    return (M.x86.R_BX + displacement) & 0xffff; -	} -    } -    HALT_SYS(); -    return 0; -    /*NOTREACHED */ -} |