The following patch is my first submission to this list, so please let me know if I should be doing something differently. -- Chuck Crayne ----------------------------------------------------------- ccrayne@crayne.org ----------------------------------------------------------- Change Log: include/miscemu.h, msdos/dosmem.c, msdos/int2f.c ccrayne@crayne.org Fix Error Table handling to eliminate "No real-mode handler for errors yet!" fixme, and associated SIGILL abort. --- 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 Thu Jan 3 11:08:26 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 */ @@ -359,52 +361,51 @@ */ static void DOSMEM_InitErrorTable() { -#if 0 /* no longer used */ DWORD x; char *call; - /* We will use a snippet of real mode code that calls */ + /* We use a snippet of real mode code that calls */ /* a WINE-only interrupt to handle moving the requested */ - /* message into the buffer... */ + /* 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 ) + DI contains table number + Return, ES:DI points to counted string ) + PUSH AX PUSH BX + PUSH DX MOV BX, AX - MOV AX, (arbitrary subfunction number) - INT (WINE-only interrupt) + MOV AX, 122eh ;Get or Set Table Address + MOV DX, 007fh ;Wine helper function + INT 2fh ;Multiplex interupt + POP DX POP BX - RET + POP AX + RETF */ - 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. */ - - x = GlobalDOSAlloc16(SIZE_TO_ALLOCATE); + const int codesz = 32; /* For alignment - current code 1s 17 bytes */ + const int buffersz = 80; /* Just a guess */ + const int SIZE_TO_ALLOCATE = codesz + buffersz; + const char *code = "\x50\x53\x52\x89\xc3\xb8\x2e\x12\xba\x7f\x00\xcd\x2f\x5a\x5b\x58\xcB"; + + /* LOGIC - The "Get Table Address" subfunctions of Int2f AX = 0x122e + return 1 as the segment address, and error table number as the offset, + which tells the caller to invoke the above routine to find the + desired error message. + */ + x = GlobalDOSAlloc16(SIZE_TO_ALLOCATE); DOSMEM_ErrorCall = MAKELONG(0,(x>>16)); - DOSMEM_ErrorBuffer = DOSMEM_ErrorCall + code; + DOSMEM_ErrorBuffer = DOSMEM_ErrorCall + codesz; call = DOSMEM_MapRealToLinear(DOSMEM_ErrorCall); memset(call, 0, SIZE_TO_ALLOCATE); -#endif - /* Fixme - Copy assembly into buffer here */ + memcpy(call,code,17); } /*********************************************************************** --- msdos/int2f.c.20011226 Wed Jan 2 18:04:33 2002 +++ msdos/int2f.c Thu Jan 3 10:50:46 2002 @@ -61,6 +61,7 @@ case 0x2e: /* get or set DOS error table address */ switch (DL_reg(context)) { + char *buff; /* Four tables: even commands are 'get', odd are 'set' */ /* DOS 5.0+ ignores "set" commands */ case 0x01: @@ -77,10 +78,19 @@ 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; + /* Return address of error message counted string */ + case 0x7f: + buff = DOSMEM_MapRealToLinear(DOSMEM_ErrorBuffer); + sprintf(buff,"\x18""Error %3d from table %1d\n",BX_reg(context),DI_reg(context)); + context->SegEs = DOSMEM_ErrorBuffer >> 16; + DI_reg(context) = DOSMEM_ErrorBuffer & 0xffff; break; default: INT_BARF(context, 0x2f);