- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
207 lines
5.8 KiB
Plaintext
207 lines
5.8 KiB
Plaintext
/*------------------------------------------------------------------------
|
|
* filename - acosasin.cas
|
|
*
|
|
* function(s)
|
|
* AcosAsin - compute acos or asin
|
|
* acos - trigonometric function
|
|
* asin - trigonometric function
|
|
*-----------------------------------------------------------------------*/
|
|
|
|
/*
|
|
* C/C++ Run Time Library - Version 6.5
|
|
*
|
|
* Copyright (c) 1987, 1994 by Borland International
|
|
* All Rights Reserved.
|
|
*
|
|
*/
|
|
|
|
|
|
#pragma inline
|
|
#include <asmrules.h>
|
|
|
|
#include <_math.h>
|
|
#include <math.h>
|
|
#include <errno.h>
|
|
|
|
typedef unsigned short bits16;
|
|
|
|
#ifndef NULL
|
|
# define NULL ((void *)0)
|
|
#endif
|
|
|
|
static unsigned short NANINVTRIG [4] = {0,0,0x0440, 0x7FF8};
|
|
|
|
/*---------------------------------------------------------------------*
|
|
|
|
Name AcosAsin - compute sin or cos
|
|
|
|
Usage double AcosAsin (char *whoS, bits16 flags, double *xP);
|
|
|
|
Description Computes acos or sin of the number pointed to by xP.
|
|
|
|
Return value Returns acos or asin of xP.
|
|
|
|
*---------------------------------------------------------------------*/
|
|
#pragma warn -use
|
|
static double near AcosAsin (char *whoS, bits16 flags, double *xP)
|
|
{
|
|
volatile bits16 status;
|
|
volatile int temp;
|
|
|
|
asm mov dx, flags
|
|
asm mov si, W0 (xP)
|
|
|
|
asm mov cx, SS_ [si+6]
|
|
asm and BY0 (SS_ [si+7]), 07Fh /* absolute value */
|
|
asm fld DOUBLE (SS_ [si])
|
|
|
|
asm shl cx, 1
|
|
asm rcr dh, 1 /* DH = sign bit */
|
|
asm jcxz acs_zero
|
|
|
|
asm cmp cx, 7FE0h /* biased exponent of 1.0 */
|
|
asm jnb acs_extreme
|
|
/*
|
|
Use the trig identity asin (x) = atan (x / sqrt (1 - x^2)).
|
|
*/
|
|
asm FLD1
|
|
asm FLD ST(1) /* duplicate X */
|
|
asm FMUL ST(0), ST(0) /* square it */
|
|
asm FSUBP ST(1), ST /* 1 - X^2 */
|
|
asm FSQRT
|
|
/*
|
|
We now have tangent = ST(1)/ST. In order to use the FPATAN instruction
|
|
we must order them so that ST(1) < ST. The special case of equality
|
|
(angle pi/4) must be treated separately.
|
|
*/
|
|
asm FCOM
|
|
asm FSTSW W0 (status)
|
|
asm mov ah, 41h /* C3, C0 are the important bits */
|
|
asm FWAIT
|
|
/*
|
|
At this stage note that acos (x) = atan (sqrt (1-x^2) / x), which is
|
|
the inverse of the tangent ratio used for asin (x). That is why
|
|
DL, the inversion flag, started as 0FF for acos, and 0 for asin.
|
|
*/
|
|
asm and ah, BY1 (status)
|
|
asm jz acs_atan
|
|
asm add ah, ah
|
|
asm js acs_pi_4
|
|
asm FXCH
|
|
asm not dl /* remember the exchanged order */
|
|
|
|
acs_atan:
|
|
asm FPATAN /* arctan (ST(1) / ST) */
|
|
|
|
asm or dl, dl /* should ratio be inverted ? */
|
|
asm jz acs_sign
|
|
|
|
asm mov W0 (temp), -1
|
|
asm FILD W0 (temp)
|
|
asm FLDPI
|
|
asm FSCALE /* pi/2 */
|
|
asm FSTP ST(1)
|
|
asm FSUBRP st(1), st /* ST = pi/2 - ST */
|
|
|
|
acs_sign:
|
|
asm or dh, dh
|
|
asm jns acs_end
|
|
|
|
asm FCHS
|
|
|
|
asm cmp BY0 (flags), 0FFh /* are we doing acos () ? */
|
|
asm jne acs_end
|
|
|
|
asm FLDPI
|
|
asm FADDP ST(1), ST
|
|
|
|
acs_end:
|
|
#pragma noretval
|
|
return;
|
|
|
|
/*
|
|
Special cases.
|
|
*/
|
|
acs_extreme:
|
|
asm ja acs_domain
|
|
asm mov ax, SS_ [si+4] /* check for an exact value +- 1.0 */
|
|
asm or ax, SS_ [si+2]
|
|
asm or ax, SS_ [si]
|
|
asm jnz acs_domain
|
|
asm jmp short acs_one
|
|
|
|
acs_zero:
|
|
asm mov dh, 0 /* make zero unsigned. */
|
|
asm FSTP ST(0) /* pop stack */
|
|
asm cmp BY0 (flags), 0FFh /* are we doing acos () ? */
|
|
asm je acs_resultP2
|
|
acs_resultZ:
|
|
asm FLDZ
|
|
asm jmp short acs_sign
|
|
|
|
acs_one:
|
|
asm FSTP ST(0) /* pop stack */
|
|
asm cmp BY0 (flags), 0FFh /* are we doing acos () ? */
|
|
asm je acs_resultZ
|
|
acs_resultP2:
|
|
asm mov W0 (temp), -1
|
|
asm FILD W0 (temp)
|
|
asm FLDPI
|
|
asm FSCALE /* pi/2 */
|
|
asm FSTP ST(1)
|
|
asm jmp short acs_sign
|
|
|
|
acs_pi_4:
|
|
asm FSTP ST(0) /* pop two items off the stack */
|
|
asm FSTP ST(0)
|
|
asm mov W0 (temp), -2
|
|
asm FILD W0 (temp)
|
|
asm FLDPI
|
|
asm FSCALE /* pi/4 */
|
|
asm FSTP ST(1)
|
|
asm jmp short acs_sign
|
|
|
|
/*
|
|
If the argument was outside [-1,+1] then it is a domain error.
|
|
*/
|
|
acs_domain:
|
|
asm or BY0 (SS_ [si+7]), dh /* put the sign back */
|
|
asm FSTP ST (0) /* pop x from stack */
|
|
|
|
#pragma warn -ret
|
|
return __matherr (DOMAIN, whoS, xP, NULL, *((double *) NANINVTRIG));
|
|
#pragma warn .ret
|
|
}
|
|
#pragma warn .use
|
|
|
|
/*--------------------------------------------------------------------------*
|
|
|
|
Name acos & asin - trigonometric functions
|
|
|
|
Usage double acos(double x);
|
|
double asin(double x);
|
|
|
|
Prototype in math.h
|
|
|
|
Description asin, acos return the arc sine, and arc cosine,
|
|
respectively, of the input value. Arguments to asin and
|
|
acos must be in the range -1 to 1. Arguments outside that
|
|
range will cause asin or acos to return 0 and set errno to:
|
|
EDOM Domain error
|
|
|
|
Return value acos returns a value in the range 0 to pi.
|
|
asin returns a value in the range -pi/2 to pi/2.
|
|
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
double _FARFUNC acos( double x )
|
|
{
|
|
return AcosAsin ("acos", 0xFF, &x);
|
|
}
|
|
|
|
|
|
double _FARFUNC asin( double x )
|
|
{
|
|
return AcosAsin ("asin", 0x00, &x);
|
|
}
|