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>
This commit is contained in:
@@ -0,0 +1,426 @@
|
||||
;[]------------------------------------------------------------[]
|
||||
;| C0D.ASM -- Start Up Code For Windows DLLs |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
;
|
||||
; C/C++ Run Time Library - Version 6.5
|
||||
;
|
||||
; Copyright (c) 1991, 1994 by Borland International
|
||||
; All Rights Reserved.
|
||||
;
|
||||
|
||||
locals
|
||||
|
||||
__C0__ = 1
|
||||
include RULES.ASI
|
||||
|
||||
ASSUME CS:_TEXT, DS:DGROUP
|
||||
|
||||
public __acrtused ;satisfy MS for now
|
||||
__acrtused equ 0
|
||||
|
||||
|
||||
extrn LIBMAIN:far ;the C routine to be called
|
||||
extrn LOCALINIT:far ;Windows heap init routine
|
||||
extrn LOCKSEGMENT:far
|
||||
extrn UNLOCKSEGMENT:far
|
||||
extrn GETWINFLAGS:far
|
||||
extrn __WEP:far
|
||||
extrn __cexit:DIST
|
||||
ifdef __LARGE__
|
||||
ifndef _BUILDRTLDLL
|
||||
extrn FREELIBRARY:far
|
||||
extrn __LockDLL:DIST
|
||||
endif
|
||||
endif
|
||||
extrn __setupio:near ;required!
|
||||
|
||||
public LibEntry ;Entry point for the DLL
|
||||
publicdll WEP
|
||||
|
||||
NULL segment
|
||||
db 16 dup (0) ;Windows
|
||||
db 4 dup (0) ;destructor count
|
||||
db 2 dup (0) ;exception list
|
||||
db 4 dup (0) ;exception vptr
|
||||
db 6 dup (0) ;reserved
|
||||
db 2 dup (0) ;VBX control jump vector
|
||||
;MUST be at SS:20h
|
||||
db 2 dup (0) ;reserved
|
||||
ends
|
||||
|
||||
_CVTSEG segment
|
||||
public __RealCvtVector
|
||||
__RealCvtVector label word
|
||||
ends
|
||||
|
||||
_SCNSEG segment
|
||||
public __ScanTodVector
|
||||
__ScanTodVector label word
|
||||
ends
|
||||
|
||||
_FPSEG segment
|
||||
public __FPVector
|
||||
__FPVector dd 0
|
||||
ends
|
||||
|
||||
_DATA segment
|
||||
public _errno
|
||||
_errno dw 0
|
||||
public __protected
|
||||
__protected dw 0
|
||||
public __8086
|
||||
__8086 dw 0
|
||||
public __8087
|
||||
__8087 dw 0
|
||||
public __version
|
||||
__version label word
|
||||
public __osversion
|
||||
__osversion label word
|
||||
public __osmajor
|
||||
__osmajor db 0
|
||||
public __osminor
|
||||
__osminor db 0
|
||||
public __osmode ;Used for OS/2 protected mode by MS,
|
||||
__osmode db 0 ;currently set to 0 under Windows
|
||||
public __hInstance
|
||||
__hInstance dw 0
|
||||
public __WinAllocFlag ;Used by malloc for additional flags
|
||||
__WinAllocFlag dw 2000h ;to pass to GlobalAlloc (used in DLLs)
|
||||
;default value is GMEM_SHARE
|
||||
public __LockWIN87EM ;Used do lock down WIN87EM to avoid
|
||||
__LockWIN87EM dw 1 ;DLL unload ordering problem
|
||||
|
||||
ifdef __LARGE__
|
||||
ifndef _BUILDRTLDLL
|
||||
public __LockRTLHandle
|
||||
__LockRTLHandle dw 0 ;Handle of RTLDLL (locked)
|
||||
endif
|
||||
endif
|
||||
|
||||
public __abend
|
||||
__abend label word
|
||||
_abend dw 1 ;If LibEntry is called gets set to
|
||||
;normal state (0). If it is 1 then
|
||||
;exit routines are not performed
|
||||
;Gets set to 1 if DLL is terminated
|
||||
;by a call to abort() or _exit().
|
||||
|
||||
CopyRight db 'Borland C++ - Copyright 1994 Borland Intl.',0
|
||||
ends
|
||||
|
||||
_TEXT segment
|
||||
|
||||
LibEntry proc far
|
||||
mov __hInstance, di ;save SI and DI
|
||||
push si
|
||||
|
||||
push di ;handle of the module instance
|
||||
push ds ;library data segment
|
||||
push cx ;heap size
|
||||
push es ;command line segment
|
||||
push si ;command line offset
|
||||
|
||||
;if we have some heap then initialize it
|
||||
jcxz @@Init ;jump if no heap specified
|
||||
|
||||
;call the Windows function LocalInit() to set up the heap
|
||||
;LocalInit((LPSTR)start, WORD cbHeap);
|
||||
|
||||
push ds ;Heap segment
|
||||
xor ax,ax
|
||||
push ax ;Heap start offset in segment
|
||||
push cx ;Heap end offset in segment
|
||||
call LOCALINIT
|
||||
xchg ax,cx
|
||||
jcxz @@JmpExit ;quit if it failed
|
||||
jmp short @@Init
|
||||
@@JmpExit: jmp @@Exit
|
||||
|
||||
@@Init:
|
||||
|
||||
IF LDATA EQ false
|
||||
mov ax,-1
|
||||
push ax
|
||||
call LOCKSEGMENT
|
||||
ENDIF
|
||||
|
||||
;Clear _BSS, uninitialized data area
|
||||
|
||||
xor ax, ax
|
||||
push ds
|
||||
pop es
|
||||
mov di,offset DGROUP:BeginBSS
|
||||
mov cx,offset DGROUP:EndBSS
|
||||
sub cx,di
|
||||
cld
|
||||
rep
|
||||
stosb
|
||||
|
||||
;Determine DOS version
|
||||
|
||||
mov ah, 30h
|
||||
int 21h
|
||||
mov __version, ax ; save minor and major revision
|
||||
|
||||
;Determine whether we are in protected mode
|
||||
|
||||
call GETWINFLAGS
|
||||
test ax,1 ; WF_PMODE = 1
|
||||
jz @@realmode ; Note: GETWINFLAGS returns a long,
|
||||
; so if WF_PMODE changed it could be
|
||||
; in the high word.
|
||||
mov __protected, 8 ; Eight is for convenience.
|
||||
@@realmode:
|
||||
|
||||
;Test for 8087 presence
|
||||
|
||||
test ax,0400h ; WF_8087 = 0x0400
|
||||
jz @@no8087
|
||||
mov __8087, 1
|
||||
@@no8087:
|
||||
and ax,08h+04h+02h ; WF_CPU486|WF_CPU386|WF_CPU286
|
||||
shr ax,1 ; Convert to 4 or 2 or 1 or 0
|
||||
test ax,0004h ; Have 4, 486 done
|
||||
jnz @@NoAdjust
|
||||
or ax,ax ; Have 0, 8086 done
|
||||
jz @@NoAdjust
|
||||
inc ax ; Have 2 or 1, need 3 or 2
|
||||
@@NoAdjust:
|
||||
mov __8086,ax ; Set CPU Type
|
||||
|
||||
;Call our initialization functions, including C++ static constructors.
|
||||
|
||||
mov ax,ds
|
||||
mov es,ax
|
||||
mov si,offset DGROUP:InitStart ;si = start of table
|
||||
mov di,offset DGROUP:InitEnd ;di = end of table
|
||||
|
||||
call Initialize
|
||||
mov _abend, 0 ; Set LibEntry called
|
||||
|
||||
;invoke the C routine to do any special initialization
|
||||
@@Main: call LIBMAIN ;invoke the 'C' routine (result in AX)
|
||||
or ax, ax
|
||||
|
||||
ifdef __LARGE__
|
||||
ifndef _BUILDRTLDLL
|
||||
jz @@LibMainRet
|
||||
|
||||
push ax
|
||||
call __LockDLL
|
||||
mov __LockRTLHandle, ax
|
||||
pop ax
|
||||
@@LibMainRet:
|
||||
endif
|
||||
endif
|
||||
mov di, __hInstance ;restore SI and DI
|
||||
pop si
|
||||
ret
|
||||
|
||||
@@Exit: mov ax, 0 ;set return code
|
||||
pop si ;remove arguments to LIBMAIN
|
||||
pop es ; since we didn't call it.
|
||||
pop cx
|
||||
pop ds
|
||||
pop di
|
||||
pop si ;restore saved SI. DI is restored
|
||||
ret ; by removing arguments to LIBMAIN
|
||||
endp
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; _cleanup() call all #pragma exit cleanup routines.
|
||||
; _checknull() check for null pointer zapping copyright message
|
||||
; _terminate(exitcode, quick) exit program with error code
|
||||
; _restorezero() restore interrupt vectors
|
||||
;
|
||||
; These functions are called by exit(), _exit(), _cexit(),
|
||||
; and _c_exit().
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
; Call cleanup routines
|
||||
|
||||
__cleanup PROC DIST
|
||||
PUBLIC __cleanup
|
||||
|
||||
mov ax,ds
|
||||
mov es,ax
|
||||
push si
|
||||
push di
|
||||
mov si,offset DGROUP:ExitStart
|
||||
mov di,offset DGROUP:ExitEnd
|
||||
call Cleanup
|
||||
pop di
|
||||
pop si
|
||||
ret
|
||||
__cleanup ENDP
|
||||
|
||||
; Check for null pointers before exit. NO-OP on Windows.
|
||||
|
||||
__checknull PROC DIST
|
||||
PUBLIC __checknull
|
||||
ret
|
||||
__checknull ENDP
|
||||
|
||||
; Restore grabbed interrupt vectors. NO-OP on Windows.
|
||||
|
||||
__restorezero PROC DIST
|
||||
PUBLIC __restorezero
|
||||
ret
|
||||
__restorezero ENDP
|
||||
|
||||
; Exit to DOS
|
||||
;
|
||||
; Usage: void _terminate(int exitcode, int quick);
|
||||
|
||||
__terminate PROC DIST
|
||||
PUBLIC __terminate
|
||||
|
||||
mov bp,sp
|
||||
mov al,[bp+cPtrSize] ; get exitcode
|
||||
mov ah,4ch
|
||||
int 21h
|
||||
ret
|
||||
endp
|
||||
|
||||
WEP proc windows pascal far nParam:WORD
|
||||
push si
|
||||
push di
|
||||
|
||||
cmp _abend, 0
|
||||
jne @@error
|
||||
push nParam
|
||||
call __WEP
|
||||
push ax
|
||||
call __cexit ; perform cleanup without exiting
|
||||
|
||||
@@unlock:
|
||||
|
||||
ifdef __LARGE__
|
||||
ifndef _BUILDRTLDLL
|
||||
mov ax, __LockRTLHandle
|
||||
or ax, ax
|
||||
jz @@RTLNotLocked
|
||||
push ax
|
||||
call FreeLibrary
|
||||
@@RTLNotLocked:
|
||||
endif
|
||||
endif
|
||||
|
||||
IF LDATA EQ false
|
||||
mov ax,-1
|
||||
push ax
|
||||
call UNLOCKSEGMENT
|
||||
ENDIF
|
||||
|
||||
pop ax
|
||||
pop di
|
||||
pop si
|
||||
ret
|
||||
|
||||
@@error:
|
||||
push 1
|
||||
jmp @@unlock
|
||||
|
||||
endp
|
||||
|
||||
; Return default data segment in AX
|
||||
|
||||
__GetDGROUP PROC FAR
|
||||
PUBLIC __GetDGROUP
|
||||
mov ax, DGROUP
|
||||
ret
|
||||
endp
|
||||
|
||||
;------------------------------------------------------------------
|
||||
; Loop through a startup/exit (SE) table,
|
||||
; calling functions in order of priority.
|
||||
; ES:SI is assumed to point to the beginning of the SE table
|
||||
; ES:DI is assumed to point to the end of the SE table
|
||||
; First 64 priorities are reserved by Borland
|
||||
;------------------------------------------------------------------
|
||||
PNEAR EQU 0
|
||||
PFAR EQU 1
|
||||
NOTUSED EQU 0ffh
|
||||
|
||||
SE STRUC
|
||||
calltype db ? ; 0=near,1=far,ff=not used
|
||||
priority db ? ; 0=highest,ff=lowest
|
||||
addrlow dw ?
|
||||
addrhigh dw ?
|
||||
SE ENDS
|
||||
|
||||
Initialize proc near
|
||||
@@Start: mov ax,100h ;start with lowest priority
|
||||
mov dx,di ;set sentinel to end of table
|
||||
mov bx,si ;bx = start of table
|
||||
|
||||
@@TopOfTable: cmp bx,di ;and the end of the table?
|
||||
je @@EndOfTable ;yes, exit the loop
|
||||
cmp es:[bx.calltype],NOTUSED;check the call type
|
||||
je @@Next
|
||||
mov cl, es:[bx.priority] ;move priority to CX
|
||||
xor ch, ch
|
||||
cmp cx,ax ;check the priority
|
||||
jae @@Next ;too high? skip
|
||||
mov ax,cx ;keep priority
|
||||
mov dx,bx ;keep index in dx
|
||||
@@Next: add bx,SIZE SE ;bx = next item in table
|
||||
jmp @@TopOfTable
|
||||
|
||||
@@EndOfTable: cmp dx,di ;did we exhaust the table?
|
||||
je @@Done ;yes, quit
|
||||
mov bx,dx ;bx = highest priority item
|
||||
cmp es:[bx.calltype],PNEAR ;is it near or far?
|
||||
mov es:[bx.calltype],NOTUSED;wipe the call type
|
||||
push es ;save es
|
||||
je @@NearCall
|
||||
|
||||
@@FarCall: call DWORD PTR es:[bx.addrlow]
|
||||
pop es ;restore es
|
||||
jmp short @@Start
|
||||
|
||||
@@NearCall: call WORD PTR es:[bx.addrlow]
|
||||
pop es ;restore es
|
||||
jmp short @@Start
|
||||
|
||||
@@Done: ret
|
||||
endp
|
||||
|
||||
Cleanup proc near
|
||||
@@Start: mov ah,0 ;start with highest priority
|
||||
mov dx,di ;set sentinel to end of table
|
||||
mov bx,si ;bx = start of table
|
||||
|
||||
@@TopOfTable: cmp bx,di ;and the end of the table?
|
||||
je @@EndOfTable ;yes, exit the loop
|
||||
cmp es:[bx.calltype],NOTUSED;check the call type
|
||||
je @@Next
|
||||
cmp es:[bx.priority],ah ;check the priority
|
||||
jb @@Next ;too low? skip
|
||||
mov ah,es:[bx.priority] ;keep priority
|
||||
mov dx,bx ;keep index in dx
|
||||
@@Next: add bx,SIZE SE ;bx = next item in table
|
||||
jmp @@TopOfTable
|
||||
|
||||
@@EndOfTable: cmp dx,di ;did we exhaust the table?
|
||||
je @@Done ;yes, quit
|
||||
mov bx,dx ;bx = highest priority item
|
||||
cmp es:[bx.calltype],PNEAR ;is it near or far?
|
||||
mov es:[bx.calltype],NOTUSED;wipe the call type
|
||||
push es ;save es
|
||||
je @@NearCall
|
||||
|
||||
@@FarCall: call DWORD PTR es:[bx.addrlow]
|
||||
pop es ;restore es
|
||||
jmp short @@Start
|
||||
|
||||
@@NearCall: call WORD PTR es:[bx.addrlow]
|
||||
pop es ;restore es
|
||||
jmp short @@Start
|
||||
|
||||
@@Done: ret
|
||||
endp
|
||||
|
||||
ends
|
||||
end LibEntry
|
||||
Reference in New Issue
Block a user