INT13 / floppy handling from CW

Duane Clark dclark at akamail.com
Sat Jan 26 14:32:38 CST 2002


This patch from codeweavers is a major rewrite of INT13/floppy handling.

Modified files:
	files			: drive.c
	files			: dos_fs.c
	files			: file.c
	include			: drive.h
	msdos			: int13.c
	win32			: device.c

Log message:
	Codeweavers
	Rewrite of INT13/floppy handling.

-------------- next part --------------
Index: files/drive.c
===================================================================
RCS file: /home/wine/wine/files/drive.c,v
retrieving revision 1.64
diff -u -r1.64 drive.c
--- files/drive.c	2002/01/13 01:44:00	1.64
+++ files/drive.c	2002/01/26 18:30:59
@@ -71,6 +71,7 @@
     UINT      flags;     /* drive flags */
     dev_t     dev;       /* unix device number */
     ino_t     ino;       /* unix inode number */
+    unsigned char floppy_params[13]; /* drive paramaters table for floppies */
 } DOSDRIVE;
 
 
@@ -139,6 +140,32 @@
 }
 
 
+/**********************************************************************
+ *	    DRIVE_GetFloppyParams
+ */
+unsigned char *DRIVE_GetFloppyParams(BYTE drive_nr)
+{
+    if( ! DRIVE_IsValid(drive_nr) )
+        return NULL;
+    if( DOSDrives[drive_nr].type != DRIVE_REMOVABLE )
+        return NULL;
+
+    return DOSDrives[drive_nr].floppy_params;
+}
+
+static unsigned char DRIVE_default_params[] = { 
+    0xaf, 0x02, 0x25, 0x02, 0x12, 0x1b, 0xff, 0x6c, 0xf6, 0x0f, 0x08
+};
+
+/**********************************************************************
+ *	    DRIVE_GetFloppyParams
+ */
+static void DRIVE_InitFloppyParams(DOSDRIVE *drive)
+{
+    memcpy(drive->floppy_params,DRIVE_default_params,
+           sizeof DRIVE_default_params);
+}
+
 /***********************************************************************
  *           DRIVE_GetFSFlags
  */
@@ -212,6 +239,9 @@
             drive->flags    = 0;
             drive->dev      = drive_stat_buffer.st_dev;
             drive->ino      = drive_stat_buffer.st_ino;
+
+            if(drive->type == DRIVE_REMOVABLE)
+               DRIVE_InitFloppyParams(drive);
 
             /* Get the drive label */
             PROFILE_GetWineIniString( name, "Label", "", drive->label_conf, 12 );
Index: files/dos_fs.c
===================================================================
RCS file: /home/wine/wine/files/dos_fs.c,v
retrieving revision 1.99
diff -u -r1.99 dos_fs.c
--- files/dos_fs.c	2001/11/30 18:46:45	1.99
+++ files/dos_fs.c	2002/01/26 18:31:01
@@ -59,6 +59,12 @@
 #undef VFAT_IOCTL_READDIR_BOTH  /* just in case... */
 #endif  /* linux */
 
+/* 
+ * HACK HACK UMSDOS reports handling this, but then fails to perserve case
+ * the umsdos peopls are working on this, but for now...
+ */ 
+#undef VFAT_IOCTL_READDIR_BOTH 
+
 /* Chars we don't want to see in DOS file names */
 #define INVALID_DOS_CHARS  "*?<>|\"+=,;[] \345"
 
@@ -1218,15 +1224,16 @@
     char drivecur[]="c:.";
     char driveletter=0;
     int namelen,drive=0;
+
+    if (!name[0]) return 0;
 
-    if ((strlen(name) >1)&& (name[1]==':'))
-      /* drive letter given */
+    if (name[1]==':')
+      /*drive letter given */
       {
 	driveletter = name[0];
       }
