mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 13:26:17 +00:00
[NTVDM]
Remove the old "INT 0xFF" hack and instead use an invalid opcode sequence for emulator operations. Fix the flags register update bug. svn path=/branches/ntvdm/; revision=59565
This commit is contained in:
parent
7bcfe7b2a8
commit
6be35ef0bb
3 changed files with 57 additions and 31 deletions
|
@ -374,20 +374,19 @@ BOOLEAN BiosInitialize()
|
|||
IntVecTable[i * 2] = Offset;
|
||||
IntVecTable[i * 2 + 1] = BIOS_SEGMENT;
|
||||
|
||||
if (i != SPECIAL_INT_NUM)
|
||||
{
|
||||
BiosCode[Offset++] = 0xFA; // cli
|
||||
BiosCode[Offset++] = 0xFA; // cli
|
||||
|
||||
BiosCode[Offset++] = 0x6A; // push i
|
||||
BiosCode[Offset++] = (BYTE)i;
|
||||
BiosCode[Offset++] = 0x6A; // push i
|
||||
BiosCode[Offset++] = (BYTE)i;
|
||||
|
||||
BiosCode[Offset++] = 0xCD; // int SPECIAL_INT_NUM
|
||||
BiosCode[Offset++] = SPECIAL_INT_NUM;
|
||||
BiosCode[Offset++] = LOBYTE(EMULATOR_BOP); // BOP sequence
|
||||
BiosCode[Offset++] = HIBYTE(EMULATOR_BOP);
|
||||
BiosCode[Offset++] = LOBYTE(EMULATOR_INT_BOP);
|
||||
BiosCode[Offset++] = HIBYTE(EMULATOR_INT_BOP);
|
||||
|
||||
BiosCode[Offset++] = 0x83; // add sp, 2
|
||||
BiosCode[Offset++] = 0xC4;
|
||||
BiosCode[Offset++] = 0x02;
|
||||
}
|
||||
BiosCode[Offset++] = 0x83; // add sp, 2
|
||||
BiosCode[Offset++] = 0xC4;
|
||||
BiosCode[Offset++] = 0x02;
|
||||
|
||||
BiosCode[Offset++] = 0xCF; // iret
|
||||
}
|
||||
|
|
|
@ -165,34 +165,32 @@ static VOID EmulatorWriteIo(PVOID Context, UINT Address, LPBYTE Buffer, INT Size
|
|||
}
|
||||
}
|
||||
|
||||
static VOID EmulatorSoftwareInt(PVOID Context, BYTE Number)
|
||||
static VOID EmulatorBop(WORD Code)
|
||||
{
|
||||
WORD StackSegment, StackPointer, CodeSegment, InstructionPointer;
|
||||
BYTE IntNum;
|
||||
LPWORD Stack;
|
||||
|
||||
/* Check if this is the special interrupt */
|
||||
if (Number == SPECIAL_INT_NUM)
|
||||
{
|
||||
/* Get the SS:SP */
|
||||
/* Get the SS:SP */
|
||||
#ifndef NEW_EMULATOR
|
||||
StackSegment = EmulatorContext.state->segment_reg[SX86_SREG_SS].val;
|
||||
StackPointer = EmulatorContext.state->general_reg[SX86_REG_SP].val;
|
||||
StackSegment = EmulatorContext.state->segment_reg[SX86_SREG_SS].val;
|
||||
StackPointer = EmulatorContext.state->general_reg[SX86_REG_SP].val;
|
||||
#else
|
||||
StackSegment = EmulatorContext.Registers[EMULATOR_REG_SS].LowWord;
|
||||
StackPointer = EmulatorContext.Registers[EMULATOR_REG_SP].LowWord;
|
||||
StackSegment = EmulatorContext.Registers[EMULATOR_REG_SS].LowWord;
|
||||
StackPointer = EmulatorContext.Registers[EMULATOR_REG_SP].LowWord;
|
||||
#endif
|
||||
|
||||
/* Get the interrupt number */
|
||||
IntNum = *(LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(StackSegment, StackPointer));
|
||||
/* Get the stack */
|
||||
Stack = (LPWORD)((ULONG_PTR)BaseAddress + TO_LINEAR(StackSegment, StackPointer));
|
||||
|
||||
/* Move the stack pointer forward one word to skip the interrupt number */
|
||||
StackPointer += sizeof(WORD);
|
||||
if (Code == EMULATOR_INT_BOP)
|
||||
{
|
||||
/* Get the interrupt number */
|
||||
IntNum = LOBYTE(Stack[0]);
|
||||
|
||||
/* Get the CS:IP */
|
||||
InstructionPointer = *(LPWORD)((ULONG_PTR)BaseAddress
|
||||
+ TO_LINEAR(StackSegment, StackPointer));
|
||||
CodeSegment = *(LPWORD)((ULONG_PTR)BaseAddress
|
||||
+ TO_LINEAR(StackSegment, StackPointer + sizeof(WORD)));
|
||||
InstructionPointer = Stack[1];
|
||||
CodeSegment = Stack[2];
|
||||
|
||||
/* Check if this was an exception */
|
||||
if (IntNum < 8)
|
||||
|
@ -275,9 +273,21 @@ static VOID EmulatorSoftwareInt(PVOID Context, BYTE Number)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the flags on the stack */
|
||||
#ifndef NEW_EMULATOR
|
||||
Stack[3] = EmulatorContext.state->reg_flags.val;
|
||||
#else
|
||||
Stack[3] = EmulatorContext.Flags.LowWord;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static VOID EmulatorSoftwareInt(PVOID Context, BYTE Number)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
static VOID EmulatorHardwareInt(PVOID Context, BYTE Number)
|
||||
{
|
||||
/* Do nothing */
|
||||
|
@ -445,14 +455,30 @@ VOID EmulatorClearFlag(ULONG Flag)
|
|||
#endif
|
||||
}
|
||||
|
||||
VOID EmulatorStep()
|
||||
VOID EmulatorStep(VOID)
|
||||
{
|
||||
LPWORD Instruction;
|
||||
|
||||
#ifndef NEW_EMULATOR
|
||||
/* Print the current position - useful for debugging */
|
||||
DPRINT("Executing at CS:IP = %04X:%04X\n",
|
||||
EmulatorGetRegister(EMULATOR_REG_CS),
|
||||
EmulatorContext.state->reg_ip);
|
||||
|
||||
Instruction = (LPWORD)((ULONG_PTR)BaseAddress
|
||||
+ TO_LINEAR(EmulatorGetRegister(EMULATOR_REG_CS),
|
||||
EmulatorContext.state->reg_ip));
|
||||
|
||||
/* Check for the BIOS operation (BOP) sequence */
|
||||
if (Instruction[0] == EMULATOR_BOP)
|
||||
{
|
||||
/* Skip the opcodes */
|
||||
EmulatorContext.state->reg_ip += 4;
|
||||
|
||||
/* Call the BOP handler */
|
||||
EmulatorBop(Instruction[1]);
|
||||
}
|
||||
|
||||
/* Call the softx86 API */
|
||||
if (!softx86_step(&EmulatorContext))
|
||||
{
|
||||
|
@ -464,7 +490,7 @@ VOID EmulatorStep()
|
|||
#endif
|
||||
}
|
||||
|
||||
VOID EmulatorCleanup()
|
||||
VOID EmulatorCleanup(VOID)
|
||||
{
|
||||
/* Free the memory allocated for the 16-bit address space */
|
||||
if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
|
||||
|
|
|
@ -70,7 +70,8 @@
|
|||
#define EMULATOR_NUM_CONTROL_REGS 8
|
||||
#define EMULATOR_NUM_DEBUG_REGS 8
|
||||
#define MAX_GDT_ENTRIES 8192
|
||||
#define SPECIAL_INT_NUM 0xFF
|
||||
#define EMULATOR_BOP 0xC4C4
|
||||
#define EMULATOR_INT_BOP 0xBEEF
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue