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,71 @@
|
||||
@echo off
|
||||
if not "%TASM%"=="" goto skip
|
||||
set tasm=tasm
|
||||
:skip
|
||||
|
||||
if not %3.==. goto noobjdir
|
||||
set objdir=.
|
||||
goto objdirset
|
||||
:noobjdir
|
||||
set objdir=%3
|
||||
:objdirset
|
||||
|
||||
if not %2.==. goto noc0dir
|
||||
set c0dir=.
|
||||
goto c0dirset
|
||||
:noc0dir
|
||||
set c0dir=%2
|
||||
:c0dirset
|
||||
|
||||
if %1.==clib. goto clib
|
||||
if %1.==winlib. goto winlib
|
||||
if %1.==dpmi16. goto dpmi16
|
||||
goto error
|
||||
:clib
|
||||
echo Building DOS startups
|
||||
cd %c0dir%
|
||||
%TASM% /M /MX /Q /T /D__TINY__ c0, %objdir%\c0t
|
||||
%TASM% /M /MX /Q /T /D__SMALL__ c0, %objdir%\c0s
|
||||
%TASM% /M /MX /Q /T /D__COMPACT__ c0, %objdir%\c0c
|
||||
%TASM% /M /MX /Q /T /D__MEDIUM__ c0, %objdir%\c0m
|
||||
%TASM% /M /MX /Q /T /D__LARGE__ c0, %objdir%\c0l
|
||||
%TASM% /M /MX /Q /T /D__HUGE__ c0, %objdir%\c0h
|
||||
|
||||
%TASM% /M /MX /Q /T /D__TINY__ /D_DSSTACK_ c0, %objdir%\c0ft
|
||||
%TASM% /M /MX /Q /T /D__SMALL__ /D_DSSTACK_ c0, %objdir%\c0fs
|
||||
%TASM% /M /MX /Q /T /D__COMPACT__ /D_DSSTACK_ c0, %objdir%\c0fc
|
||||
%TASM% /M /MX /Q /T /D__MEDIUM__ /D_DSSTACK_ c0, %objdir%\c0fm
|
||||
%TASM% /M /MX /Q /T /D__LARGE__ /D_DSSTACK_ c0, %objdir%\c0fl
|
||||
%TASM% /M /MX /Q /T /D__HUGE__ c0, %objdir%\c0fh
|
||||
if not %c0dir%==. cd ..
|
||||
goto exit
|
||||
:winlib
|
||||
echo Building Windows startups
|
||||
cd %c0dir%
|
||||
%TASM% /M /MX /Q /T /D__SMALL__ /D__WINDOWS__ c0w, %objdir%\c0ws
|
||||
%TASM% /M /MX /Q /T /D__COMPACT__ /D__WINDOWS__ c0w, %objdir%\c0wc
|
||||
%TASM% /M /MX /Q /T /D__MEDIUM__ /D__WINDOWS__ c0w, %objdir%\c0wm
|
||||
%TASM% /M /MX /Q /T /D__LARGE__ /D__WINDOWS__ c0w, %objdir%\c0wl
|
||||
|
||||
%TASM% /M /MX /Q /T /D__SMALL__ /D__WINDOWS__ c0d, %objdir%\c0ds
|
||||
%TASM% /M /MX /Q /T /D__COMPACT__ /D__WINDOWS__ c0d, %objdir%\c0dc
|
||||
%TASM% /M /MX /Q /T /D__MEDIUM__ /D__WINDOWS__ c0d, %objdir%\c0dm
|
||||
%TASM% /M /MX /Q /T /D__LARGE__ /D__WINDOWS__ c0d, %objdir%\c0dl
|
||||
if not %c0dir%==. cd ..
|
||||
goto exit
|
||||
:dpmi16
|
||||
echo Building DPMI16 startup
|
||||
cd %c0dir%
|
||||
%TASM% /M /MX /Q /T /D__LARGE__ /D__WINDOWS__ /D__DPMI16__ c0w, %objdir%\c0x
|
||||
if not %c0dir%==. cd ..
|
||||
goto exit
|
||||
:error
|
||||
echo BUILD-C0.BAT
|
||||
echo Usage: build-c0 libtype [srcdir [objdir]]
|
||||
echo libtype clib (DOS) or winlib (Windows) or dpmi16 (DPMI16)
|
||||
echo srcdir source subdirectory (default is ".")
|
||||
echo objdir object subdirectory relative to srcdir (default is ".")
|
||||
echo Example: build-c0 clib startup ..\lib
|
||||
echo This batch file builds the C startup module (or modules) for
|
||||
echo DOS or Windows. All memory models are built.
|
||||
:exit
|
||||
@@ -0,0 +1,745 @@
|
||||
;[]------------------------------------------------------------[]
|
||||
;| C0.ASM -- Start Up Code for DOS |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
;
|
||||
; C/C++ Run Time Library - Version 6.5
|
||||
;
|
||||
; Copyright (c) 1987, 1994 by Borland International
|
||||
; All Rights Reserved.
|
||||
;
|
||||
|
||||
locals
|
||||
|
||||
__C0__ = 1
|
||||
INCLUDE RULES.ASI
|
||||
|
||||
; Segment and Group declarations
|
||||
|
||||
_TEXT SEGMENT BYTE PUBLIC 'CODE'
|
||||
ENDS
|
||||
_FARDATA SEGMENT PARA PUBLIC 'FAR_DATA'
|
||||
ENDS
|
||||
_FARBSS SEGMENT PARA PUBLIC 'FAR_BSS'
|
||||
ENDS
|
||||
IFNDEF __TINY__
|
||||
_OVERLAY_ SEGMENT PARA PUBLIC 'OVRINFO'
|
||||
ENDS
|
||||
_1STUB_ SEGMENT PARA PUBLIC 'STUBSEG'
|
||||
ENDS
|
||||
ENDIF
|
||||
_DATA SEGMENT PARA PUBLIC 'DATA'
|
||||
ENDS
|
||||
_INIT_ SEGMENT WORD PUBLIC 'INITDATA'
|
||||
InitStart label byte
|
||||
ENDS
|
||||
_INITEND_ SEGMENT BYTE PUBLIC 'INITDATA'
|
||||
InitEnd label byte
|
||||
ENDS
|
||||
_EXIT_ SEGMENT WORD PUBLIC 'EXITDATA'
|
||||
ExitStart label byte
|
||||
ENDS
|
||||
_EXITEND_ SEGMENT BYTE PUBLIC 'EXITDATA'
|
||||
ExitEnd label byte
|
||||
ENDS
|
||||
_CVTSEG SEGMENT WORD PUBLIC 'DATA'
|
||||
ENDS
|
||||
_SCNSEG SEGMENT WORD PUBLIC 'DATA'
|
||||
ENDS
|
||||
IFNDEF __HUGE__
|
||||
_BSS SEGMENT WORD PUBLIC 'BSS'
|
||||
ENDS
|
||||
_BSSEND SEGMENT BYTE PUBLIC 'BSSEND'
|
||||
ENDS
|
||||
ENDIF
|
||||
IFNDEF __TINY__
|
||||
_STACK SEGMENT STACK 'STACK'
|
||||
ENDS
|
||||
ENDIF
|
||||
|
||||
ASSUME CS:_TEXT, DS:DGROUP
|
||||
|
||||
; External References
|
||||
|
||||
extrn _main:DIST
|
||||
extrn _exit:DIST
|
||||
extrn __exit:DIST
|
||||
extrn __abort:DIST
|
||||
extrn ___ErrorMessage:DIST
|
||||
extrn __nfile:word
|
||||
extrn __setupio:near ;required!
|
||||
extrn __stklen:word
|
||||
IFNDEF __TINY__
|
||||
extrn __ExceptInit:DIST
|
||||
ENDIF
|
||||
IF LDATA EQ false
|
||||
extrn __heaplen:word
|
||||
ENDIF
|
||||
|
||||
SUBTTL Start Up Code
|
||||
PAGE
|
||||
;/* */
|
||||
;/*-----------------------------------------------------*/
|
||||
;/* */
|
||||
;/* Start Up Code */
|
||||
;/* ------------- */
|
||||
;/* */
|
||||
;/*-----------------------------------------------------*/
|
||||
;/* */
|
||||
PSPHigh equ 00002h
|
||||
PSPEnv equ 0002ch
|
||||
PSPCmd equ 00080h
|
||||
|
||||
public __AHINCR
|
||||
public __AHSHIFT
|
||||
__AHINCR equ 1000h
|
||||
__AHSHIFT equ 12
|
||||
|
||||
IFDEF __NOFLOAT__
|
||||
MINSTACK equ 128 ; minimal stack size in words
|
||||
ELSE
|
||||
MINSTACK equ 256 ; minimal stack size in words
|
||||
ENDIF
|
||||
;
|
||||
; At the start, DS and ES both point to the segment prefix.
|
||||
; SS points to the stack segment except in TINY model where
|
||||
; SS is equal to CS
|
||||
;
|
||||
_TEXT SEGMENT
|
||||
IFDEF __TINY__
|
||||
ORG 100h
|
||||
ENDIF
|
||||
STARTX PROC NEAR
|
||||
; Save general information, such as :
|
||||
; DGROUP segment address
|
||||
; DOS version number
|
||||
; Program Segment Prefix address
|
||||
; Environment address
|
||||
; Top of far heap
|
||||
|
||||
IFDEF __TINY__
|
||||
mov dx, cs ; DX = GROUP Segment address
|
||||
ELSE
|
||||
mov dx, DGROUP ; DX = GROUP Segment address
|
||||
ENDIF
|
||||
mov cs:DGROUP@@, dx ;
|
||||
mov ah, 30h
|
||||
int 21h ; get DOS version number
|
||||
mov bp, ds:[PSPHigh]; BP = Highest Memory Segment Addr
|
||||
mov bx, ds:[PSPEnv] ; BX = Environment Segment address
|
||||
mov ds, dx
|
||||
mov _version@, ax ; Keep major and minor version number
|
||||
mov _psp@, es ; Keep Program Segment Prefix address
|
||||
mov _envseg@, bx ; Keep Environment Segment address
|
||||
mov word ptr _heaptop@ + 2, bp
|
||||
;
|
||||
; Save several vectors and install default divide by zero handler.
|
||||
;
|
||||
call SaveVectors
|
||||
|
||||
; Count the number of environment variables and compute the size.
|
||||
; Each variable is ended by a 0 and a zero-length variable stops
|
||||
; the environment. The environment can NOT be greater than 32k.
|
||||
|
||||
mov ax, _envseg@
|
||||
mov es, ax
|
||||
xor ax, ax
|
||||
mov bx, ax
|
||||
mov di, ax
|
||||
|
||||
mov cx, 07FFFh ; Environment cannot be > 32 Kbytes
|
||||
cld
|
||||
@@EnvLoop:
|
||||
repnz scasb
|
||||
jcxz InitFailed ; Bad environment !!!
|
||||
inc bx ; BX = Nb environment variables
|
||||
cmp es:[di], al
|
||||
jne @@EnvLoop ; Next variable ...
|
||||
or ch, 10000000b
|
||||
neg cx
|
||||
mov _envLng@, cx ; Save Environment size
|
||||
mov cx, dPtrSize / 2
|
||||
shl bx, cl
|
||||
add bx, dPtrSize * 4
|
||||
and bx, not ((dPtrSize * 4) - 1)
|
||||
mov _envSize@, bx ; Save Environment Variables Nb.
|
||||
|
||||
; Determine the amount of memory that we need to keep
|
||||
|
||||
IFDEF _DSSTACK_
|
||||
mov dx, ds
|
||||
ELSE
|
||||
mov dx, ss
|
||||
ENDIF
|
||||
sub bp, dx ; BP = remaining size in paragraphs
|
||||
IF LDATA
|
||||
mov di, seg __stklen
|
||||
mov es, di
|
||||
mov di, es:__stklen ; DI = Requested stack size
|
||||
ELSE
|
||||
mov di, __stklen ; DI = Requested stack size
|
||||
ENDIF
|
||||
;
|
||||
; Make sure that the requested stack size is at least MINSTACK words.
|
||||
;
|
||||
cmp di, 2*MINSTACK ; requested stack big enough ?
|
||||
jae AskedStackOK
|
||||
mov di, 2*MINSTACK ; no --> use minimal value
|
||||
IF LDATA
|
||||
mov es:__stklen, di ; override requested stack size
|
||||
ELSE
|
||||
mov __stklen, di ; override requested stack size
|
||||
ENDIF
|
||||
|
||||
AskedStackOK label near
|
||||
IFDEF _DSSTACK_
|
||||
add di, offset DGROUP: edata@
|
||||
jb InitFailed ; DATA segment can NOT be > 64 Kbytes
|
||||
ENDIF
|
||||
IF LDATA EQ false
|
||||
add di, __heaplen
|
||||
jb InitFailed ; DATA segment can NOT be > 64 Kbytes
|
||||
ENDIF
|
||||
mov cl, 4
|
||||
shr di, cl ; $$$ Do not destroy CL $$$
|
||||
inc di ; DI = DS size in paragraphs
|
||||
cmp bp, di
|
||||
IF LDATA EQ false
|
||||
jb InitFailed ; Not enough memory
|
||||
cmp __stklen, 0
|
||||
je ExpandDS ; Expand DS up to 64 Kb
|
||||
cmp __heaplen, 0
|
||||
jne ExcessOfMemory ; Much more available than needed
|
||||
ExpandDS label near
|
||||
mov di, 1000h
|
||||
cmp bp, di
|
||||
ja ExcessOfMemory ; Enough to run the program
|
||||
mov di, bp
|
||||
jmp short ExcessOfMemory ; Enough to run the program
|
||||
ELSE
|
||||
jnb ExcessOfMemory ; Much more available than needed
|
||||
ENDIF
|
||||
|
||||
; All initialization errors arrive here
|
||||
|
||||
InitFailed label near
|
||||
call __abort
|
||||
|
||||
; Return to DOS the amount of memory in excess
|
||||
; Set far heap base and pointer
|
||||
|
||||
ExcessOfMemory label near
|
||||
mov bx, di
|
||||
add bx, dx
|
||||
mov word ptr _heapbase@ + 2, bx
|
||||
mov word ptr _brklvl@ + 2, bx
|
||||
mov ax, _psp@
|
||||
sub bx, ax ; BX = Number of paragraphs to keep
|
||||
mov es, ax ; ES = Program Segment Prefix address
|
||||
mov ah, 04Ah
|
||||
push di ; preserve DI
|
||||
int 021h ; this call clobbers SI,DI,BP !!!!!!
|
||||
pop di ; restore DI
|
||||
|
||||
shl di, cl ; $$$ CX is still equal to 4 $$$
|
||||
|
||||
cli ; req'd for pre-1983 88/86s
|
||||
mov ss, dx ; Set the program stack
|
||||
mov sp, di
|
||||
sti
|
||||
|
||||
IFNDEF _DSSTACK_
|
||||
mov ax, seg __stklen
|
||||
mov es, ax
|
||||
mov es:__stklen, di ; If separate stack segment, save size
|
||||
ENDIF
|
||||
|
||||
IFNDEF __HUGE__
|
||||
|
||||
; Reset uninitialized data area
|
||||
|
||||
xor ax, ax
|
||||
mov es, cs:DGROUP@@
|
||||
mov di, offset DGROUP: bdata@
|
||||
mov cx, offset DGROUP: edata@
|
||||
sub cx, di
|
||||
cld
|
||||
rep stosb
|
||||
ENDIF
|
||||
|
||||
; If default number of file handles have changed then tell DOS
|
||||
cmp __nfile, 20
|
||||
jbe @@NoChange
|
||||
|
||||
cmp _osmajor@, 3 ; Check for >= DOS 3.3
|
||||
jb @@NoChange
|
||||
ja @@DoChange
|
||||
cmp _osminor@, 1Eh
|
||||
jb @@NoChange
|
||||
@@DoChange:
|
||||
mov ax, 5801h ; Set last fit allocation
|
||||
mov bx, 2
|
||||
int 21h
|
||||
jc @@BadInit
|
||||
|
||||
mov ah, 67h ; Expand handle table
|
||||
mov bx, __nfile
|
||||
int 21h
|
||||
jc @@BadInit
|
||||
|
||||
mov ah, 48h ; Allocate 16 bytes to find new
|
||||
mov bx, 1 ; top of memory address
|
||||
int 21h
|
||||
jc @@BadInit
|
||||
inc ax ; Adjust address to point after block
|
||||
mov word ptr _heaptop@ + 2, ax
|
||||
|
||||
dec ax ; Change back and release block
|
||||
mov es, ax
|
||||
mov ah, 49h
|
||||
int 21h
|
||||
jc @@BadInit
|
||||
|
||||
mov ax, 5801h ; Set first fit allocation
|
||||
mov bx, 0
|
||||
int 21h
|
||||
jnc @@NoChange
|
||||
|
||||
@@BadInit: call __abort
|
||||
|
||||
@@NoChange:
|
||||
|
||||
; Prepare main arguments
|
||||
|
||||
xor bp,bp ; set BP to 0 for overlay mgr
|
||||
|
||||
IFNDEF __TINY__
|
||||
push bp
|
||||
call __ExceptInit
|
||||
pop ax
|
||||
ENDIF
|
||||
mov es, cs:DGROUP@@
|
||||
mov si,offset DGROUP:InitStart ;si = start of table
|
||||
mov di,offset DGROUP:InitEnd ;di = end of table
|
||||
call Initialize
|
||||
|
||||
; ExitCode = main(argc,argv,envp);
|
||||
|
||||
IF LDATA
|
||||
push word ptr __C0environ+2
|
||||
push word ptr __C0environ
|
||||
push word ptr __C0argv+2
|
||||
push word ptr __C0argv
|
||||
ELSE
|
||||
push word ptr __C0environ
|
||||
push word ptr __C0argv
|
||||
ENDIF
|
||||
push __C0argc
|
||||
call _main
|
||||
|
||||
; Flush and close streams and files
|
||||
|
||||
push ax
|
||||
call _exit
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; _cleanup() call all #pragma exit cleanup routines.
|
||||
; _checknull() check for null pointer zapping copyright message
|
||||
; _terminate(int) exit program with error code
|
||||
;
|
||||
; These functions are called by exit(), _exit(), _cexit(),
|
||||
; and _c_exit().
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
; Call cleanup routines
|
||||
|
||||
__cleanup PROC DIST
|
||||
PUBLIC __cleanup
|
||||
|
||||
mov es, cs:DGROUP@@
|
||||
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
|
||||
|
||||
__checknull PROC DIST
|
||||
PUBLIC __checknull
|
||||
IF LDATA EQ false
|
||||
IFNDEF __TINY__
|
||||
push si
|
||||
push di
|
||||
mov es, cs:DGROUP@@
|
||||
xor ax, ax
|
||||
mov si, ax
|
||||
mov cx, 16
|
||||
ComputeChecksum label near
|
||||
add al, es:[si]
|
||||
adc ah, 0
|
||||
inc si
|
||||
loop ComputeChecksum
|
||||
sub ax, CheckSum
|
||||
jz @@SumOK
|
||||
mov dx, offset DGROUP:NullCheck
|
||||
pushDS_
|
||||
push dx
|
||||
call ___ErrorMessage
|
||||
pop dx
|
||||
popDS_
|
||||
@@SumOK: pop di
|
||||
pop si
|
||||
ENDIF
|
||||
ENDIF
|
||||
ret
|
||||
__checknull ENDP
|
||||
|
||||
; Exit to DOS
|
||||
|
||||
__terminate PROC DIST
|
||||
PUBLIC __terminate
|
||||
mov bp,sp
|
||||
mov ah,4Ch
|
||||
mov al,[bp+cPtrSize]
|
||||
int 21h ; Exit to DOS
|
||||
__terminate ENDP
|
||||
|
||||
STARTX ENDP
|
||||
|
||||
SUBTTL Vector save/restore & default Zero divide routines
|
||||
PAGE
|
||||
;[]------------------------------------------------------------[]
|
||||
;| |
|
||||
;| Interrupt Save/Restore routines and default divide by zero |
|
||||
;| handler. |
|
||||
;| |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
ZeroDivision PROC FAR
|
||||
mov dx, offset DGROUP:ZeroDivMSG
|
||||
pushDS_
|
||||
push dx
|
||||
call ___ErrorMessage
|
||||
pop dx
|
||||
popDS_
|
||||
mov ax, 3
|
||||
push ax
|
||||
call __exit ; _exit(3);
|
||||
ZeroDivision ENDP
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
; savevectors()
|
||||
;
|
||||
; Save vectors for 0, 4, 5 & 6 interrupts. This is for extended
|
||||
; signal()/raise() support as the signal functions can steal these
|
||||
; vectors during runtime.
|
||||
;--------------------------------------------------------------------------
|
||||
SaveVectors PROC NEAR
|
||||
push ds
|
||||
; Save INT 0
|
||||
mov ax, 3500h
|
||||
int 021h
|
||||
mov word ptr _Int0Vector@, bx
|
||||
mov word ptr _Int0Vector@+2, es
|
||||
; Save INT 4
|
||||
mov ax, 3504h
|
||||
int 021h
|
||||
mov word ptr _Int4Vector@, bx
|
||||
mov word ptr _Int4Vector@+2, es
|
||||
; Save INT 5
|
||||
mov ax, 3505h
|
||||
int 021h
|
||||
mov word ptr _Int5Vector@, bx
|
||||
mov word ptr _Int5Vector@+2, es
|
||||
; Save INT 6
|
||||
mov ax, 3506h
|
||||
int 021h
|
||||
mov word ptr _Int6Vector@, bx
|
||||
mov word ptr _Int6Vector@+2, es
|
||||
;
|
||||
; Install default divide by zero handler.
|
||||
;
|
||||
mov ax, 2500h
|
||||
mov dx, cs
|
||||
mov ds, dx
|
||||
mov dx, offset ZeroDivision
|
||||
int 21h
|
||||
|
||||
pop ds
|
||||
ret
|
||||
SaveVectors ENDP
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
; _restorezero() puts back all the vectors that SaveVectors took.
|
||||
;
|
||||
;NOTE : TSRs must BE AWARE that signal() functions which take these
|
||||
; vectors will be deactivated if the keep() function is executed.
|
||||
; If a TSR wants to use the signal functions when it is active it
|
||||
; will have to save/restore these vectors itself when activated and
|
||||
; deactivated.
|
||||
;--------------------------------------------------------------------------
|
||||
__restorezero PROC DIST
|
||||
PUBLIC __restorezero
|
||||
IFDEF __HUGE__
|
||||
push ds
|
||||
mov ds, cs: DGROUP@@
|
||||
ENDIF
|
||||
push ds
|
||||
mov ax, 2500h
|
||||
lds dx, _Int0Vector@
|
||||
int 21h
|
||||
pop ds
|
||||
|
||||
push ds
|
||||
mov ax, 2504h
|
||||
lds dx, _Int4Vector@
|
||||
int 21h
|
||||
pop ds
|
||||
|
||||
push ds
|
||||
mov ax, 2505h
|
||||
lds dx, _Int5Vector@
|
||||
int 21h
|
||||
pop ds
|
||||
|
||||
IFNDEF __HUGE__
|
||||
push ds
|
||||
ENDIF
|
||||
mov ax, 2506h
|
||||
lds dx, _Int6Vector@
|
||||
int 21h
|
||||
pop ds
|
||||
|
||||
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
|
||||
|
||||
;------------------------------------------------------------------
|
||||
|
||||
; The DGROUP@ variable is used to reload DS with DGROUP
|
||||
|
||||
PubSym@ DGROUP@, <dw ?>, __PASCAL__
|
||||
|
||||
; __MMODEL is used to determine the memory model or the default
|
||||
; pointer types at run time.
|
||||
|
||||
public __MMODEL
|
||||
__MMODEL dw MMODEL
|
||||
|
||||
_TEXT ENDS
|
||||
|
||||
SUBTTL Start Up Data Area
|
||||
PAGE
|
||||
;[]------------------------------------------------------------[]
|
||||
;| Start Up Data Area |
|
||||
;| |
|
||||
;| WARNING Do not move any variables in the data |
|
||||
;| segment unless you're absolutely sure |
|
||||
;| that it does not matter. |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
_DATA SEGMENT
|
||||
|
||||
; Magic symbol used by the debug info to locate the data segment
|
||||
public DATASEG@
|
||||
DATASEG@ label byte
|
||||
|
||||
; The Check string must NOT be moved or changed without
|
||||
; changing the null pointer check logic
|
||||
|
||||
IFNDEF __TINY__
|
||||
NULL db 4 dup(0)
|
||||
CheckStr db 'NULL CHECK'
|
||||
db 2 dup (0)
|
||||
db 4 dup (0) ;destructor count
|
||||
db 2 dup (0) ;exception list
|
||||
db 4 dup (0) ;exception vptr
|
||||
db 6 dup (0) ;reserved
|
||||
ENDIF
|
||||
|
||||
CopyRight db 'Borland C++ - Copyright 1994 Borland Intl.',0
|
||||
|
||||
IF LDATA EQ false
|
||||
IFNDEF __TINY__
|
||||
CheckSum equ 002B9h
|
||||
NullCheck db 'Null pointer assignment', 13, 10, 0
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
ZeroDivMSG db 'Divide error', 13, 10, 0
|
||||
|
||||
;
|
||||
; Interrupt vector save areas
|
||||
;
|
||||
; Interrupt vectors 0,4,5 & 6 are saved at startup and then restored
|
||||
; when the program terminates. The signal/raise functions might
|
||||
; steal these vectors during execution.
|
||||
;
|
||||
; Note: These vectors save area must not be altered
|
||||
; without changing the save/restore logic.
|
||||
;
|
||||
PubSym@ _Int0Vector <dd 0>, __CDECL__
|
||||
PubSym@ _Int4Vector <dd 0>, __CDECL__
|
||||
PubSym@ _Int5Vector <dd 0>, __CDECL__
|
||||
PubSym@ _Int6Vector <dd 0>, __CDECL__
|
||||
;
|
||||
; Miscellaneous variables
|
||||
;
|
||||
PubSym@ _C0argc, <dw 0>, __CDECL__
|
||||
dPtrPub@ _C0argv, 0, __CDECL__
|
||||
dPtrPub@ _C0environ, 0, __CDECL__
|
||||
PubSym@ _envLng, <dw 0>, __CDECL__
|
||||
PubSym@ _envseg, <dw 0>, __CDECL__
|
||||
PubSym@ _envSize, <dw 0>, __CDECL__
|
||||
PubSym@ _psp, <dw 0>, __CDECL__
|
||||
PubSym@ _version, <label word>, __CDECL__
|
||||
PubSym@ _osversion, <label word>, __CDECL__
|
||||
PubSym@ _osmajor, <db 0>, __CDECL__
|
||||
PubSym@ _osminor, <db 0>, __CDECL__
|
||||
PubSym@ errno, <dw 0>, __CDECL__
|
||||
PubSym@ _Exception_list,<dw -1>, __CDECL__
|
||||
|
||||
|
||||
; Memory management variables
|
||||
|
||||
IF LDATA EQ false
|
||||
PubSym@ __heapbase, <dw DGROUP:edata@>, __CDECL__
|
||||
ENDIF
|
||||
IFNDEF __HUGE__
|
||||
PubSym@ __brklvl, <dw DGROUP:edata@>, __CDECL__
|
||||
ENDIF
|
||||
PubSym@ _heapbase, <dd 0>, __CDECL__
|
||||
PubSym@ _brklvl, <dd 0>, __CDECL__
|
||||
PubSym@ _heaptop, <dd 0>, __CDECL__
|
||||
|
||||
; If stack in DS and Large data model then override location of __emu
|
||||
|
||||
IFDEF _DSSTACK_
|
||||
IF LDATA
|
||||
public __emu
|
||||
__emu db 044h DUP (0)
|
||||
db 0CCh DUP (?)
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
_DATA ENDS
|
||||
|
||||
|
||||
_CVTSEG SEGMENT
|
||||
PubSym@ _RealCvtVector, <label word>, __CDECL__
|
||||
ENDS
|
||||
|
||||
_SCNSEG SEGMENT
|
||||
PubSym@ _ScanTodVector, <label word>, __CDECL__
|
||||
ENDS
|
||||
|
||||
IFNDEF __HUGE__
|
||||
_BSS SEGMENT
|
||||
bdata@ label byte
|
||||
ENDS
|
||||
|
||||
_BSSEND SEGMENT
|
||||
edata@ label byte
|
||||
ENDS
|
||||
ENDIF
|
||||
|
||||
IFNDEF __TINY__
|
||||
_STACK SEGMENT
|
||||
db 128 dup(?) ;minimum stack size
|
||||
ENDS
|
||||
ENDIF ; __TINY__
|
||||
END STARTX
|
||||
@@ -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
|
||||
@@ -0,0 +1,448 @@
|
||||
;[]------------------------------------------------------------[]
|
||||
;| C0W.ASM -- Start Up Code For Windows |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
;
|
||||
; 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
|
||||
IFNDEF __DPMI16__
|
||||
public __WINMAINCALL ; used internally
|
||||
ENDIF
|
||||
public __INITAPPCALLED ; used internally
|
||||
|
||||
IFNDEF __DPMI16__
|
||||
extrn WINMAIN:DIST
|
||||
ENDIF
|
||||
|
||||
extrn INITAPP:far
|
||||
extrn INITTASK:far
|
||||
extrn FATALEXIT:far
|
||||
extrn WAITEVENT:far
|
||||
extrn LOCKSEGMENT:far
|
||||
extrn UNLOCKSEGMENT:far
|
||||
extrn GETWINFLAGS:far
|
||||
IFDEF __DPMI16__
|
||||
extrn _main:DIST
|
||||
extrn _OkToInitWindowsRTL:DIST
|
||||
extrn __abort:DIST
|
||||
ENDIF
|
||||
extrn _exit:DIST
|
||||
extrn __exit:DIST
|
||||
extrn __exitbuf:DIST
|
||||
extrn __exitfopen:DIST
|
||||
extrn __exitopen:DIST
|
||||
extrn __setupio:near ;required!
|
||||
extrn __ExceptInit:DIST
|
||||
|
||||
public __DestructorCount ;Offset to global destructor count
|
||||
__DestructorCount EQU 10H
|
||||
public __Exception_list ;Offset to global exception list
|
||||
__Exception_list EQU 14H
|
||||
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 __psp
|
||||
__psp dw 0
|
||||
public __hInstance
|
||||
__hInstance dw 0
|
||||
public __hPrev
|
||||
__hPrev dw 0
|
||||
public __pszCmdline
|
||||
__pszCmdline dw 0
|
||||
public __cmdShow
|
||||
__cmdShow 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 __WinAllocFlag ;Used by malloc to get additional flags
|
||||
__WinAllocFlag dw 0 ; to pass to GlobalAlloc (for DLL use)
|
||||
public __LockWIN87EM ;Used do lock down WIN87EM to avoid
|
||||
__LockWIN87EM dw 1 ; DLL unload ordering problem
|
||||
public __abend
|
||||
__abend dw 0 ;Signals abnormal end, don't run destructors etc.
|
||||
|
||||
IFDEF __DPMI16__
|
||||
extrn __C0environ:dword
|
||||
extrn __C0argv:dword
|
||||
extrn __C0argc:word
|
||||
ENDIF
|
||||
|
||||
CopyRight db 'Borland C++ - Copyright 1994 Borland Intl.',0
|
||||
IFDEF __DPMI16__
|
||||
DPMI16Error_s db 'This DPMI16 application was linked incorrectly and'
|
||||
db ' will fail.',10,13,'$'
|
||||
ENDIF
|
||||
ends
|
||||
|
||||
_TEXT segment
|
||||
|
||||
Main proc near
|
||||
|
||||
;Windows initialization. Sets up registers and stack.
|
||||
|
||||
IFDEF __DPMI16__
|
||||
mov ax, seg DGROUP
|
||||
mov ds, ax
|
||||
ENDIF
|
||||
|
||||
push bx cx es
|
||||
xor ax,ax
|
||||
push ax
|
||||
call __ExceptInit
|
||||
pop ax
|
||||
pop es cx bx
|
||||
|
||||
;INITTASK returns:
|
||||
; 'Failure:
|
||||
; AX = zero if it failed
|
||||
; Success:
|
||||
; AX = 1
|
||||
; CX = stack limit
|
||||
; DX = cmdShow parameter to CreateWindow
|
||||
; ES:BX = -> DOS format command line (ES = PSP address)
|
||||
; SI = hPrevinstance
|
||||
; DI = hinstance
|
||||
call INITTASK
|
||||
or ax,ax
|
||||
jnz @@OK
|
||||
jmp @@Fail
|
||||
@@OK: mov word ptr ss:[__Exception_list], -1
|
||||
mov __psp,es
|
||||
mov word ptr __pszCmdline,bx
|
||||
mov __hPrev,si
|
||||
mov __hInstance,di
|
||||
mov __cmdShow,dx
|
||||
|
||||
IF LDATA EQ false
|
||||
mov ax,-1
|
||||
push ax
|
||||
call LOCKSEGMENT
|
||||
ENDIF
|
||||
|
||||
;Clear _BSS, uninitialized data area
|
||||
|
||||
IFNDEF __HUGE__
|
||||
xor ax, ax
|
||||
push ds
|
||||
pop es
|
||||
mov di,offset DGROUP:BeginBSS
|
||||
mov cx,offset DGROUP:EndBSS
|
||||
sub cx,di
|
||||
cld
|
||||
rep
|
||||
stosb
|
||||
ENDIF
|
||||
|
||||
;Init the Windows App
|
||||
|
||||
xor ax,ax
|
||||
push ax
|
||||
call WAITEVENT
|
||||
push __hInstance
|
||||
call INITAPP
|
||||
__INITAPPCALLED:or ax,ax
|
||||
jnz @@InitOK
|
||||
jmp @@Fail
|
||||
@@InitOK:
|
||||
|
||||
;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 8086/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
|
||||
|
||||
|
||||
IFDEF __DPMI16__
|
||||
;
|
||||
; Here we attempt to prevent an early death caused by linking
|
||||
; the libs in the wrong order
|
||||
;
|
||||
call _OkToInitWindowsRTL
|
||||
or ax, ax
|
||||
jnz DPMI16Error
|
||||
ENDIF
|
||||
|
||||
;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
|
||||
|
||||
IFDEF __DPMI16__
|
||||
;Set up and call _main for DPMI16 application
|
||||
|
||||
push word ptr [__C0environ+2]
|
||||
push word ptr [__C0environ]
|
||||
push word ptr [__C0argv+2]
|
||||
push word ptr [__C0argv]
|
||||
push [__C0argc]
|
||||
call _main
|
||||
ELSE
|
||||
;Set up and call WinMain for Windows application
|
||||
push __hInstance
|
||||
push __hPrev
|
||||
push __psp
|
||||
push word ptr __pszCmdline
|
||||
push __cmdShow
|
||||
__WINMAINCALL: call WINMAIN
|
||||
ENDIF
|
||||
push ax ; Push return value
|
||||
|
||||
cmp __abend, 0
|
||||
jne @@abnormalexit
|
||||
call _exit ; Normal exit
|
||||
@@abnormalexit: call __exit ; Abnormal exit, don't call destructors etc.
|
||||
|
||||
IFDEF __DPMI16__
|
||||
DPMI16Error:
|
||||
mov ah, 9
|
||||
mov dx, offset DPMI16Error_s
|
||||
int 21h
|
||||
call __abort
|
||||
ENDIF
|
||||
;---------------------------------------------------------------------------
|
||||
; _cleanup() call all #pragma exit cleanup routines.
|
||||
; _checknull() check for null pointer zapping copyright message
|
||||
; _terminate(int) 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
|
||||
|
||||
__terminate PROC DIST
|
||||
PUBLIC __terminate
|
||||
|
||||
IF LDATA EQ false
|
||||
mov ax,-1
|
||||
push ax
|
||||
call UNLOCKSEGMENT
|
||||
ENDIF
|
||||
mov bp,sp
|
||||
mov al,[bp+cPtrSize]
|
||||
mov ah,4ch ;exit
|
||||
int 21h
|
||||
__terminate ENDP
|
||||
|
||||
@@Fail: mov al,0ffh
|
||||
push ax
|
||||
call _exit
|
||||
|
||||
mov ah,4ch ;exit
|
||||
int 21h
|
||||
endp
|
||||
|
||||
; Return default data segment in AX
|
||||
|
||||
__GetDGROUP PROC FAR
|
||||
PUBLIC __GetDGROUP
|
||||
mov ax, ss
|
||||
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 Main
|
||||
@@ -0,0 +1,698 @@
|
||||
;[]-----------------------------------------------------------------[]
|
||||
;| RULES.ASI -- Rules & Structures for assembler |
|
||||
;[]-----------------------------------------------------------------[]
|
||||
|
||||
;
|
||||
; C/C++ Run Time Library - Version 6.5
|
||||
;
|
||||
; Copyright (c) 1987, 1994 by Borland International
|
||||
; All Rights Reserved.
|
||||
;
|
||||
|
||||
;*** First we begin with a few of the major constants of C.
|
||||
|
||||
false equ 0 ; Beware ! For incoming parameters, non-false = true.
|
||||
true equ 1 ; For results, we generate the proper numbers.
|
||||
|
||||
lesser equ -1 ; Incoming, lesser < 0
|
||||
equal equ 0
|
||||
greater equ 1 ; Incoming, greater > 0
|
||||
|
||||
PAGE
|
||||
;[]------------------------------------------------------------[]
|
||||
;| |
|
||||
;| Conditional Assembly Directives |
|
||||
;| |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
;memory model aliases, for the convenience of building the library
|
||||
|
||||
IFDEF __t__
|
||||
__TINY__ equ 1
|
||||
ENDIF
|
||||
|
||||
IFDEF __s__
|
||||
__SMALL__ equ 1
|
||||
ENDIF
|
||||
|
||||
IFDEF __c__
|
||||
__COMPACT__ equ 1
|
||||
ENDIF
|
||||
|
||||
IFDEF __m__
|
||||
__MEDIUM__ equ 1
|
||||
ENDIF
|
||||
|
||||
IFDEF __l__
|
||||
__LARGE__ equ 1
|
||||
ENDIF
|
||||
|
||||
IFDEF __h__
|
||||
__HUGE__ equ 1
|
||||
ENDIF
|
||||
|
||||
IFNDEF __TINY__
|
||||
IFNDEF __SMALL__
|
||||
IFNDEF __MEDIUM__
|
||||
IFNDEF __COMPACT__
|
||||
IFNDEF __LARGE__
|
||||
IFNDEF __HUGE__
|
||||
%OUT You must supply a model symbol.
|
||||
.ERR
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
;bit masks to extract default pointer types from MMODEL (at run-time)
|
||||
FCODE equ 8000h
|
||||
FDATA equ 4000h
|
||||
|
||||
IFDEF __TINY__ ; Small Code - Small Data
|
||||
LPROG equ false
|
||||
LDATA equ false
|
||||
MMODEL equ 0
|
||||
_DSSTACK_ equ <>
|
||||
ENDIF
|
||||
|
||||
IFDEF __SMALL__ ; Small Code - Small Data
|
||||
LPROG equ false
|
||||
LDATA equ false
|
||||
MMODEL equ 1
|
||||
_DSSTACK_ equ <>
|
||||
ENDIF
|
||||
|
||||
IFDEF __MEDIUM__ ; Large Code - Small Data
|
||||
LPROG equ true
|
||||
LDATA equ false
|
||||
MMODEL equ FCODE+2
|
||||
_DSSTACK_ equ <>
|
||||
ENDIF
|
||||
|
||||
IFDEF __COMPACT__ ; Small Code - Large Data
|
||||
LPROG equ false
|
||||
LDATA equ true
|
||||
MMODEL equ FDATA+3
|
||||
ENDIF
|
||||
|
||||
IFDEF __LARGE__ ; Large Code - Large Data
|
||||
LPROG equ true
|
||||
LDATA equ true
|
||||
MMODEL equ FCODE+FDATA+4
|
||||
ENDIF
|
||||
|
||||
IFDEF __HUGE__ ; Large Code - Large Data
|
||||
LPROG equ true
|
||||
LDATA equ true
|
||||
MMODEL equ FCODE+FDATA+5
|
||||
ENDIF
|
||||
|
||||
IF LPROG
|
||||
DIST equ FAR
|
||||
ELSE
|
||||
DIST equ NEAR
|
||||
ENDIF
|
||||
|
||||
PAGE
|
||||
;[]------------------------------------------------------------[]
|
||||
;| |
|
||||
;| Segment Declarations Macros |
|
||||
;| |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
Code_Seg@ MACRO ;; Open a Code Segment
|
||||
IFDEF __WINDOWS__
|
||||
_TEXT SEGMENT WORD PUBLIC 'CODE'
|
||||
ELSE
|
||||
_TEXT SEGMENT BYTE PUBLIC 'CODE'
|
||||
ENDIF
|
||||
ASSUME CS:_TEXT
|
||||
ENDM
|
||||
|
||||
Code_EndS@ MACRO ;; Close a Code Segment
|
||||
_TEXT ENDS
|
||||
ENDM
|
||||
|
||||
Data_Seg@ MACRO ;; Open a Data Segment (initialized)
|
||||
_DATA SEGMENT WORD PUBLIC 'DATA'
|
||||
ENDM
|
||||
|
||||
Data_EndS@ MACRO ;; Close a Data Segment (initialized)
|
||||
_DATA ENDS
|
||||
ENDM
|
||||
|
||||
IFNDEF __HUGE__
|
||||
BSS_Seg@ MACRO ;; Open a Data Segment (un-initialized)
|
||||
_BSS SEGMENT WORD PUBLIC 'BSS'
|
||||
ENDM
|
||||
|
||||
BSS_EndS@ MACRO ;; Close a Data Segment (un-initialized)
|
||||
_BSS ENDS
|
||||
ENDM
|
||||
ENDIF
|
||||
|
||||
FarData_Seg@ MACRO ;; Open a FAR Data Segment
|
||||
_FARDATA SEGMENT PARA PUBLIC 'FAR_DATA'
|
||||
ENDM
|
||||
|
||||
FarData_EndS@ MACRO ;; Close a FAR Data Segment
|
||||
_FARDATA ENDS
|
||||
ENDM
|
||||
|
||||
FarBSS_Seg@ MACRO ;; Open a FAR BSS Segment
|
||||
_FARBSS SEGMENT PARA PUBLIC 'FAR_BSS'
|
||||
ENDM
|
||||
|
||||
FarBSS_EndS@ MACRO ;; Close a FAR BSS Segment
|
||||
_FARBSS ENDS
|
||||
ENDM
|
||||
|
||||
Const_Seg@ MACRO ;; Open a CONST Segment
|
||||
_CONST SEGMENT WORD PUBLIC 'CONST'
|
||||
ENDM
|
||||
|
||||
Const_EndS@ MACRO ;; Close a CONST Segment
|
||||
_CONST ENDS
|
||||
ENDM
|
||||
|
||||
Init_Seg@ MACRO ;; Open a INIT Segment
|
||||
_INIT_ SEGMENT WORD PUBLIC 'INITDATA'
|
||||
ENDM
|
||||
|
||||
Init_EndS@ MACRO ;; Close a INIT Segment
|
||||
_INIT_ ENDS
|
||||
ENDM
|
||||
|
||||
Exit_Seg@ MACRO ;; Open a EXIT Segment
|
||||
_EXIT_ SEGMENT WORD PUBLIC 'EXITDATA'
|
||||
ENDM
|
||||
|
||||
Exit_EndS@ MACRO ;; Close a EXIT Segment
|
||||
_EXIT_ ENDS
|
||||
ENDM
|
||||
|
||||
CVT_Seg@ MACRO
|
||||
_CVTSEG SEGMENT WORD PUBLIC 'DATA'
|
||||
ENDM
|
||||
|
||||
CVT_EndS@ MACRO
|
||||
_CVTSEG ENDS
|
||||
ENDM
|
||||
|
||||
SCN_Seg@ MACRO
|
||||
_SCNSEG SEGMENT WORD PUBLIC 'DATA'
|
||||
ENDM
|
||||
|
||||
SCN_EndS@ MACRO
|
||||
_SCNSEG ENDS
|
||||
ENDM
|
||||
|
||||
Header@ MACRO
|
||||
Code_Seg@
|
||||
Code_EndS@
|
||||
Data_Seg@
|
||||
Data_EndS@
|
||||
BSS_Seg@
|
||||
BSS_EndS@
|
||||
ASSUME CS:_TEXT, DS:DGROUP
|
||||
ENDM
|
||||
|
||||
;[]------------------------------------------------------------[]
|
||||
;| |
|
||||
;| Segment Definitions |
|
||||
;| |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
IFDEF __C0__
|
||||
|
||||
IFDEF __WINDOWS__
|
||||
_TEXT SEGMENT WORD PUBLIC 'CODE'
|
||||
ENDS
|
||||
ELSE
|
||||
_TEXT SEGMENT BYTE PUBLIC 'CODE'
|
||||
ENDS
|
||||
ENDIF
|
||||
|
||||
_FARDATA SEGMENT PARA PUBLIC 'FAR_DATA'
|
||||
ENDS
|
||||
|
||||
_FARBSS SEGMENT PARA PUBLIC 'FAR_BSS'
|
||||
ENDS
|
||||
|
||||
IFNDEF __WINDOWS__
|
||||
IFNDEF __TINY__
|
||||
_OVERLAY_ SEGMENT PARA PUBLIC 'OVRINFO'
|
||||
ENDS
|
||||
_1STUB_ SEGMENT PARA PUBLIC 'STUBSEG'
|
||||
ENDS
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
IFDEF __WINDOWS__
|
||||
NULL SEGMENT PARA PUBLIC 'BEGDATA'
|
||||
ENDS
|
||||
ENDIF
|
||||
|
||||
_DATA SEGMENT PARA PUBLIC 'DATA'
|
||||
ENDS
|
||||
ENDS
|
||||
|
||||
_CONST SEGMENT WORD PUBLIC 'CONST'
|
||||
ENDS
|
||||
|
||||
IFDEF __WINDOWS__
|
||||
_FPSEG SEGMENT WORD PUBLIC 'DATA'
|
||||
ENDS
|
||||
ENDIF
|
||||
|
||||
_CVTSEG SEGMENT WORD PUBLIC 'DATA'
|
||||
ENDS
|
||||
|
||||
_SCNSEG SEGMENT WORD PUBLIC 'DATA'
|
||||
ENDS
|
||||
|
||||
_INIT_ SEGMENT WORD PUBLIC 'INITDATA'
|
||||
InitStart label byte
|
||||
ENDS
|
||||
_INITEND_ SEGMENT BYTE PUBLIC 'INITDATA'
|
||||
InitEnd label byte
|
||||
ENDS
|
||||
|
||||
_EXIT_ SEGMENT WORD PUBLIC 'EXITDATA'
|
||||
ExitStart label byte
|
||||
ENDS
|
||||
_EXITEND_ SEGMENT BYTE PUBLIC 'EXITDATA'
|
||||
ExitEnd label byte
|
||||
ENDS
|
||||
|
||||
IFNDEF __HUGE__
|
||||
_BSS SEGMENT WORD PUBLIC 'BSS'
|
||||
BeginBSS label byte
|
||||
ENDS
|
||||
_BSSEND SEGMENT BYTE PUBLIC 'BSSEND'
|
||||
EndBSS label byte
|
||||
ENDS
|
||||
ENDIF
|
||||
|
||||
|
||||
IFDEF __WINDOWS__
|
||||
|
||||
IFDEF __HUGE__
|
||||
DGROUP GROUP NULL,_DATA,_CONST,_FPSEG,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_
|
||||
ELSE
|
||||
DGROUP GROUP NULL,_DATA,_CONST,_FPSEG,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
|
||||
ENDIF
|
||||
|
||||
ELSE
|
||||
|
||||
IFNDEF __NOFLOAT__
|
||||
IF LDATA
|
||||
IFDEF __HUGE__
|
||||
DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_
|
||||
ELSE
|
||||
DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
|
||||
ENDIF
|
||||
ELSE
|
||||
IFDEF __TINY__
|
||||
DGROUP GROUP _TEXT,_DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
|
||||
ELSE
|
||||
DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
|
||||
ENDIF
|
||||
ENDIF
|
||||
ELSE
|
||||
IF LDATA
|
||||
IFDEF __HUGE__
|
||||
DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_
|
||||
ELSE
|
||||
DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_BSS,_BSSEND
|
||||
ENDIF
|
||||
ELSE
|
||||
IFDEF __TINY__
|
||||
DGROUP GROUP _TEXT,_DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
|
||||
ELSE
|
||||
DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF ; __NOFLOAT__
|
||||
|
||||
ENDIF ; __WINDOWS__
|
||||
|
||||
ELSE
|
||||
|
||||
Code_Seg@
|
||||
Code_EndS@
|
||||
Data_Seg@
|
||||
Data_EndS@
|
||||
DGROUP GROUP _DATA
|
||||
|
||||
ENDIF ; __C0__
|
||||
|
||||
PAGE
|
||||
;[]------------------------------------------------------------[]
|
||||
;| |
|
||||
;| Old Segment Declarations Macros |
|
||||
;| |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
|
||||
CSeg@ MACRO ;; Open a Code Segment
|
||||
IFDEF __WINDOWS__
|
||||
_TEXT SEGMENT WORD PUBLIC 'CODE'
|
||||
ELSE
|
||||
_TEXT SEGMENT BYTE PUBLIC 'CODE'
|
||||
ENDIF
|
||||
ASSUME CS:_TEXT
|
||||
ENDM
|
||||
|
||||
CSegEnd@ MACRO ;; Close a Code Segment
|
||||
_TEXT ENDS
|
||||
ENDM
|
||||
|
||||
DSeg@ MACRO ;; Open a Data Segment (initialized)
|
||||
_DATA SEGMENT WORD PUBLIC 'DATA'
|
||||
ENDM
|
||||
|
||||
DSegEnd@ MACRO ;; Close a Data Segment (initialized)
|
||||
_DATA ENDS
|
||||
ENDM
|
||||
|
||||
IFDEF __BSS__
|
||||
IFNDEF __HUGE__
|
||||
BSeg@ MACRO ;; Open a Data Segment (un-initialized)
|
||||
_BSS SEGMENT WORD PUBLIC 'BSS'
|
||||
ENDM
|
||||
|
||||
BSegEnd@ MACRO ;; Close a Data Segment (un-initialized)
|
||||
_BSS ENDS
|
||||
ENDM
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
Header@ MACRO
|
||||
IFDEF __WINDOWS__
|
||||
_TEXT SEGMENT WORD PUBLIC 'CODE'
|
||||
ELSE
|
||||
_TEXT SEGMENT BYTE PUBLIC 'CODE'
|
||||
ENDIF
|
||||
_TEXT ENDS
|
||||
_DATA SEGMENT WORD PUBLIC 'DATA'
|
||||
_DATA ENDS
|
||||
IFDEF __BSS__
|
||||
IFNDEF __HUGE__
|
||||
_BSS SEGMENT WORD PUBLIC 'BSS'
|
||||
_BSS ENDS
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
ASSUME CS:_TEXT, DS:DGROUP
|
||||
ENDM
|
||||
|
||||
PAGE
|
||||
;[]------------------------------------------------------------[]
|
||||
;| |
|
||||
;| C Naming Convention Macros |
|
||||
;| |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
UNDERSCORE EQU 1
|
||||
|
||||
ExtSym@ MACRO Sym, sType, sName
|
||||
IFNB <sName>
|
||||
IFIDN <sName>, <__PASCAL__>
|
||||
NAMING = 0
|
||||
ELSE
|
||||
NAMING = UNDERSCORE
|
||||
ENDIF
|
||||
ENDIF
|
||||
IF NAMING
|
||||
EXTRN _&Sym : sType
|
||||
Sym&@ equ _&Sym
|
||||
ELSE
|
||||
EXTRN Sym : sType
|
||||
Sym&@ equ Sym
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
PubSym@ MACRO Sym, Definition, sName
|
||||
IFNB <sName>
|
||||
IFIDN <sName>, <__PASCAL__>
|
||||
NAMING = 0
|
||||
ELSE
|
||||
NAMING = UNDERSCORE
|
||||
ENDIF
|
||||
ENDIF
|
||||
IF NAMING
|
||||
PUBLIC _&Sym
|
||||
_&Sym Definition
|
||||
Sym&@ equ _&Sym
|
||||
ELSE
|
||||
PUBLIC Sym
|
||||
Sym Definition
|
||||
Sym&@ equ Sym
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
Static@ MACRO Sym, Definition, sName
|
||||
IFNB <sName>
|
||||
IFIDN <sName>, <__PASCAL__>
|
||||
NAMING = 0
|
||||
ELSE
|
||||
NAMING = UNDERSCORE
|
||||
ENDIF
|
||||
ENDIF
|
||||
IF NAMING
|
||||
_&Sym Definition
|
||||
Sym&@ equ _&Sym
|
||||
ELSE
|
||||
Sym Definition
|
||||
Sym&@ equ Sym
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
PAGE
|
||||
;[]------------------------------------------------------------[]
|
||||
;| |
|
||||
;| Macros which are Data Size Dependent |
|
||||
;| |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
IF LDATA
|
||||
DPTR_ equ DWORD PTR
|
||||
dPtrSize equ 4
|
||||
LES_ equ LES
|
||||
ES_ equ ES:
|
||||
SS_ equ SS:
|
||||
LDS_ equ LDS
|
||||
|
||||
pushDS_ MACRO
|
||||
PUSH DS
|
||||
ENDM
|
||||
|
||||
popDS_ MACRO
|
||||
POP DS
|
||||
ENDM
|
||||
|
||||
PushPtr MACRO dPtrOff, dPtrSeg
|
||||
PUSH dPtrSeg
|
||||
PUSH dPtrOff
|
||||
ENDM
|
||||
|
||||
|
||||
dPtr@ MACRO Sym, VALUE, sName ;; Static Data pointer
|
||||
Static@ Sym, <DD VALUE>, sName
|
||||
ENDM
|
||||
|
||||
dPtrPub@ MACRO Sym, VALUE, sName ;; Global Data Pointer
|
||||
PubSym@ Sym, <DD VALUE>, sName
|
||||
ENDM
|
||||
|
||||
dPtrExt@ MACRO Sym, sName ;; External Data Pointer
|
||||
ExtSym@ Sym, DWORD, sName
|
||||
ENDM
|
||||
ELSE
|
||||
DPTR_ equ WORD PTR
|
||||
dPtrSize equ 2
|
||||
LES_ equ MOV
|
||||
ES_ equ DS:
|
||||
SS_ equ DS:
|
||||
LDS_ equ MOV
|
||||
|
||||
pushDS_ MACRO
|
||||
ENDM
|
||||
|
||||
popDS_ MACRO
|
||||
ENDM
|
||||
|
||||
PushPtr MACRO dPtrOff, dPtrSeg
|
||||
PUSH dPtrOff
|
||||
ENDM
|
||||
|
||||
dPtr@ MACRO Sym, VALUE, sName ;; Static Data pointer
|
||||
Static@ Sym, <DW VALUE>, sName
|
||||
ENDM
|
||||
|
||||
dPtrPub@ MACRO Sym, VALUE, sName ;; Global Data Pointer
|
||||
PubSym@ Sym, <DW VALUE>, sName
|
||||
ENDM
|
||||
|
||||
dPtrExt@ MACRO Sym, sName ;; External Data Pointer
|
||||
ExtSym@ Sym, WORD, sName
|
||||
ENDM
|
||||
ENDIF
|
||||
PAGE
|
||||
;[]------------------------------------------------------------[]
|
||||
;| |
|
||||
;| Macros which are Code Size Dependent |
|
||||
;| |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
IF LPROG
|
||||
CPTR_ equ DWORD PTR
|
||||
cPtrSize equ 4
|
||||
|
||||
Proc@ MACRO Sym, sName ;; Open a Static function
|
||||
Static@ Sym, <PROC FAR>, sName
|
||||
ENDM
|
||||
|
||||
PubProc@ MACRO Sym, sName ;; Open a Public function
|
||||
PubSym@ Sym, <PROC FAR>, sName
|
||||
ENDM
|
||||
|
||||
ExtProc@ MACRO Sym, sName ;; External Function
|
||||
ExtSym@ Sym, FAR, sName
|
||||
ENDM
|
||||
|
||||
cPtr@ MACRO Sym, VALUE, sName ;; Static Function pointer
|
||||
Static@ Sym, <DD VALUE>, sName
|
||||
ENDM
|
||||
|
||||
cPtrPub@ MACRO Sym, VALUE, sName;; Global Function Pointer
|
||||
PubSym@ Sym, <DD VALUE>, sName
|
||||
ENDM
|
||||
|
||||
cPtrExt@ MACRO Sym, sName ;; External Function Pointer
|
||||
ExtSym@ Sym, DWORD, sName
|
||||
ENDM
|
||||
ELSE
|
||||
CPTR_ equ WORD PTR
|
||||
cPtrSize equ 2
|
||||
|
||||
Proc@ MACRO Sym, sName ;; Open a Static function
|
||||
Static@ Sym, <PROC NEAR>, sName
|
||||
ENDM
|
||||
|
||||
PubProc@ MACRO Sym, sName ;; Open a Public function
|
||||
PubSym@ Sym, <PROC NEAR>, sName
|
||||
ENDM
|
||||
|
||||
ExtProc@ MACRO Sym, sName ;; External Function
|
||||
ExtSym@ Sym, NEAR, sName
|
||||
ENDM
|
||||
|
||||
cPtr@ MACRO Sym, VALUE, sName ;; Static Function pointer
|
||||
Static@ Sym, <DW VALUE>, sName
|
||||
ENDM
|
||||
|
||||
cPtrPub@ MACRO Sym, VALUE, sName ;; Global Function Pointer
|
||||
PubSym@ Sym, <DW VALUE>, sName
|
||||
ENDM
|
||||
|
||||
cPtrExt@ MACRO Sym, sName ;; External Function Pointer
|
||||
ExtSym@ Sym, WORD, sName
|
||||
ENDM
|
||||
ENDIF
|
||||
|
||||
EndProc@ MACRO Sym, sName ;; Close a function
|
||||
Static@ Sym, ENDP, sName
|
||||
ENDM
|
||||
|
||||
PAGE
|
||||
;[]------------------------------------------------------------[]
|
||||
;| |
|
||||
;| Miscellaneous Definitions |
|
||||
;| |
|
||||
;[]------------------------------------------------------------[]
|
||||
|
||||
;*** Set up some macros for procedure parameters and export/import
|
||||
|
||||
nearCall STRUC
|
||||
nearBP dw ?
|
||||
nearIP dw ?
|
||||
nearParam dw ?
|
||||
nearCall ENDS
|
||||
|
||||
farCall STRUC
|
||||
farBP dw ?
|
||||
farCSIP dd ?
|
||||
aParam dw ?
|
||||
farCall ENDS
|
||||
|
||||
;*** Next, we define some convenient structures to access the parts
|
||||
; of larger objects.
|
||||
|
||||
_twoBytes STRUC
|
||||
BY0 db ?
|
||||
BY1 db ?
|
||||
_twoBytes ENDS
|
||||
|
||||
_fourWords STRUC
|
||||
W0 dw ?
|
||||
W1 dw ?
|
||||
W2 dw ?
|
||||
W3 dw ?
|
||||
_fourWords ENDS
|
||||
|
||||
_twoDwords STRUC
|
||||
DD0 dd ?
|
||||
DD1 dd ?
|
||||
_twoDwords ENDS
|
||||
|
||||
_aFloat STRUC
|
||||
double dq ?
|
||||
_aFloat ENDS
|
||||
|
||||
; How to invoke MSDOS.
|
||||
|
||||
MSDOS@ MACRO
|
||||
int 21h
|
||||
ENDM
|
||||
PAGE
|
||||
|
||||
; The next section concerns the use of registers. SI and DI are used
|
||||
; for register variables, and must be conserved.
|
||||
|
||||
; Registers AX, BX, CX, DX will not be preserved across function calls.
|
||||
|
||||
; Firstly, the registers to be conserved through function calls, including
|
||||
; the setup of local variables.
|
||||
|
||||
link@ MACRO _si,_di,_ES,locals
|
||||
push bp
|
||||
mov bp, sp
|
||||
IFNB <locals>
|
||||
lea sp, locals
|
||||
ENDIF
|
||||
IFNB <_si>
|
||||
push si
|
||||
ENDIF
|
||||
IFNB <_di>
|
||||
push di
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
unLink@ MACRO _si,_di,_ES,locals
|
||||
IFNB <_di>
|
||||
pop di
|
||||
ENDIF
|
||||
IFNB <_si>
|
||||
pop si
|
||||
ENDIF
|
||||
IFNB <locals>
|
||||
mov sp, bp
|
||||
ENDIF
|
||||
pop bp
|
||||
ENDM
|
||||
|
||||
.LIST
|
||||
Reference in New Issue
Block a user