Author: aandrejevic Date: Sun Oct 20 00:25:41 2013 New Revision: 60716
URL: http://svn.reactos.org/svn/reactos?rev=60716&view=rev Log: [FAST486] Implement BT, BTS, BTR and BTC.
Modified: branches/ntvdm/lib/fast486/extraops.c branches/ntvdm/lib/fast486/extraops.h
Modified: branches/ntvdm/lib/fast486/extraops.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/extraops.c?rev... ============================================================================== --- branches/ntvdm/lib/fast486/extraops.c [iso-8859-1] (original) +++ branches/ntvdm/lib/fast486/extraops.c [iso-8859-1] Sun Oct 20 00:25:41 2013 @@ -201,7 +201,7 @@ Fast486ExtOpcodePushFs, Fast486ExtOpcodePopFs, NULL, // Invalid - NULL, // TODO: OPCODE 0xA3 NOT IMPLEMENTED + Fast486ExtOpcodeBitTest, NULL, // TODO: OPCODE 0xA4 NOT IMPLEMENTED NULL, // TODO: OPCODE 0xA5 NOT IMPLEMENTED NULL, // Invalid @@ -209,7 +209,7 @@ Fast486ExtOpcodePushGs, Fast486ExtOpcodePopGs, NULL, // TODO: OPCODE 0xAA NOT IMPLEMENTED - NULL, // TODO: OPCODE 0xAB NOT IMPLEMENTED + Fast486ExtOpcodeBts, NULL, // TODO: OPCODE 0xAC NOT IMPLEMENTED NULL, // TODO: OPCODE 0xAD NOT IMPLEMENTED NULL, // TODO: OPCODE 0xAE NOT IMPLEMENTED @@ -217,7 +217,7 @@ Fast486ExtOpcodeCmpXchgByte, Fast486ExtOpcodeCmpXchg, NULL, // TODO: OPCODE 0xB2 NOT IMPLEMENTED - NULL, // TODO: OPCODE 0xB3 NOT IMPLEMENTED + Fast486ExtOpcodeBtr, NULL, // TODO: OPCODE 0xB4 NOT IMPLEMENTED NULL, // TODO: OPCODE 0xB5 NOT IMPLEMENTED NULL, // TODO: OPCODE 0xB6 NOT IMPLEMENTED @@ -225,7 +225,7 @@ NULL, // TODO: OPCODE 0xB8 NOT IMPLEMENTED NULL, // TODO: OPCODE 0xB9 NOT IMPLEMENTED NULL, // TODO: OPCODE 0xBA NOT IMPLEMENTED - NULL, // TODO: OPCODE 0xBB NOT IMPLEMENTED + Fast486ExtOpcodeBtc, NULL, // TODO: OPCODE 0xBC NOT IMPLEMENTED NULL, // TODO: OPCODE 0xBD NOT IMPLEMENTED NULL, // TODO: OPCODE 0xBE NOT IMPLEMENTED @@ -318,6 +318,77 @@ return Fast486LoadSegment(State, FAST486_REG_FS, LOWORD(NewSelector)); }
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBitTest) +{ + BOOLEAN OperandSize, AddressSize; + FAST486_MOD_REG_RM ModRegRm; + UINT DataSize; + ULONG 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; + + /* Get the operands */ + if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) + { + /* Exception occurred */ + return FALSE; + } + + /* Get the bit number */ + BitNumber = OperandSize ? State->GeneralRegs[ModRegRm.Register].Long + : (ULONG)State->GeneralRegs[ModRegRm.Register].LowWord; + + 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; + } + 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; + } + + /* Return success */ + return TRUE; +} + FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushGs) { /* Call the internal API */ @@ -336,6 +407,97 @@
/* Call the internal API */ return Fast486LoadSegment(State, FAST486_REG_GS, LOWORD(NewSelector)); +} + +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBts) +{ + BOOLEAN OperandSize, AddressSize; + FAST486_MOD_REG_RM ModRegRm; + UINT DataSize; + ULONG 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; + + /* Get the operands */ + if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) + { + /* Exception occurred */ + return FALSE; + } + + /* Get the bit number */ + BitNumber = OperandSize ? State->GeneralRegs[ModRegRm.Register].Long + : (ULONG)State->GeneralRegs[ModRegRm.Register].LowWord; + + 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; + + /* Set the bit */ + Value |= 1 << BitNumber; + + /* 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; + + /* Set the bit */ + Value |= 1 << BitNumber; + + /* Write back the result */ + if (!Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value)) + { + /* Exception occurred */ + return FALSE; + } + } + + /* Return success */ + return TRUE; }
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchgByte) @@ -343,7 +505,7 @@ FAST486_MOD_REG_RM ModRegRm; UCHAR Accumulator = State->GeneralRegs[FAST486_REG_EAX].LowByte; UCHAR Source, Destination, Result; - BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;; + BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
TOGGLE_ADSIZE(AddressSize);
@@ -478,7 +640,188 @@
/* Return success */ return TRUE; - +} + +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtr) +{ + BOOLEAN OperandSize, AddressSize; + FAST486_MOD_REG_RM ModRegRm; + UINT DataSize; + ULONG 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; + + /* Get the operands */ + if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) + { + /* Exception occurred */ + return FALSE; + } + + /* Get the bit number */ + BitNumber = OperandSize ? State->GeneralRegs[ModRegRm.Register].Long + : (ULONG)State->GeneralRegs[ModRegRm.Register].LowWord; + + 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; + + /* Clear the bit */ + Value &= ~(1 << BitNumber); + + /* 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; + + /* Clear the bit */ + Value &= ~(1 << BitNumber); + + /* Write back the result */ + if (!Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value)) + { + /* Exception occurred */ + return FALSE; + } + } + + /* Return success */ + return TRUE; +} + +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtc) +{ + BOOLEAN OperandSize, AddressSize; + FAST486_MOD_REG_RM ModRegRm; + UINT DataSize; + ULONG 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; + + /* Get the operands */ + if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) + { + /* Exception occurred */ + return FALSE; + } + + /* Get the bit number */ + BitNumber = OperandSize ? State->GeneralRegs[ModRegRm.Register].Long + : (ULONG)State->GeneralRegs[ModRegRm.Register].LowWord; + + 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; + + /* Toggle the bit */ + Value ^= 1 << BitNumber; + + /* 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; + + /* Toggle the bit */ + Value ^= 1 << BitNumber; + + /* Write back the result */ + if (!Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value)) + { + /* Exception occurred */ + return FALSE; + } + } + + /* Return success */ + return TRUE; }
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalJmp)
Modified: branches/ntvdm/lib/fast486/extraops.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/extraops.h?rev... ============================================================================== --- branches/ntvdm/lib/fast486/extraops.h [iso-8859-1] (original) +++ branches/ntvdm/lib/fast486/extraops.h [iso-8859-1] Sun Oct 20 00:25:41 2013 @@ -25,10 +25,14 @@ /* DEFINES ********************************************************************/ FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushFs); FAST486_OPCODE_HANDLER(Fast486ExtOpcodePopFs); +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBitTest); FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushGs); FAST486_OPCODE_HANDLER(Fast486ExtOpcodePopGs); +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBts); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchgByte); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchg); +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtr); +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtc); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalJmp); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalSet); FAST486_OPCODE_HANDLER(Fast486OpcodeExtended);