MSDOS Error Table Handling
ccrayne at crayne.org
ccrayne at crayne.org
Thu Jan 3 18:44:44 CST 2002
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 at crayne.org
-----------------------------------------------------------
Change Log:
include/miscemu.h, msdos/dosmem.c, msdos/int2f.c
ccrayne at 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);
More information about the wine-patches
mailing list