mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 14:23:18 +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] = Offset;
|
||||||
IntVecTable[i * 2 + 1] = BIOS_SEGMENT;
|
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++] = 0x6A; // push i
|
||||||
BiosCode[Offset++] = (BYTE)i;
|
BiosCode[Offset++] = (BYTE)i;
|
||||||
|
|
||||||
BiosCode[Offset++] = 0xCD; // int SPECIAL_INT_NUM
|
BiosCode[Offset++] = LOBYTE(EMULATOR_BOP); // BOP sequence
|
||||||
BiosCode[Offset++] = SPECIAL_INT_NUM;
|
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++] = 0x83; // add sp, 2
|
||||||
BiosCode[Offset++] = 0xC4;
|
BiosCode[Offset++] = 0xC4;
|
||||||
BiosCode[Offset++] = 0x02;
|
BiosCode[Offset++] = 0x02;
|
||||||
}
|
|
||||||
|
|
||||||
BiosCode[Offset++] = 0xCF; // iret
|
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;
|
WORD StackSegment, StackPointer, CodeSegment, InstructionPointer;
|
||||||
BYTE IntNum;
|
BYTE IntNum;
|
||||||
|
LPWORD Stack;
|
||||||
|
|
||||||
/* Check if this is the special interrupt */
|
/* Get the SS:SP */
|
||||||
if (Number == SPECIAL_INT_NUM)
|
|
||||||
{
|
|
||||||
/* Get the SS:SP */
|
|
||||||
#ifndef NEW_EMULATOR
|
#ifndef NEW_EMULATOR
|
||||||
StackSegment = EmulatorContext.state->segment_reg[SX86_SREG_SS].val;
|
StackSegment = EmulatorContext.state->segment_reg[SX86_SREG_SS].val;
|
||||||
StackPointer = EmulatorContext.state->general_reg[SX86_REG_SP].val;
|
StackPointer = EmulatorContext.state->general_reg[SX86_REG_SP].val;
|
||||||
#else
|
#else
|
||||||
StackSegment = EmulatorContext.Registers[EMULATOR_REG_SS].LowWord;
|
StackSegment = EmulatorContext.Registers[EMULATOR_REG_SS].LowWord;
|
||||||
StackPointer = EmulatorContext.Registers[EMULATOR_REG_SP].LowWord;
|
StackPointer = EmulatorContext.Registers[EMULATOR_REG_SP].LowWord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get the interrupt number */
|
/* Get the stack */
|
||||||
IntNum = *(LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(StackSegment, StackPointer));
|
Stack = (LPWORD)((ULONG_PTR)BaseAddress + TO_LINEAR(StackSegment, StackPointer));
|
||||||
|
|
||||||
/* Move the stack pointer forward one word to skip the interrupt number */
|
if (Code == EMULATOR_INT_BOP)
|
||||||
StackPointer += sizeof(WORD);
|
{
|
||||||
|
/* Get the interrupt number */
|
||||||
|
IntNum = LOBYTE(Stack[0]);
|
||||||
|
|
||||||
/* Get the CS:IP */
|
/* Get the CS:IP */
|
||||||
InstructionPointer = *(LPWORD)((ULONG_PTR)BaseAddress
|
InstructionPointer = Stack[1];
|
||||||
+ TO_LINEAR(StackSegment, StackPointer));
|
CodeSegment = Stack[2];
|
||||||
CodeSegment = *(LPWORD)((ULONG_PTR)BaseAddress
|
|
||||||
+ TO_LINEAR(StackSegment, StackPointer + sizeof(WORD)));
|
|
||||||
|
|
||||||
/* Check if this was an exception */
|
/* Check if this was an exception */
|
||||||
if (IntNum < 8)
|
if (IntNum < 8)
|
||||||
|
@ -275,9 +273,21 @@ static VOID EmulatorSoftwareInt(PVOID Context, BYTE Number)
|
||||||
break;
|
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)
|
static VOID EmulatorHardwareInt(PVOID Context, BYTE Number)
|
||||||
{
|
{
|
||||||
/* Do nothing */
|
/* Do nothing */
|
||||||
|
@ -445,14 +455,30 @@ VOID EmulatorClearFlag(ULONG Flag)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID EmulatorStep()
|
VOID EmulatorStep(VOID)
|
||||||
{
|
{
|
||||||
|
LPWORD Instruction;
|
||||||
|
|
||||||
#ifndef NEW_EMULATOR
|
#ifndef NEW_EMULATOR
|
||||||
/* Print the current position - useful for debugging */
|
/* Print the current position - useful for debugging */
|
||||||
DPRINT("Executing at CS:IP = %04X:%04X\n",
|
DPRINT("Executing at CS:IP = %04X:%04X\n",
|
||||||
EmulatorGetRegister(EMULATOR_REG_CS),
|
EmulatorGetRegister(EMULATOR_REG_CS),
|
||||||
EmulatorContext.state->reg_ip);
|
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 */
|
/* Call the softx86 API */
|
||||||
if (!softx86_step(&EmulatorContext))
|
if (!softx86_step(&EmulatorContext))
|
||||||
{
|
{
|
||||||
|
@ -464,7 +490,7 @@ VOID EmulatorStep()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID EmulatorCleanup()
|
VOID EmulatorCleanup(VOID)
|
||||||
{
|
{
|
||||||
/* Free the memory allocated for the 16-bit address space */
|
/* Free the memory allocated for the 16-bit address space */
|
||||||
if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
|
if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
|
||||||
|
|
|
@ -70,7 +70,8 @@
|
||||||
#define EMULATOR_NUM_CONTROL_REGS 8
|
#define EMULATOR_NUM_CONTROL_REGS 8
|
||||||
#define EMULATOR_NUM_DEBUG_REGS 8
|
#define EMULATOR_NUM_DEBUG_REGS 8
|
||||||
#define MAX_GDT_ENTRIES 8192
|
#define MAX_GDT_ENTRIES 8192
|
||||||
#define SPECIAL_INT_NUM 0xFF
|
#define EMULATOR_BOP 0xC4C4
|
||||||
|
#define EMULATOR_INT_BOP 0xBEEF
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue