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.
7 * This code is licensed under the LGPL.
8 * <insert LGPL legal text here>
16 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
26 #include <hw/cpu/cpu.h>
27 #include <hw/dos/dos.h>
28 #include <hw/dos/doswin.h>
29 #include <hw/dos/dosntvdm.h>
31 #if TARGET_MSDOS == 16 || (TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2))
32 unsigned short smartdrv_version = 0xFFFF;
36 #if (TARGET_MSDOS == 16 || TARGET_MSDOS == 32) && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2)
37 int smartdrv_close() {
38 if (smartdrv_fd >= 0) {
46 int smartdrv_flush() {
47 if (smartdrv_version == 0xFFFF || smartdrv_version == 0)
50 if (smartdrv_version >= 0x400) { /* SMARTDRV 4.xx and later */
51 #if TARGET_MSDOS == 32
55 mov eax,0x4A10 ; SMARTDRV
56 mov ebx,0x0001 ; FLUSH BUFFERS (COMMIT CACHE)
65 mov ax,0x4A10 ; SMARTDRV
66 mov bx,0x0001 ; FLUSH BUFFERS (COMMIT CACHE)
73 else if (smartdrv_version >= 0x300 && smartdrv_version <= 0x3FF) { /* SMARTDRV 3.xx */
75 #if TARGET_MSDOS == 32
77 char far *bptr = (char far*)buffer;
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 */
95 mov ax,0x4403 ; IOCTL SMARTAAR CACHE CONTROL
97 mov cx,0x1 ; 0x01 bytes
98 lds dx,word ptr [bptr]
101 mov rd,ax ; CF=0, AX=bytes written
117 int smartdrv_detect() {
118 unsigned int rvax=0,rvbp=0;
120 if (smartdrv_version == 0xFFFF) {
121 /* Is Microsoft SMARTDRV 4.x or equivalent disk cache present? */
123 #if TARGET_MSDOS == 32
133 mov eax,0x4A10 ; SMARTDRV 4.xx INSTALLATION CHECK AND HIT RATIOS
135 mov ecx,0xEBAB ; "BABE" backwards
137 int 0x2F ; multiplex (hope your DOS extender supports it properly!)
139 mov ebx,ebp ; copy EBP to EBX. Watcom C uses EBP to refer to the stack!
141 mov rvax,eax ; we only care about EAX and EBP(now EBX)
160 mov ax,0x4A10 ; SMARTDRV 4.xx INSTALLATION CHECK AND HIT RATIOS
162 mov cx,0xEBAB ; "BABE" backwards
166 mov bx,bp ; copy BP to BX. Watcom C uses BP to refer to the stack!
168 mov rvax,ax ; we only care about EAX and EBP(now EBX)
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 */
184 if (smartdrv_version == 0xFFFF) {
186 #if TARGET_MSDOS == 32
188 char far *bptr = (char far*)buffer;
192 memset(buffer,0,sizeof(buffer));
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 */
208 mov ax,0x4402 ; IOCTL SMARTAAR GET CACHE STATUS
210 mov cx,0x28 ; 0x28 bytes
211 lds dx,word ptr [bptr]
214 mov rd,ax ; CF=0, AX=bytes read
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]);
236 /* didn't find anything. then no SMARTDRV */
237 if (smartdrv_version == 0xFFFF)
238 smartdrv_version = 0;
241 return (smartdrv_version != 0);