* Fast486 386/486 CPU Emulation Library
* opgroups.c
*
- * Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
/* PRIVATE FUNCTIONS **********************************************************/
-inline
static
+inline
ULONG
Fast486ArithmeticOperation(PFAST486_STATE State,
INT Operation,
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Fetch the immediate operand */
if (!Fast486FetchByte(State, &Immediate))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Read the operands */
if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* Unless this is CMP, write back the result */
if (ModRegRm.Register != 7)
{
- return Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup81)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (OperandSize)
if (!Fast486FetchDword(State, &Immediate))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Read the operands */
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* Unless this is CMP, write back the result */
if (ModRegRm.Register != 7)
{
- return Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
}
}
else
if (!Fast486FetchWord(State, &Immediate))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Read the operands */
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* Unless this is CMP, write back the result */
if (ModRegRm.Register != 7)
{
- return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
}
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup83)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Fetch the immediate operand */
if (!Fast486FetchByte(State, (PUCHAR)&ImmByte))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (OperandSize)
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* Unless this is CMP, write back the result */
if (ModRegRm.Register != 7)
{
- return Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
}
}
else
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* Unless this is CMP, write back the result */
if (ModRegRm.Register != 7)
{
- return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
}
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup8F)
if (!Fast486StackPop(State, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
if (OperandSize) State->GeneralRegs[FAST486_REG_ESP].Long -= sizeof(ULONG);
else State->GeneralRegs[FAST486_REG_ESP].LowWord -= sizeof(USHORT);
- return FALSE;
+ return;
}
if (ModRegRm.Register != 0)
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
- if (OperandSize)
- {
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- FALSE,
- Value);
- }
- else
- {
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- FALSE,
- LOWORD(Value));
- }
+ if (OperandSize) Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
+ else Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, LOWORD(Value));
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC0)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Fetch the count */
if (!Fast486FetchByte(State, &Count))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Read the operands */
if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
Count));
/* Write back the result */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- FALSE,
- Value);
+ Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC1)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Fetch the count */
if (!Fast486FetchByte(State, &Count))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (OperandSize)
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
Count);
/* Write back the result */
- return Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
}
else
{
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
Count));
/* Write back the result */
- return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
}
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (ModRegRm.Register != 0)
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Get the immediate operand */
if (!Fast486FetchByte(State, &Immediate))
{
/* Exception occurred */
- return FALSE;
+ return;
}
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- FALSE,
- Immediate);
+ Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Immediate);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupC7)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (ModRegRm.Register != 0)
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (OperandSize)
if (!Fast486FetchDword(State, &Immediate))
{
/* Exception occurred */
- return FALSE;
+ return;
}
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- FALSE,
- Immediate);
+ Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Immediate);
}
else
{
if (!Fast486FetchWord(State, &Immediate))
{
/* Exception occurred */
- return FALSE;
+ return;
}
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- FALSE,
- Immediate);
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Immediate);
}
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Read the operands */
if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
Value = LOBYTE(Fast486RotateOperation(State, ModRegRm.Register, Value, 8, 1));
/* Write back the result */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- FALSE,
- Value);
+ Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (OperandSize)
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
Value = Fast486RotateOperation(State, ModRegRm.Register, Value, 32, 1);
/* Write back the result */
- return Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
}
else
{
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
Value = LOWORD(Fast486RotateOperation(State, ModRegRm.Register, Value, 16, 1));
/* Write back the result */
- return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
}
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Read the operands */
if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
State->GeneralRegs[FAST486_REG_ECX].LowByte));
/* Write back the result */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- FALSE,
- Value);
+ Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupD3)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (OperandSize)
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
State->GeneralRegs[FAST486_REG_ECX].LowByte);
/* Write back the result */
- return Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
}
else
{
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
State->GeneralRegs[FAST486_REG_ECX].LowByte));
/* Write back the result */
- return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
}
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Read the operands */
if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
switch (ModRegRm.Register)
if (!Fast486FetchByte(State, &Immediate))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
case 2:
{
/* Write back the result */
- return Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, ~Value);
+ Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, ~Value);
+
+ break;
}
/* NEG */
State->Flags.Pf = Fast486CalculateParity(Result);
/* Write back the result */
- return Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Result);
+ Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Result);
+
+ break;
}
/* MUL */
{
/* Divide error */
Fast486Exception(State, FAST486_EXCEPTION_DE);
- return FALSE;
+ return;
}
Quotient = State->GeneralRegs[FAST486_REG_EAX].LowWord / Value;
{
/* Divide error */
Fast486Exception(State, FAST486_EXCEPTION_DE);
- return FALSE;
+ return;
}
Quotient = (SHORT)State->GeneralRegs[FAST486_REG_EAX].LowWord / (CHAR)Value;
break;
}
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupF7)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the sign flag */
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
else
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, (PUSHORT)&Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
if (!Fast486FetchDword(State, &Immediate))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
else
if (!Fast486FetchWord(State, (PUSHORT)&Immediate))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
if (OperandSize)
{
/* 32-bit */
- return Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, ~Value);
+ Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, ~Value);
}
else
{
/* 16-bit */
- return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, LOWORD(~Value));
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, LOWORD(~Value));
}
+
+ break;
}
/* NEG */
if (OperandSize)
{
/* 32-bit */
- return Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Result);
+ Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Result);
}
else
{
/* 16-bit */
- return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, LOWORD(Result));
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, LOWORD(Result));
}
+
+ break;
}
/* MUL */
{
/* Divide error */
Fast486Exception(State, FAST486_EXCEPTION_DE);
- return FALSE;
+ return;
}
if (OperandSize)
{
/* Divide error */
Fast486Exception(State, FAST486_EXCEPTION_DE);
- return FALSE;
+ return;
}
if (OperandSize)
break;
}
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFE)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (ModRegRm.Register > 1)
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Read the operands */
if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (ModRegRm.Register == 0)
State->Flags.Pf = Fast486CalculateParity(Value);
/* Write back the result */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- FALSE,
- Value);
+ Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFF)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (ModRegRm.Register == 7)
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Read the operands */
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (ModRegRm.Register == 0)
if (!Fast486StackPush(State, State->InstPtr.Long))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the EIP to the address */
sizeof(USHORT)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Push the current value of CS */
if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Push the current value of EIP */
if (!Fast486StackPush(State, State->InstPtr.Long))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load the new code segment */
if (!Fast486LoadSegment(State, FAST486_REG_CS, Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the EIP to the address */
sizeof(USHORT)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load the new code segment */
if (!Fast486LoadSegment(State, FAST486_REG_CS, Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the EIP to the address */
else if (ModRegRm.Register == 6)
{
/* Push the value on to the stack */
- return Fast486StackPush(State, Value);
+ Fast486StackPush(State, Value);
+ return;
}
if (ModRegRm.Register <= 1)
State->Flags.Pf = Fast486CalculateParity(Value);
/* Write back the result */
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- FALSE,
- Value);
+ Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
}
}
else
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (ModRegRm.Register == 0)
if (!Fast486StackPush(State, State->InstPtr.LowWord))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the IP to the address */
sizeof(USHORT)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Push the current value of CS */
if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Push the current value of IP */
if (!Fast486StackPush(State, State->InstPtr.LowWord))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load the new code segment */
if (!Fast486LoadSegment(State, FAST486_REG_CS, Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the IP to the address */
sizeof(USHORT)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load the new code segment */
if (!Fast486LoadSegment(State, FAST486_REG_CS, Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the IP to the address */
else if (ModRegRm.Register == 6)
{
/* Push the value on to the stack */
- return Fast486StackPush(State, Value);
+ Fast486StackPush(State, Value);
+ return;
}
else
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (ModRegRm.Register <= 1)
State->Flags.Pf = Fast486CalculateParity(Value);
/* Write back the result */
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- FALSE,
- Value);
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
}
}
-
- return TRUE;
}
-FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F00)
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0F00)
{
FAST486_MOD_REG_RM ModRegRm;
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check which operation this is */
|| State->Flags.Vm)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- FALSE,
- State->Ldtr.Selector);
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, State->Ldtr.Selector);
+ break;
}
/* STR */
|| State->Flags.Vm)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- FALSE,
- State->TaskReg.Selector);
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, State->TaskReg.Selector);
+ break;
}
/* LLDT */
|| State->Flags.Vm)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* This is a privileged instruction */
if (Fast486GetCurrentPrivLevel(State) != 0)
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
if (!Fast486ReadModrmWordOperands(State,
&Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Make sure the GDT contains the entry */
if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1))
{
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
- return FALSE;
+ return;
}
/* Read the GDT */
sizeof(GdtEntry)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (GET_SEGMENT_INDEX(Selector) == 0)
{
RtlZeroMemory(&State->Ldtr, sizeof(State->Ldtr));
- return TRUE;
+ return;
}
if (!GdtEntry.Present)
{
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector);
- return FALSE;
+ return;
}
if (GdtEntry.Signature != FAST486_LDT_SIGNATURE)
{
/* This is not a LDT descriptor */
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
- return FALSE;
+ return;
}
/* Update the LDTR */
State->Ldtr.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
if (GdtEntry.Granularity) State->Ldtr.Limit <<= 12;
- return TRUE;
+ break;
}
/* LTR */
|| State->Flags.Vm)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* This is a privileged instruction */
if (Fast486GetCurrentPrivLevel(State) != 0)
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
if (!Fast486ReadModrmWordOperands(State,
&Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Make sure the GDT contains the entry */
if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1))
{
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
- return FALSE;
+ return;
}
/* Read the GDT */
sizeof(GdtEntry)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (GET_SEGMENT_INDEX(Selector) == 0)
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
if (!GdtEntry.Present)
{
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector);
- return FALSE;
+ return;
}
if (GdtEntry.Signature != FAST486_TSS_SIGNATURE)
{
/* This is not a TSS descriptor */
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
- return FALSE;
+ return;
}
/* Update the TR */
if (GdtEntry.Granularity) State->TaskReg.Limit <<= 12;
State->TaskReg.Busy = TRUE;
- return TRUE;
+ break;
}
/* VERR/VERW */
|| State->Flags.Vm)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* This is a privileged instruction */
if (Fast486GetCurrentPrivLevel(State) != 0)
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
if (!Fast486ReadModrmWordOperands(State,
&Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!(Selector & SEGMENT_TABLE_INDICATOR))
{
/* Clear ZF */
State->Flags.Zf = FALSE;
- return TRUE;
+ return;
}
/* Read the GDT */
sizeof(GdtEntry)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
else
{
/* Clear ZF */
State->Flags.Zf = FALSE;
- return TRUE;
+ return;
}
/* Read the LDT */
sizeof(GdtEntry)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
&& (GdtEntry.Dpl <= Fast486GetCurrentPrivLevel(State)));
- return TRUE;
+ break;
}
/* Invalid */
default:
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
}
}
}
-FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01)
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0F01)
{
+ // FAST486_TABLE_REG TableReg;
UCHAR TableReg[6];
FAST486_MOD_REG_RM ModRegRm;
- BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ BOOLEAN OperandSize, AddressSize;
FAST486_SEG_REGS Segment = FAST486_REG_DS;
+ OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+
NO_LOCK_PREFIX();
+ TOGGLE_OPSIZE(OperandSize);
TOGGLE_ADSIZE(AddressSize);
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check for the segment override */
{
/* The second operand must be a memory location */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Fill the 6-byte table register */
- RtlCopyMemory(TableReg, &State->Gdtr.Size, sizeof(USHORT));
- RtlCopyMemory(&TableReg[sizeof(USHORT)], &State->Gdtr.Address, sizeof(ULONG));
+ // TableReg = State->Gdtr;
+ *((PUSHORT)&TableReg) = State->Gdtr.Size;
+ *((PULONG)&TableReg[sizeof(USHORT)]) = State->Gdtr.Address;
/* Store the GDTR */
- return Fast486WriteMemory(State,
- Segment,
- ModRegRm.MemoryAddress,
- TableReg,
- sizeof(TableReg));
+ Fast486WriteMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress,
+ TableReg,
+ sizeof(TableReg));
+
+ break;
}
/* SIDT */
{
/* The second operand must be a memory location */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Fill the 6-byte table register */
- RtlCopyMemory(TableReg, &State->Idtr.Size, sizeof(USHORT));
- RtlCopyMemory(&TableReg[sizeof(USHORT)], &State->Idtr.Address, sizeof(ULONG));
+ // TableReg = State->Idtr;
+ *((PUSHORT)&TableReg) = State->Idtr.Size;
+ *((PULONG)&TableReg[sizeof(USHORT)]) = State->Idtr.Address;
/* Store the IDTR */
- return Fast486WriteMemory(State,
- Segment,
- ModRegRm.MemoryAddress,
- TableReg,
- sizeof(TableReg));
+ Fast486WriteMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress,
+ TableReg,
+ sizeof(TableReg));
+
+ break;
}
/* LGDT */
if (Fast486GetCurrentPrivLevel(State) != 0)
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
if (!ModRegRm.Memory)
{
/* The second operand must be a memory location */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Read the new GDTR */
sizeof(TableReg)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load the new GDT */
- State->Gdtr.Size = *((PUSHORT)TableReg);
+ // State->Gdtr = TableReg;
+ State->Gdtr.Size = *((PUSHORT)&TableReg);
State->Gdtr.Address = *((PULONG)&TableReg[sizeof(USHORT)]);
- return TRUE;
+ /* In 16-bit mode the highest byte is masked out */
+ if (!OperandSize) State->Gdtr.Address &= 0x00FFFFFF;
+
+ break;
}
/* LIDT */
if (Fast486GetCurrentPrivLevel(State) != 0)
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
if (!ModRegRm.Memory)
{
/* The second operand must be a memory location */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Read the new IDTR */
sizeof(TableReg)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load the new IDT */
- State->Idtr.Size = *((PUSHORT)TableReg);
+ // State->Idtr = TableReg;
+ State->Idtr.Size = *((PUSHORT)&TableReg);
State->Idtr.Address = *((PULONG)&TableReg[sizeof(USHORT)]);
- return TRUE;
+ /* In 16-bit mode the highest byte is masked out */
+ if (!OperandSize) State->Idtr.Address &= 0x00FFFFFF;
+
+ break;
}
/* SMSW */
case 4:
{
/* Store the lower 16 bits (Machine Status Word) of CR0 */
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- FALSE,
- LOWORD(State->ControlRegisters[FAST486_REG_CR0]));
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ FALSE,
+ LOWORD(State->ControlRegisters[FAST486_REG_CR0]));
+
+ break;
}
/* LMSW */
if (Fast486GetCurrentPrivLevel(State) != 0)
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
/* Read the new Machine Status Word */
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &MachineStatusWord))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* This instruction cannot be used to return to real mode */
&& !(MachineStatusWord & FAST486_CR0_PE))
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
/* Set the lowest 4 bits */
State->ControlRegisters[FAST486_REG_CR0] &= 0xFFFFFFF0;
State->ControlRegisters[FAST486_REG_CR0] |= MachineStatusWord & 0x0F;
- return TRUE;
+ break;
}
/* INVLPG */
case 7:
{
UNIMPLEMENTED;
- return FALSE;
+ break;
}
/* Invalid */
default:
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
}
}
}
-FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FB9)
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0FB9)
{
FAST486_MOD_REG_RM ModRegRm;
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* All of them are reserved (UD2) */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
-FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FBA)
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0FBA)
{
FAST486_MOD_REG_RM ModRegRm;
BOOLEAN OperandSize, AddressSize;
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (ModRegRm.Register < 4)
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Get the bit number */
if (!Fast486FetchByte(State, &BitNumber))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (ModRegRm.Memory)
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set CF to the bit value */
if (!Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
}
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set CF to the bit value */
if (!Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
}
-
- /* Return success */
- return TRUE;
}
/* EOF */