From: Aleksandar Andrejevic Date: Sat, 25 Jan 2014 00:53:10 +0000 (+0000) Subject: [NTVDM] X-Git-Tag: backups/0.3.17@66124~1365^2~122 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=a3a28181c22b72d2b7f403b7a2077c358c475a9f [NTVDM] Add two general-purpose variables to the interrupt handler stub stack. Fix INT 29h so that it works correctly when the INT 10h, AH = 0Eh call is hooked. svn path=/branches/ntvdm/; revision=61797 --- diff --git a/subsystems/ntvdm/dos/dos.c b/subsystems/ntvdm/dos/dos.c index 1136807b63e..53223c91a26 100644 --- a/subsystems/ntvdm/dos/dos.c +++ b/subsystems/ntvdm/dos/dos.c @@ -2675,15 +2675,31 @@ VOID WINAPI DosFastConOut(LPWORD Stack) * See Ralf Brown: http://www.ctyme.com/intr/rb-4124.htm * for more information. */ - UNREFERENCED_PARAMETER(Stack); - /* - * The default handler under DOS 2.x and 3.x simply calls INT 10/AH=0Eh. - * Do better and call directly VidBiosPrintCharacter: it's what INT 10/AH=0Eh - * does. Otherwise we would have to set BL to DOS_CHAR_ATTRIBUTE and - * BH to Bda->VideoPage. - */ - VidBiosPrintCharacter(getAL(), DOS_CHAR_ATTRIBUTE, Bda->VideoPage); + if (Stack[STACK_COUNTER] == 0) + { + Stack[STACK_COUNTER]++; + + /* Save AX and BX */ + Stack[STACK_VAR_A] = getAX(); + Stack[STACK_VAR_B] = getBX(); + + /* Rewind the BOP manually, we can't use CF because the interrupt could modify it */ + EmulatorExecute(getCS(), getIP() - 4); + + /* Call INT 0x10, AH = 0x0E */ + setAH(0x0E); + setBL(DOS_CHAR_ATTRIBUTE); + setBH(Bda->VideoPage); + + EmulatorInterrupt(0x10); + } + else + { + /* Restore AX and BX */ + setAX(Stack[STACK_VAR_A]); + setBX(Stack[STACK_VAR_B]); + } } VOID WINAPI DosInt2Fh(LPWORD Stack) diff --git a/subsystems/ntvdm/emulator.h b/subsystems/ntvdm/emulator.h index 3e25b5f39d2..24749688fee 100644 --- a/subsystems/ntvdm/emulator.h +++ b/subsystems/ntvdm/emulator.h @@ -34,11 +34,13 @@ #define EMULATOR_FLAG_VIP (1 << 20) #define EMULATOR_FLAG_ID (1 << 21) -#define STACK_COUNTER 0 -#define STACK_INT_NUM 1 -#define STACK_IP 2 -#define STACK_CS 3 -#define STACK_FLAGS 4 +#define STACK_VAR_B 0 +#define STACK_VAR_A 1 +#define STACK_COUNTER 2 +#define STACK_INT_NUM 3 +#define STACK_IP 4 +#define STACK_CS 5 +#define STACK_FLAGS 6 /* Basic Memory Management */ diff --git a/subsystems/ntvdm/int32.c b/subsystems/ntvdm/int32.c index d61625148a8..b89eb137e03 100644 --- a/subsystems/ntvdm/int32.c +++ b/subsystems/ntvdm/int32.c @@ -74,9 +74,15 @@ VOID InitializeInt32(WORD BiosSegment) BiosCode[Offset++] = 0x6A; // push i BiosCode[Offset++] = (UCHAR)i; + /* The counter variable (initialized to 0) */ BiosCode[Offset++] = 0x6A; // push 0 BiosCode[Offset++] = 0x00; + /* Stack variables */ + BiosCode[Offset++] = 0x83; // sub sp, 4 + BiosCode[Offset++] = 0xEC; + BiosCode[Offset++] = 0x04; + BopSeqOffset = COMMON_STUB_OFFSET - (Offset + 3); BiosCode[Offset++] = 0xE9; // jmp near BOP_SEQ @@ -107,9 +113,9 @@ VOID InitializeInt32(WORD BiosSegment) BiosCode[Offset++] = 0xF5; // EXIT: - BiosCode[Offset++] = 0x83; // add sp, 4 + BiosCode[Offset++] = 0x83; // add sp, 8 BiosCode[Offset++] = 0xC4; - BiosCode[Offset++] = 0x04; + BiosCode[Offset++] = 0x08; BiosCode[Offset++] = 0xCF; // iret