Interrupts / move int13 to winedos

Jukka Heinonen jhei at iki.fi
Sat Nov 30 13:58:53 CST 2002


For some strange reason int13 handler was implemented in win32/device.c.
This patch moves the handler to winedos because I found lots of good
reasons for this migration:

- all interrupt handlers end up under one directory
- less code is required
- most win32 programs really don't need int13 handling
- vxd->int->vxd parameter marshalling can be done automatically while
  int->vxd->int requires manual marshalling of pointers (int13 does not
  yet implement any functions requiring pointers even though int13 has
  several functions of this kind)



Changelog:
  Move int13 handler to winedos.




Index: dlls/winedos/int13.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int13.c,v
retrieving revision 1.1
diff -u -r1.1 int13.c
--- dlls/winedos/int13.c	12 Nov 2002 23:29:48 -0000	1.1
+++ dlls/winedos/int13.c	30 Nov 2002 19:48:54 -0000
@@ -19,6 +19,9 @@
  */
 
 #include "config.h"
+#include "miscemu.h"
+#include "wine/debug.h"
+#include "drive.h"
 
 #include <stdlib.h>
 #include <sys/types.h>
@@ -26,46 +29,147 @@
 # include <unistd.h>
 #endif
 
-#include "winbase.h"
-#include "winioctl.h"
-#include "miscemu.h"
-#include "wine/debug.h"
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#include <fcntl.h>
+#ifdef linux
+# include <linux/fd.h>
+#endif
 
 WINE_DEFAULT_DEBUG_CHANNEL(int);
 
-static void DIOCRegs_2_CONTEXT( DIOC_REGISTERS *pIn, CONTEXT86 *pCxt )
+
+/*
+ * Status of last int13 operation.
+ */
+static BYTE INT13_last_status;
+
+
+/**********************************************************************
+ *         INT13_SetStatus
+ *
+ * Write status to AH register and set carry flag on error (AH != 0).
+ *
+ * Despite what Ralf Brown says, at least functions 0x06 and 0x07 
+ * seem to set carry, too.
+ */
+static void INT13_SetStatus( CONTEXT86 *context, BYTE status )
 {
-    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;
+    INT13_last_status = status;
+
+    SET_AH( context, status );
 
-    /* FIXME: Only partial CONTEXT86_CONTROL */
-    pCxt->EFlags = pIn->reg_Flags;
+    if (status)
+        SET_CFLAG( context );
+    else
+        RESET_CFLAG( context );        
 }
 
