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