]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/dos/ddpmidsc.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / dos / ddpmidsc.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 /* TODO: Windows 3.1/95/98/ME have a DPMI server underneath.
32  *       It would be neato at some point if these functions were
33  *       available for use from Windows 3.1 Win16/Win32, and
34  *       Windows 95/98/ME Win32 */
35 #if TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2)
36 void dpmi_free_descriptor(uint16_t d) {
37         union REGS regs = {0};
38         regs.w.ax = 0x0001;     /* DPMI free descriptor */
39         regs.w.bx = d;
40         int386(0x31,&regs,&regs);
41 }
42
43 uint16_t dpmi_alloc_descriptors(uint16_t c) {
44         union REGS regs = {0};
45         regs.w.ax = 0x0000;     /* allocate descriptor */
46         regs.w.cx = 1;          /* just one */
47         int386(0x31,&regs,&regs);
48         if (regs.w.cflag & 1) return 0;
49         return regs.w.ax;
50 }
51
52 unsigned int dpmi_set_segment_base(uint16_t sel,uint32_t base) {
53         union REGS regs = {0};
54         regs.w.ax = 0x0007;     /* set segment base */
55         regs.w.bx = sel;
56         regs.w.cx = base >> 16UL;
57         regs.w.dx = base;
58         int386(0x31,&regs,&regs);
59         if (regs.w.cflag & 1) return 0;
60         return 1;
61 }
62
63 unsigned int dpmi_set_segment_limit(uint16_t sel,uint32_t limit) {
64         union REGS regs = {0};
65         regs.w.ax = 0x0008;     /* set segment limit */
66         regs.w.bx = sel;
67         regs.w.cx = limit >> 16UL;
68         regs.w.dx = limit;
69         int386(0x31,&regs,&regs);
70         if (regs.w.cflag & 1) return 0;
71         return 1;
72 }
73
74 unsigned int dpmi_set_segment_access(uint16_t sel,uint16_t access) {
75         union REGS regs = {0};
76         unsigned char c=0;
77
78         /* the DPL/CPL value we give to the DPMI function below must match our privilege level, so
79          * get that value from our own selector */
80         __asm {
81                 push    eax
82                 movzx   eax,sel
83                 and     al,3
84                 mov     c,al
85                 pop     eax
86         }
87
88         regs.w.ax = 0x0009;     /* set segment access rights */
89         regs.w.bx = sel;
90         regs.w.cx = (access & 0xFF9F) | (c << 5);       /* readable, code, CPL=same, present=1, 16-bit byte granular */
91         int386(0x31,&regs,&regs);
92         if (regs.w.cflag & 1) return 0;
93         return 1;
94 }
95 #endif
96