[FAST486]

Implement extended opcode groups 0xB9 (UD2) and 0xBA (BT/BTS/BTR/BTC).


svn path=/branches/ntvdm/; revision=60745
This commit is contained in:
Aleksandar Andrejevic
2013-10-25 18:15:24 +00:00
parent 01d5a36cf5
commit 87f5903d48
3 changed files with 158 additions and 2 deletions
+3 -2
View File
@@ -31,6 +31,7 @@
#include <fast486.h>
#include "opcodes.h"
#include "common.h"
#include "opgroups.h"
#include "extraops.h"
/* PUBLIC VARIABLES ***********************************************************/
@@ -223,8 +224,8 @@ Fast486ExtendedHandlers[FAST486_NUM_OPCODE_HANDLERS] =
NULL, // TODO: OPCODE 0xB6 NOT IMPLEMENTED
NULL, // TODO: OPCODE 0xB7 NOT IMPLEMENTED
NULL, // TODO: OPCODE 0xB8 NOT IMPLEMENTED
NULL, // TODO: OPCODE 0xB9 NOT IMPLEMENTED
NULL, // TODO: OPCODE 0xBA NOT IMPLEMENTED
Fast486OpcodeGroup0FB9,
Fast486OpcodeGroup0FBA,
Fast486ExtOpcodeBtc,
NULL, // TODO: OPCODE 0xBC NOT IMPLEMENTED
NULL, // TODO: OPCODE 0xBD NOT IMPLEMENTED
+153
View File
@@ -1659,5 +1659,158 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFF)
return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FB9)
{
FAST486_MOD_REG_RM ModRegRm;
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
TOGGLE_ADSIZE(AddressSize);
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
return FALSE;
}
/* All of them are reserved (UD2) */
Fast486Exception(State, FAST486_EXCEPTION_UD);
return FALSE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FBA)
{
FAST486_MOD_REG_RM ModRegRm;
BOOLEAN OperandSize, AddressSize;
UINT DataSize;
UCHAR BitNumber;
OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
TOGGLE_OPSIZE(OperandSize);
TOGGLE_ADSIZE(AddressSize);
/* Get the number of bits */
if (OperandSize) DataSize = 32;
else DataSize = 16;
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
return FALSE;
}
if (ModRegRm.Register < 4)
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
return FALSE;
}
/* Get the bit number */
if (!Fast486FetchByte(State, &BitNumber))
{
/* Exception occurred */
return FALSE;
}
if (ModRegRm.Memory)
{
/*
* For memory operands, add the bit offset divided by
* the data size to the address
*/
ModRegRm.MemoryAddress += BitNumber / DataSize;
}
/* Normalize the bit number */
BitNumber &= (1 << DataSize) - 1;
if (OperandSize)
{
ULONG Dummy, Value;
/* Read the value */
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Dummy, &Value))
{
/* Exception occurred */
return FALSE;
}
/* Set CF to the bit value */
State->Flags.Cf = (Value >> BitNumber) & 1;
if (ModRegRm.Register == 5)
{
/* BTS */
Value |= 1 << BitNumber;
}
else if (ModRegRm.Register == 6)
{
/* BTR */
Value &= ~(1 << BitNumber);
}
else if (ModRegRm.Register == 7)
{
/* BTC */
Value ^= 1 << BitNumber;
}
if (ModRegRm.Register >= 5)
{
/* Write back the result */
if (!Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value))
{
/* Exception occurred */
return FALSE;
}
}
}
else
{
USHORT Dummy, Value;
/* Read the value */
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Dummy, &Value))
{
/* Exception occurred */
return FALSE;
}
/* Set CF to the bit value */
State->Flags.Cf = (Value >> BitNumber) & 1;
if (ModRegRm.Register == 5)
{
/* BTS */
Value |= 1 << BitNumber;
}
else if (ModRegRm.Register == 6)
{
/* BTR */
Value &= ~(1 << BitNumber);
}
else if (ModRegRm.Register == 7)
{
/* BTC */
Value ^= 1 << BitNumber;
}
if (ModRegRm.Register >= 5)
{
/* Write back the result */
if (!Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value))
{
/* Exception occurred */
return FALSE;
}
}
}
/* Return success */
return TRUE;
return TRUE;
}
/* EOF */
+2
View File
@@ -40,6 +40,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroupF6);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupF7);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFE);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFF);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FB9);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FBA);
#endif // _OPGROUPS_H_