-    if ((strlen(name) >2)&& (name[1]==':') &&
-	     ((name[2]=='\\') || (name[2]=='/')))
-      /* absolute path given */
+    if ((name[1]==':') && ((name[2]=='\\') || (name[2]=='/')))
+      /*absolute path given */
       {
 	lstrcpynA(full_name.short_name,name,MAX_PATHNAME_LEN);
 	drive = (int)FILE_toupper(name[0]) - 'A';
Index: files/file.c
===================================================================
RCS file: /home/wine/wine/files/file.c,v
retrieving revision 1.131
diff -u -r1.131 file.c
--- files/file.c	2002/01/21 17:37:24	1.131
+++ files/file.c	2002/01/26 18:31:02
@@ -417,7 +417,7 @@
         SetLastError( ERROR_INVALID_PARAMETER );
         return INVALID_HANDLE_VALUE;
     }
-    TRACE("%s %s%s%s%s%s%s%s\n",filename,
+    TRACE("%s %s%s%s%s%s%s%s attributes 0x%lx\n",filename,
 	  ((access & GENERIC_READ)==GENERIC_READ)?"GENERIC_READ ":"",
 	  ((access & GENERIC_WRITE)==GENERIC_WRITE)?"GENERIC_WRITE ":"",
 	  (!access)?"QUERY_ACCESS ":"",
@@ -428,7 +428,7 @@
 	  (creation ==CREATE_ALWAYS)?"CREATE_ALWAYS ":
 	  (creation ==OPEN_EXISTING)?"OPEN_EXISTING ":
 	  (creation ==OPEN_ALWAYS)?"OPEN_ALWAYS ":
-	  (creation ==TRUNCATE_EXISTING)?"TRUNCATE_EXISTING ":"");
+	  (creation ==TRUNCATE_EXISTING)?"TRUNCATE_EXISTING ":"", attributes);
 
     /* If the name starts with '\\?\', ignore the first 4 chars. */
     if (!strncmp(filename, "\\\\?\\", 4))
@@ -516,6 +516,7 @@
                            GetDriveTypeA( full_name.short_name ) );
  done:
     if (!ret) ret = INVALID_HANDLE_VALUE;
+    TRACE("returning %08x\n", ret);
     return ret;
 }
 
@@ -1529,9 +1530,12 @@
 	    return FALSE;    
 	if (overlapped)
 	{
+	    ERR("ovelapped parameter ignored\n");
+#if 0
 	    close(unix_handle);
 	    SetLastError(ERROR_INVALID_PARAMETER);
 	    return FALSE;
+#endif
 	}
 	break;
     }
@@ -2048,6 +2052,7 @@
 BOOL WINAPI DeleteFileA( LPCSTR path )
 {
     DOS_FULL_NAME full_name;
+    HANDLE hFile;
 
     if (!path)
     {
@@ -2069,6 +2074,12 @@
     }
 
     if (!DOSFS_GetFullName( path, TRUE, &full_name )) return FALSE;
+
+    /* check, if we are allowed to delete the source */
+    hFile = CreateFileA(full_name.long_name, 0, 0, NULL, OPEN_EXISTING, 0, 0);
+    if(hFile == INVALID_HANDLE_VALUE) return FALSE;
+    CloseHandle(hFile);
+
     if (unlink( full_name.long_name ) == -1)
     {
         FILE_SetDosError();
@@ -2123,6 +2134,7 @@
 BOOL WINAPI MoveFileExA( LPCSTR fn1, LPCSTR fn2, DWORD flag )
 {
     DOS_FULL_NAME full_name1, full_name2;
+    HANDLE hFile;
 
     TRACE("(%s,%s,%04lx)\n", fn1, fn2, flag);
 
@@ -2159,6 +2171,18 @@
                   full_name1.long_name, full_name2.long_name);
             return TRUE;
         }
+
+	/* check, if we are allowed to delete the source */
+	hFile = CreateFileA(full_name1.long_name, 0, 0, NULL, OPEN_EXISTING, 0, 0);
+	if(hFile == INVALID_HANDLE_VALUE) return FALSE;
+	CloseHandle(hFile);
+
+	/* check, if we are allowed to delete the destination, 
+        **     (but the file not being there is fine) */
+	hFile = CreateFileA(full_name2.long_name, 0, 0, NULL, OPEN_EXISTING, 0, 0);
+	if(hFile == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_NOT_FOUND) 
+            return FALSE;
+	CloseHandle(hFile);
 
         if (full_name1.drive != full_name2.drive)
         {
Index: include/drive.h
===================================================================
RCS file: /home/wine/wine/include/drive.h,v
retrieving revision 1.8
diff -u -r1.8 drive.h
--- include/drive.h	2000/12/12 00:44:43	1.8
+++ include/drive.h	2002/01/26 18:31:02
@@ -41,5 +41,6 @@
 extern int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD length, BYTE *dataptr, BOOL fake_success );
 extern int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD length, BYTE *dataptr, BOOL fake_success );
 extern char *DRIVE_BuildEnv(void);