-static void CONTEXT_2_DIOCRegs( CONTEXT86 *pCxt, DIOC_REGISTERS *pOut )
+
+/**********************************************************************
+ *	    INT13_ReadFloppyParams
+ *
+ * Read floppy disk parameters.
+ */
+static void INT13_ReadFloppyParams( CONTEXT86 *context )
 {
-    memset( pOut, 0, sizeof(DIOC_REGISTERS) );
+#ifdef linux
+    static const BYTE floppy_params[2][13] =
+    {
+        { 0xaf, 0x02, 0x25, 0x02, 0x12, 0x1b, 0xff, 0x6c, 0xf6, 0x0f, 0x08 },
+        { 0xaf, 0x02, 0x25, 0x02, 0x12, 0x1b, 0xff, 0x6c, 0xf6, 0x0f, 0x08 }
+    };
+
+    static const DWORD drive_type_info[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 */
+    };
+
+    unsigned int i;
+    unsigned int nr_of_drives = 0;
+    BYTE drive_nr = DL_reg( context );
+    int floppy_fd;
+    int r;
+    struct floppy_drive_params floppy_parm;
+    char root[] = "A:\\";
+
+    TRACE("in  [ EDX=%08lx ]\n", context->Edx );
+
+    SET_AL( context, 0 );
+    SET_BX( context, 0 );
+    SET_CX( context, 0 );
+    SET_DH( context, 0 );
+
+    for (i = 0; i < MAX_DOS_DRIVES; i++, root[0]++)
+        if (GetDriveTypeA(root) == DRIVE_REMOVABLE) nr_of_drives++;
+    SET_DL( context, nr_of_drives );
+
+    if (drive_nr > 1) { 
+        /* invalid drive ? */
+        INT13_SetStatus( context, 0x07 ); /* drive parameter activity failed */
+        return;
+    }
+
+    if ( (floppy_fd = DRIVE_OpenDevice( drive_nr, O_NONBLOCK)) == -1)
+    {
+        WARN("Can't determine floppy geometry !\n");
+        INT13_SetStatus( context, 0x07 ); /* drive parameter activity failed */
+        return;
+    }
+    r = ioctl(floppy_fd, FDGETDRVPRM, &floppy_parm);
+ 
+    close(floppy_fd);
+
+    if(r<0)
+    {
+        INT13_SetStatus( context, 0x07 ); /* drive parameter activity failed */
+        return;
+    }
+
+    SET_BL( 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 
+     */
+    if(BL_reg( context ) && BL_reg( context ) < 7)
+    {
+        SET_DH( context, 0x01 );
+        SET_CX( context, drive_type_info[BL_reg( context )] );
+    }
+
+    context->Edi = (DWORD)floppy_params[drive_nr];
+
+    if(!context->Edi)
+    {
+        ERR("Get floppy params failed for drive %d\n", drive_nr);
+        INT13_SetStatus( context, 0x07 ); /* drive parameter activity failed */
+        return;
+    }
 
-    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;
+    TRACE("out [ EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx EDI=%08lx ]\n",
+          context->Eax, context->Ebx, context->Ecx, context->Edx, context->Edi);
 
-    /* FIXME: Only partial CONTEXT86_CONTROL */
-    pOut->reg_Flags = pCxt->EFlags;
+    INT13_SetStatus( context, 0x00 ); /* success */
+
+    /* FIXME: Word exits quietly if we return with no error. Why? */
+    FIXME("Returned ERROR!\n");
+    SET_CFLAG( context );
+
+#else
+    INT13_SetStatus( context, 0x01 ); /* invalid function */
+#endif
 }
 
+
 /**********************************************************************
  *         DOSVM_Int13Handler (WINEDOS16.119)
  *
@@ -73,28 +177,120 @@
  */
 void WINAPI DOSVM_Int13Handler( CONTEXT86 *context )
 {
-    HANDLE hVWin32;
-    DIOC_REGISTERS regs;
-    DWORD dwRet;
-
-    hVWin32 = CreateFileA("\\\\.\\VWIN32", GENERIC_READ|GENERIC_WRITE,
-               0, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
+    TRACE( "AH=%02x\n", AH_reg( context ) );
 
-    if(hVWin32!=INVALID_HANDLE_VALUE)
+    switch( AH_reg( context ) )
     {
-        CONTEXT_2_DIOCRegs( context, &regs);
+    case 0x00: /* RESET DISK SYSTEM */
+        INT13_SetStatus( context, 0x00 ); /* success */
+        break;
+
+    case 0x01: /* STATUS OF DISK SYSTEM */
+        INT13_SetStatus( context, INT13_last_status );
+        break;
+
+    case 0x02: /* READ SECTORS INTO MEMORY */
+        SET_AL( context, 0 ); /* number of sectors transferred */
+        INT13_SetStatus( context, 0x00 ); /* success */
+        break;
+
+    case 0x03: /* WRITE SECTORS FROM MEMORY */
+        SET_AL( context, 0 ); /* number of sectors transferred */
+        INT13_SetStatus( context, 0x00 ); /* success */
+        break;
+
+    case 0x04: /* VERIFY DISK SECTOR(S) */
+        SET_AL( context, 0 ); /* number of sectors verified */
+        INT13_SetStatus( context, 0x00 ); /* success */
+        break;
+
+    case 0x05: /* FORMAT TRACK */
+    case 0x06: /* FORMAT TRACK AND SET BAD SECTOR FLAGS */
+    case 0x07: /* FORMAT DRIVE STARTING AT GIVEN TRACK  */
+        INT13_SetStatus( context, 0x0c ); /* unsupported track or invalid media */
+        break;
+
+    case 0x08: /* GET DRIVE PARAMETERS  */
+        if (DL_reg( context ) & 0x80) 
+        {
+            /* hard disk ? */
+            INT13_SetStatus( context, 0x07 ); /* drive parameter activity failed */
+        }
+        else
+        { 
+            /* floppy disk */
+            INT13_ReadFloppyParams( context );
+        }
+        break;
+
+    case 0x09: /* INITIALIZE CONTROLLER WITH DRIVE PARAMETERS */
+    case 0x0a: /* FIXED DISK - READ LONG */
+    case 0x0b: /* FIXED DISK - WRITE LONG */
+    case 0x0c: /* SEEK TO CYLINDER */
+    case 0x0d: /* ALTERNATE RESET HARD DISK */
+        INT13_SetStatus( context, 0x00 ); /* success */
+        break;
+
+    case 0x0e: /* READ SECTOR BUFFER */
+    case 0x0f: /* WRITE SECTOR BUFFER */
+        INT13_SetStatus( context, 0x01 ); /* invalid function */
+        break;
+
+    case 0x10: /* CHECK IF DRIVE READY */
+    case 0x11: /* RECALIBRATE DRIVE */
+        INT13_SetStatus( context, 0x00 ); /* success */
+        break;
+
+    case 0x12: /* CONTROLLER RAM DIAGNOSTIC */
+    case 0x13: /* DRIVE DIAGNOSTIC */
+        INT13_SetStatus( context, 0x01 ); /* invalid function */
+        break;
+
+    case 0x14: /* CONTROLLER INTERNAL DIAGNOSTIC */
+        INT13_SetStatus( context, 0x00 ); /* success */
+        break;
+
+    case 0x15: /* GET DISK TYPE */
+        if (DL_reg( context ) & 0x80) 
+        {
+            /* hard disk ? */
+            INT13_SetStatus( context, 0x00 ); /* success */
+            /* type is fixed disk, overwrites status */
+            SET_AH( context, 0x03 );
+        }
+        else
+        { 
+            /* floppy disk */
+            INT13_SetStatus( context, 0x00 ); /* success */
+            /* type is floppy with change detection, overwrites status */
+            SET_AH( context, 0x02 );
+        }
+        break;
+
+    case 0x16: /* FLOPPY - CHANGE OF DISK STATUS */
+        INT13_SetStatus( context, 0x00 ); /* success */
+        break;
+
+    case 0x17: /* SET DISK TYPE FOR FORMAT */
+        if (DL_reg( context ) < 4)
+            INT13_SetStatus( context, 0x00 ); /* successful completion */
+        else
+            INT13_SetStatus( context, 0x01 ); /* error */
+        break;
 
-        if(!DeviceIoControl(hVWin32, VWIN32_DIOC_DOS_INT13,
-                &regs, sizeof regs, &regs, sizeof regs, &dwRet, NULL))
-            DIOCRegs_2_CONTEXT(&regs, context);
+    case 0x18: /* SET MEDIA TYPE FOR FORMAT */
+        if (DL_reg( context ) < 4)
+            INT13_SetStatus( context, 0x00 ); /* success */
         else
-            SET_CFLAG(context);
+            INT13_SetStatus( context, 0x01 ); /* error */
+        break;
 
-        CloseHandle(hVWin32);
-    }
-    else
-    {
-        ERR("Failed to open device VWIN32\n");
-        SET_CFLAG(context);
-    }
+    case 0x19: /* FIXED DISK - PARK HEADS */
+        INT13_SetStatus( context, 0x00 ); /* success */
+        break;
+
+    default:
+        INT_BARF( context, 0x13 );
+        INT13_SetStatus( context, 0x01 ); /* invalid function */
+    } 
 }




Index: win32/device.c
===================================================================
RCS file: /home/wine/wine/win32/device.c,v
retrieving revision 1.73
diff -u -r1.73 device.c
--- win32/device.c	21 Nov 2002 03:45:01 -0000	1.73
+++ win32/device.c	30 Nov 2002 19:49:13 -0000
@@ -46,16 +46,6 @@
 #include "wine/debug.h"
 #include "callback.h"
 
-/* int 13 stuff */
-#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#include <fcntl.h>
-#ifdef linux
-# include <linux/fd.h>
-#endif
-#include "drive.h"
-
 WINE_DEFAULT_DEBUG_CHANNEL(file);
 
 
@@ -1750,215 +1740,6 @@
 
 #define DIOC_SET_CARRY(regs) (((regs)->reg_Flags)|=0x00000001)
 
-static const 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
-    static BYTE floppy_params[2][13] =
-    {
-        { 0xaf, 0x02, 0x25, 0x02, 0x12, 0x1b, 0xff, 0x6c, 0xf6, 0x0f, 0x08 },
-        { 0xaf, 0x02, 0x25, 0x02, 0x12, 0x1b, 0xff, 0x6c, 0xf6, 0x0f, 0x08 }
-    };
-
-    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)floppy_params[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,
@@ -1969,18 +1750,9 @@
 
     switch (dwIoControlCode)
     {
-    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 0x10: /* Int 0x21 call, call it VWIN_DIOC_INT21 ? */
+    case VWIN32_DIOC_DOS_INT13:
     case VWIN32_DIOC_DOS_INT25:
     case VWIN32_DIOC_DOS_INT26:
     case 0x29: /* Int 0x31 call, call it VWIN_DIOC_INT31 ? */
@@ -2009,6 +1781,9 @@
         case 0x10: /* Int 0x21 call, call it VWIN_DIOC_INT21 ? */
         case VWIN32_DIOC_DOS_DRIVEINFO:        /* Call int 21h 730x */
             intnum = 0x21;
+            break;
+        case VWIN32_DIOC_DOS_INT13:
+            intnum = 0x13;
             break;
         case VWIN32_DIOC_DOS_INT25: 
             intnum = 0x25;




-- 
Jukka Heinonen <http://www.iki.fi/jhei/>



More information about the wine-patches mailing list