1 /* $OpenBSD: x86emu_util.c,v 1.5 2009/06/18 14:19:21 pirofti Exp $ */ 2 /* $NetBSD: x86emu_util.c,v 1.2 2007/12/04 17:32:22 joerg Exp $ */ 3 4 /* 5 * 6 * Realmode X86 Emulator Library 7 * 8 * Copyright (C) 1996-1999 SciTech Software, Inc. 9 * Copyright (C) David Mosberger-Tang 10 * Copyright (C) 1999 Egbert Eich 11 * Copyright (C) 2007 Joerg Sonnenberger 12 * 13 * ======================================================================== 14 * 15 * Permission to use, copy, modify, distribute, and sell this software and 16 * its documentation for any purpose is hereby granted without fee, 17 * provided that the above copyright notice appear in all copies and that 18 * both that copyright notice and this permission notice appear in 19 * supporting documentation, and that the name of the authors not be used 20 * in advertising or publicity pertaining to distribution of the software 21 * without specific, written prior permission. The authors makes no 22 * representations about the suitability of this software for any purpose. 23 * It is provided "as is" without express or implied warranty. 24 * 25 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 26 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 27 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 28 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 29 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 30 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 31 * PERFORMANCE OF THIS SOFTWARE. 32 * 33 */ 34 35 #include <sys/param.h> 36 #include <sys/endian.h> 37 38 #include <dev/x86emu/x86emu.h> 39 #include <dev/x86emu/x86emu_regs.h> 40 41 42 43 /* 44 * PARAMETERS: 45 * addr - Emulator memory address to read 46 * 47 * RETURNS: 48 * Byte value read from emulator memory. 49 * 50 * REMARKS: 51 * Reads a byte value from the emulator memory. 52 */ 53 static uint8_t 54 rdb(struct x86emu *emu, uint32_t addr) 55 { 56 if (addr > emu->mem_size - 1) 57 x86emu_halt_sys(emu); 58 return emu->mem_base[addr]; 59 } 60 61 /* 62 * PARAMETERS: 63 * addr - Emulator memory address to read 64 * 65 * RETURNS: 66 * Word value read from emulator memory. 67 * 68 * REMARKS: 69 * Reads a word value from the emulator memory. 70 */ 71 static uint16_t 72 rdw(struct x86emu *emu, uint32_t addr) 73 { 74 if (addr > emu->mem_size - 2) 75 x86emu_halt_sys(emu); 76 #ifdef __STRICT_ALIGNMENT 77 if (addr & 1) { 78 u_int8_t *a = emu->mem_base + addr; 79 u_int16_t r; 80 81 r = ((*(a + 0) << 0) & 0x00ff) | 82 ((*(a + 1) << 8) & 0xff00); 83 return r; 84 } else 85 return letoh32(*(u_int32_t *)(emu->mem_base + addr)); 86 #else 87 return letoh16(*(u_int16_t *)(emu->mem_base + addr)); 88 #endif 89 } 90 91 /* 92 * PARAMETERS: 93 * addr - Emulator memory address to read 94 * 95 * RETURNS: 96 * Long value read from emulator memory. 97 * REMARKS: 98 * Reads a long value from the emulator memory. 99 */ 100 static uint32_t 101 rdl(struct x86emu *emu, uint32_t addr) 102 { 103 if (addr > emu->mem_size - 4) 104 x86emu_halt_sys(emu); 105 #ifdef __STRICT_ALIGNMENT 106 if (addr & 3) { 107 u_int8_t *a = emu->mem_base + addr; 108 u_int32_t r; 109 110 r = ((*(a + 0) << 0) & 0x000000ff) | 111 ((*(a + 1) << 8) & 0x0000ff00) | 112 ((*(a + 2) << 16) & 0x00ff0000) | 113 ((*(a + 3) << 24) & 0xff000000); 114 return r; 115 } else 116 return letoh32(*(u_int32_t *)(emu->mem_base + addr)); 117 #else 118 return letoh32(*(u_int32_t *)(emu->mem_base + addr)); 119 #endif 120 } 121 122 /* 123 * PARAMETERS: 124 * addr - Emulator memory address to read 125 * val - Value to store 126 * 127 * REMARKS: 128 * Writes a byte value to emulator memory. 129 */ 130 static void 131 wrb(struct x86emu *emu, uint32_t addr, uint8_t val) 132 { 133 if (addr > emu->mem_size - 1) 134 x86emu_halt_sys(emu); 135 emu->mem_base[addr] = val; 136 } 137 138 /* 139 * PARAMETERS: 140 * addr - Emulator memory address to read 141 * val - Value to store 142 * 143 * REMARKS: 144 * Writes a word value to emulator memory. 145 */ 146 static void 147 wrw(struct x86emu *emu, uint32_t addr, uint16_t val) 148 { 149 if (addr > emu->mem_size - 2) 150 x86emu_halt_sys(emu); 151 #ifdef __STRICT_ALIGNMENT 152 if (addr & 1) { 153 u_int8_t *a = emu->mem_base + addr; 154 155 *((a + 0)) = (val >> 0) & 0xff; 156 *((a + 1)) = (val >> 8) & 0xff; 157 } else 158 *((u_int16_t *)(emu->mem_base + addr)) = htole16(val); 159 #else 160 *((u_int16_t *)(emu->mem_base + addr)) = htole16(val); 161 #endif 162 } 163 164 /* 165 * PARAMETERS: 166 * addr - Emulator memory address to read 167 * val - Value to store 168 * 169 * REMARKS: 170 * Writes a long value to emulator memory. 171 */ 172 static void 173 wrl(struct x86emu *emu, uint32_t addr, uint32_t val) 174 { 175 if (addr > emu->mem_size - 4) 176 x86emu_halt_sys(emu); 177 #ifdef __STRICT_ALIGNMENT 178 if (addr & 3) { 179 u_int8_t *a = emu->mem_base + addr; 180 181 *((a + 0) = (val >> 0) & 0xff; 182 *((a + 1) = (val >> 8) & 0xff; 183 *((a + 2) = (val >> 16) & 0xff; 184 *((a + 3) = (val >> 24) & 0xff; 185 } else 186 *((u_int32_t *)(emu->mem_base + addr)) = htole32(val); 187 #else 188 *((u_int32_t *)(emu->mem_base + addr)) = htole32(val); 189 #endif 190 } 191 192 /* Setup */ 193 194 void 195 x86emu_init_default(struct x86emu *emu) 196 { 197 int i; 198 199 emu->emu_rdb = rdb; 200 emu->emu_rdw = rdw; 201 emu->emu_rdl = rdl; 202 emu->emu_wrb = wrb; 203 emu->emu_wrw = wrw; 204 emu->emu_wrl = wrl; 205 206 for (i = 0; i < 256; i++) 207 emu->_x86emu_intrTab[i] = NULL; 208 } 209