Author: aandrejevic Date: Tue May 26 19:11:33 2015 New Revision: 67932
URL: http://svn.reactos.org/svn/reactos?rev=67932&view=rev Log: [FAST486] Implement FPTAN by calculating the sine and then dividing it by the approximated cosine: sqrt(1 - sin(x) ^ 2). This method turned out to be faster and more precise than the Maclaurin series for tan(x), which converges very slowly.
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=67932... ============================================================================== --- trunk/reactos/lib/fast486/fpu.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/fpu.c [iso-8859-1] Tue May 26 19:11:33 2015 @@ -1173,7 +1173,7 @@ */ static inline VOID FASTCALL Fast486FpuCalculateTwoPowerMinusOne(PFAST486_STATE State, - PFAST486_FPU_DATA_REG Operand, + PCFAST486_FPU_DATA_REG Operand, PFAST486_FPU_DATA_REG Result) { INT i; @@ -1221,7 +1221,7 @@
static inline BOOLEAN FASTCALL Fast486FpuCalculateLogBase2(PFAST486_STATE State, - PFAST486_FPU_DATA_REG Operand, + PCFAST486_FPU_DATA_REG Operand, PFAST486_FPU_DATA_REG Result) { INT i; @@ -1345,7 +1345,7 @@ */ static inline BOOLEAN FASTCALL Fast486FpuCalculateSine(PFAST486_STATE State, - PFAST486_FPU_DATA_REG Operand, + PCFAST486_FPU_DATA_REG Operand, PFAST486_FPU_DATA_REG Result) { INT i; @@ -1425,7 +1425,7 @@ */ static inline BOOLEAN FASTCALL Fast486FpuCalculateCosine(PFAST486_STATE State, - PFAST486_FPU_DATA_REG Operand, + PCFAST486_FPU_DATA_REG Operand, PFAST486_FPU_DATA_REG Result) { FAST486_FPU_DATA_REG Value = *Operand; @@ -2136,9 +2136,23 @@ /* FPTAN */ case 0x32: { - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; - + FAST486_FPU_DATA_REG Sine; + FAST486_FPU_DATA_REG Cosine; + + /* Compute the sine */ + if (!Fast486FpuCalculateSine(State, &FPU_ST(0), &Sine)) break; + + /* Find the cosine by calculating sqrt(1 - sin(x) ^ 2) */ + if (!Fast486FpuMultiply(State, &Sine, &Sine, &Cosine)) break; + if (!Fast486FpuSubtract(State, &FpuOne, &Cosine, &Cosine)) break; + if (!Fast486FpuCalculateSquareRoot(State, &Cosine, &Cosine)) break; + + /* Divide the sine by the cosine to get the tangent */ + if (!Fast486FpuDivide(State, &Sine, &Cosine, &FPU_ST(0))) break; + FPU_UPDATE_TAG(0); + + /* Push 1.00 */ + Fast486FpuPush(State, &FpuOne); break; }