]>
Commit | Line | Data |
---|---|---|
93afd047 MT |
1 | /**************************************************************************** |
2 | * | |
3 | * Realmode X86 Emulator Library | |
4 | * | |
5 | * Copyright (C) 1996-1999 SciTech Software, Inc. | |
6 | * Copyright (C) David Mosberger-Tang | |
7 | * Copyright (C) 1999 Egbert Eich | |
8 | * | |
9 | * ======================================================================== | |
10 | * | |
11 | * Permission to use, copy, modify, distribute, and sell this software and | |
12 | * its documentation for any purpose is hereby granted without fee, | |
13 | * provided that the above copyright notice appear in all copies and that | |
14 | * both that copyright notice and this permission notice appear in | |
15 | * supporting documentation, and that the name of the authors not be used | |
16 | * in advertising or publicity pertaining to distribution of the software | |
17 | * without specific, written prior permission. The authors makes no | |
18 | * representations about the suitability of this software for any purpose. | |
19 | * It is provided "as is" without express or implied warranty. | |
20 | * | |
21 | * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
22 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
23 | * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
24 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |
25 | * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | |
26 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
27 | * PERFORMANCE OF THIS SOFTWARE. | |
28 | * | |
29 | * ======================================================================== | |
30 | * | |
31 | * Language: ANSI C | |
32 | * Environment: Any | |
33 | * Developer: Kendall Bennett | |
34 | * | |
35 | * Description: This file includes subroutines which are related to | |
36 | * programmed I/O and memory access. Included in this module | |
37 | * are default functions with limited usefulness. For real | |
38 | * uses these functions will most likely be overriden by the | |
39 | * user library. | |
40 | * | |
41 | ****************************************************************************/ | |
42 | /* $XFree86: xc/extras/x86emu/src/x86emu/sys.c,v 1.6 2002/09/16 18:05:18 eich Exp $ */ | |
43 | ||
44 | #include "x86emu.h" | |
45 | #include "x86emu/x86emui.h" | |
46 | #include "x86emu/regs.h" | |
47 | #include "x86emu/debug.h" | |
48 | #include "x86emu/prim_ops.h" | |
49 | #ifdef IN_MODULE | |
50 | #include "xf86_ansic.h" | |
51 | #else | |
52 | #include <string.h> | |
53 | #endif | |
54 | /*------------------------- Global Variables ------------------------------*/ | |
55 | ||
56 | X86EMU_sysEnv _X86EMU_env; /* Global emulator machine state */ | |
57 | X86EMU_intrFuncs _X86EMU_intrTab[256]; | |
58 | ||
59 | /*----------------------------- Implementation ----------------------------*/ | |
60 | #if defined(__alpha__) || defined(__alpha) | |
61 | /* to cope with broken egcs-1.1.2 :-(((( */ | |
62 | ||
63 | #define ALPHA_UALOADS | |
64 | /* | |
65 | * inline functions to do unaligned accesses | |
66 | * from linux/include/asm-alpha/unaligned.h | |
67 | */ | |
68 | ||
69 | /* | |
70 | * EGCS 1.1 knows about arbitrary unaligned loads. Define some | |
71 | * packed structures to talk about such things with. | |
72 | */ | |
73 | ||
74 | #if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91)) | |
75 | struct __una_u64 { unsigned long x __attribute__((packed)); }; | |
76 | struct __una_u32 { unsigned int x __attribute__((packed)); }; | |
77 | struct __una_u16 { unsigned short x __attribute__((packed)); }; | |
78 | #endif | |
79 | ||
80 | static __inline__ unsigned long ldq_u(unsigned long * r11) | |
81 | { | |
82 | #if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91)) | |
83 | const struct __una_u64 *ptr = (const struct __una_u64 *) r11; | |
84 | return ptr->x; | |
85 | #else | |
86 | unsigned long r1,r2; | |
87 | __asm__("ldq_u %0,%3\n\t" | |
88 | "ldq_u %1,%4\n\t" | |
89 | "extql %0,%2,%0\n\t" | |
90 | "extqh %1,%2,%1" | |
91 | :"=&r" (r1), "=&r" (r2) | |
92 | :"r" (r11), | |
93 | "m" (*r11), | |
94 | "m" (*(const unsigned long *)(7+(char *) r11))); | |
95 | return r1 | r2; | |
96 | #endif | |
97 | } | |
98 | ||
99 | static __inline__ unsigned long ldl_u(unsigned int * r11) | |
100 | { | |
101 | #if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91)) | |
102 | const struct __una_u32 *ptr = (const struct __una_u32 *) r11; | |
103 | return ptr->x; | |
104 | #else | |
105 | unsigned long r1,r2; | |
106 | __asm__("ldq_u %0,%3\n\t" | |
107 | "ldq_u %1,%4\n\t" | |
108 | "extll %0,%2,%0\n\t" | |
109 | "extlh %1,%2,%1" | |
110 | :"=&r" (r1), "=&r" (r2) | |
111 | :"r" (r11), | |
112 | "m" (*r11), | |
113 | "m" (*(const unsigned long *)(3+(char *) r11))); | |
114 | return r1 | r2; | |
115 | #endif | |
116 | } | |
117 | ||
118 | static __inline__ unsigned long ldw_u(unsigned short * r11) | |
119 | { | |
120 | #if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91)) | |
121 | const struct __una_u16 *ptr = (const struct __una_u16 *) r11; | |
122 | return ptr->x; | |
123 | #else | |
124 | unsigned long r1,r2; | |
125 | __asm__("ldq_u %0,%3\n\t" | |
126 | "ldq_u %1,%4\n\t" | |
127 | "extwl %0,%2,%0\n\t" | |
128 | "extwh %1,%2,%1" | |
129 | :"=&r" (r1), "=&r" (r2) | |
130 | :"r" (r11), | |
131 | "m" (*r11), | |
132 | "m" (*(const unsigned long *)(1+(char *) r11))); | |
133 | return r1 | r2; | |
134 | #endif | |
135 | } | |
136 | ||
137 | /* | |
138 | * Elemental unaligned stores | |
139 | */ | |
140 | ||
141 | static __inline__ void stq_u(unsigned long r5, unsigned long * r11) | |
142 | { | |
143 | #if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91)) | |
144 | struct __una_u64 *ptr = (struct __una_u64 *) r11; | |
145 | ptr->x = r5; | |
146 | #else | |
147 | unsigned long r1,r2,r3,r4; | |
148 | ||
149 | __asm__("ldq_u %3,%1\n\t" | |
150 | "ldq_u %2,%0\n\t" | |
151 | "insqh %6,%7,%5\n\t" | |
152 | "insql %6,%7,%4\n\t" | |
153 | "mskqh %3,%7,%3\n\t" | |
154 | "mskql %2,%7,%2\n\t" | |
155 | "bis %3,%5,%3\n\t" | |
156 | "bis %2,%4,%2\n\t" | |
157 | "stq_u %3,%1\n\t" | |
158 | "stq_u %2,%0" | |
159 | :"=m" (*r11), | |
160 | "=m" (*(unsigned long *)(7+(char *) r11)), | |
161 | "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4) | |
162 | :"r" (r5), "r" (r11)); | |
163 | #endif | |
164 | } | |
165 | ||
166 | static __inline__ void stl_u(unsigned long r5, unsigned int * r11) | |
167 | { | |
168 | #if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91)) | |
169 | struct __una_u32 *ptr = (struct __una_u32 *) r11; | |
170 | ptr->x = r5; | |
171 | #else | |
172 | unsigned long r1,r2,r3,r4; | |
173 | ||
174 | __asm__("ldq_u %3,%1\n\t" | |
175 | "ldq_u %2,%0\n\t" | |
176 | "inslh %6,%7,%5\n\t" | |
177 | "insll %6,%7,%4\n\t" | |
178 | "msklh %3,%7,%3\n\t" | |
179 | "mskll %2,%7,%2\n\t" | |
180 | "bis %3,%5,%3\n\t" | |
181 | "bis %2,%4,%2\n\t" | |
182 | "stq_u %3,%1\n\t" | |
183 | "stq_u %2,%0" | |
184 | :"=m" (*r11), | |
185 | "=m" (*(unsigned long *)(3+(char *) r11)), | |
186 | "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4) | |
187 | :"r" (r5), "r" (r11)); | |
188 | #endif | |
189 | } | |
190 | ||
191 | static __inline__ void stw_u(unsigned long r5, unsigned short * r11) | |
192 | { | |
193 | #if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC_MINOR__ >= 91)) | |
194 | struct __una_u16 *ptr = (struct __una_u16 *) r11; | |
195 | ptr->x = r5; | |
196 | #else | |
197 | unsigned long r1,r2,r3,r4; | |
198 | ||
199 | __asm__("ldq_u %3,%1\n\t" | |
200 | "ldq_u %2,%0\n\t" | |
201 | "inswh %6,%7,%5\n\t" | |
202 | "inswl %6,%7,%4\n\t" | |
203 | "mskwh %3,%7,%3\n\t" | |
204 | "mskwl %2,%7,%2\n\t" | |
205 | "bis %3,%5,%3\n\t" | |
206 | "bis %2,%4,%2\n\t" | |
207 | "stq_u %3,%1\n\t" | |
208 | "stq_u %2,%0" | |
209 | :"=m" (*r11), | |
210 | "=m" (*(unsigned long *)(1+(char *) r11)), | |
211 | "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4) | |
212 | :"r" (r5), "r" (r11)); | |
213 | #endif | |
214 | } | |
215 | ||
216 | #elif defined(__GNUC__) && ((__GNUC__ < 3)) && \ | |
217 | (defined (__ia64__) || defined (ia64__)) | |
218 | #define IA64_UALOADS | |
219 | /* | |
220 | * EGCS 1.1 knows about arbitrary unaligned loads. Define some | |
221 | * packed structures to talk about such things with. | |
222 | */ | |
223 | struct __una_u64 { unsigned long x __attribute__((packed)); }; | |
224 | struct __una_u32 { unsigned int x __attribute__((packed)); }; | |
225 | struct __una_u16 { unsigned short x __attribute__((packed)); }; | |
226 | ||
227 | static __inline__ unsigned long | |
228 | __uldq (const unsigned long * r11) | |
229 | { | |
230 | const struct __una_u64 *ptr = (const struct __una_u64 *) r11; | |
231 | return ptr->x; | |
232 | } | |
233 | ||
234 | static __inline__ unsigned long | |
235 | uldl (const unsigned int * r11) | |
236 | { | |
237 | const struct __una_u32 *ptr = (const struct __una_u32 *) r11; | |
238 | return ptr->x; | |
239 | } | |
240 | ||
241 | static __inline__ unsigned long | |
242 | uldw (const unsigned short * r11) | |
243 | { | |
244 | const struct __una_u16 *ptr = (const struct __una_u16 *) r11; | |
245 | return ptr->x; | |
246 | } | |
247 | ||
248 | static __inline__ void | |
249 | ustq (unsigned long r5, unsigned long * r11) | |
250 | { | |
251 | struct __una_u64 *ptr = (struct __una_u64 *) r11; | |
252 | ptr->x = r5; | |
253 | } | |
254 | ||
255 | static __inline__ void | |
256 | ustl (unsigned long r5, unsigned int * r11) | |
257 | { | |
258 | struct __una_u32 *ptr = (struct __una_u32 *) r11; | |
259 | ptr->x = r5; | |
260 | } | |
261 | ||
262 | static __inline__ void | |
263 | ustw (unsigned long r5, unsigned short * r11) | |
264 | { | |
265 | struct __una_u16 *ptr = (struct __una_u16 *) r11; | |
266 | ptr->x = r5; | |
267 | } | |
268 | ||
269 | #endif | |
270 | ||
271 | /**************************************************************************** | |
272 | PARAMETERS: | |
273 | addr - Emulator memory address to read | |
274 | ||
275 | RETURNS: | |
276 | Byte value read from emulator memory. | |
277 | ||
278 | REMARKS: | |
279 | Reads a byte value from the emulator memory. | |
280 | ****************************************************************************/ | |
281 | u8 X86API rdb( | |
282 | u32 addr) | |
283 | { | |
284 | u8 val; | |
285 | ||
286 | if (addr > M.mem_size - 1) { | |
287 | DB(printk("mem_read: address %#lx out of range!\n", addr);) | |
288 | HALT_SYS(); | |
289 | } | |
290 | val = *(u8*)(M.mem_base + addr); | |
291 | DB( if (DEBUG_MEM_TRACE()) | |
292 | printk("%#08x 1 -> %#x\n", addr, val);) | |
293 | return val; | |
294 | } | |
295 | ||
296 | /**************************************************************************** | |
297 | PARAMETERS: | |
298 | addr - Emulator memory address to read | |
299 | ||
300 | RETURNS: | |
301 | Word value read from emulator memory. | |
302 | ||
303 | REMARKS: | |
304 | Reads a word value from the emulator memory. | |
305 | ****************************************************************************/ | |
306 | u16 X86API rdw( | |
307 | u32 addr) | |
308 | { | |
309 | u16 val = 0; | |
310 | ||
311 | if (addr > M.mem_size - 2) { | |
312 | DB(printk("mem_read: address %#lx out of range!\n", addr);) | |
313 | HALT_SYS(); | |
314 | } | |
315 | #ifdef __BIG_ENDIAN__ | |
316 | if (addr & 0x1) { | |
317 | val = (*(u8*)(M.mem_base + addr) | | |
318 | (*(u8*)(M.mem_base + addr + 1) << 8)); | |
319 | } | |
320 | else | |
321 | #endif | |
322 | #if defined(ALPHA_UALOADS) | |
323 | val = ldw_u((u16*)(M.mem_base + addr)); | |
324 | #elif defined(IA64_UALOADS) | |
325 | val = uldw((u16*)(M.mem_base + addr)); | |
326 | #else | |
327 | val = *(u16*)(M.mem_base + addr); | |
328 | #endif | |
329 | DB( if (DEBUG_MEM_TRACE()) | |
330 | printk("%#08x 2 -> %#x\n", addr, val);) | |
331 | return val; | |
332 | } | |
333 | ||
334 | /**************************************************************************** | |
335 | PARAMETERS: | |
336 | addr - Emulator memory address to read | |
337 | ||
338 | RETURNS: | |
339 | Long value read from emulator memory. | |
340 | REMARKS: | |
341 | Reads a long value from the emulator memory. | |
342 | ****************************************************************************/ | |
343 | u32 X86API rdl( | |
344 | u32 addr) | |
345 | { | |
346 | u32 val = 0; | |
347 | ||
348 | if (addr > M.mem_size - 4) { | |
349 | DB(printk("mem_read: address %#lx out of range!\n", addr);) | |
350 | HALT_SYS(); | |
351 | } | |
352 | #ifdef __BIG_ENDIAN__ | |
353 | if (addr & 0x3) { | |
354 | val = (*(u8*)(M.mem_base + addr + 0) | | |
355 | (*(u8*)(M.mem_base + addr + 1) << 8) | | |
356 | (*(u8*)(M.mem_base + addr + 2) << 16) | | |
357 | (*(u8*)(M.mem_base + addr + 3) << 24)); | |
358 | } | |
359 | else | |
360 | #endif | |
361 | #if defined(ALPHA_UALOADS) | |
362 | val = ldl_u((u32*)(M.mem_base + addr)); | |
363 | #elif defined(IA64_UALOADS) | |
364 | val = uldl((u32*)(M.mem_base + addr)); | |
365 | #else | |
366 | val = *(u32*)(M.mem_base + addr); | |
367 | #endif | |
368 | DB( if (DEBUG_MEM_TRACE()) | |
369 | printk("%#08x 4 -> %#x\n", addr, val);) | |
370 | return val; | |
371 | } | |
372 | ||
373 | /**************************************************************************** | |
374 | PARAMETERS: | |
375 | addr - Emulator memory address to read | |
376 | val - Value to store | |
377 | ||
378 | REMARKS: | |
379 | Writes a byte value to emulator memory. | |
380 | ****************************************************************************/ | |
381 | void X86API wrb( | |
382 | u32 addr, | |
383 | u8 val) | |
384 | { | |
385 | DB( if (DEBUG_MEM_TRACE()) | |
386 | printk("%#08x 1 <- %#x\n", addr, val);) | |
387 | if (addr > M.mem_size - 1) { | |
388 | DB(printk("mem_write: address %#lx out of range!\n", addr);) | |
389 | HALT_SYS(); | |
390 | } | |
391 | *(u8*)(M.mem_base + addr) = val; | |
392 | } | |
393 | ||
394 | /**************************************************************************** | |
395 | PARAMETERS: | |
396 | addr - Emulator memory address to read | |
397 | val - Value to store | |
398 | ||
399 | REMARKS: | |
400 | Writes a word value to emulator memory. | |
401 | ****************************************************************************/ | |
402 | void X86API wrw( | |
403 | u32 addr, | |
404 | u16 val) | |
405 | { | |
406 | DB( if (DEBUG_MEM_TRACE()) | |
407 | printk("%#08x 2 <- %#x\n", addr, val);) | |
408 | if (addr > M.mem_size - 2) { | |
409 | DB(printk("mem_write: address %#lx out of range!\n", addr);) | |
410 | HALT_SYS(); | |
411 | } | |
412 | #ifdef __BIG_ENDIAN__ | |
413 | if (addr & 0x1) { | |
414 | *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff; | |
415 | *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff; | |
416 | } | |
417 | else | |
418 | #endif | |
419 | #if defined(ALPHA_UALOADS) | |
420 | stw_u(val,(u16*)(M.mem_base + addr)); | |
421 | #elif defined(IA64_UALOADS) | |
422 | ustw(val,(u16*)(M.mem_base + addr)); | |
423 | #else | |
424 | *(u16*)(M.mem_base + addr) = val; | |
425 | #endif | |
426 | } | |
427 | ||
428 | /**************************************************************************** | |
429 | PARAMETERS: | |
430 | addr - Emulator memory address to read | |
431 | val - Value to store | |
432 | ||
433 | REMARKS: | |
434 | Writes a long value to emulator memory. | |
435 | ****************************************************************************/ | |
436 | void X86API wrl( | |
437 | u32 addr, | |
438 | u32 val) | |
439 | { | |
440 | DB( if (DEBUG_MEM_TRACE()) | |
441 | printk("%#08x 4 <- %#x\n", addr, val);) | |
442 | if (addr > M.mem_size - 4) { | |
443 | DB(printk("mem_write: address %#lx out of range!\n", addr);) | |
444 | HALT_SYS(); | |
445 | } | |
446 | #ifdef __BIG_ENDIAN__ | |
447 | if (addr & 0x1) { | |
448 | *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff; | |
449 | *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff; | |
450 | *(u8*)(M.mem_base + addr + 2) = (val >> 16) & 0xff; | |
451 | *(u8*)(M.mem_base + addr + 3) = (val >> 24) & 0xff; | |
452 | } | |
453 | else | |
454 | #endif | |
455 | #if defined(ALPHA_UALOADS) | |
456 | stl_u(val,(u32*)(M.mem_base + addr)); | |
457 | #elif defined(IA64_UALOADS) | |
458 | ustl(val,(u32*)(M.mem_base + addr)); | |
459 | #else | |
460 | *(u32*)(M.mem_base + addr) = val; | |
461 | #endif | |
462 | } | |
463 | ||
464 | /**************************************************************************** | |
465 | PARAMETERS: | |
466 | addr - PIO address to read | |
467 | RETURN: | |
468 | 0 | |
469 | REMARKS: | |
470 | Default PIO byte read function. Doesn't perform real inb. | |
471 | ****************************************************************************/ | |
472 | static u8 X86API p_inb( | |
473 | X86EMU_pioAddr addr) | |
474 | { | |
475 | DB( if (DEBUG_IO_TRACE()) | |
476 | printk("inb %#04x \n", addr);) | |
477 | return 0; | |
478 | } | |
479 | ||
480 | /**************************************************************************** | |
481 | PARAMETERS: | |
482 | addr - PIO address to read | |
483 | RETURN: | |
484 | 0 | |
485 | REMARKS: | |
486 | Default PIO word read function. Doesn't perform real inw. | |
487 | ****************************************************************************/ | |
488 | static u16 X86API p_inw( | |
489 | X86EMU_pioAddr addr) | |
490 | { | |
491 | DB( if (DEBUG_IO_TRACE()) | |
492 | printk("inw %#04x \n", addr);) | |
493 | return 0; | |
494 | } | |
495 | ||
496 | /**************************************************************************** | |
497 | PARAMETERS: | |
498 | addr - PIO address to read | |
499 | RETURN: | |
500 | 0 | |
501 | REMARKS: | |
502 | Default PIO long read function. Doesn't perform real inl. | |
503 | ****************************************************************************/ | |
504 | static u32 X86API p_inl( | |
505 | X86EMU_pioAddr addr) | |
506 | { | |
507 | DB( if (DEBUG_IO_TRACE()) | |
508 | printk("inl %#04x \n", addr);) | |
509 | return 0; | |
510 | } | |
511 | ||
512 | /**************************************************************************** | |
513 | PARAMETERS: | |
514 | addr - PIO address to write | |
515 | val - Value to store | |
516 | REMARKS: | |
517 | Default PIO byte write function. Doesn't perform real outb. | |
518 | ****************************************************************************/ | |
519 | static void X86API p_outb( | |
520 | X86EMU_pioAddr addr, | |
521 | u8 val) | |
522 | { | |
523 | DB( if (DEBUG_IO_TRACE()) | |
524 | printk("outb %#02x -> %#04x \n", val, addr);) | |
525 | return; | |
526 | } | |
527 | ||
528 | /**************************************************************************** | |
529 | PARAMETERS: | |
530 | addr - PIO address to write | |
531 | val - Value to store | |
532 | REMARKS: | |
533 | Default PIO word write function. Doesn't perform real outw. | |
534 | ****************************************************************************/ | |
535 | static void X86API p_outw( | |
536 | X86EMU_pioAddr addr, | |
537 | u16 val) | |
538 | { | |
539 | DB( if (DEBUG_IO_TRACE()) | |
540 | printk("outw %#04x -> %#04x \n", val, addr);) | |
541 | return; | |
542 | } | |
543 | ||
544 | /**************************************************************************** | |
545 | PARAMETERS: | |
546 | addr - PIO address to write | |
547 | val - Value to store | |
548 | REMARKS: | |
549 | Default PIO ;ong write function. Doesn't perform real outl. | |
550 | ****************************************************************************/ | |
551 | static void X86API p_outl( | |
552 | X86EMU_pioAddr addr, | |
553 | u32 val) | |
554 | { | |
555 | DB( if (DEBUG_IO_TRACE()) | |
556 | printk("outl %#08x -> %#04x \n", val, addr);) | |
557 | return; | |
558 | } | |
559 | ||
560 | /*------------------------- Global Variables ------------------------------*/ | |
561 | ||
562 | u8 (X86APIP sys_rdb)(u32 addr) = rdb; | |
563 | u16 (X86APIP sys_rdw)(u32 addr) = rdw; | |
564 | u32 (X86APIP sys_rdl)(u32 addr) = rdl; | |
565 | void (X86APIP sys_wrb)(u32 addr,u8 val) = wrb; | |
566 | void (X86APIP sys_wrw)(u32 addr,u16 val) = wrw; | |
567 | void (X86APIP sys_wrl)(u32 addr,u32 val) = wrl; | |
568 | u8 (X86APIP sys_inb)(X86EMU_pioAddr addr) = p_inb; | |
569 | u16 (X86APIP sys_inw)(X86EMU_pioAddr addr) = p_inw; | |
570 | u32 (X86APIP sys_inl)(X86EMU_pioAddr addr) = p_inl; | |
571 | void (X86APIP sys_outb)(X86EMU_pioAddr addr, u8 val) = p_outb; | |
572 | void (X86APIP sys_outw)(X86EMU_pioAddr addr, u16 val) = p_outw; | |
573 | void (X86APIP sys_outl)(X86EMU_pioAddr addr, u32 val) = p_outl; | |
574 | ||
575 | /*----------------------------- Setup -------------------------------------*/ | |
576 | ||
577 | /**************************************************************************** | |
578 | PARAMETERS: | |
579 | funcs - New memory function pointers to make active | |
580 | ||
581 | REMARKS: | |
582 | This function is used to set the pointers to functions which access | |
583 | memory space, allowing the user application to override these functions | |
584 | and hook them out as necessary for their application. | |
585 | ****************************************************************************/ | |
586 | void X86EMU_setupMemFuncs( | |
587 | X86EMU_memFuncs *funcs) | |
588 | { | |
589 | sys_rdb = funcs->rdb; | |
590 | sys_rdw = funcs->rdw; | |
591 | sys_rdl = funcs->rdl; | |
592 | sys_wrb = funcs->wrb; | |
593 | sys_wrw = funcs->wrw; | |
594 | sys_wrl = funcs->wrl; | |
595 | } | |
596 | ||
597 | /**************************************************************************** | |
598 | PARAMETERS: | |
599 | funcs - New programmed I/O function pointers to make active | |
600 | ||
601 | REMARKS: | |
602 | This function is used to set the pointers to functions which access | |
603 | I/O space, allowing the user application to override these functions | |
604 | and hook them out as necessary for their application. | |
605 | ****************************************************************************/ | |
606 | void X86EMU_setupPioFuncs( | |
607 | X86EMU_pioFuncs *funcs) | |
608 | { | |
609 | sys_inb = funcs->inb; | |
610 | sys_inw = funcs->inw; | |
611 | sys_inl = funcs->inl; | |
612 | sys_outb = funcs->outb; | |
613 | sys_outw = funcs->outw; | |
614 | sys_outl = funcs->outl; | |
615 | } | |
616 | ||
617 | /**************************************************************************** | |
618 | PARAMETERS: | |
619 | funcs - New interrupt vector table to make active | |
620 | ||
621 | REMARKS: | |
622 | This function is used to set the pointers to functions which handle | |
623 | interrupt processing in the emulator, allowing the user application to | |
624 | hook interrupts as necessary for their application. Any interrupts that | |
625 | are not hooked by the user application, and reflected and handled internally | |
626 | in the emulator via the interrupt vector table. This allows the application | |
627 | to get control when the code being emulated executes specific software | |
628 | interrupts. | |
629 | ****************************************************************************/ | |
630 | void X86EMU_setupIntrFuncs( | |
631 | X86EMU_intrFuncs funcs[]) | |
632 | { | |
633 | int i; | |
634 | ||
635 | for (i=0; i < 256; i++) | |
636 | _X86EMU_intrTab[i] = NULL; | |
637 | if (funcs) { | |
638 | for (i = 0; i < 256; i++) | |
639 | _X86EMU_intrTab[i] = funcs[i]; | |
640 | } | |
641 | } | |
642 | ||
643 | /**************************************************************************** | |
644 | PARAMETERS: | |
645 | int - New software interrupt to prepare for | |
646 | ||
647 | REMARKS: | |
648 | This function is used to set up the emulator state to exceute a software | |
649 | interrupt. This can be used by the user application code to allow an | |
650 | interrupt to be hooked, examined and then reflected back to the emulator | |
651 | so that the code in the emulator will continue processing the software | |
652 | interrupt as per normal. This essentially allows system code to actively | |
653 | hook and handle certain software interrupts as necessary. | |
654 | ****************************************************************************/ | |
655 | void X86EMU_prepareForInt( | |
656 | int num) | |
657 | { | |
658 | push_word((u16)M.x86.R_FLG); | |
659 | CLEAR_FLAG(F_IF); | |
660 | CLEAR_FLAG(F_TF); | |
661 | push_word(M.x86.R_CS); | |
662 | M.x86.R_CS = mem_access_word(num * 4 + 2); | |
663 | push_word(M.x86.R_IP); | |
664 | M.x86.R_IP = mem_access_word(num * 4); | |
665 | M.x86.intr = 0; | |
666 | } |