]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/dos/dossmdrv.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / dos / dossmdrv.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 == 16 || (TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2))
32 unsigned short smartdrv_version = 0xFFFF;
33 int smartdrv_fd = -1;
34 #endif
35
36 #if (TARGET_MSDOS == 16 || TARGET_MSDOS == 32) && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2)
37 int smartdrv_close() {
38         if (smartdrv_fd >= 0) {
39                 close(smartdrv_fd);
40                 smartdrv_fd = -1;
41         }
42
43         return 0;
44 }
45
46 int smartdrv_flush() {
47         if (smartdrv_version == 0xFFFF || smartdrv_version == 0)
48                 return 0;
49
50         if (smartdrv_version >= 0x400) { /* SMARTDRV 4.xx and later */
51 #if TARGET_MSDOS == 32
52                 __asm {
53                         push    eax
54                         push    ebx
55                         mov     eax,0x4A10              ; SMARTDRV
56                         mov     ebx,0x0001              ; FLUSH BUFFERS (COMMIT CACHE)
57                         int     0x2F
58                         pop     ebx
59                         pop     eax
60                 }
61 #else
62                 __asm {
63                         push    ax
64                         push    bx
65                         mov     ax,0x4A10               ; SMARTDRV
66                         mov     bx,0x0001               ; FLUSH BUFFERS (COMMIT CACHE)
67                         int     0x2F
68                         pop     bx
69                         pop     ax
70                 }
71 #endif
72         }
73         else if (smartdrv_version >= 0x300 && smartdrv_version <= 0x3FF) { /* SMARTDRV 3.xx */
74                 char buffer[0x1];
75 #if TARGET_MSDOS == 32
76 #else
77                 char far *bptr = (char far*)buffer;
78 #endif
79                 int rd=0;
80
81                 if (smartdrv_fd < 0)
82                         return 0;
83
84                 buffer[0] = 0; /* flush cache */
85 #if TARGET_MSDOS == 32
86                 /* FIXME: We do not yet have a 32-bit protected mode version.
87                  *        DOS extenders do not appear to translate AX=0x4403 properly */
88 #else
89                 __asm {
90                         push    ax
91                         push    bx
92                         push    cx
93                         push    dx
94                         push    ds
95                         mov     ax,0x4403               ; IOCTL SMARTAAR CACHE CONTROL
96                         mov     bx,smartdrv_fd
97                         mov     cx,0x1                  ; 0x01 bytes
98                         lds     dx,word ptr [bptr]
99                         int     0x21
100                         jc      err1
101                         mov     rd,ax                   ; CF=0, AX=bytes written
102 err1:                   pop     ds
103                         pop     dx
104                         pop     cx
105                         pop     bx
106                         pop     ax
107                 }
108 #endif
109
110                 if (rd == 0)
111                         return 0;
112         }
113
114         return 1;
115 }
116
117 int smartdrv_detect() {
118         unsigned int rvax=0,rvbp=0;
119
120         if (smartdrv_version == 0xFFFF) {
121                 /* Is Microsoft SMARTDRV 4.x or equivalent disk cache present? */
122
123 #if TARGET_MSDOS == 32
124                 __asm {
125                         push    eax
126                         push    ebx
127                         push    ecx
128                         push    edx
129                         push    esi
130                         push    edi
131                         push    ebp
132                         push    ds
133                         mov     eax,0x4A10              ; SMARTDRV 4.xx INSTALLATION CHECK AND HIT RATIOS
134                         mov     ebx,0
135                         mov     ecx,0xEBAB              ; "BABE" backwards
136                         xor     ebp,ebp
137                         int     0x2F                    ; multiplex (hope your DOS extender supports it properly!)
138                         pop     ds
139                         mov     ebx,ebp                 ; copy EBP to EBX. Watcom C uses EBP to refer to the stack!
140                         pop     ebp
141                         mov     rvax,eax                ; we only care about EAX and EBP(now EBX)
142                         mov     rvbp,ebx
143                         pop     edi
144                         pop     esi
145                         pop     edx
146                         pop     ecx
147                         pop     ebx
148                         pop     eax
149                 }
150 #else
151                 __asm {
152                         push    ax
153                         push    bx
154                         push    cx
155                         push    dx
156                         push    si
157                         push    di
158                         push    bp
159                         push    ds
160                         mov     ax,0x4A10               ; SMARTDRV 4.xx INSTALLATION CHECK AND HIT RATIOS
161                         mov     bx,0
162                         mov     cx,0xEBAB               ; "BABE" backwards
163                         xor     bp,bp
164                         int     0x2F                    ; multiplex
165                         pop     ds
166                         mov     bx,bp                   ; copy BP to BX. Watcom C uses BP to refer to the stack!
167                         pop     bp
168                         mov     rvax,ax                 ; we only care about EAX and EBP(now EBX)
169                         mov     rvbp,bx
170                         pop     di
171                         pop     si
172                         pop     dx
173                         pop     cx
174                         pop     bx
175                         pop     ax
176                 }
177 #endif
178
179                 if ((rvax&0xFFFF) == 0xBABE && (rvbp&0xFFFF) >= 0x400 && (rvbp&0xFFFF) <= 0x5FF) {
180                         /* yup. SMARTDRV 4.xx! */
181                         smartdrv_version = (rvbp&0xFF00) + (((rvbp>>4)&0xF) * 10) + (rvbp&0xF); /* convert BCD to decimal */
182                 }
183
184                 if (smartdrv_version == 0xFFFF) {
185                         char buffer[0x28];
186 #if TARGET_MSDOS == 32
187 #else
188                         char far *bptr = (char far*)buffer;
189 #endif
190                         int rd=0;
191
192                         memset(buffer,0,sizeof(buffer));
193
194                         /* check for SMARTDRV 3.xx */
195                         smartdrv_fd = open("SMARTAAR",O_RDONLY);
196                         if (smartdrv_fd >= 0) {
197                                 /* FIXME: The DOS library should provide a common function to do IOCTL read/write character "control channel" functions */
198 #if TARGET_MSDOS == 32
199                                 /* FIXME: We do not yet have a 32-bit protected mode version.
200                                  *        DOS extenders do not appear to translate AX=0x4402 properly */
201 #else
202                                 __asm {
203                                         push    ax
204                                         push    bx
205                                         push    cx
206                                         push    dx
207                                         push    ds
208                                         mov     ax,0x4402               ; IOCTL SMARTAAR GET CACHE STATUS
209                                         mov     bx,smartdrv_fd
210                                         mov     cx,0x28                 ; 0x28 bytes
211                                         lds     dx,word ptr [bptr]
212                                         int     0x21
213                                         jc      err1
214                                         mov     rd,ax                   ; CF=0, AX=bytes read
215 err1:                                   pop     ds
216                                         pop     dx
217                                         pop     cx
218                                         pop     bx
219                                         pop     ax
220                                 }
221 #endif
222
223                                 /* NTS: Despite reading back 0x28 bytes of data, this IOCTL
224                                  *      returns AX=1 for some reason. */
225                                 if (rd > 0 && rd <= 0x28) {
226                                         if (buffer[0] == 1/*write through flag*/ && buffer[15] == 3/*major version number*/) { /* SMARTDRV 3.xx */
227                                                 smartdrv_version = ((unsigned short)buffer[15] << 8) + ((unsigned short)buffer[14]);
228                                         }
229                                         else {
230                                                 close(smartdrv_fd);
231                                         }
232                                 }
233                         }
234                 }
235
236                 /* didn't find anything. then no SMARTDRV */
237                 if (smartdrv_version == 0xFFFF)
238                         smartdrv_version = 0;
239         }
240
241         return (smartdrv_version != 0);
242 }
243 #endif
244