Interrupts / Move most of int31 to winedos

Jukka Heinonen jhei at iki.fi
Tue Nov 5 10:47:35 CST 2002


After this patch winedos contains almost complete int31
emulation. What has not been moved to winedos is mostly
functions that require either W32S_WINE2APP or W32S_APP2WINE.
This makes me wonder whether Wine still needs to support WIN32S...


Changelog:
  Move most int31 functions to winedos.
  Add DPMI32 fixes.


Index: int31.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int31.c,v
retrieving revision 1.12
diff -u -r1.12 int31.c
--- int31.c     4 Nov 2002 22:35:36 -0000       1.12
+++ int31.c     5 Nov 2002 16:33:09 -0000
@@ -355,7 +355,9 @@
 {
     CONTEXT86 realmode_ctx;
     FARPROC16 rm_int = DOSVM_GetRMHandler( BL_reg(context) );
-    REALMODECALL *call = MapSL( MAKESEGPTR( context->SegEs, DI_reg(context) ));
+    REALMODECALL *call = CTX_SEG_OFF_TO_LIN( context, 
+                                             context->SegEs, 
+                                             context->Edi );
     INT_GetRealModeContext( call, &realmode_ctx );
 
     /* we need to check if a real-mode program has hooked the interrupt */
@@ -380,7 +382,9 @@
  */
 void WINAPI DOSVM_CallRMProc( CONTEXT86 *context, int iret )
 {
-    REALMODECALL *p = MapSL( MAKESEGPTR( context->SegEs, DI_reg(context) ));
+    REALMODECALL *p = CTX_SEG_OFF_TO_LIN( context, 
+                                          context->SegEs, 
+                                          context->Edi );
     CONTEXT86 context16;
 
     TRACE("RealModeCall: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n",
@@ -585,10 +589,9 @@
 
     if (NewRMCB)
     {
-       /* FIXME: if 32-bit DPMI client, use ESI and EDI */
-       NewRMCB->proc_ofs = LOWORD(context->Esi);
+       NewRMCB->proc_ofs = DOSVM_IsDos32() ? context->Esi : LOWORD(context->Esi);
        NewRMCB->proc_sel = context->SegDs;
-       NewRMCB->regs_ofs = LOWORD(context->Edi);
+       NewRMCB->regs_ofs = DOSVM_IsDos32() ? context->Edi : LOWORD(context->Edi);
        NewRMCB->regs_sel = context->SegEs;
        SET_LOWORD( context->Ecx, HIWORD(NewRMCB->address) );
        SET_LOWORD( context->Edx, LOWORD(NewRMCB->address) );
@@ -678,22 +681,99 @@
     RESET_CFLAG(context);
     switch(AX_reg(context))
     {
+    case 0x0000:  /* Allocate LDT descriptors */
+        TRACE( "allocate LDT descriptors (%d)\n", CX_reg(context) );
+        {
+            WORD sel =  AllocSelectorArray16( CX_reg(context) );
+            if(!sel) 
+            {
+               TRACE( "failed\n" );
+               SET_AX( context, 0x8011 ); /* descriptor unavailable */
+               SET_CFLAG( context );
+            } 
+            else 
+            { 
+                TRACE( "success, array starts at 0x%04x\n", sel );
+                SET_AX( context, sel );      
+            }
+        }
+        break;
+
+    case 0x0001:  /* Free LDT descriptor */
+        TRACE( "free LDT descriptor (0x%04x)\n", BX_reg(context) );
+        if (FreeSelector16( BX_reg(context) ))
+        {
+            SET_AX( context, 0x8022 );  /* invalid selector */
+            SET_CFLAG( context );
+        }
+        else
+        {
+            /* If a segment register contains the selector being freed, */
+            /* set it to zero. */
+            if (!((context->SegDs^BX_reg(context)) & ~3)) context->SegDs = 0;
+            if (!((context->SegEs^BX_reg(context)) & ~3)) context->SegEs = 0;
+            if (!((context->SegFs^BX_reg(context)) & ~3)) context->SegFs = 0;
+            if (!((context->SegGs^BX_reg(context)) & ~3)) context->SegGs = 0;
+        }
+        break;
+
+    case 0x0002:  /* Real mode segment to descriptor */
+    case 0x0003:  /* Get next selector increment */
+    case 0x0004:  /* Lock selector (not supported) */
+    case 0x0005:  /* Unlock selector (not supported) */
+    case 0x0006:  /* Get selector base address */
+    case 0x0007:  /* Set selector base address */
+        /* chain to protected mode handler */
+        INT_Int31Handler( context ); /* FIXME: move DPMI code here */
+        break;
+
     case 0x0008:  /* Set selector limit */
         {
-           DWORD limit = MAKELONG( DX_reg(context), CX_reg(context) );
-           TRACE( "set selector limit (0x%04x,0x%08lx)\n",
-                  BX_reg(context), limit );
-           SetSelectorLimit16( BX_reg(context), limit );
-       }
+            DWORD limit = MAKELONG( DX_reg(context), CX_reg(context) );
+            TRACE( "set selector limit (0x%04x,0x%08lx)\n",
+                   BX_reg(context), limit );
+            SetSelectorLimit16( BX_reg(context), limit );
+        }
+        break;
+
+    case 0x0009:  /* Set selector access rights */
+    case 0x000a:  /* Allocate selector alias */
+    case 0x000b:  /* Get descriptor */
+    case 0x000c:  /* Set descriptor */
+    case 0x000d:  /* Allocate specific LDT descriptor */
+    case 0x0100:  /* Allocate DOS memory block */
+    case 0x0101:  /* Free DOS memory block */
+        /* chain to protected mode handler */
+        INT_Int31Handler( context ); /* FIXME: move DPMI code here */
+        break;
+
+    case 0x0200: /* get real mode interrupt vector */
+        TRACE( "get realmode interupt vector (0x%02x)\n",
+               BL_reg(context) );
+        {
+            FARPROC16 proc = DOSVM_GetRMHandler( BL_reg(context) );
+            SET_CX( context, SELECTOROF(proc) );
+            SET_DX( context, OFFSETOF(proc) );
+        }
+        break;
+
+    case 0x0201: /* set real mode interrupt vector */
+        TRACE( "set realmode interrupt vector (0x%02x, 0x%04x:0x%04x)\n", 
+               BL_reg(context), CX_reg(context), DX_reg(context) );
+        DOSVM_SetRMHandler( BL_reg(context), 
+                            (FARPROC16)MAKESEGPTR(CX_reg(context), DX_reg(context)) );
         break;
 
     case 0x0202:  /* Get Processor Exception Handler Vector */
         FIXME( "Get Processor Exception Handler Vector (0x%02x)\n",
                BL_reg(context) );
-        if (DOSVM_IsDos32()) {
+        if (DOSVM_IsDos32()) 
+        {
             SET_CX( context, 0 );
             context->Edx = 0;
-        } else {
+        } 
+        else 
+        {
             SET_CX( context, 0 );
             SET_DX( context, 0 );
         }
@@ -701,17 +781,20 @@
 
     case 0x0203:  /* Set Processor Exception Handler Vector */
          FIXME( "Set Processor Exception Handler Vector (0x%02x)\n",
-               BL_reg(context) );
+                BL_reg(context) );
          break;
 
     case 0x0204:  /* Get protected mode interrupt vector */
         TRACE("get protected mode interrupt handler (0x%02x)\n",
-             BL_reg(context));
-        if (DOSVM_IsDos32()) {
+              BL_reg(context));
+        if (DOSVM_IsDos32()) 
+        {
             FARPROC48 handler = DOSVM_GetPMHandler48( BL_reg(context) );
             SET_CX( context, handler.selector );
             context->Edx = handler.offset;
-        } else {
+        } 
+        else 
+        {
             FARPROC16 handler = DOSVM_GetPMHandler16( BL_reg(context) );
             SET_CX( context, SELECTOROF(handler) );
             SET_DX( context, OFFSETOF(handler) );
@@ -720,21 +803,136 @@
 
     case 0x0205:  /* Set protected mode interrupt vector */
         TRACE("set protected mode interrupt handler (0x%02x,0x%04x:0x%08lx)\n",
-             BL_reg(context), CX_reg(context), context->Edx);
-        if (DOSVM_IsDos32()) {
+              BL_reg(context), CX_reg(context), context->Edx);
+        if (DOSVM_IsDos32()) 
+        {
             FARPROC48 handler;
             handler.selector = CX_reg(context);
             handler.offset = context->Edx;
             DOSVM_SetPMHandler48( BL_reg(context), handler );
-        } else {
+        } 
+        else 
+        {
             FARPROC16 handler;
             handler = (FARPROC16)MAKESEGPTR( CX_reg(context), DX_reg(context)); 
             DOSVM_SetPMHandler16( BL_reg(context), handler );
         }
         break;
 
-    default:
+    case 0x0300:  /* Simulate real mode interrupt */
+        DOSVM_CallRMInt( context );
+        break;
+
+    case 0x0301:  /* Call real mode procedure with far return */
+        DOSVM_CallRMProc( context, FALSE );
+        break;
+
+    case 0x0302:  /* Call real mode procedure with interrupt return */
+        DOSVM_CallRMProc( context, TRUE );
+        break;
+
+    case 0x0303:  /* Allocate Real Mode Callback Address */
+        DOSVM_AllocRMCB( context );
+        break;
+
+    case 0x0304:  /* Free Real Mode Callback Address */
+        DOSVM_FreeRMCB( context );
+        break;
+
+    case 0x0305:  /* Get State Save/Restore Addresses */
+        TRACE("get state save/restore addresses\n");
+        /* we probably won't need this kind of state saving */
+        SET_AX( context, 0 );
+
+        /* real mode: just point to the lret */
+        SET_BX( context, DOSVM_dpmi_segments->wrap_seg );
+        SET_CX( context, 2 );
+
+        /* protected mode: don't have any handler yet... */
+        /* FIXME: Use DI in 16-bit DPMI and EDI in 32-bit DPMI */
+        FIXME("no protected-mode dummy state save/restore handler yet\n");
+        SET_SI( context, 0 );
+        context->Edi = 0;
+        break;
+
+    case 0x0306:  /* Get Raw Mode Switch Addresses */
+        TRACE("get raw mode switch addresses\n");
+
+        /* real mode, point to standard DPMI return wrapper */
+        SET_BX( context, DOSVM_dpmi_segments->wrap_seg );
+        SET_CX( context, 0 );
+
+        /* protected mode, point to DPMI call wrapper */
+        /* FIXME: Use DI in 16-bit DPMI and EDI in 32-bit DPMI */
+        /* FIXME: Doesn't work in DPMI32... */
+        SET_SI( context, DOSVM_dpmi_segments->dpmi_sel );
+        context->Edi = 8; /* offset of the INT 0x31 call */
+        break;
+
+    case 0x0400:  /* Get DPMI version */
+        TRACE("get DPMI version\n");
+        {
+            SYSTEM_INFO si;
+
+            GetSystemInfo(&si);
+            SET_AX( context, 0x005a );  /* DPMI version 0.90 */
+            SET_BX( context, 0x0005 );  /* Flags: 32-bit, virtual memory */
+            SET_CL( context, si.wProcessorLevel );
+            SET_DX( context, 0x0102 );  /* Master/slave interrupt controller base */
+        }
+        break;
+
+    case 0x0500:  /* Get free memory information */
+    case 0x0501:  /* Allocate memory block */
+    case 0x0502:  /* Free memory block */
+    case 0x0503:  /* Resize memory block */
+        /* chain to protected mode handler */
+        INT_Int31Handler( context ); /* FIXME: move DPMI code here */
+        break;
+
+    case 0x0507:  /* Set page attributes (1.0) */
+        FIXME("set page attributes unimplemented\n");
+        break;  /* Just ignore it */
+
+    case 0x0600:  /* Lock linear region */
+        FIXME("lock linear region unimplemented\n");
+        break;  /* Just ignore it */
+
+    case 0x0601:  /* Unlock linear region */
+        FIXME("unlock linear region unimplemented\n");
+        break;  /* Just ignore it */
+
+    case 0x0602:  /* Unlock real-mode region */
+        FIXME("unlock realmode region unimplemented\n");
+        break;  /* Just ignore it */
+
+    case 0x0603:  /* Lock real-mode region */
+        FIXME("lock realmode region unimplemented\n");
+        break;  /* Just ignore it */
+
+    case 0x0604:  /* Get page size */
+        TRACE("get pagesize\n");
+        SET_BX( context, HIWORD(getpagesize()) );
+        SET_CX( context, LOWORD(getpagesize()) );
+        break;
+
+    case 0x0702:  /* Mark page as demand-paging candidate */
+        FIXME("mark page as demand-paging candidate\n");
+        break;  /* Just ignore it */
+
+    case 0x0703:  /* Discard page contents */
+        FIXME("discard page contents\n");
+        break;  /* Just ignore it */
+
+    case 0x0800:  /* Physical address mapping */
         /* chain to protected mode handler */
         INT_Int31Handler( context ); /* FIXME: move DPMI code here */
+        break;
+
+    default:
+        INT_BARF( context, 0x31 );
+        SET_AX( context, 0x8001 );  /* unsupported function */
+        SET_CFLAG(context);
+        break;
     }  
 }



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



More information about the wine-patches mailing list