mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:52:56 +00:00
[NTVDM]
Save/restore the processor state when executing/terminating nested tasks. svn path=/trunk/; revision=67513
This commit is contained in:
parent
a4901dfae5
commit
af48f83e26
2 changed files with 78 additions and 16 deletions
|
@ -46,6 +46,56 @@ static inline VOID DosSetPspCommandLine(WORD Segment, LPCSTR CommandLine)
|
||||||
RtlCopyMemory(PspBlock->CommandLine, CommandLine, DOS_CMDLINE_LENGTH);
|
RtlCopyMemory(PspBlock->CommandLine, CommandLine, DOS_CMDLINE_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline VOID DosSaveState(VOID)
|
||||||
|
{
|
||||||
|
PDOS_REGISTER_STATE State;
|
||||||
|
WORD StackPointer = getSP();
|
||||||
|
|
||||||
|
/* Allocate stack space for the registers */
|
||||||
|
StackPointer -= sizeof(DOS_REGISTER_STATE);
|
||||||
|
State = SEG_OFF_TO_PTR(getSS(), StackPointer);
|
||||||
|
|
||||||
|
/* Save */
|
||||||
|
State->EAX = getEAX();
|
||||||
|
State->ECX = getECX();
|
||||||
|
State->EDX = getEDX();
|
||||||
|
State->EBX = getEBX();
|
||||||
|
State->ESP = getESP();
|
||||||
|
State->EBP = getEBP();
|
||||||
|
State->ESI = getESI();
|
||||||
|
State->EDI = getEDI();
|
||||||
|
State->DS = getDS();
|
||||||
|
State->ES = getES();
|
||||||
|
State->FS = getFS();
|
||||||
|
State->GS = getGS();
|
||||||
|
State->Flags = getEFLAGS();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline VOID DosRestoreState(VOID)
|
||||||
|
{
|
||||||
|
PDOS_REGISTER_STATE State;
|
||||||
|
WORD StackPointer = getSP();
|
||||||
|
|
||||||
|
/* SS:SP points to the stack on the last entry to INT 21h */
|
||||||
|
StackPointer -= (STACK_FLAGS + 1) * 2; /* Interrupt parameters */
|
||||||
|
StackPointer -= sizeof(DOS_REGISTER_STATE); /* Pushed state structure */
|
||||||
|
State = SEG_OFF_TO_PTR(getSS(), StackPointer);
|
||||||
|
|
||||||
|
/* Restore */
|
||||||
|
setEAX(State->EAX);
|
||||||
|
setECX(State->ECX);
|
||||||
|
setEDX(State->EDX);
|
||||||
|
setEBX(State->EBX);
|
||||||
|
setEBP(State->EBP);
|
||||||
|
setESI(State->ESI);
|
||||||
|
setEDI(State->EDI);
|
||||||
|
setDS(State->DS);
|
||||||
|
setES(State->ES);
|
||||||
|
setFS(State->FS);
|
||||||
|
setGS(State->GS);
|
||||||
|
setEFLAGS(State->Flags);
|
||||||
|
}
|
||||||
|
|
||||||
static WORD DosCopyEnvironmentBlock(LPCSTR Environment OPTIONAL,
|
static WORD DosCopyEnvironmentBlock(LPCSTR Environment OPTIONAL,
|
||||||
LPCSTR ProgramName)
|
LPCSTR ProgramName)
|
||||||
{
|
{
|
||||||
|
@ -432,6 +482,9 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
||||||
|
|
||||||
if (LoadType == DOS_LOAD_AND_EXECUTE)
|
if (LoadType == DOS_LOAD_AND_EXECUTE)
|
||||||
{
|
{
|
||||||
|
/* Save the program state */
|
||||||
|
if (CurrentPsp != SYSTEM_PSP) DosSaveState();
|
||||||
|
|
||||||
/* Set the initial segment registers */
|
/* Set the initial segment registers */
|
||||||
setDS(Segment);
|
setDS(Segment);
|
||||||
setES(Segment);
|
setES(Segment);
|
||||||
|
@ -750,6 +803,9 @@ VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode, WORD KeepResident)
|
||||||
PDOS_MCB CurrentMcb;
|
PDOS_MCB CurrentMcb;
|
||||||
LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
|
LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
|
||||||
PDOS_PSP PspBlock = SEGMENT_TO_PSP(Psp);
|
PDOS_PSP PspBlock = SEGMENT_TO_PSP(Psp);
|
||||||
|
#ifndef STANDALONE
|
||||||
|
VDM_COMMAND_INFO CommandInfo;
|
||||||
|
#endif
|
||||||
|
|
||||||
DPRINT("DosTerminateProcess: Psp 0x%04X, ReturnCode 0x%02X, KeepResident 0x%04X\n",
|
DPRINT("DosTerminateProcess: Psp 0x%04X, ReturnCode 0x%02X, KeepResident 0x%04X\n",
|
||||||
Psp,
|
Psp,
|
||||||
|
@ -818,15 +874,11 @@ Done:
|
||||||
{
|
{
|
||||||
ResetEvent(VdmTaskEvent);
|
ResetEvent(VdmTaskEvent);
|
||||||
CpuUnsimulate();
|
CpuUnsimulate();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef STANDALONE
|
#ifndef STANDALONE
|
||||||
// FIXME: This is probably not the best way to do it
|
|
||||||
/* Check if this was a nested DOS task */
|
|
||||||
if (CurrentPsp != SYSTEM_PSP)
|
|
||||||
{
|
|
||||||
VDM_COMMAND_INFO CommandInfo;
|
|
||||||
|
|
||||||
/* Decrement the re-entry count */
|
/* Decrement the re-entry count */
|
||||||
CommandInfo.TaskId = SessionId;
|
CommandInfo.TaskId = SessionId;
|
||||||
|
@ -840,7 +892,7 @@ Done:
|
||||||
CommandInfo.TaskId = SessionId;
|
CommandInfo.TaskId = SessionId;
|
||||||
CommandInfo.VDMState = VDM_FLAG_DONT_WAIT;
|
CommandInfo.VDMState = VDM_FLAG_DONT_WAIT;
|
||||||
GetNextVDMCommand(&CommandInfo);
|
GetNextVDMCommand(&CommandInfo);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Save the return code - Normal termination */
|
/* Save the return code - Normal termination */
|
||||||
|
@ -850,6 +902,9 @@ Done:
|
||||||
setSS(HIWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack));
|
setSS(HIWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack));
|
||||||
setSP(LOWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack));
|
setSP(LOWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack));
|
||||||
|
|
||||||
|
/* Restore the program state */
|
||||||
|
DosRestoreState();
|
||||||
|
|
||||||
/* Return control to the parent process */
|
/* Return control to the parent process */
|
||||||
CpuExecute(HIWORD(PspBlock->TerminateAddress),
|
CpuExecute(HIWORD(PspBlock->TerminateAddress),
|
||||||
LOWORD(PspBlock->TerminateAddress));
|
LOWORD(PspBlock->TerminateAddress));
|
||||||
|
|
|
@ -72,6 +72,13 @@ typedef struct _DOS_EXEC_PARAM_BLOCK
|
||||||
};
|
};
|
||||||
} DOS_EXEC_PARAM_BLOCK, *PDOS_EXEC_PARAM_BLOCK;
|
} DOS_EXEC_PARAM_BLOCK, *PDOS_EXEC_PARAM_BLOCK;
|
||||||
|
|
||||||
|
typedef struct _DOS_REGISTER_STATE
|
||||||
|
{
|
||||||
|
DWORD Flags;
|
||||||
|
WORD GS, FS, ES, DS;
|
||||||
|
DWORD EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX;
|
||||||
|
} DOS_REGISTER_STATE, *PDOS_REGISTER_STATE;
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
/* VARIABLES ******************************************************************/
|
/* VARIABLES ******************************************************************/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue