mirror of
https://github.com/reactos/reactos.git
synced 2024-07-12 07:35:10 +00:00
[FAST486]
The 486 doesn't have AC, VIF, VIP or ID. Fix and simplify POPF. [NTVDM] Fix the count in the XMS copy function (INT 15h, AH = 87h). svn path=/branches/ntvdm/; revision=61082
This commit is contained in:
parent
9a8c7e2a04
commit
8e356f7a95
|
@ -341,12 +341,8 @@ typedef union _FAST486_FLAGS_REG
|
|||
ULONG Reserved2 : 1;
|
||||
ULONG Rf : 1;
|
||||
ULONG Vm : 1;
|
||||
ULONG Ac : 1;
|
||||
ULONG Vif : 1;
|
||||
ULONG Vip : 1;
|
||||
ULONG Id : 1;
|
||||
|
||||
// ULONG Reserved : 10;
|
||||
// ULONG Reserved : 14;
|
||||
};
|
||||
} FAST486_FLAGS_REG, *PFAST486_FLAGS_REG;
|
||||
|
||||
|
|
|
@ -330,7 +330,7 @@ Fast486DumpState(PFAST486_STATE State)
|
|||
State->SegmentRegs[FAST486_REG_GS].Base,
|
||||
State->SegmentRegs[FAST486_REG_GS].Limit,
|
||||
State->SegmentRegs[FAST486_REG_GS].Dpl);
|
||||
DPRINT1("\nFlags: %08X (%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s) Iopl: %u\n",
|
||||
DPRINT1("\nFlags: %08X (%s %s %s %s %s %s %s %s %s %s %s %s) Iopl: %u\n",
|
||||
State->Flags.Long,
|
||||
State->Flags.Cf ? "CF" : "cf",
|
||||
State->Flags.Pf ? "PF" : "pf",
|
||||
|
@ -344,9 +344,6 @@ Fast486DumpState(PFAST486_STATE State)
|
|||
State->Flags.Nt ? "NT" : "nt",
|
||||
State->Flags.Rf ? "RF" : "rf",
|
||||
State->Flags.Vm ? "VM" : "vm",
|
||||
State->Flags.Ac ? "AC" : "ac",
|
||||
State->Flags.Vif ? "VIF" : "vif",
|
||||
State->Flags.Vip ? "VIP" : "vip",
|
||||
State->Flags.Iopl);
|
||||
DPRINT1("\nControl Registers:\n"
|
||||
"CR0 = %08X\tCR2 = %08X\tCR3 = %08X\n",
|
||||
|
|
|
@ -4163,121 +4163,37 @@ FAST486_OPCODE_HANDLER(Fast486OpcodePopFlags)
|
|||
{
|
||||
BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
INT Cpl = Fast486GetCurrentPrivLevel(State);
|
||||
ULONG NewFlags;
|
||||
FAST486_FLAGS_REG NewFlags;
|
||||
|
||||
NO_LOCK_PREFIX();
|
||||
TOGGLE_OPSIZE(Size);
|
||||
|
||||
/* Pop the new flags */
|
||||
if (!Fast486StackPop(State, &NewFlags))
|
||||
if (!Fast486StackPop(State, &NewFlags.Long))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!State->Flags.Vm)
|
||||
if (State->Flags.Vm && (State->Flags.Iopl != 3))
|
||||
{
|
||||
/* Check the current privilege level */
|
||||
if (Cpl == 0)
|
||||
{
|
||||
/* Supervisor */
|
||||
|
||||
/* Set the flags */
|
||||
if (Size)
|
||||
{
|
||||
/* Memorize the old state of RF */
|
||||
BOOLEAN OldRf = State->Flags.Rf;
|
||||
|
||||
State->Flags.Long = NewFlags;
|
||||
|
||||
/* Restore VM and RF */
|
||||
State->Flags.Vm = FALSE;
|
||||
State->Flags.Rf = OldRf;
|
||||
|
||||
/* Clear VIF and VIP */
|
||||
State->Flags.Vif = State->Flags.Vip = FALSE;
|
||||
}
|
||||
else State->Flags.LowWord = LOWORD(NewFlags);
|
||||
|
||||
/* Restore the reserved bits */
|
||||
State->Flags.AlwaysSet = TRUE;
|
||||
State->Flags.Reserved0 = FALSE;
|
||||
State->Flags.Reserved1 = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* User */
|
||||
|
||||
/* Memorize the old state of IF and IOPL */
|
||||
BOOLEAN OldIf = State->Flags.If;
|
||||
UINT OldIopl = State->Flags.Iopl;
|
||||
|
||||
/* Set the flags */
|
||||
if (Size)
|
||||
{
|
||||
/* Memorize the old state of RF */
|
||||
BOOLEAN OldRf = State->Flags.Rf;
|
||||
|
||||
State->Flags.Long = NewFlags;
|
||||
|
||||
/* Restore VM and RF */
|
||||
State->Flags.Vm = FALSE;
|
||||
State->Flags.Rf = OldRf;
|
||||
|
||||
/* Clear VIF and VIP */
|
||||
State->Flags.Vif = State->Flags.Vip = FALSE;
|
||||
}
|
||||
else State->Flags.LowWord = LOWORD(NewFlags);
|
||||
|
||||
/* Restore the reserved bits and IOPL */
|
||||
State->Flags.AlwaysSet = TRUE;
|
||||
State->Flags.Reserved0 = FALSE;
|
||||
State->Flags.Reserved1 = FALSE;
|
||||
State->Flags.Iopl = OldIopl;
|
||||
|
||||
/* Check if the user doesn't have the privilege to change IF */
|
||||
if (Cpl > State->Flags.Iopl)
|
||||
{
|
||||
/* Restore IF */
|
||||
State->Flags.If = OldIf;
|
||||
}
|
||||
}
|
||||
/* Call the VM86 monitor */
|
||||
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the IOPL */
|
||||
if (State->Flags.Iopl == 3)
|
||||
{
|
||||
if (Size)
|
||||
{
|
||||
/* Memorize the old state of RF, VIF and VIP */
|
||||
BOOLEAN OldRf = State->Flags.Rf;
|
||||
BOOLEAN OldVif = State->Flags.Vif;
|
||||
BOOLEAN OldVip = State->Flags.Vip;
|
||||
|
||||
State->Flags.Long = NewFlags;
|
||||
State->Flags.Cf = NewFlags.Cf;
|
||||
State->Flags.Pf = NewFlags.Pf;
|
||||
State->Flags.Af = NewFlags.Af;
|
||||
State->Flags.Zf = NewFlags.Zf;
|
||||
State->Flags.Sf = NewFlags.Sf;
|
||||
State->Flags.Tf = NewFlags.Tf;
|
||||
State->Flags.Df = NewFlags.Df;
|
||||
State->Flags.Of = NewFlags.Of;
|
||||
State->Flags.Nt = NewFlags.Nt;
|
||||
|
||||
/* Restore VM, RF, VIF and VIP */
|
||||
State->Flags.Vm = TRUE;
|
||||
State->Flags.Rf = OldRf;
|
||||
State->Flags.Vif = OldVif;
|
||||
State->Flags.Vip = OldVip;
|
||||
}
|
||||
else State->Flags.LowWord = LOWORD(NewFlags);
|
||||
|
||||
/* Restore the reserved bits and IOPL */
|
||||
State->Flags.AlwaysSet = TRUE;
|
||||
State->Flags.Reserved0 = FALSE;
|
||||
State->Flags.Reserved1 = FALSE;
|
||||
State->Flags.Iopl = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call the VM86 monitor */
|
||||
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
|
||||
}
|
||||
|
||||
}
|
||||
if (Cpl == 0) State->Flags.Iopl = NewFlags.Iopl;
|
||||
if (Cpl <= State->Flags.Iopl) State->Flags.If = NewFlags.If;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -1226,7 +1226,7 @@ VOID WINAPI BiosMiscService(LPWORD Stack)
|
|||
/* Copy Extended Memory */
|
||||
case 0x87:
|
||||
{
|
||||
WORD Count = getCX() * 2 - 1;
|
||||
DWORD Count = (DWORD)getCX() * 2;
|
||||
PFAST486_GDT_ENTRY Gdt = (PFAST486_GDT_ENTRY)SEG_OFF_TO_PTR(getES(), getSI());
|
||||
DWORD SourceBase = Gdt[2].Base + (Gdt[2].BaseMid << 16) + (Gdt[2].BaseHigh << 24);
|
||||
DWORD SourceLimit = Gdt[2].Limit + (Gdt[2].LimitHigh << 16);
|
||||
|
|
Loading…
Reference in a new issue