mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[HAL/x64] Fix x86BiosCall
Use an INT call stub and exit on the address after the stub instead or using iret (some BIOS code uses int / iret internally). This fixes the messed up display when trying to switch modes.
This commit is contained in:
parent
38fc6e1274
commit
3381bf39db
1 changed files with 20 additions and 21 deletions
|
@ -412,12 +412,8 @@ x86BiosCall(
|
||||||
_In_ ULONG InterruptNumber,
|
_In_ ULONG InterruptNumber,
|
||||||
_Inout_ PX86_BIOS_REGISTERS Registers)
|
_Inout_ PX86_BIOS_REGISTERS Registers)
|
||||||
{
|
{
|
||||||
|
const ULONG StackBase = 0x2000;
|
||||||
FAST486_STATE EmulatorContext;
|
FAST486_STATE EmulatorContext;
|
||||||
struct
|
|
||||||
{
|
|
||||||
USHORT Ip;
|
|
||||||
USHORT SegCs;
|
|
||||||
} *Ivt;
|
|
||||||
ULONG FlatIp;
|
ULONG FlatIp;
|
||||||
PUCHAR InstructionPointer;
|
PUCHAR InstructionPointer;
|
||||||
|
|
||||||
|
@ -432,8 +428,6 @@ x86BiosCall(
|
||||||
NULL, // FpuCallback,
|
NULL, // FpuCallback,
|
||||||
NULL); // Tlb
|
NULL); // Tlb
|
||||||
|
|
||||||
//RegisterBop(BOP_UNSIMULATE, CpuUnsimulateBop);
|
|
||||||
|
|
||||||
/* Copy the registers */
|
/* Copy the registers */
|
||||||
EmulatorContext.GeneralRegs[FAST486_REG_EAX].Long = Registers->Eax;
|
EmulatorContext.GeneralRegs[FAST486_REG_EAX].Long = Registers->Eax;
|
||||||
EmulatorContext.GeneralRegs[FAST486_REG_EBX].Long = Registers->Ebx;
|
EmulatorContext.GeneralRegs[FAST486_REG_EBX].Long = Registers->Ebx;
|
||||||
|
@ -449,36 +443,41 @@ x86BiosCall(
|
||||||
EmulatorContext.Flags.AlwaysSet = 1;
|
EmulatorContext.Flags.AlwaysSet = 1;
|
||||||
EmulatorContext.Flags.If = 1;
|
EmulatorContext.Flags.If = 1;
|
||||||
|
|
||||||
/* Set the stack pointer */
|
/* Set up the INT stub */
|
||||||
Fast486SetStack(&EmulatorContext, 0, 0x2000 - 2); // FIXME
|
FlatIp = StackBase - 4;
|
||||||
|
InstructionPointer = x86BiosMemoryMapping + FlatIp;
|
||||||
|
InstructionPointer[0] = 0xCD; // INT instruction
|
||||||
|
InstructionPointer[1] = (UCHAR)InterruptNumber;
|
||||||
|
InstructionPointer[2] = 0x90; // NOP. We will stop at this address.
|
||||||
|
|
||||||
/* Set CS:EIP from the IVT entry */
|
/* Set the stack pointer */
|
||||||
Ivt = (PVOID)x86BiosMemoryMapping;
|
Fast486SetStack(&EmulatorContext, 0, StackBase - 8);
|
||||||
Fast486ExecuteAt(&EmulatorContext,
|
|
||||||
Ivt[InterruptNumber].SegCs,
|
/* Start execution at the INT stub */
|
||||||
Ivt[InterruptNumber].Ip);
|
Fast486ExecuteAt(&EmulatorContext, 0x00, FlatIp);
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
/* Step one instruction */
|
/* Get the current flat IP */
|
||||||
Fast486StepInto(&EmulatorContext);
|
|
||||||
|
|
||||||
/* Check for iret */
|
|
||||||
FlatIp = (EmulatorContext.SegmentRegs[FAST486_REG_CS].Selector << 4) +
|
FlatIp = (EmulatorContext.SegmentRegs[FAST486_REG_CS].Selector << 4) +
|
||||||
EmulatorContext.InstPtr.Long;
|
EmulatorContext.InstPtr.Long;
|
||||||
|
|
||||||
|
/* Make sure we haven't left the allowed memory range */
|
||||||
if (FlatIp >= 0x100000)
|
if (FlatIp >= 0x100000)
|
||||||
{
|
{
|
||||||
DPRINT1("x86BiosCall: invalid IP (0x%lx) during BIOS execution", FlatIp);
|
DPRINT1("x86BiosCall: invalid IP (0x%lx) during BIOS execution", FlatIp);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the next instruction and check if it's IRET */
|
/* Check if we returned from our int stub */
|
||||||
InstructionPointer = x86BiosMemoryMapping + FlatIp;
|
if (FlatIp == (StackBase - 2))
|
||||||
if (*InstructionPointer == 0xCF)
|
|
||||||
{
|
{
|
||||||
/* We are done! */
|
/* We are done! */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Emulate one instruction */
|
||||||
|
Fast486StepInto(&EmulatorContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the registers back */
|
/* Copy the registers back */
|
||||||
|
|
Loading…
Reference in a new issue