1706f2543Smrg/**************************************************************************** 2706f2543Smrg* 3706f2543Smrg* Realmode X86 Emulator Library 4706f2543Smrg* 5706f2543Smrg* Copyright (C) 1996-1999 SciTech Software, Inc. 6706f2543Smrg* Copyright (C) David Mosberger-Tang 7706f2543Smrg* Copyright (C) 1999 Egbert Eich 8706f2543Smrg* 9706f2543Smrg* ======================================================================== 10706f2543Smrg* 11706f2543Smrg* Permission to use, copy, modify, distribute, and sell this software and 12706f2543Smrg* its documentation for any purpose is hereby granted without fee, 13706f2543Smrg* provided that the above copyright notice appear in all copies and that 14706f2543Smrg* both that copyright notice and this permission notice appear in 15706f2543Smrg* supporting documentation, and that the name of the authors not be used 16706f2543Smrg* in advertising or publicity pertaining to distribution of the software 17706f2543Smrg* without specific, written prior permission. The authors makes no 18706f2543Smrg* representations about the suitability of this software for any purpose. 19706f2543Smrg* It is provided "as is" without express or implied warranty. 20706f2543Smrg* 21706f2543Smrg* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 22706f2543Smrg* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 23706f2543Smrg* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 24706f2543Smrg* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 25706f2543Smrg* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 26706f2543Smrg* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 27706f2543Smrg* PERFORMANCE OF THIS SOFTWARE. 28706f2543Smrg* 29706f2543Smrg* ======================================================================== 30706f2543Smrg* 31706f2543Smrg* Language: ANSI C 32706f2543Smrg* Environment: Any 33706f2543Smrg* Developer: Kendall Bennett 34706f2543Smrg* 35706f2543Smrg* Description: This file includes subroutines which are related to 36706f2543Smrg* programmed I/O and memory access. Included in this module 37706f2543Smrg* are default functions with limited usefulness. For real 38706f2543Smrg* uses these functions will most likely be overriden by the 39706f2543Smrg* user library. 40706f2543Smrg* 41706f2543Smrg****************************************************************************/ 42706f2543Smrg 43706f2543Smrg#include "x86emu.h" 44706f2543Smrg#include "x86emu/x86emui.h" 45706f2543Smrg#include "x86emu/regs.h" 46706f2543Smrg#include "x86emu/debug.h" 47706f2543Smrg#include "x86emu/prim_ops.h" 48706f2543Smrg#ifndef NO_SYS_HEADERS 49706f2543Smrg#include <string.h> 50706f2543Smrg#endif 51706f2543Smrg 52706f2543Smrg# ifndef NO_INLINE 53706f2543Smrg# ifdef __GNUC__ 54706f2543Smrg 55706f2543Smrg/* Define some packed structures to use with unaligned accesses */ 56706f2543Smrg 57706f2543Smrgstruct __una_u64 { u64 x __attribute__((packed)); }; 58706f2543Smrgstruct __una_u32 { u32 x __attribute__((packed)); }; 59706f2543Smrgstruct __una_u16 { u16 x __attribute__((packed)); }; 60706f2543Smrg 61706f2543Smrg/* Elemental unaligned loads */ 62706f2543Smrg 63706f2543Smrgstatic __inline__ u64 ldq_u(u64 *p) 64706f2543Smrg{ 65706f2543Smrg const struct __una_u64 *ptr = (const struct __una_u64 *) p; 66706f2543Smrg return ptr->x; 67706f2543Smrg} 68706f2543Smrg 69706f2543Smrgstatic __inline__ u32 ldl_u(u32 *p) 70706f2543Smrg{ 71706f2543Smrg const struct __una_u32 *ptr = (const struct __una_u32 *) p; 72706f2543Smrg return ptr->x; 73706f2543Smrg} 74706f2543Smrg 75706f2543Smrgstatic __inline__ u16 ldw_u(u16 *p) 76706f2543Smrg{ 77706f2543Smrg const struct __una_u16 *ptr = (const struct __una_u16 *) p; 78706f2543Smrg return ptr->x; 79706f2543Smrg} 80706f2543Smrg 81706f2543Smrg/* Elemental unaligned stores */ 82706f2543Smrg 83706f2543Smrgstatic __inline__ void stq_u(u64 val, u64 *p) 84706f2543Smrg{ 85706f2543Smrg struct __una_u64 *ptr = (struct __una_u64 *) p; 86706f2543Smrg ptr->x = val; 87706f2543Smrg} 88706f2543Smrg 89706f2543Smrgstatic __inline__ void stl_u(u32 val, u32 *p) 90706f2543Smrg{ 91706f2543Smrg struct __una_u32 *ptr = (struct __una_u32 *) p; 92706f2543Smrg ptr->x = val; 93706f2543Smrg} 94706f2543Smrg 95706f2543Smrgstatic __inline__ void stw_u(u16 val, u16 *p) 96706f2543Smrg{ 97706f2543Smrg struct __una_u16 *ptr = (struct __una_u16 *) p; 98706f2543Smrg ptr->x = val; 99706f2543Smrg} 100706f2543Smrg# else /* !__GNUC__ */ 101706f2543Smrg 102706f2543Smrgstatic __inline__ u64 ldq_u(u64 *p) 103706f2543Smrg{ 104706f2543Smrg u64 ret; 105706f2543Smrg memmove(&ret, p, sizeof(*p)); 106706f2543Smrg return ret; 107706f2543Smrg} 108706f2543Smrg 109706f2543Smrgstatic __inline__ u32 ldl_u(u32 *p) 110706f2543Smrg{ 111706f2543Smrg u32 ret; 112706f2543Smrg memmove(&ret, p, sizeof(*p)); 113706f2543Smrg return ret; 114706f2543Smrg} 115706f2543Smrg 116706f2543Smrgstatic __inline__ u16 ldw_u(u16 *p) 117706f2543Smrg{ 118706f2543Smrg u16 ret; 119706f2543Smrg memmove(&ret, p, sizeof(*p)); 120706f2543Smrg return ret; 121706f2543Smrg} 122706f2543Smrg 123706f2543Smrgstatic __inline__ void stq_u(u64 val, u64 *p) 124706f2543Smrg{ 125706f2543Smrg u64 tmp = val; 126706f2543Smrg memmove(p, &tmp, sizeof(*p)); 127706f2543Smrg} 128706f2543Smrg 129706f2543Smrgstatic __inline__ void stl_u(u32 val, u32 *p) 130706f2543Smrg{ 131706f2543Smrg u32 tmp = val; 132706f2543Smrg memmove(p, &tmp, sizeof(*p)); 133706f2543Smrg} 134706f2543Smrg 135706f2543Smrgstatic __inline__ void stw_u(u16 val, u16 *p) 136706f2543Smrg{ 137706f2543Smrg u16 tmp = val; 138706f2543Smrg memmove(p, &tmp, sizeof(*p)); 139706f2543Smrg} 140706f2543Smrg 141706f2543Smrg# endif /* __GNUC__ */ 142706f2543Smrg# endif /* NO_INLINE */ 143706f2543Smrg/*------------------------- Global Variables ------------------------------*/ 144706f2543Smrg 145706f2543SmrgX86EMU_sysEnv _X86EMU_env; /* Global emulator machine state */ 146706f2543SmrgX86EMU_intrFuncs _X86EMU_intrTab[256]; 147706f2543Smrg 148706f2543Smrg/*----------------------------- Implementation ----------------------------*/ 149706f2543Smrg 150706f2543Smrg/**************************************************************************** 151706f2543SmrgPARAMETERS: 152706f2543Smrgaddr - Emulator memory address to read 153706f2543Smrg 154706f2543SmrgRETURNS: 155706f2543SmrgByte value read from emulator memory. 156706f2543Smrg 157706f2543SmrgREMARKS: 158706f2543SmrgReads a byte value from the emulator memory. 159706f2543Smrg****************************************************************************/ 160706f2543Smrgu8 X86API rdb( 161706f2543Smrg u32 addr) 162706f2543Smrg{ 163706f2543Smrg u8 val; 164706f2543Smrg 165706f2543Smrg if (addr > M.mem_size - 1) { 166706f2543Smrg DB(printk("mem_read: address %#lx out of range!\n", addr);) 167706f2543Smrg HALT_SYS(); 168706f2543Smrg } 169706f2543Smrg val = *(u8*)(M.mem_base + addr); 170706f2543SmrgDB( if (DEBUG_MEM_TRACE()) 171706f2543Smrg printk("%#08x 1 -> %#x\n", addr, val);) 172706f2543Smrg return val; 173706f2543Smrg} 174706f2543Smrg 175706f2543Smrg/**************************************************************************** 176706f2543SmrgPARAMETERS: 177706f2543Smrgaddr - Emulator memory address to read 178706f2543Smrg 179706f2543SmrgRETURNS: 180706f2543SmrgWord value read from emulator memory. 181706f2543Smrg 182706f2543SmrgREMARKS: 183706f2543SmrgReads a word value from the emulator memory. 184706f2543Smrg****************************************************************************/ 185706f2543Smrgu16 X86API rdw( 186706f2543Smrg u32 addr) 187706f2543Smrg{ 188706f2543Smrg u16 val = 0; 189706f2543Smrg 190706f2543Smrg if (addr > M.mem_size - 2) { 191706f2543Smrg DB(printk("mem_read: address %#lx out of range!\n", addr);) 192706f2543Smrg HALT_SYS(); 193706f2543Smrg } 194706f2543Smrg#ifdef __BIG_ENDIAN__ 195706f2543Smrg if (addr & 0x1) { 196706f2543Smrg val = (*(u8*)(M.mem_base + addr) | 197706f2543Smrg (*(u8*)(M.mem_base + addr + 1) << 8)); 198706f2543Smrg } 199706f2543Smrg else 200706f2543Smrg#endif 201706f2543Smrg val = ldw_u((u16*)(M.mem_base + addr)); 202706f2543Smrg DB( if (DEBUG_MEM_TRACE()) 203706f2543Smrg printk("%#08x 2 -> %#x\n", addr, val);) 204706f2543Smrg return val; 205706f2543Smrg} 206706f2543Smrg 207706f2543Smrg/**************************************************************************** 208706f2543SmrgPARAMETERS: 209706f2543Smrgaddr - Emulator memory address to read 210706f2543Smrg 211706f2543SmrgRETURNS: 212706f2543SmrgLong value read from emulator memory. 213706f2543SmrgREMARKS: 214706f2543SmrgReads a long value from the emulator memory. 215706f2543Smrg****************************************************************************/ 216706f2543Smrgu32 X86API rdl( 217706f2543Smrg u32 addr) 218706f2543Smrg{ 219706f2543Smrg u32 val = 0; 220706f2543Smrg 221706f2543Smrg if (addr > M.mem_size - 4) { 222706f2543Smrg DB(printk("mem_read: address %#lx out of range!\n", addr);) 223706f2543Smrg HALT_SYS(); 224706f2543Smrg } 225706f2543Smrg#ifdef __BIG_ENDIAN__ 226706f2543Smrg if (addr & 0x3) { 227706f2543Smrg val = (*(u8*)(M.mem_base + addr + 0) | 228706f2543Smrg (*(u8*)(M.mem_base + addr + 1) << 8) | 229706f2543Smrg (*(u8*)(M.mem_base + addr + 2) << 16) | 230706f2543Smrg (*(u8*)(M.mem_base + addr + 3) << 24)); 231706f2543Smrg } 232706f2543Smrg else 233706f2543Smrg#endif 234706f2543Smrg val = ldl_u((u32*)(M.mem_base + addr)); 235706f2543SmrgDB( if (DEBUG_MEM_TRACE()) 236706f2543Smrg printk("%#08x 4 -> %#x\n", addr, val);) 237706f2543Smrg return val; 238706f2543Smrg} 239706f2543Smrg 240706f2543Smrg/**************************************************************************** 241706f2543SmrgPARAMETERS: 242706f2543Smrgaddr - Emulator memory address to read 243706f2543Smrgval - Value to store 244706f2543Smrg 245706f2543SmrgREMARKS: 246706f2543SmrgWrites a byte value to emulator memory. 247706f2543Smrg****************************************************************************/ 248706f2543Smrgvoid X86API wrb( 249706f2543Smrg u32 addr, 250706f2543Smrg u8 val) 251706f2543Smrg{ 252706f2543SmrgDB( if (DEBUG_MEM_TRACE()) 253706f2543Smrg printk("%#08x 1 <- %#x\n", addr, val);) 254706f2543Smrg if (addr > M.mem_size - 1) { 255706f2543Smrg DB(printk("mem_write: address %#lx out of range!\n", addr);) 256706f2543Smrg HALT_SYS(); 257706f2543Smrg } 258706f2543Smrg *(u8*)(M.mem_base + addr) = val; 259706f2543Smrg} 260706f2543Smrg 261706f2543Smrg/**************************************************************************** 262706f2543SmrgPARAMETERS: 263706f2543Smrgaddr - Emulator memory address to read 264706f2543Smrgval - Value to store 265706f2543Smrg 266706f2543SmrgREMARKS: 267706f2543SmrgWrites a word value to emulator memory. 268706f2543Smrg****************************************************************************/ 269706f2543Smrgvoid X86API wrw( 270706f2543Smrg u32 addr, 271706f2543Smrg u16 val) 272706f2543Smrg{ 273706f2543SmrgDB( if (DEBUG_MEM_TRACE()) 274706f2543Smrg printk("%#08x 2 <- %#x\n", addr, val);) 275706f2543Smrg if (addr > M.mem_size - 2) { 276706f2543Smrg DB(printk("mem_write: address %#lx out of range!\n", addr);) 277706f2543Smrg HALT_SYS(); 278706f2543Smrg } 279706f2543Smrg#ifdef __BIG_ENDIAN__ 280706f2543Smrg if (addr & 0x1) { 281706f2543Smrg *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff; 282706f2543Smrg *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff; 283706f2543Smrg } 284706f2543Smrg else 285706f2543Smrg#endif 286706f2543Smrg stw_u(val,(u16*)(M.mem_base + addr)); 287706f2543Smrg} 288706f2543Smrg 289706f2543Smrg/**************************************************************************** 290706f2543SmrgPARAMETERS: 291706f2543Smrgaddr - Emulator memory address to read 292706f2543Smrgval - Value to store 293706f2543Smrg 294706f2543SmrgREMARKS: 295706f2543SmrgWrites a long value to emulator memory. 296706f2543Smrg****************************************************************************/ 297706f2543Smrgvoid X86API wrl( 298706f2543Smrg u32 addr, 299706f2543Smrg u32 val) 300706f2543Smrg{ 301706f2543SmrgDB( if (DEBUG_MEM_TRACE()) 302706f2543Smrg printk("%#08x 4 <- %#x\n", addr, val);) 303706f2543Smrg if (addr > M.mem_size - 4) { 304706f2543Smrg DB(printk("mem_write: address %#lx out of range!\n", addr);) 305706f2543Smrg HALT_SYS(); 306706f2543Smrg } 307706f2543Smrg#ifdef __BIG_ENDIAN__ 308706f2543Smrg if (addr & 0x1) { 309706f2543Smrg *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff; 310706f2543Smrg *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff; 311706f2543Smrg *(u8*)(M.mem_base + addr + 2) = (val >> 16) & 0xff; 312706f2543Smrg *(u8*)(M.mem_base + addr + 3) = (val >> 24) & 0xff; 313706f2543Smrg } 314706f2543Smrg else 315706f2543Smrg#endif 316706f2543Smrg stl_u(val,(u32*)(M.mem_base + addr)); 317706f2543Smrg} 318706f2543Smrg 319706f2543Smrg/**************************************************************************** 320706f2543SmrgPARAMETERS: 321706f2543Smrgaddr - PIO address to read 322706f2543SmrgRETURN: 323706f2543Smrg0 324706f2543SmrgREMARKS: 325706f2543SmrgDefault PIO byte read function. Doesn't perform real inb. 326706f2543Smrg****************************************************************************/ 327706f2543Smrgstatic u8 X86API p_inb( 328706f2543Smrg X86EMU_pioAddr addr) 329706f2543Smrg{ 330706f2543SmrgDB( if (DEBUG_IO_TRACE()) 331706f2543Smrg printk("inb %#04x \n", addr);) 332706f2543Smrg return 0; 333706f2543Smrg} 334706f2543Smrg 335706f2543Smrg/**************************************************************************** 336706f2543SmrgPARAMETERS: 337706f2543Smrgaddr - PIO address to read 338706f2543SmrgRETURN: 339706f2543Smrg0 340706f2543SmrgREMARKS: 341706f2543SmrgDefault PIO word read function. Doesn't perform real inw. 342706f2543Smrg****************************************************************************/ 343706f2543Smrgstatic u16 X86API p_inw( 344706f2543Smrg X86EMU_pioAddr addr) 345706f2543Smrg{ 346706f2543SmrgDB( if (DEBUG_IO_TRACE()) 347706f2543Smrg printk("inw %#04x \n", addr);) 348706f2543Smrg return 0; 349706f2543Smrg} 350706f2543Smrg 351706f2543Smrg/**************************************************************************** 352706f2543SmrgPARAMETERS: 353706f2543Smrgaddr - PIO address to read 354706f2543SmrgRETURN: 355706f2543Smrg0 356706f2543SmrgREMARKS: 357706f2543SmrgDefault PIO long read function. Doesn't perform real inl. 358706f2543Smrg****************************************************************************/ 359706f2543Smrgstatic u32 X86API p_inl( 360706f2543Smrg X86EMU_pioAddr addr) 361706f2543Smrg{ 362706f2543SmrgDB( if (DEBUG_IO_TRACE()) 363706f2543Smrg printk("inl %#04x \n", addr);) 364706f2543Smrg return 0; 365706f2543Smrg} 366706f2543Smrg 367706f2543Smrg/**************************************************************************** 368706f2543SmrgPARAMETERS: 369706f2543Smrgaddr - PIO address to write 370706f2543Smrgval - Value to store 371706f2543SmrgREMARKS: 372706f2543SmrgDefault PIO byte write function. Doesn't perform real outb. 373706f2543Smrg****************************************************************************/ 374706f2543Smrgstatic void X86API p_outb( 375706f2543Smrg X86EMU_pioAddr addr, 376706f2543Smrg u8 val) 377706f2543Smrg{ 378706f2543SmrgDB( if (DEBUG_IO_TRACE()) 379706f2543Smrg printk("outb %#02x -> %#04x \n", val, addr);) 380706f2543Smrg return; 381706f2543Smrg} 382706f2543Smrg 383706f2543Smrg/**************************************************************************** 384706f2543SmrgPARAMETERS: 385706f2543Smrgaddr - PIO address to write 386706f2543Smrgval - Value to store 387706f2543SmrgREMARKS: 388706f2543SmrgDefault PIO word write function. Doesn't perform real outw. 389706f2543Smrg****************************************************************************/ 390706f2543Smrgstatic void X86API p_outw( 391706f2543Smrg X86EMU_pioAddr addr, 392706f2543Smrg u16 val) 393706f2543Smrg{ 394706f2543SmrgDB( if (DEBUG_IO_TRACE()) 395706f2543Smrg printk("outw %#04x -> %#04x \n", val, addr);) 396706f2543Smrg return; 397706f2543Smrg} 398706f2543Smrg 399706f2543Smrg/**************************************************************************** 400706f2543SmrgPARAMETERS: 401706f2543Smrgaddr - PIO address to write 402706f2543Smrgval - Value to store 403706f2543SmrgREMARKS: 404706f2543SmrgDefault PIO ;ong write function. Doesn't perform real outl. 405706f2543Smrg****************************************************************************/ 406706f2543Smrgstatic void X86API p_outl( 407706f2543Smrg X86EMU_pioAddr addr, 408706f2543Smrg u32 val) 409706f2543Smrg{ 410706f2543SmrgDB( if (DEBUG_IO_TRACE()) 411706f2543Smrg printk("outl %#08x -> %#04x \n", val, addr);) 412706f2543Smrg return; 413706f2543Smrg} 414706f2543Smrg 415706f2543Smrg/*------------------------- Global Variables ------------------------------*/ 416706f2543Smrg 417706f2543Smrgu8 (X86APIP sys_rdb)(u32 addr) = rdb; 418706f2543Smrgu16 (X86APIP sys_rdw)(u32 addr) = rdw; 419706f2543Smrgu32 (X86APIP sys_rdl)(u32 addr) = rdl; 420706f2543Smrgvoid (X86APIP sys_wrb)(u32 addr,u8 val) = wrb; 421706f2543Smrgvoid (X86APIP sys_wrw)(u32 addr,u16 val) = wrw; 422706f2543Smrgvoid (X86APIP sys_wrl)(u32 addr,u32 val) = wrl; 423706f2543Smrgu8 (X86APIP sys_inb)(X86EMU_pioAddr addr) = p_inb; 424706f2543Smrgu16 (X86APIP sys_inw)(X86EMU_pioAddr addr) = p_inw; 425706f2543Smrgu32 (X86APIP sys_inl)(X86EMU_pioAddr addr) = p_inl; 426706f2543Smrgvoid (X86APIP sys_outb)(X86EMU_pioAddr addr, u8 val) = p_outb; 427706f2543Smrgvoid (X86APIP sys_outw)(X86EMU_pioAddr addr, u16 val) = p_outw; 428706f2543Smrgvoid (X86APIP sys_outl)(X86EMU_pioAddr addr, u32 val) = p_outl; 429706f2543Smrg 430706f2543Smrg/*----------------------------- Setup -------------------------------------*/ 431706f2543Smrg 432706f2543Smrg/**************************************************************************** 433706f2543SmrgPARAMETERS: 434706f2543Smrgfuncs - New memory function pointers to make active 435706f2543Smrg 436706f2543SmrgREMARKS: 437706f2543SmrgThis function is used to set the pointers to functions which access 438706f2543Smrgmemory space, allowing the user application to override these functions 439706f2543Smrgand hook them out as necessary for their application. 440706f2543Smrg****************************************************************************/ 441706f2543Smrgvoid X86EMU_setupMemFuncs( 442706f2543Smrg X86EMU_memFuncs *funcs) 443706f2543Smrg{ 444706f2543Smrg sys_rdb = funcs->rdb; 445706f2543Smrg sys_rdw = funcs->rdw; 446706f2543Smrg sys_rdl = funcs->rdl; 447706f2543Smrg sys_wrb = funcs->wrb; 448706f2543Smrg sys_wrw = funcs->wrw; 449706f2543Smrg sys_wrl = funcs->wrl; 450706f2543Smrg} 451706f2543Smrg 452706f2543Smrg/**************************************************************************** 453706f2543SmrgPARAMETERS: 454706f2543Smrgfuncs - New programmed I/O function pointers to make active 455706f2543Smrg 456706f2543SmrgREMARKS: 457706f2543SmrgThis function is used to set the pointers to functions which access 458706f2543SmrgI/O space, allowing the user application to override these functions 459706f2543Smrgand hook them out as necessary for their application. 460706f2543Smrg****************************************************************************/ 461706f2543Smrgvoid X86EMU_setupPioFuncs( 462706f2543Smrg X86EMU_pioFuncs *funcs) 463706f2543Smrg{ 464706f2543Smrg sys_inb = funcs->inb; 465706f2543Smrg sys_inw = funcs->inw; 466706f2543Smrg sys_inl = funcs->inl; 467706f2543Smrg sys_outb = funcs->outb; 468706f2543Smrg sys_outw = funcs->outw; 469706f2543Smrg sys_outl = funcs->outl; 470706f2543Smrg} 471706f2543Smrg 472706f2543Smrg/**************************************************************************** 473706f2543SmrgPARAMETERS: 474706f2543Smrgfuncs - New interrupt vector table to make active 475706f2543Smrg 476706f2543SmrgREMARKS: 477706f2543SmrgThis function is used to set the pointers to functions which handle 478706f2543Smrginterrupt processing in the emulator, allowing the user application to 479706f2543Smrghook interrupts as necessary for their application. Any interrupts that 480706f2543Smrgare not hooked by the user application, and reflected and handled internally 481706f2543Smrgin the emulator via the interrupt vector table. This allows the application 482706f2543Smrgto get control when the code being emulated executes specific software 483706f2543Smrginterrupts. 484706f2543Smrg****************************************************************************/ 485706f2543Smrgvoid X86EMU_setupIntrFuncs( 486706f2543Smrg X86EMU_intrFuncs funcs[]) 487706f2543Smrg{ 488706f2543Smrg int i; 489706f2543Smrg 490706f2543Smrg for (i=0; i < 256; i++) 491706f2543Smrg _X86EMU_intrTab[i] = NULL; 492706f2543Smrg if (funcs) { 493706f2543Smrg for (i = 0; i < 256; i++) 494706f2543Smrg _X86EMU_intrTab[i] = funcs[i]; 495706f2543Smrg } 496706f2543Smrg} 497706f2543Smrg 498706f2543Smrg/**************************************************************************** 499706f2543SmrgPARAMETERS: 500706f2543Smrgint - New software interrupt to prepare for 501706f2543Smrg 502706f2543SmrgREMARKS: 503706f2543SmrgThis function is used to set up the emulator state to exceute a software 504706f2543Smrginterrupt. This can be used by the user application code to allow an 505706f2543Smrginterrupt to be hooked, examined and then reflected back to the emulator 506706f2543Smrgso that the code in the emulator will continue processing the software 507706f2543Smrginterrupt as per normal. This essentially allows system code to actively 508706f2543Smrghook and handle certain software interrupts as necessary. 509706f2543Smrg****************************************************************************/ 510706f2543Smrgvoid X86EMU_prepareForInt( 511706f2543Smrg int num) 512706f2543Smrg{ 513706f2543Smrg push_word((u16)M.x86.R_FLG); 514706f2543Smrg CLEAR_FLAG(F_IF); 515706f2543Smrg CLEAR_FLAG(F_TF); 516706f2543Smrg push_word(M.x86.R_CS); 517706f2543Smrg M.x86.R_CS = mem_access_word(num * 4 + 2); 518706f2543Smrg push_word(M.x86.R_IP); 519706f2543Smrg M.x86.R_IP = mem_access_word(num * 4); 520706f2543Smrg M.x86.intr = 0; 521706f2543Smrg} 522