From 87f5903d48f179b8ee32cee0ddadcc37dfb25440 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Fri, 25 Oct 2013 18:15:24 +0000 Subject: [PATCH] [FAST486] Implement extended opcode groups 0xB9 (UD2) and 0xBA (BT/BTS/BTR/BTC). svn path=/branches/ntvdm/; revision=60745 --- lib/fast486/extraops.c | 5 +- lib/fast486/opgroups.c | 153 +++++++++++++++++++++++++++++++++++++++++ lib/fast486/opgroups.h | 2 + 3 files changed, 158 insertions(+), 2 deletions(-) diff --git a/lib/fast486/extraops.c b/lib/fast486/extraops.c index 6890a66941f..e83312e3f36 100644 --- a/lib/fast486/extraops.c +++ b/lib/fast486/extraops.c @@ -31,6 +31,7 @@ #include #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 diff --git a/lib/fast486/opgroups.c b/lib/fast486/opgroups.c index 86ff1a485bd..2ab82e5c923 100644 --- a/lib/fast486/opgroups.c +++ b/lib/fast486/opgroups.c @@ -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 */ diff --git a/lib/fast486/opgroups.h b/lib/fast486/opgroups.h index fb7dcd40c34..f88bdea4f10 100644 --- a/lib/fast486/opgroups.h +++ b/lib/fast486/opgroups.h @@ -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_