+extern unsigned char *DRIVE_GetFloppyParams(BYTE drive);
 
 #endif  /* __WINE_DRIVE_H */
Index: msdos/int13.c
===================================================================
RCS file: /home/wine/wine/msdos/int13.c,v
retrieving revision 1.10
diff -u -r1.10 int13.c
--- msdos/int13.c	2001/06/20 23:03:18	1.10
+++ msdos/int13.c	2002/01/26 18:31:02
@@ -2,21 +2,46 @@
  * BIOS interrupt 13h handler
  */
 
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#ifdef linux
-# include <linux/fd.h>
-#endif
-#include "miscemu.h"
-/* #define DEBUG_INT */
+#include <winbase.h>
+#include <winioctl.h>
+
 #include "debugtools.h"
-#include "drive.h"
 
 DEFAULT_DEBUG_CHANNEL(int);
 
+static void DIOCRegs_2_CONTEXT( DIOC_REGISTERS *pIn, CONTEXT86 *pCxt )
+{
+    memset( pCxt, 0, sizeof(*pCxt) );
+    /* Note: segment registers == 0 means that CTX_SEG_OFF_TO_LIN
+             will interpret 32-bit register contents as linear pointers */
+
+    pCxt->ContextFlags=CONTEXT86_INTEGER|CONTEXT86_CONTROL;
+    pCxt->Eax = pIn->reg_EAX;
+    pCxt->Ebx = pIn->reg_EBX;
+    pCxt->Ecx = pIn->reg_ECX;
+    pCxt->Edx = pIn->reg_EDX;
+    pCxt->Esi = pIn->reg_ESI;
+    pCxt->Edi = pIn->reg_EDI;
+
+    /* FIXME: Only partial CONTEXT86_CONTROL */
+    pCxt->EFlags = pIn->reg_Flags;
+}
+
+static void CONTEXT_2_DIOCRegs( CONTEXT86 *pCxt, DIOC_REGISTERS *pOut )
+{
+    memset( pOut, 0, sizeof(DIOC_REGISTERS) );
+
+    pOut->reg_EAX = pCxt->Eax;
+    pOut->reg_EBX = pCxt->Ebx;
+    pOut->reg_ECX = pCxt->Ecx;
+    pOut->reg_EDX = pCxt->Edx;
+    pOut->reg_ESI = pCxt->Esi;
+    pOut->reg_EDI = pCxt->Edi;
+
+    /* FIXME: Only partial CONTEXT86_CONTROL */
+    pOut->reg_Flags = pCxt->EFlags;
+}
+
 /**********************************************************************
  *	    INT_Int13Handler (WPROCS.119)
  *
@@ -24,156 +49,29 @@
  */
 void WINAPI INT_Int13Handler( CONTEXT86 *context )
 {
-    switch(AH_reg(context))
-    {
-	case 0x00:                            /* RESET DISK SYSTEM     */
-		break; /* no return ? */
-	case 0x01:			      /* STATUS OF DISK SYSTEM */
-		AL_reg(context) = 0; /* successful completion */
-		break;
-	case 0x02:			      /* READ SECTORS INTO MEMORY */
-		AL_reg(context) = 0; /* number of sectors read */
-		AH_reg(context) = 0; /* status */
-		break;
-	case 0x03:			      /* WRITE SECTORS FROM MEMORY */
-		break; /* no return ? */
-	case 0x04:                            /* VERIFY DISK SECTOR(S) */
-		AL_reg(context) = 0; /* number of sectors verified */
-		AH_reg(context) = 0;
-		break;
-	       
-	case 0x05:                                     /* FORMAT TRACK */
-        case 0x06:             /* FORMAT TRACK AND SET BAD SECTOR FLAGS */
-        case 0x07:             /* FORMAT DRIVE STARTING AT GIVEN TRACK  */
-            /* despite what Ralf Brown says, 0x06 and 0x07 seem to
-             * set CFLAG, too (at least my BIOS does that) */
-            AH_reg(context) = 0x0c;
-            SET_CFLAG(context);
-            break;
-
-	case 0x08:                              /* GET DRIVE PARAMETERS  */
-		if (DL_reg(context) & 0x80) { /* hard disk ? */
-			AH_reg(context) = 0x07;
-			SET_CFLAG(context);
-		}
-		else { /* floppy disk */
-#ifdef linux
-			unsigned int i, nr_of_drives = 0;			
-			BYTE drive_nr = DL_reg(context);
-                        int floppy_fd;
-                        struct floppy_drive_params floppy_parm;
-                        char root[] = "A:\\";
-
-                        AH_reg(context) = 0x00; /* success */
-
-                        for (i = 0; i < MAX_DOS_DRIVES; i++, root[0]++)
-                            if (GetDriveTypeA(root) == DRIVE_REMOVABLE) nr_of_drives++;
-                        DL_reg(context) = nr_of_drives;
-
-			if (drive_nr > 1) { /* invalid drive ? */
-				BX_reg(context) = 0;
-				CX_reg(context) = 0;
-				DH_reg(context) = 0;
-				break;
-			}
+    HANDLE hVWin32;
+    DIOC_REGISTERS regs;
+    DWORD dwRet;
+
+    hVWin32 = CreateFileA("\\\\.\\VWIN32", GENERIC_READ|GENERIC_WRITE, 
+               0, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
 
-                        if ( (floppy_fd = DRIVE_OpenDevice( drive_nr, O_NONBLOCK)) == -1)
+    if(hVWin32!=INVALID_HANDLE_VALUE)
                         {
-                                WARN("(GET DRIVE PARAMETERS): Can't determine floppy geometry !\n");
-                                BX_reg(context) = 0;
-                                CX_reg(context) = 0;
-                                DH_reg(context) = 0;
-                                break;
-                        }
-                        ioctl(floppy_fd, FDGETDRVPRM, &floppy_parm);
-                        close(floppy_fd);
-
-			BL_reg(context) = floppy_parm.cmos;
-
-			/* CH = low eight bits of max cyl
-			   CL = max sec nr (bits 5-0),
-			   hi two bits of max cyl (bits 7-6)
-			   DH = max head nr */ 
-			DH_reg(context) = 0x01;
-			switch (BL_reg(context))
-			{
-			    case 0: /* no drive */
-				CX_reg(context) = 0x0;
-				DX_reg(context) = 0x0;
-				break;
-			    case 1: /* 360 K */
-				CX_reg(context) = 0x2709;
-				break;
-			    case 2: /* 1.2 M */
-				CX_reg(context) = 0x4f0f;
-				break;
-			    case 3: /* 720 K */
-				CX_reg(context) = 0x4f09;
-				break;
-			    case 4: /* 1.44 M */
-				CX_reg(context) = 0x4f12;
-				break;
-			    case 5:
-			    case 6: /* 2.88 M */
-				CX_reg(context) = 0x4f24;
-				break;
-			}
-			context->SegEs = 0x0000; /* FIXME: drive parameter table */
-			DI_reg(context) = 0x0000;
-#else
-                	AH_reg(context) = 0x01;
+        CONTEXT_2_DIOCRegs( context, &regs);
+
+        if(!DeviceIoControl(hVWin32, VWIN32_DIOC_DOS_INT13, 
+                &regs, sizeof regs, &regs, sizeof regs, &dwRet, NULL))
+            DIOCRegs_2_CONTEXT(&regs, context);
+        else
                 	SET_CFLAG(context);
-                	break;
-#endif
-		}
-		break;
 
-        case 0x09:         /* INITIALIZE CONTROLLER WITH DRIVE PARAMETERS */
-	case 0x0a:         /* FIXED DISK - READ LONG (XT,AT,XT286,PS)     */
-	case 0x0b:	   /* FIXED DISK - WRITE LONG (XT,AT,XT286,PS)    */
-	case 0x0c:         /* SEEK TO CYLINDER                            */
-	case 0x0d:         /* ALTERNATE RESET HARD DISKS                  */
-	case 0x10:         /* CHECK IF DRIVE READY                        */
-	case 0x11:         /* RECALIBRATE DRIVE                           */
-	case 0x14:         /* CONTROLLER INTERNAL DIAGNOSTIC              */
-		AH_reg(context) = 0;
-		break;
-
-	case 0x15:	   /* GET DISK TYPE (AT,XT2,XT286,CONV,PS) */
-		if (DL_reg(context) & 0x80) { /* hard disk ? */
-			AH_reg(context) = 3; /* fixed disk */
-			SET_CFLAG(context);
+        CloseHandle(hVWin32);
 		}
-		else { /* floppy disk ? */
-			AH_reg(context) = 2; /* floppy with change detection */
-			SET_CFLAG(context);
-		}
-		break;
-	case 0x0e:                    /* READ SECTOR BUFFER (XT only)      */
-	case 0x0f:                    /* WRITE SECTOR BUFFER (XT only)     */
-        case 0x12:                    /* CONTROLLER RAM DIAGNOSTIC (XT,PS) */
-	case 0x13:                    /* DRIVE DIAGNOSTIC (XT,PS)          */
-		AH_reg(context) = 0x01;
-                SET_CFLAG(context);
-		break;
-
-	case 0x16:	   /* FLOPPY - CHANGE OF DISK STATUS */
-		AH_reg(context) = 0; /* FIXME - no change */
-		break;
-	case 0x17:	   /* SET DISK TYPE FOR FORMAT */
-		if (DL_reg(context) < 4)
-		    AH_reg(context) = 0x00; /* successful completion */
-		else
-		    AH_reg(context) = 0x01; /* error */
-		break;
-	case 0x18:         /* SET MEDIA TYPE FOR FORMAT */
-		if (DL_reg(context) < 4)
-		    AH_reg(context) = 0x00; /* successful completion */
 		else
-		    AH_reg(context) = 0x01; /* error */
-		break;
-	case 0x19:	   /* FIXED DISK - PARK HEADS */
-	default:
-		INT_BARF( context, 0x13 );
+    {
+        ERR("Failed to open device VWIN32\n");
+        SET_CFLAG(context);
     }
 }
+
Index: win32/device.c
===================================================================
RCS file: /home/wine/wine/win32/device.c,v
retrieving revision 1.58
diff -u -r1.58 device.c
--- win32/device.c	2002/01/13 01:44:01	1.58
+++ win32/device.c	2002/01/26 18:31:05
@@ -30,7 +30,15 @@
 #include "wine/server.h"
 #include "debugtools.h"
 
-DEFAULT_DEBUG_CHANNEL(win32);
+/* int 13 stuff */
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#ifdef linux
+# include <linux/fd.h>
+#endif
+#include "drive.h"
+
+DEFAULT_DEBUG_CHANNEL(file);
 
 
 static BOOL DeviceIo_VTDAPI(DWORD dwIoControlCode, 
@@ -1139,7 +1147,224 @@
     pOut->reg_Flags = pCxt->EFlags;
 }
 
+#define DIOC_AH(regs) (((unsigned char*)&((regs)->reg_EAX))[1])
+#define DIOC_AL(regs) (((unsigned char*)&((regs)->reg_EAX))[0])
+#define DIOC_BH(regs) (((unsigned char*)&((regs)->reg_EBX))[1])
+#define DIOC_BL(regs) (((unsigned char*)&((regs)->reg_EBX))[0])
+#define DIOC_DH(regs) (((unsigned char*)&((regs)->reg_EDX))[1])
+#define DIOC_DL(regs) (((unsigned char*)&((regs)->reg_EDX))[0])
+
+#define DIOC_AX(regs) (((unsigned short*)&((regs)->reg_EAX))[0])
+#define DIOC_BX(regs) (((unsigned short*)&((regs)->reg_EBX))[0])
+#define DIOC_CX(regs) (((unsigned short*)&((regs)->reg_ECX))[0])
+#define DIOC_DX(regs) (((unsigned short*)&((regs)->reg_EDX))[0])
+
+#define DIOC_SET_CARRY(regs) (((regs)->reg_Flags)|=0x00000001)
+
+static DWORD VWIN32_DriveTypeInfo[7]={
+    0x0000, /* none */
+    0x2709, /* 360 K */
+    0x4f0f, /* 1.2 M */
+    0x4f09, /* 720 K */
+    0x4f12, /* 1.44 M */
+    0x4f24, /* 2.88 M */
+    0x4f24  /* 2.88 M */
+};
+
+/**********************************************************************
+ *	    VWIN32_ReadFloppyParams
+ *
+ * Handler for int 13h (disk I/O).
+ */
+static VOID VWIN32_ReadFloppyParams(DIOC_REGISTERS *regs)
+{
+#ifdef linux
+    unsigned int i, nr_of_drives = 0;            
+    BYTE drive_nr = DIOC_DL(regs);
+    int floppy_fd,r;
+    struct floppy_drive_params floppy_parm;
+    char root[] = "A:\\";
+
+    TRACE("in  [ EDX=%08lx ]\n", regs->reg_EDX );
+
+    DIOC_AH(regs) = 0x00; /* success */
+
+    for (i = 0; i < MAX_DOS_DRIVES; i++, root[0]++)
+        if (GetDriveTypeA(root) == DRIVE_REMOVABLE) nr_of_drives++;
+    DIOC_DL(regs) = nr_of_drives;
+
+    if (drive_nr > 1) { /* invalid drive ? */
+        DIOC_BX(regs) = 0;
+        DIOC_CX(regs) = 0;
+        DIOC_DH(regs) = 0;
+        DIOC_SET_CARRY(regs);
+        return;
+    }
+
+    if ( (floppy_fd = DRIVE_OpenDevice( drive_nr, O_NONBLOCK)) == -1)
+    {
+        WARN("Can't determine floppy geometry !\n");
+        DIOC_BX(regs) = 0;
+        DIOC_CX(regs) = 0;
+        DIOC_DH(regs) = 0;
+        DIOC_SET_CARRY(regs);
+        return;
+    }
+    r = ioctl(floppy_fd, FDGETDRVPRM, &floppy_parm);
+
+    close(floppy_fd);
+
+    if(r<0)
+    {
+        DIOC_SET_CARRY(regs);
+        return;
+    }
+
+    regs->reg_ECX = 0;
+    DIOC_AL(regs) = 0;
+    DIOC_BL(regs) = floppy_parm.cmos;
+
+    /* CH = low eight bits of max cyl
+       CL = max sec nr (bits 5-0),
+       hi two bits of max cyl (bits 7-6)
+       DH = max head nr */ 
+    if(DIOC_BL(regs) && (DIOC_BL(regs)<7))
+    {
+        DIOC_DH(regs) = 0x01;
+        DIOC_CX(regs) = VWIN32_DriveTypeInfo[DIOC_BL(regs)];
+    }
+    else 
+    {
+        DIOC_CX(regs) = 0x0;
+        DIOC_DX(regs) = 0x0;
+    }
+
+    regs->reg_EDI = (DWORD) DRIVE_GetFloppyParams(drive_nr);
+
+    if(!regs->reg_EDI)
+    {
+        ERR("Get floppy params failed for drive %d\n",drive_nr);
+        DIOC_SET_CARRY(regs);
+    }
+
+    TRACE("out [ EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx EDI=%08lx ]\n",
+	regs->reg_EAX, regs->reg_EBX, regs->reg_ECX, regs->reg_EDX, 
+        regs->reg_EDI);
+
+    /* FIXME: Word exits quietly if we return with no error. Why? */
+    FIXME("Returned ERROR!\n");
+    DIOC_SET_CARRY(regs);
+
+#else
+    DIOC_AH(regs) = 0x01;
+    DIOC_SET_CARRY(regs);
+#endif
+}
+
+/**********************************************************************
+ *	    VWIN32_Int13Handler
+ *
+ * Handler for VWIN32_DIOC_DOS_INT13 (disk I/O).
+ */
+static VOID VWIN32_Int13Handler( DIOC_REGISTERS *regs)
+{
+    TRACE("AH=%02x\n",DIOC_AH(regs));
+    switch(DIOC_AH(regs)) /* AH */
+    {
+    case 0x00:             /* RESET DISK SYSTEM     */
+        break; /* no return ? */
+
+    case 0x01:             /* STATUS OF DISK SYSTEM */
+        DIOC_AL(regs) = 0; /* successful completion */
+        break;
+
+    case 0x02:	           /* READ SECTORS INTO MEMORY */
+        DIOC_AL(regs) = 0; /* number of sectors read */
+        DIOC_AH(regs) = 0; /* status */
+        break;
+
+    case 0x03:             /* WRITE SECTORS FROM MEMORY */
+        break; /* no return ? */
+
+    case 0x04:             /* VERIFY DISK SECTOR(S) */
+        DIOC_AL(regs) = 0; /* number of sectors verified */
+        DIOC_AH(regs) = 0;
+        break;
+           
+    case 0x05:             /* FORMAT TRACK */
+    case 0x06:             /* FORMAT TRACK AND SET BAD SECTOR FLAGS */
+    case 0x07:             /* FORMAT DRIVE STARTING AT GIVEN TRACK  */
+        /* despite what Ralf Brown says, 0x06 and 0x07 seem to
+         * set CFLAG, too (at least my BIOS does that) */
+        DIOC_AH(regs) = 0x0c;
+        DIOC_SET_CARRY(regs);
+        break;
+
+    case 0x08:             /* GET DRIVE PARAMETERS  */
+        if (DIOC_DL(regs) & 0x80) { /* hard disk ? */
+            DIOC_AH(regs) = 0x07;
+            DIOC_SET_CARRY(regs);
+        }
+        else  /* floppy disk */
+            VWIN32_ReadFloppyParams(regs);
+        break;
+
+    case 0x09:         /* INITIALIZE CONTROLLER WITH DRIVE PARAMETERS */
+    case 0x0a:         /* FIXED DISK - READ LONG (XT,AT,XT286,PS)     */
+    case 0x0b:         /* FIXED DISK - WRITE LONG (XT,AT,XT286,PS)    */
+    case 0x0c:         /* SEEK TO CYLINDER                            */
+    case 0x0d:         /* ALTERNATE RESET HARD DISKS                  */
+    case 0x10:         /* CHECK IF DRIVE READY                        */
+    case 0x11:         /* RECALIBRATE DRIVE                           */
+    case 0x14:         /* CONTROLLER INTERNAL DIAGNOSTIC              */
+        DIOC_AH(regs) = 0;
+        break;
+
+    case 0x15:         /* GET DISK TYPE (AT,XT2,XT286,CONV,PS) */
+        if (DIOC_DL(regs) & 0x80) { /* hard disk ? */
+            DIOC_AH(regs) = 3; /* fixed disk */
+            DIOC_SET_CARRY(regs);
+        }
+        else { /* floppy disk ? */
+            DIOC_AH(regs) = 2; /* floppy with change detection */
+            DIOC_SET_CARRY(regs);
+        }
+        break;
+
+    case 0x0e:         /* READ SECTOR BUFFER (XT only)      */
+    case 0x0f:         /* WRITE SECTOR BUFFER (XT only)     */
+    case 0x12:         /* CONTROLLER RAM DIAGNOSTIC (XT,PS) */
+    case 0x13:         /* DRIVE DIAGNOSTIC (XT,PS)          */
+        DIOC_AH(regs) = 0x01;
+        DIOC_SET_CARRY(regs);
+        break;
+
+    case 0x16:         /* FLOPPY - CHANGE OF DISK STATUS */
+        DIOC_AH(regs) = 0; /* FIXME - no change */
+        break;
 
+    case 0x17:         /* SET DISK TYPE FOR FORMAT */
+        if (DIOC_DL(regs) < 4)
+            DIOC_AH(regs) = 0x00; /* successful completion */
+        else
+            DIOC_AH(regs) = 0x01; /* error */
+        break;
+
+    case 0x18:         /* SET MEDIA TYPE FOR FORMAT */
+        if (DIOC_DL(regs) < 4)
+            DIOC_AH(regs) = 0x00; /* successful completion */
+        else
+            DIOC_AH(regs) = 0x01; /* error */
+        break;
+
+    case 0x19:       /* FIXED DISK - PARK HEADS */
+        break;
+
+    default:
+        FIXME("Unknown VWIN32 INT13 call AX=%04X\n",DIOC_AX(regs));
+    }
+}
+
 static BOOL DeviceIo_VWin32(DWORD dwIoControlCode, 
 			      LPVOID lpvInBuffer, DWORD cbInBuffer,
 			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
@@ -1150,8 +1375,17 @@
 
     switch (dwIoControlCode)
     {
-    case VWIN32_DIOC_DOS_IOCTL:
     case VWIN32_DIOC_DOS_INT13:
+    {
+        DIOC_REGISTERS *pIn  = (DIOC_REGISTERS *)lpvInBuffer;
+        DIOC_REGISTERS *pOut = (DIOC_REGISTERS *)lpvOutBuffer;
+
+        memcpy(pOut, pIn, sizeof (DIOC_REGISTERS));
+	VWIN32_Int13Handler(pOut);
+        break;
+    }
+
+    case VWIN32_DIOC_DOS_IOCTL:
     case VWIN32_DIOC_DOS_INT25:
     case VWIN32_DIOC_DOS_INT26:
     case VWIN32_DIOC_DOS_DRIVEINFO:
@@ -1162,9 +1396,8 @@
 
         TRACE( "Control '%s': "
                "eax=0x%08lx, ebx=0x%08lx, ecx=0x%08lx, "
-               "edx=0x%08lx, esi=0x%08lx, edi=0x%08lx ",
+               "edx=0x%08lx, esi=0x%08lx, edi=0x%08lx \n",
                (dwIoControlCode == VWIN32_DIOC_DOS_IOCTL)? "VWIN32_DIOC_DOS_IOCTL" :
-               (dwIoControlCode == VWIN32_DIOC_DOS_INT13)? "VWIN32_DIOC_DOS_INT13" :
                (dwIoControlCode == VWIN32_DIOC_DOS_INT25)? "VWIN32_DIOC_DOS_INT25" :
                (dwIoControlCode == VWIN32_DIOC_DOS_INT26)? "VWIN32_DIOC_DOS_INT26" : 
                (dwIoControlCode == VWIN32_DIOC_DOS_DRIVEINFO)? "VWIN32_DIOC_DOS_DRIVEINFO" :  "???",
@@ -1176,7 +1409,6 @@
         switch (dwIoControlCode)
         {
         case VWIN32_DIOC_DOS_IOCTL: DOS3Call( &cxt ); break; /* Call int 21h */
-        case VWIN32_DIOC_DOS_INT13: INT_Int13Handler( &cxt ); break;
         case VWIN32_DIOC_DOS_INT25: INT_Int25Handler( &cxt ); break;
         case VWIN32_DIOC_DOS_INT26: INT_Int26Handler( &cxt ); break;
         case VWIN32_DIOC_DOS_DRIVEINFO:	DOS3Call( &cxt ); break; /* Call int 21h 730x */


More information about the wine-patches mailing list