]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/dos/dos_nmi.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / dos / dos_nmi.c
1 /* dos.c
2  *
3  * Code to detect the surrounding DOS/Windows environment and support routines to work with it
4  * (C) 2009-2012 Jonathan Campbell.
5  * Hackipedia DOS library.
6  *
7  * This code is licensed under the LGPL.
8  * <insert LGPL legal text here>
9  */
10
11 #ifdef TARGET_WINDOWS
12 # include <windows.h>
13 #endif
14
15 #include <stdio.h>
16 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
17 #include <stdlib.h>
18 #include <string.h>
19 #include <stddef.h>
20 #include <unistd.h>
21 #include <malloc.h>
22 #include <assert.h>
23 #include <fcntl.h>
24 #include <dos.h>
25
26 #include <hw/cpu/cpu.h>
27 #include <hw/dos/dos.h>
28 #include <hw/dos/doswin.h>
29 #include <hw/dos/dosntvdm.h>
30
31 #if TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2)
32 /* TODO: This should be moved into the hw/DOS library */
33 unsigned char                   nmi_32_hooked = 0;
34 int                             nmi_32_refcount = 0;
35 void                            (interrupt *nmi_32_old_vec)() = NULL;
36 #endif
37
38 #if TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2)
39 /* NMI reflection (32-bit -> 16-bit)
40    This code is VITAL if we want to work with SBOS and MEGA-EM
41    from protected mode. */
42 static struct dpmi_realmode_call nmi_32_nr={0};
43 static void interrupt far nmi_32() {
44         /* trigger a real-mode INT 02h */
45         __asm {
46                 mov     ax,0x0300
47                 mov     bx,0x02
48                 xor     cx,cx
49                 mov     edi,offset nmi_32_nr    ; we trust Watcom has left ES == DS
50                 int     0x31                    ; call DPMI
51         }
52 }
53
54 void do_nmi_32_unhook() {
55         if (nmi_32_refcount > 0)
56                 nmi_32_refcount--;
57
58         if (nmi_32_refcount == 0) {
59                 if (nmi_32_hooked) {
60                         nmi_32_hooked = 0;
61                         _dos_setvect(0x02,nmi_32_old_vec);
62                         nmi_32_old_vec = NULL;
63                 }
64         }
65 }
66
67 void do_nmi_32_hook() {
68         if (nmi_32_refcount == 0) {
69                 if (!nmi_32_hooked) {
70                         nmi_32_hooked = 1;
71                         nmi_32_old_vec = _dos_getvect(0x02);
72                         _dos_setvect(0x02,nmi_32);
73                 }
74         }
75         nmi_32_refcount++;
76 }
77 #endif
78