📄 sys.c
字号:
/****************************************************************************** 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* programmed I/O and memory access. Included in this module* are default functions with limited usefulness. For real* uses these functions will most likely be overriden by the* user library.*****************************************************************************/#include "x86emu.h"#include "x86emu/regs.h"#include "x86emu/debug.h"#include "x86emu/prim_ops.h"#include <string.h>/*------------------------- Global Variables ------------------------------*/X86EMU_sysEnv _X86EMU_env; /* Global emulator machine state */X86EMU_intrFuncs _X86EMU_intrTab[256];/*----------------------------- Implementation ----------------------------*/#ifdef __alpha__/* to cope with broken egcs-1.1.2 :-(((( *//* * inline functions to do unaligned accesses * from linux/include/asm-alpha/unaligned.h *//* * EGCS 1.1 knows about arbitrary unaligned loads. Define some * packed structures to talk about such things with. */#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91struct __una_u64 { unsigned long x __attribute__((packed)); };struct __una_u32 { unsigned int x __attribute__((packed)); };struct __una_u16 { unsigned short x __attribute__((packed)); };#endifstatic __inline__ unsigned long ldq_u(unsigned long * r11){#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 const struct __una_u64 *ptr = (const struct __una_u64 *) r11; return ptr->x;#else unsigned long r1,r2; __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extql %0,%2,%0\n\t" "extqh %1,%2,%1" :"=&r" (r1), "=&r" (r2) :"r" (r11), "m" (*r11), "m" (*(const unsigned long *)(7+(char *) r11))); return r1 | r2;#endif}static __inline__ unsigned long ldl_u(unsigned int * r11){#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 const struct __una_u32 *ptr = (const struct __una_u32 *) r11; return ptr->x;#else unsigned long r1,r2; __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extll %0,%2,%0\n\t" "extlh %1,%2,%1" :"=&r" (r1), "=&r" (r2) :"r" (r11), "m" (*r11), "m" (*(const unsigned long *)(3+(char *) r11))); return r1 | r2;#endif}static __inline__ unsigned long ldw_u(unsigned short * r11){#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 const struct __una_u16 *ptr = (const struct __una_u16 *) r11; return ptr->x;#else unsigned long r1,r2; __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extwl %0,%2,%0\n\t" "extwh %1,%2,%1" :"=&r" (r1), "=&r" (r2) :"r" (r11), "m" (*r11), "m" (*(const unsigned long *)(1+(char *) r11))); return r1 | r2;#endif}/* * Elemental unaligned stores */static __inline__ void stq_u(unsigned long r5, unsigned long * r11){#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 struct __una_u64 *ptr = (struct __una_u64 *) r11; ptr->x = r5;#else unsigned long r1,r2,r3,r4; __asm__("ldq_u %3,%1\n\t" "ldq_u %2,%0\n\t" "insqh %6,%7,%5\n\t" "insql %6,%7,%4\n\t" "mskqh %3,%7,%3\n\t" "mskql %2,%7,%2\n\t" "bis %3,%5,%3\n\t" "bis %2,%4,%2\n\t" "stq_u %3,%1\n\t" "stq_u %2,%0" :"=m" (*r11), "=m" (*(unsigned long *)(7+(char *) r11)), "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4) :"r" (r5), "r" (r11));#endif}static __inline__ void stl_u(unsigned long r5, unsigned int * r11){#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 struct __una_u32 *ptr = (struct __una_u32 *) r11; ptr->x = r5;#else unsigned long r1,r2,r3,r4; __asm__("ldq_u %3,%1\n\t" "ldq_u %2,%0\n\t" "inslh %6,%7,%5\n\t" "insll %6,%7,%4\n\t" "msklh %3,%7,%3\n\t" "mskll %2,%7,%2\n\t" "bis %3,%5,%3\n\t" "bis %2,%4,%2\n\t" "stq_u %3,%1\n\t" "stq_u %2,%0" :"=m" (*r11), "=m" (*(unsigned long *)(3+(char *) r11)), "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4) :"r" (r5), "r" (r11));#endif}static __inline__ void stw_u(unsigned long r5, unsigned short * r11){#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91 struct __una_u16 *ptr = (struct __una_u16 *) r11; ptr->x = r5;#else unsigned long r1,r2,r3,r4; __asm__("ldq_u %3,%1\n\t" "ldq_u %2,%0\n\t" "inswh %6,%7,%5\n\t" "inswl %6,%7,%4\n\t" "mskwh %3,%7,%3\n\t" "mskwl %2,%7,%2\n\t" "bis %3,%5,%3\n\t" "bis %2,%4,%2\n\t" "stq_u %3,%1\n\t" "stq_u %2,%0" :"=m" (*r11), "=m" (*(unsigned long *)(1+(char *) r11)), "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4) :"r" (r5), "r" (r11));#endif}#elif defined (__ia64__)/* * EGCS 1.1 knows about arbitrary unaligned loads. Define some * packed structures to talk about such things with. */struct __una_u64 { unsigned long x __attribute__((packed)); };struct __una_u32 { unsigned int x __attribute__((packed)); };struct __una_u16 { unsigned short x __attribute__((packed)); };static __inline__ unsigned long__uldq (const unsigned long * r11){ const struct __una_u64 *ptr = (const struct __una_u64 *) r11; return ptr->x;}static __inline__ unsigned longuldl (const unsigned int * r11){ const struct __una_u32 *ptr = (const struct __una_u32 *) r11; return ptr->x;}static __inline__ unsigned longuldw (const unsigned short * r11){ const struct __una_u16 *ptr = (const struct __una_u16 *) r11; return ptr->x;}static __inline__ voidustq (unsigned long r5, unsigned long * r11){ struct __una_u64 *ptr = (struct __una_u64 *) r11; ptr->x = r5;}static __inline__ voidustl (unsigned long r5, unsigned int * r11){ struct __una_u32 *ptr = (struct __una_u32 *) r11; ptr->x = r5;}static __inline__ voidustw (unsigned long r5, unsigned short * r11){ struct __una_u16 *ptr = (struct __una_u16 *) r11; ptr->x = r5;}#endif/****************************************************************************PARAMETERS:addr - Emulator memory address to readRETURNS:Byte value read from emulator memory.REMARKS:Reads a byte value from the emulator memory.****************************************************************************/u8 X86API rdb( u32 addr){ u8 val; if (addr > M.mem_size - 1) { DB(printk("mem_read: address %#lx out of range!\n", addr);) HALT_SYS(); } val = *(u8*)(M.mem_base + addr);DB( if (DEBUG_MEM_TRACE()) printk("%#08x 1 -> %#x\n", addr, val);) return val;}/****************************************************************************PARAMETERS:addr - Emulator memory address to readRETURNS:Word value read from emulator memory.REMARKS:Reads a word value from the emulator memory.****************************************************************************/u16 X86API rdw( u32 addr){ u16 val = 0; if (addr > M.mem_size - 2) { DB(printk("mem_read: address %#lx out of range!\n", addr);) HALT_SYS(); }#ifdef __BIG_ENDIAN__ if (addr & 0x1) { val = (*(u8*)(M.mem_base + addr) | (*(u8*)(M.mem_base + addr + 1) << 8)); } else#endif#ifdef __alpha__ val = ldw_u((u16*)(M.mem_base + addr));#elif defined (__ia64__) val = uldw((u16*)(M.mem_base + addr));#else val = *(u16*)(M.mem_base + addr);#endif DB( if (DEBUG_MEM_TRACE()) printk("%#08x 2 -> %#x\n", addr, val);) return val;}/****************************************************************************PARAMETERS:addr - Emulator memory address to readRETURNS:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -