Author: aandrejevic Date: Sat Jan 31 22:47:05 2015 New Revision: 66134
URL: http://svn.reactos.org/svn/reactos?rev=66134&view=rev Log: [FAST486] Implement FLDENV and FRSTOR.
Modified: trunk/reactos/lib/fast486/fpu.c
Modified: trunk/reactos/lib/fast486/fpu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/fpu.c?rev=66134... ============================================================================== --- trunk/reactos/lib/fast486/fpu.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/fpu.c [iso-8859-1] Sat Jan 31 22:47:05 2015 @@ -920,6 +920,49 @@ }
static inline BOOLEAN FASTCALL +Fast486FpuLoadEnvironment(PFAST486_STATE State, + INT Segment, + ULONG Address, + BOOLEAN Size) +{ + UCHAR Buffer[28]; + + if (!Fast486ReadMemory(State, Segment, Address, FALSE, Buffer, (Size + 1) * 14)) + { + /* Exception occurred */ + return FALSE; + } + + /* Check if this is a 32-bit save or a 16-bit save */ + if (Size) + { + PULONG Data = (PULONG)Buffer; + + State->FpuControl.Value = (USHORT)Data[0]; + State->FpuStatus.Value = (USHORT)Data[1]; + State->FpuTag = (USHORT)Data[2]; + State->FpuLastInstPtr.Long = Data[3]; + State->FpuLastCodeSel = (USHORT)Data[4]; + State->FpuLastOpPtr.Long = Data[5]; + State->FpuLastDataSel = (USHORT)Data[6]; + } + else + { + PUSHORT Data = (PUSHORT)Buffer; + + State->FpuControl.Value = Data[0]; + State->FpuStatus.Value = Data[1]; + State->FpuTag = Data[2]; + State->FpuLastInstPtr.LowWord = Data[3]; + State->FpuLastCodeSel = Data[4]; + State->FpuLastOpPtr.LowWord = Data[5]; + State->FpuLastDataSel = Data[6]; + } + + return TRUE; +} + +static inline BOOLEAN FASTCALL Fast486FpuSaveEnvironment(PFAST486_STATE State, INT Segment, ULONG Address, @@ -1136,9 +1179,11 @@ /* FLDENV */ case 4: { - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; - + Fast486FpuLoadEnvironment(State, + (State->PrefixFlags & FAST486_PREFIX_SEG) + ? FAST486_REG_DS : State->SegmentOverride, + ModRegRm.MemoryAddress, + OperandSize); break; }
@@ -1698,8 +1743,47 @@ /* FRSTOR */ case 4: { - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; + INT i; + UCHAR AllRegs[80]; + + /* Save the environment */ + if (!Fast486FpuLoadEnvironment(State, + (State->PrefixFlags & FAST486_PREFIX_SEG) + ? FAST486_REG_DS : State->SegmentOverride, + ModRegRm.MemoryAddress, + OperandSize)) + { + /* Exception occurred */ + return; + } + + /* Load the registers */ + if (!Fast486ReadMemory(State, + (State->PrefixFlags & FAST486_PREFIX_SEG) + ? FAST486_REG_DS : State->SegmentOverride, + ModRegRm.MemoryAddress + (OperandSize + 1) * 14, + FALSE, + AllRegs, + sizeof(AllRegs))) + { + /* Exception occurred */ + return; + } + + for (i = 0; i < FAST486_NUM_FPU_REGS; i++) + { + State->FpuRegisters[i].Mantissa = *((PULONGLONG)&AllRegs[i * 10]); + State->FpuRegisters[i].Exponent = *((PUSHORT)&AllRegs[(i * 10) + sizeof(ULONGLONG)]) & 0x7FFF; + + if (*((PUSHORT)&AllRegs[(i * 10) + sizeof(ULONGLONG)]) & 0x8000) + { + State->FpuRegisters[i].Sign = TRUE; + } + else + { + State->FpuRegisters[i].Sign = FALSE; + } + }
break; } @@ -1709,8 +1793,6 @@ { INT i; UCHAR AllRegs[80]; - - FPU_SAVE_LAST_INST();
/* Save the environment */ if (!Fast486FpuSaveEnvironment(State, @@ -1748,9 +1830,6 @@ /* FSTSW */ case 7: { - FPU_SAVE_LAST_INST(); - FPU_SAVE_LAST_OPERAND(); - Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, State->FpuStatus.Value); break; }