Release 970305
[wine/multimedia.git] / msdos / int2f.c
blobd8dbae1b33781b67d438863e5a20802261fb39f7
1 /*
2 * DOS interrupt 2fh handler
3 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include "ldt.h"
10 #include "drive.h"
11 #include "msdos.h"
12 #include "miscemu.h"
13 #include "module.h"
14 #include "options.h"
15 #include "stddebug.h"
16 /* #define DEBUG_INT */
17 #include "debug.h"
19 /* base WPROCS.DLL ordinal number for VxDs */
20 #define VXD_BASE 400
22 static void do_int2f_16( CONTEXT *context );
23 void do_mscdex( CONTEXT *context );
25 /**********************************************************************
26 * INT_Int2fHandler
28 * Handler for int 2fh (multiplex).
30 void INT_Int2fHandler( CONTEXT *context )
32 switch(AH_reg(context))
34 case 0x10:
35 AL_reg(context) = 0xff; /* share is installed */
36 break;
38 case 0x15: /* mscdex */
39 do_mscdex(context);
40 break;
42 case 0x16:
43 do_int2f_16( context );
44 break;
46 case 0x4a:
47 switch(AL_reg(context))
49 case 0x10: /* smartdrv */
50 break; /* not installed */
51 case 0x11: /* dblspace */
52 break; /* not installed */
53 case 0x12: /* realtime compression interface */
54 break; /* not installed */
55 default:
56 INT_BARF( context, 0x2f );
58 break;
59 case 0xb7: /* append */
60 AL_reg(context) = 0; /* not installed */
61 break;
62 default:
63 INT_BARF( context, 0x2f );
64 break;
69 /**********************************************************************
70 * do_int2f_16
72 static void do_int2f_16( CONTEXT *context )
74 DWORD addr;
76 switch(AL_reg(context))
78 case 0x00: /* Windows enhanced mode installation check */
79 AX_reg(context) = (Options.mode == MODE_ENHANCED) ? WINVERSION : 0;
80 break;
82 case 0x0a: /* Get Windows version and type */
83 AX_reg(context) = 0;
84 BX_reg(context) = (WINVERSION >> 8) | ((WINVERSION << 8) & 0xff00);
85 CX_reg(context) = (Options.mode == MODE_ENHANCED) ? 3 : 2;
86 break;
88 case 0x80: /* Release time-slice */
89 AL_reg(context) = 0;
90 /* FIXME: We need to do something that lets some other process run
91 here. */
92 sleep(0);
93 break;
95 case 0x83: /* Return Current Virtual Machine ID */
96 /* Virtual Machines are usually created/destroyed when Windows runs
97 * DOS programs. Since we never do, we are always in the System VM.
98 * According to Ralf Brown's Interrupt List, never return 0. But it
99 * seems to work okay (returning 0), just to be sure we return 1.
101 BX_reg(context) = 1; /* VM 1 is probably the System VM */
102 break;
104 case 0x84: /* Get device API entry point */
105 addr = (DWORD)MODULE_GetEntryPoint( GetModuleHandle16("WPROCS"),
106 VXD_BASE + BX_reg(context) );
107 if (!addr) /* not supported */
109 fprintf( stderr,"Application attempted to access VxD %04x\n",
110 BX_reg(context) );
111 fprintf( stderr,"This device is not known to Wine.");
112 fprintf( stderr,"Expect a failure now\n");
114 ES_reg(context) = SELECTOROF(addr);
115 DI_reg(context) = OFFSETOF(addr);
116 break;
118 case 0x86: /* DPMI detect mode */
119 AX_reg(context) = 0; /* Running under DPMI */
120 break;
122 /* FIXME: is this right? Specs say that this should only be callable
123 in real (v86) mode which we never enter. */
124 case 0x87: /* DPMI installation check */
126 SYSTEM_INFO si;
128 GetSystemInfo(&si);
129 AX_reg(context) = 0x0000; /* DPMI Installed */
130 BX_reg(context) = 0x0001; /* 32bits available */
131 CL_reg(context) = si.wProcessorLevel;
132 DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
133 SI_reg(context) = 0; /* # of para. of DOS extended private data */
134 ES_reg(context) = 0; /* ES:DI is DPMI switch entry point */
135 DI_reg(context) = 0;
136 break;
138 case 0x8a: /* DPMI get vendor-specific API entry point. */
139 /* The 1.0 specs say this should work with all 0.9 hosts. */
140 break;
142 default:
143 INT_BARF( context, 0x2f );
147 void do_mscdex( CONTEXT *context )
149 int drive, count;
150 char *p;
152 switch(AL_reg(context))
154 case 0x00: /* Installation check */
155 /* Count the number of contiguous CDROM drives
157 for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
159 if (DRIVE_GetType(drive) == TYPE_CDROM)
161 while (DRIVE_GetType(drive + count) == TYPE_CDROM) count++;
162 break;
166 BX_reg(context) = count;
167 CX_reg(context) = (drive < MAX_DOS_DRIVES) ? drive : 0;
168 break;
170 case 0x0B: /* drive check */
171 AX_reg(context) = (DRIVE_GetType(CX_reg(context)) == TYPE_CDROM);
172 BX_reg(context) = 0xADAD;
173 break;
175 case 0x0C: /* get version */
176 BX_reg(context) = 0x020a;
177 break;
179 case 0x0D: /* get drive letters */
180 p = PTR_SEG_OFF_TO_LIN(ES_reg(context), BX_reg(context));
181 memset( p, 0, MAX_DOS_DRIVES );
182 for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
184 if (DRIVE_GetType(drive) == TYPE_CDROM) *p++ = drive;
186 break;
188 default:
189 fprintf(stderr, "Unimplemented MSCDEX function 0x%02.2X.\n", AL_reg(context));
190 break;