1 /* $OpenBSD: x86emu_util.c,v 1.6 2015/03/14 03:38:50 jsg 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 40 41 42 /* 43 * PARAMETERS: 44 * addr - Emulator memory address to read 45 * 46 * RETURNS: 47 * Byte value read from emulator memory. 48 * 49 * REMARKS: 50 * Reads a byte value from the emulator memory. 51 */ 52 static uint8_t 53 rdb(struct x86emu *emu, uint32_t addr) 54 { 55 if (addr > emu->mem_size - 1) 56 x86emu_halt_sys(emu); 57 return emu->mem_base[addr]; 58 } 59 60 /* 61 * PARAMETERS: 62 * addr - Emulator memory address to read 63 * 64 * RETURNS: 65 * Word value read from emulator memory. 66 * 67 * REMARKS: 68 * Reads a word value from the emulator memory. 69 */ 70 static uint16_t 71 rdw(struct x86emu *emu, uint32_t addr) 72 { 73 if (addr > emu->mem_size - 2) 74 x86emu_halt_sys(emu); 75 #ifdef __STRICT_ALIGNMENT 76 if (addr & 1) { 77 u_int8_t *a = emu->mem_base + addr; 78 u_int16_t r; 79 80 r = ((*(a + 0) << 0) & 0x00ff) | 81 ((*(a + 1) << 8) & 0xff00); 82 return r; 83 } else 84 return letoh32(*(u_int32_t *)(emu->mem_base + addr)); 85 #else 86 return letoh16(*(u_int16_t *)(emu->mem_base + addr)); 87 #endif 88 } 89 90 /* 91 * PARAMETERS: 92 * addr - Emulator memory address to read 93 * 94 * RETURNS: 95 * Long value read from emulator memory. 96 * REMARKS: 97 * Reads a long value from the emulator memory. 98 */ 99 static uint32_t 100 rdl(struct x86emu *emu, uint32_t addr) 101 { 102 if (addr > emu->mem_size - 4) 103 x86emu_halt_sys(emu); 104 #ifdef __STRICT_ALIGNMENT 105 if (addr & 3) { 106 u_int8_t *a = emu->mem_base + addr; 107 u_int32_t r; 108 109 r = ((*(a + 0) << 0) & 0x000000ff) | 110 ((*(a + 1) << 8) & 0x0000ff00) | 111 ((*(a + 2) << 16) & 0x00ff0000) | 112 ((*(a + 3) << 24) & 0xff000000); 113 return r; 114 } else 115 return letoh32(*(u_int32_t *)(emu->mem_base + addr)); 116 #else 117 return letoh32(*(u_int32_t *)(emu->mem_base + addr)); 118 #endif 119 } 120 121 /* 122 * PARAMETERS: 123 * addr - Emulator memory address to read 124 * val - Value to store 125 * 126 * REMARKS: 127 * Writes a byte value to emulator memory. 128 */ 129 static void 130 wrb(struct x86emu *emu, uint32_t addr, uint8_t val) 131 { 132 if (addr > emu->mem_size - 1) 133 x86emu_halt_sys(emu); 134 emu->mem_base[addr] = val; 135 } 136 137 /* 138 * PARAMETERS: 139 * addr - Emulator memory address to read 140 * val - Value to store 141 * 142 * REMARKS: 143 * Writes a word value to emulator memory. 144 */ 145 static void 146 wrw(struct x86emu *emu, uint32_t addr, uint16_t val) 147 { 148 if (addr > emu->mem_size - 2) 149 x86emu_halt_sys(emu); 150 #ifdef __STRICT_ALIGNMENT 151 if (addr & 1) { 152 u_int8_t *a = emu->mem_base + addr; 153 154 *((a + 0)) = (val >> 0) & 0xff; 155 *((a + 1)) = (val >> 8) & 0xff; 156 } else 157 *((u_int16_t *)(emu->mem_base + addr)) = htole16(val); 158 #else 159 *((u_int16_t *)(emu->mem_base + addr)) = htole16(val); 160 #endif 161 } 162 163 /* 164 * PARAMETERS: 165 * addr - Emulator memory address to read 166 * val - Value to store 167 * 168 * REMARKS: 169 * Writes a long value to emulator memory. 170 */ 171 static void 172 wrl(struct x86emu *emu, uint32_t addr, uint32_t val) 173 { 174 if (addr > emu->mem_size - 4) 175 x86emu_halt_sys(emu); 176 #ifdef __STRICT_ALIGNMENT 177 if (addr & 3) { 178 u_int8_t *a = emu->mem_base + addr; 179 180 *((a + 0) = (val >> 0) & 0xff; 181 *((a + 1) = (val >> 8) & 0xff; 182 *((a + 2) = (val >> 16) & 0xff; 183 *((a + 3) = (val >> 24) & 0xff; 184 } else 185 *((u_int32_t *)(emu->mem_base + addr)) = htole32(val); 186 #else 187 *((u_int32_t *)(emu->mem_base + addr)) = htole32(val); 188 #endif 189 } 190 191 /* Setup */ 192 193 void 194 x86emu_init_default(struct x86emu *emu) 195 { 196 int i; 197 198 emu->emu_rdb = rdb; 199 emu->emu_rdw = rdw; 200 emu->emu_rdl = rdl; 201 emu->emu_wrb = wrb; 202 emu->emu_wrw = wrw; 203 emu->emu_wrl = wrl; 204 205 for (i = 0; i < 256; i++) 206 emu->_x86emu_intrTab[i] = NULL; 207 } 208