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