Release 970824
[wine/multimedia.git] / msdos / int2f.c
blobb43e3b254da9202eb42d58cd2057ccc6d4f02dac
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 "stddebug.h"
15 /* #define DEBUG_INT */
16 #include "debug.h"
18 /* base WPROCS.DLL ordinal number for VxDs */
19 #define VXD_BASE 400
21 static void do_int2f_16( CONTEXT *context );
22 void do_mscdex( CONTEXT *context );
24 /**********************************************************************
25 * INT_Int2fHandler
27 * Handler for int 2fh (multiplex).
29 void WINAPI INT_Int2fHandler( CONTEXT *context )
31 switch(AH_reg(context))
33 case 0x10:
34 AL_reg(context) = 0xff; /* share is installed */
35 break;
37 case 0x15: /* mscdex */
38 do_mscdex(context);
39 break;
41 case 0x16:
42 do_int2f_16( context );
43 break;
45 case 0x4a:
46 switch(AL_reg(context))
48 case 0x10: /* smartdrv */
49 break; /* not installed */
50 case 0x11: /* dblspace */
51 break; /* not installed */
52 case 0x12: /* realtime compression interface */
53 break; /* not installed */
54 default:
55 INT_BARF( context, 0x2f );
57 break;
58 case 0xb7: /* append */
59 AL_reg(context) = 0; /* not installed */
60 break;
61 default:
62 INT_BARF( context, 0x2f );
63 break;
68 /**********************************************************************
69 * do_int2f_16
71 static void do_int2f_16( CONTEXT *context )
73 DWORD addr;
75 switch(AL_reg(context))
77 case 0x00: /* Windows enhanced mode installation check */
78 AX_reg(context) = (GetWinFlags() & WF_ENHANCED) ?
79 LOWORD(GetVersion16()) : 0;
80 break;
82 case 0x0a: /* Get Windows version and type */
83 AX_reg(context) = 0;
84 BX_reg(context) = (LOWORD(GetVersion16()) << 8) |
85 (LOWORD(GetVersion16()) >> 8);
86 CX_reg(context) = (GetWinFlags() & WF_ENHANCED) ? 3 : 2;
87 break;
89 case 0x80: /* Release time-slice */
90 AL_reg(context) = 0;
91 /* FIXME: We need to do something that lets some other process run
92 here. */
93 sleep(0);
94 break;
96 case 0x83: /* Return Current Virtual Machine ID */
97 /* Virtual Machines are usually created/destroyed when Windows runs
98 * DOS programs. Since we never do, we are always in the System VM.
99 * According to Ralf Brown's Interrupt List, never return 0. But it
100 * seems to work okay (returning 0), just to be sure we return 1.
102 BX_reg(context) = 1; /* VM 1 is probably the System VM */
103 break;
105 case 0x84: /* Get device API entry point */
106 addr = (DWORD)MODULE_GetEntryPoint( GetModuleHandle16("WPROCS"),
107 VXD_BASE + BX_reg(context) );
108 if (!addr) /* not supported */
110 fprintf( stderr,"Application attempted to access VxD %04x\n",
111 BX_reg(context) );
112 fprintf( stderr,"This device is not known to Wine.");
113 fprintf( stderr,"Expect a failure now\n");
115 ES_reg(context) = SELECTOROF(addr);
116 DI_reg(context) = OFFSETOF(addr);
117 break;
119 case 0x86: /* DPMI detect mode */
120 AX_reg(context) = 0; /* Running under DPMI */
121 break;
123 /* FIXME: is this right? Specs say that this should only be callable
124 in real (v86) mode which we never enter. */
125 case 0x87: /* DPMI installation check */
127 SYSTEM_INFO si;
129 GetSystemInfo(&si);
130 AX_reg(context) = 0x0000; /* DPMI Installed */
131 BX_reg(context) = 0x0001; /* 32bits available */
132 CL_reg(context) = si.wProcessorLevel;
133 DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
134 SI_reg(context) = 0; /* # of para. of DOS extended private data */
135 ES_reg(context) = 0; /* ES:DI is DPMI switch entry point */
136 DI_reg(context) = 0;
137 break;
139 case 0x8a: /* DPMI get vendor-specific API entry point. */
140 /* The 1.0 specs say this should work with all 0.9 hosts. */
141 break;
143 default:
144 INT_BARF( context, 0x2f );
148 void do_mscdex( CONTEXT *context )
150 int drive, count;
151 char *p;
153 switch(AL_reg(context))
155 case 0x00: /* Installation check */
156 /* Count the number of contiguous CDROM drives
158 for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
160 if (DRIVE_GetType(drive) == TYPE_CDROM)
162 while (DRIVE_GetType(drive + count) == TYPE_CDROM) count++;
163 break;
167 BX_reg(context) = count;
168 CX_reg(context) = (drive < MAX_DOS_DRIVES) ? drive : 0;
169 break;
171 case 0x0B: /* drive check */
172 AX_reg(context) = (DRIVE_GetType(CX_reg(context)) == TYPE_CDROM);
173 BX_reg(context) = 0xADAD;
174 break;
176 case 0x0C: /* get version */
177 BX_reg(context) = 0x020a;
178 break;
180 case 0x0D: /* get drive letters */
181 p = PTR_SEG_OFF_TO_LIN(ES_reg(context), BX_reg(context));
182 memset( p, 0, MAX_DOS_DRIVES );
183 for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
185 if (DRIVE_GetType(drive) == TYPE_CDROM) *p++ = drive;
187 break;
189 default:
190 fprintf(stderr, "Unimplemented MSCDEX function 0x%02.2X.\n", AL_reg(context));
191 break;