1d1f4d6590
x86emu is a software emulator for the real mode x86 processor, originally written by SciTech Software, Inc. for XFree86 and has been later ported to NetBSD then OpenBSD.
209 lines
4.9 KiB
C
209 lines
4.9 KiB
C
/* $OpenBSD: x86emu_util.c,v 1.5 2009/06/18 14:19:21 pirofti Exp $ */
|
|
/* $NetBSD: x86emu_util.c,v 1.2 2007/12/04 17:32:22 joerg Exp $ */
|
|
|
|
/*
|
|
*
|
|
* Realmode X86 Emulator Library
|
|
*
|
|
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
|
* Copyright (C) David Mosberger-Tang
|
|
* Copyright (C) 1999 Egbert Eich
|
|
* Copyright (C) 2007 Joerg Sonnenberger
|
|
*
|
|
* ========================================================================
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/endian.h>
|
|
|
|
#include <dev/x86emu/x86emu.h>
|
|
#include <dev/x86emu/x86emu_regs.h>
|
|
|
|
|
|
|
|
/*
|
|
* PARAMETERS:
|
|
* addr - Emulator memory address to read
|
|
*
|
|
* RETURNS:
|
|
* Byte value read from emulator memory.
|
|
*
|
|
* REMARKS:
|
|
* Reads a byte value from the emulator memory.
|
|
*/
|
|
static uint8_t
|
|
rdb(struct x86emu *emu, uint32_t addr)
|
|
{
|
|
if (addr > emu->mem_size - 1)
|
|
x86emu_halt_sys(emu);
|
|
return emu->mem_base[addr];
|
|
}
|
|
|
|
/*
|
|
* PARAMETERS:
|
|
* addr - Emulator memory address to read
|
|
*
|
|
* RETURNS:
|
|
* Word value read from emulator memory.
|
|
*
|
|
* REMARKS:
|
|
* Reads a word value from the emulator memory.
|
|
*/
|
|
static uint16_t
|
|
rdw(struct x86emu *emu, uint32_t addr)
|
|
{
|
|
if (addr > emu->mem_size - 2)
|
|
x86emu_halt_sys(emu);
|
|
#ifdef __STRICT_ALIGNMENT
|
|
if (addr & 1) {
|
|
u_int8_t *a = emu->mem_base + addr;
|
|
u_int16_t r;
|
|
|
|
r = ((*(a + 0) << 0) & 0x00ff) |
|
|
((*(a + 1) << 8) & 0xff00);
|
|
return r;
|
|
} else
|
|
return letoh32(*(u_int32_t *)(emu->mem_base + addr));
|
|
#else
|
|
return letoh16(*(u_int16_t *)(emu->mem_base + addr));
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* PARAMETERS:
|
|
* addr - Emulator memory address to read
|
|
*
|
|
* RETURNS:
|
|
* Long value read from emulator memory.
|
|
* REMARKS:
|
|
* Reads a long value from the emulator memory.
|
|
*/
|
|
static uint32_t
|
|
rdl(struct x86emu *emu, uint32_t addr)
|
|
{
|
|
if (addr > emu->mem_size - 4)
|
|
x86emu_halt_sys(emu);
|
|
#ifdef __STRICT_ALIGNMENT
|
|
if (addr & 3) {
|
|
u_int8_t *a = emu->mem_base + addr;
|
|
u_int32_t r;
|
|
|
|
r = ((*(a + 0) << 0) & 0x000000ff) |
|
|
((*(a + 1) << 8) & 0x0000ff00) |
|
|
((*(a + 2) << 16) & 0x00ff0000) |
|
|
((*(a + 3) << 24) & 0xff000000);
|
|
return r;
|
|
} else
|
|
return letoh32(*(u_int32_t *)(emu->mem_base + addr));
|
|
#else
|
|
return letoh32(*(u_int32_t *)(emu->mem_base + addr));
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* PARAMETERS:
|
|
* addr - Emulator memory address to read
|
|
* val - Value to store
|
|
*
|
|
* REMARKS:
|
|
* Writes a byte value to emulator memory.
|
|
*/
|
|
static void
|
|
wrb(struct x86emu *emu, uint32_t addr, uint8_t val)
|
|
{
|
|
if (addr > emu->mem_size - 1)
|
|
x86emu_halt_sys(emu);
|
|
emu->mem_base[addr] = val;
|
|
}
|
|
|
|
/*
|
|
* PARAMETERS:
|
|
* addr - Emulator memory address to read
|
|
* val - Value to store
|
|
*
|
|
* REMARKS:
|
|
* Writes a word value to emulator memory.
|
|
*/
|
|
static void
|
|
wrw(struct x86emu *emu, uint32_t addr, uint16_t val)
|
|
{
|
|
if (addr > emu->mem_size - 2)
|
|
x86emu_halt_sys(emu);
|
|
#ifdef __STRICT_ALIGNMENT
|
|
if (addr & 1) {
|
|
u_int8_t *a = emu->mem_base + addr;
|
|
|
|
*((a + 0)) = (val >> 0) & 0xff;
|
|
*((a + 1)) = (val >> 8) & 0xff;
|
|
} else
|
|
*((u_int16_t *)(emu->mem_base + addr)) = htole16(val);
|
|
#else
|
|
*((u_int16_t *)(emu->mem_base + addr)) = htole16(val);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* PARAMETERS:
|
|
* addr - Emulator memory address to read
|
|
* val - Value to store
|
|
*
|
|
* REMARKS:
|
|
* Writes a long value to emulator memory.
|
|
*/
|
|
static void
|
|
wrl(struct x86emu *emu, uint32_t addr, uint32_t val)
|
|
{
|
|
if (addr > emu->mem_size - 4)
|
|
x86emu_halt_sys(emu);
|
|
#ifdef __STRICT_ALIGNMENT
|
|
if (addr & 3) {
|
|
u_int8_t *a = emu->mem_base + addr;
|
|
|
|
*((a + 0) = (val >> 0) & 0xff;
|
|
*((a + 1) = (val >> 8) & 0xff;
|
|
*((a + 2) = (val >> 16) & 0xff;
|
|
*((a + 3) = (val >> 24) & 0xff;
|
|
} else
|
|
*((u_int32_t *)(emu->mem_base + addr)) = htole32(val);
|
|
#else
|
|
*((u_int32_t *)(emu->mem_base + addr)) = htole32(val);
|
|
#endif
|
|
}
|
|
|
|
/* Setup */
|
|
|
|
void
|
|
x86emu_init_default(struct x86emu *emu)
|
|
{
|
|
int i;
|
|
|
|
emu->emu_rdb = rdb;
|
|
emu->emu_rdw = rdw;
|
|
emu->emu_rdl = rdl;
|
|
emu->emu_wrb = wrb;
|
|
emu->emu_wrw = wrw;
|
|
emu->emu_wrl = wrl;
|
|
|
|
for (i = 0; i < 256; i++)
|
|
emu->_x86emu_intrTab[i] = NULL;
|
|
}
|