Files
TeslaRel410/BORLAND/BC45/SOURCE/RTL/SOURCE/MATHLIB/FBSTP.ASM
T
CydandClaude Fable 5 63312e07f9 source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived
- 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>
2026-07-19 07:33:26 -05:00

302 lines
6.9 KiB
NASM

;[]-----------------------------------------------------------------[]
;| FBSTP.ASM |
;[]-----------------------------------------------------------------[]
;
; C/C++ Run Time Library - Version 6.5
;
; Copyright (c) 1987, 1994 by Borland International
; All Rights Reserved.
;
include rules.asi
emul ; generated emulated instructions
ld_temp STRUC
ld_fraction dw ?
dw ?
dw ?
dw ?
ld_exponent dw ?
ld_temp ENDS
Code_Seg@
; void _fbstp ( long double z, short *packedDecimal)
; This is a helper function for __xcvt() used only on Windows,
; which currently doesn't emulate the FBSTP instruction.
;
; It pops and converts the floating point number on the top of the x87
; stack to a packed decimal integer, storing the result at ES:DI.
; int exp; /* exponent part of z */
; short frac[4]; /* fractional part of z */
; short res[5] /* packed BCD number */
; void PutFourDigits ( int rem, int posn )
; res.digits [posn] = rem % 10;
; rem = rem / 10;
; res.digits [posn+1] = rem % 10;
; rem = rem / 10;
; res.digits [posn+2] = rem % 10;
; res.digits [posn+3] = rem / 10;
PutFourDigits PROC ; rem in DX, posn in DI
push ax
push cx
mov al, 100
mov cl, 4
xchg ax, dx
div dl
mov dl, ah
aam ; AH, AL = AL DIV 10, AL MOD 10
shl ah, cl
or ah, al
xchg ax, dx
aam
shl ah, cl
or al, ah
mov ah, dh
stosw
pop cx
pop ax
ret
PutFourDigits ENDP
; exp = z.exp;
; frac = z.frac;
; if (exp < 1) res = 0;
; else if (exp > 60) res = +infinity;
; else
; while (exp < 64)
; frac = frac DIV 2;
; exp = exp + 1;
; frac = frac + carry; /* rounding */
; res = 0;
; PutFourDigits (frac % 10000, 0);
; frac = frac / 10000;
; PutFourDigits (frac % 10000, 4);
; frac = frac / 10000;
; PutFourDigits (frac % 10000, 8);
; frac = frac / 10000;
; PutFourDigits (frac % 10000, 12);
; frac = frac / 10000;
; res.digits [16] = frac % 10;
; res.digits [17] = frac / 10;
; res.sign = z.sign;
; return res;
public __fbstp
__fbstp PROC NEAR
; Convert floating point value on TOS to packed BCD at ES:DI
push bp
mov bp, sp
push si ; save SI
push di ; ES:DI points to result
po?zPtr equ ([bp - 4].w0)
cld ; forward string direction
; exp = z.exp;
; frac = z.frac;
FSTP tbyte ptr es:[di] ; value is converted in place
FWAIT
mov ax, es:[di].ld_exponent
and ax, 07fffh ; remove sign bit
sub ax, 03ffeh ; subtract (bias+1)
mov bx, es:[di].ld_fraction.w0
mov cx, es:[di].ld_fraction.w1
mov dx, es:[di].ld_fraction.w3
mov si, es:[di].ld_fraction.w2
; if (exp < 1)
; res = 0
;
; /* will the result exceed 999,999,999,999,999,999 ? */
; else (z > [3C, DE0B 6B3A 763F FFF0])
; res = +infinity
cmp ax, 0
jl po@underflowJmp
sub ax, 3Ch
jl po@inRange
jg po@overflowJmp
cmp dx, 0DE0Bh
jb po@inRange
ja po@overflowJmp
cmp si, 06B3Ah
jb po@inRange
ja po@overflowJmp
cmp cx, 0763Fh
jb po@inRange
ja po@overflowJmp
cmp bx, 0FFF0h
ja po@overflowJmp
; else
; while (exp < 64)
; frac = frac / 2;
; exp = exp + 1;
po@inRange:
mov ah, 0 ; excess precision for rounding
sub al, 4
po@wordAlign:
add al, 16
jg po@bitAlign
mov ah, bh
mov bx, cx
mov cx, si
mov si, dx
sub dx, dx
jmp po@wordAlign
;----
po@underflowJmp: jmp short po@underflow
po@overflowJmp: jmp short po@overflow
;----
po@bitAlign:
sub al, 16
jnl po@aligned
po@anotherBit:
shr dx, 1
rcr si, 1
rcr cx, 1
rcr bx, 1
rcr ah, 1
inc al
jl po@anotherBit
po@aligned:
; frac = frac + carry; /* rounding */
add ah, ah
adc bx, 0
adc cx, 0
adc si, 0
adc dx, 0 ; DX:SI:CX:BX is now an integer < 2^60
; PutFourDigits (frac % 10000, 0);
; frac = frac / 10000;
; DX < 4096 since 2^60 = 4096 * 2^48
xchg ax, si
mov si, 10000
div si
xchg ax, cx
div si
xchg ax, bx
div si ; frac = CX:BX:AX < 2^47, DX = mod 10000
call PutFourDigits ; DX is parameter
; PutFourDigits (frac % 10000, 4);
; frac = frac / 10000;
sub dx, dx
xchg ax, cx
div si
xchg ax, bx
div si
xchg ax, cx
div si ; frac = BX:CX:AX < 2^34, DX = mod 10000
call PutFourDigits ; DX is parameter
; PutFourDigits (frac % 10000, 8);
; frac = frac / 10000;
mov dx, bx
xchg ax, cx
div si
xchg ax, cx
div si ; frac = CX:AX < 2^20, DX = mod 10000
call PutFourDigits ; DX is parameter
; PutFourDigits (frac % 10000, 12);
; frac = frac / 10000;
mov dx, cx
div si ; frac = AX < 2^7, DX = mod 10000
call PutFourDigits ; DX is parameter
; res.digits [16] = frac % 10;
; res.digits [17] = frac / 10;
aam ; AH, AL = AL / 10, AL % 10
mov cl, 4
shl ah, cl
or al, ah
stosb
po@end:
; res.sign = z.sign;
mov si, po?zPtr
mov al, es:[si].ld_exponent.by1
and al, 080h ; isolate sign bit
stosb
pop di
pop si
pop bp
ret
; ----
po@underflow:
mov al, 0
po@extreme:
mov cx, 9
rep stosb
jmp short po@end
po@overflow:
mov al, 99h
jmp short po@extreme
; ----
__fbstp endp
Code_EndS@
end