My previous patch has been modified to use DPMI_AllocInternalRMCB, as requested by Ove. -- Chuck Crayne ----------------------------------------------------------- ccrayne@crayne.org ----------------------------------------------------------- Change Log: Makefile.in, include/miscemu.h, msdos/dosmem.c, msdos/int2f.c ccrayne@crayne.org 1. Fix Error Table handling to eliminate "No real-mode handler for errors yet" fixme, and associated SIGILL abort. 2. Fix INT_BARF message on int 2f function 5 by adding stub to return extended error handler not installed. --- Makefile.in.20011226 Sat Jan 12 18:51:55 2002 +++ Makefile.in Sat Jan 12 18:52:39 2002 @@ -19,7 +19,7 @@ LIBEXT = @LIBEXT@ LDCONFIG = @LDCONFIG@ MODULE = wine -IMPORTS = ntdll +IMPORTS = ntdll winedos # Stand-alone programs PROGRAMS = \ --- include/miscemu.h.20011226 Wed Jan 2 18:05:36 2002 +++ include/miscemu.h Wed Jan 2 21:40:13 2002 @@ -152,6 +152,10 @@ extern LPVOID DOSMEM_MapDosToLinear(UINT); /* linear DOS to Wine */ extern UINT DOSMEM_MapLinearToDos(LPVOID); /* linear Wine to DOS */ +/* DOS Error Table addresses */ +extern DWORD DOSMEM_ErrorCall; +extern DWORD DOSMEM_ErrorBuffer; + /* memory/instr.c */ extern BOOL INSTR_EmulateInstruction( CONTEXT86 *context ); --- msdos/dosmem.c.20011226 Wed Jan 2 17:27:40 2002 +++ msdos/dosmem.c Sat Jan 5 19:21:47 2002 @@ -32,6 +32,8 @@ WORD DOSMEM_BiosSysSeg; /* BIOS ROM segment at 0xf000:0 */ DWORD DOSMEM_CollateTable; +DWORD DOSMEM_ErrorCall; +DWORD DOSMEM_ErrorBuffer; /* use 2 low bits of 'size' for the housekeeping */ @@ -355,56 +357,27 @@ /*********************************************************************** * DOSMEM_InitErrorTable * - * Initialises the error tables (DOS 5+) + * Allocates real mode memory to support Int2f AX = 0x122e DL = 08 code. + * Allocation must be made at initialization time because DPMI support + * does not currently reserve any real memory for later use. + * */ static void DOSMEM_InitErrorTable() { -#if 0 /* no longer used */ DWORD x; char *call; - - /* We will use a snippet of real mode code that calls */ - /* a WINE-only interrupt to handle moving the requested */ - /* message into the buffer... */ - - /* FIXME - There is still something wrong... */ - - /* FIXME - Find hex values for opcodes... - - (On call, AX contains message number - DI contains 'offset' (??) - Resturn, ES:DI points to counted string ) - - PUSH BX - MOV BX, AX - MOV AX, (arbitrary subfunction number) - INT (WINE-only interrupt) - POP BX - RET - - */ - - const int code = 4; - const int buffer = 80; - const int SIZE_TO_ALLOCATE = code + buffer; - - /* FIXME - Complete rewrite of the table system to save */ - /* precious DOS space. Now, we return the 0001:???? as */ - /* DOS 4+ (??, it seems to be the case in MS 7.10) treats that */ - /* as a special case and programs will use the alternate */ - /* interface (a farcall returned with INT 24 (AX = 0x122e, DL = */ - /* 0x08) which lets us have a smaller memory footprint anyway. */ + const int buffersz = 80; /* Just a guess */ + extern void INT_Int2f122eCallback(); + /* Allocate and clear real mode message buffer */ + x = GlobalDOSAlloc16(buffersz); + DOSMEM_ErrorBuffer = MAKELONG(0,(x>>16)); + call = DOSMEM_MapRealToLinear(DOSMEM_ErrorBuffer); + memset(call, 0, buffersz); + + /* Allocate real mode far call address for message routine */ + DOSMEM_ErrorCall = (DWORD) DPMI_AllocInternalRMCB(INT_Int2f122eCallback); + TRACE("allocated real mode proc %x\n", DOSMEM_ErrorCall); - x = GlobalDOSAlloc16(SIZE_TO_ALLOCATE); - - DOSMEM_ErrorCall = MAKELONG(0,(x>>16)); - DOSMEM_ErrorBuffer = DOSMEM_ErrorCall + code; - - call = DOSMEM_MapRealToLinear(DOSMEM_ErrorCall); - - memset(call, 0, SIZE_TO_ALLOCATE); -#endif - /* Fixme - Copy assembly into buffer here */ } /*********************************************************************** --- msdos/int2f.c.20011226 Wed Jan 2 18:04:33 2002 +++ msdos/int2f.c Sat Jan 12 20:46:09 2002 @@ -8,7 +8,7 @@ */ #include "config.h" - +#include <stdio.h> #include <string.h> #include "wine/winbase16.h" #include "miscemu.h" @@ -24,6 +24,7 @@ static void do_int2f_16( CONTEXT86 *context ); static void MSCDEX_Handler( CONTEXT86 *context ); +void INT_Int2f122eCallback(CONTEXT86 *context); /********************************************************************** * INT_Int2fHandler (WPROCS.147) @@ -36,6 +37,11 @@ switch(AH_reg(context)) { + case 0x05: + AL_reg(context) = 0x01; /* not installed */ + RESET_CFLAG(context); + break; + case 0x10: AL_reg(context) = 0xff; /* share is installed */ break; @@ -77,10 +83,12 @@ case 0x04: case 0x06: context->SegEs = 0x0001; - DI_reg(context) = 0x0000; + DI_reg(context) = DL_reg(context)>>1; break; + /* Return address of error message retriever */ case 0x08: - FIXME("No real-mode handler for errors yet! (bye!)\n"); + context->SegEs = DOSMEM_ErrorCall >> 16; + DI_reg(context) = DOSMEM_ErrorCall & 0xffff; break; default: INT_BARF(context, 0x2f); @@ -808,4 +816,26 @@ FIXME("Unimplemented MSCDEX function 0x%02X.\n", LOBYTE(context->Eax)); break; } +} +/********************************************************************** + * INT_Int2f122eCallback + * + * Callback routine for int 2fh function 122eh subfunction 8. + */ + +void INT_Int2f122eCallback(CONTEXT86 *context) +{ + char *buff; + WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp); + + /* Return address of error message counted string */ + buff = DOSMEM_MapRealToLinear(DOSMEM_ErrorBuffer); + sprintf(buff,"\x18""Error %3d from table %1d\n",AX_reg(context),DI_reg(context)); + context->SegEs = DOSMEM_ErrorBuffer >> 16; + DI_reg(context) = DOSMEM_ErrorBuffer & 0xffff; + + /* simulate a normal RETF sequence as required by DPMI CallRMProcFar */ + context->Eip = *(stack++); + context->SegCs = *(stack++); + context->Esp += 2*sizeof(WORD); }