From: Aleksandar Andrejevic Date: Sat, 2 May 2015 02:59:21 +0000 (+0000) Subject: [NTVDM] X-Git-Tag: backups/colins-printing-for-freedom@73041~110 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=b2311765e99c32b450af4e50212987556e38385c [NTVDM] Implement INT 27h (Terminate and Stay Resident). Keep track of the last entry SS:SP in the INT 21h handler. Restore the stack in DosTerminateProcess. The number of bytes to keep resident applies only to the block which holds the PSP, other blocks are not freed. svn path=/trunk/; revision=67507 --- diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c index 54d8b53ffd8..3b3c673842f 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c @@ -178,6 +178,10 @@ VOID WINAPI DosInt21h(LPWORD Stack) (*InDos)++; + /* Save the value of SS:SP on entry in the PSP */ + SEGMENT_TO_PSP(CurrentPsp)->LastStack = + MAKELONG(getSP() + (STACK_FLAGS + 1) * 2, getSS()); + /* Check the value in the AH register */ switch (getAH()) { @@ -1817,6 +1821,11 @@ VOID WINAPI DosBreakInterrupt(LPWORD Stack) Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; } +VOID WINAPI DosInt27h(LPWORD Stack) +{ + DosTerminateProcess(getCS(), 0, (getDX() + 0x0F) >> 4); +} + VOID WINAPI DosFastConOut(LPWORD Stack) { /* @@ -2002,6 +2011,7 @@ BOOLEAN DosKRNLInitialize(VOID) // RegisterDosInt32(0x22, DosInt22h ); // Termination RegisterDosInt32(0x23, DosBreakInterrupt); // Ctrl-C / Ctrl-Break // RegisterDosInt32(0x24, DosInt24h ); // Critical Error + RegisterDosInt32(0x27, DosInt27h ); // Terminate and Stay Resident RegisterDosInt32(0x29, DosFastConOut ); // DOS 2+ Fast Console Output RegisterDosInt32(0x2F, DosInt2Fh ); diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c index 70919b80acd..75b975a8b0c 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/process.c @@ -780,23 +780,20 @@ VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode, WORD KeepResident) /* Check if this block was allocated by the process */ if (CurrentMcb->OwnerPsp == Psp) { - if (KeepResident == 0) + if (KeepResident) { - /* Free this entire block */ - DosFreeMemory(McbSegment + 1); - } - else if (KeepResident < CurrentMcb->Size) - { - /* Reduce the size of the block */ - DosResizeMemory(McbSegment + 1, KeepResident, NULL); - - /* No further paragraphs need to stay resident */ - KeepResident = 0; + /* Check if this is the PSP block and we should reduce its size */ + if (McbSegment == Psp && KeepResident < CurrentMcb->Size) + { + /* Reduce the size of the block */ + DosResizeMemory(McbSegment + 1, KeepResident, NULL); + break; + } } else { - /* Just reduce the amount of paragraphs we need to keep resident */ - KeepResident -= CurrentMcb->Size; + /* Free this entire block */ + DosFreeMemory(McbSegment + 1); } } @@ -849,6 +846,10 @@ Done: /* Save the return code - Normal termination */ DosErrorLevel = MAKEWORD(ReturnCode, 0x00); + /* Restore the old stack */ + setSS(HIWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack)); + setSP(LOWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack)); + /* Return control to the parent process */ CpuExecute(HIWORD(PspBlock->TerminateAddress), LOWORD(PspBlock->TerminateAddress));