--- /dev/null
+ NAME c0\r
+ PAGE 60,132\r
+ LOCALS\r
+;[]------------------------------------------------------------[]\r
+;| C0.ASM -- Start Up Code |\r
+;| |\r
+;| Turbo C++ Run Time Library |\r
+;| |\r
+;| Copyright (c) 1987, 1991 by Borland International Inc. |\r
+;| All Rights Reserved. |\r
+;[]------------------------------------------------------------[]\r
+\r
+ __C0__ = 1\r
+INCLUDE RULES.ASI\r
+\r
+; Segment and Group declarations\r
+\r
+_TEXT SEGMENT BYTE PUBLIC 'CODE'\r
+ ENDS\r
+_FARDATA SEGMENT PARA PUBLIC 'FAR_DATA'\r
+ ENDS\r
+_FARBSS SEGMENT PARA PUBLIC 'FAR_BSS'\r
+ ENDS\r
+IFNDEF __TINY__\r
+_OVERLAY_ SEGMENT PARA PUBLIC 'OVRINFO'\r
+ ENDS\r
+_1STUB_ SEGMENT PARA PUBLIC 'STUBSEG'\r
+ ENDS\r
+ENDIF\r
+_DATA SEGMENT PARA PUBLIC 'DATA'\r
+ ENDS\r
+_INIT_ SEGMENT WORD PUBLIC 'INITDATA'\r
+InitStart label byte\r
+ ENDS\r
+_INITEND_ SEGMENT BYTE PUBLIC 'INITDATA'\r
+InitEnd label byte\r
+ ENDS\r
+_EXIT_ SEGMENT WORD PUBLIC 'EXITDATA'\r
+ExitStart label byte\r
+ ENDS\r
+_EXITEND_ SEGMENT BYTE PUBLIC 'EXITDATA'\r
+ExitEnd label byte\r
+ ENDS\r
+_CVTSEG SEGMENT WORD PUBLIC 'DATA'\r
+ ENDS\r
+_SCNSEG SEGMENT WORD PUBLIC 'DATA'\r
+ ENDS\r
+IFNDEF __HUGE__\r
+ _BSS SEGMENT WORD PUBLIC 'BSS'\r
+ ENDS\r
+ _BSSEND SEGMENT BYTE PUBLIC 'BSSEND'\r
+ ENDS\r
+ENDIF\r
+IFNDEF __TINY__\r
+ _STACK SEGMENT STACK 'STACK'\r
+ ENDS\r
+ENDIF\r
+\r
+ ASSUME CS:_TEXT, DS:DGROUP\r
+\r
+; External References\r
+\r
+extrn _main:DIST\r
+extrn _exit:DIST\r
+extrn __exit:DIST\r
+extrn __nfile:word\r
+extrn __setupio:near ;required!\r
+extrn __stklen:word\r
+IF LDATA EQ false\r
+extrn __heaplen:word\r
+ENDIF\r
+\r
+ SUBTTL Start Up Code\r
+ PAGE\r
+;/* */\r
+;/*-----------------------------------------------------*/\r
+;/* */\r
+;/* Start Up Code */\r
+;/* ------------- */\r
+;/* */\r
+;/*-----------------------------------------------------*/\r
+;/* */\r
+PSPHigh equ 00002h\r
+PSPEnv equ 0002ch\r
+PSPCmd equ 00080h\r
+\r
+ public __AHINCR\r
+__AHINCR equ 1000h\r
+ public __AHSHIFT\r
+__AHSHIFT equ 12\r
+\r
+IFDEF __NOFLOAT__\r
+MINSTACK equ 128 ; minimal stack size in words\r
+ELSE\r
+MINSTACK equ 256 ; minimal stack size in words\r
+ENDIF\r
+;\r
+; At the start, DS and ES both point to the segment prefix.\r
+; SS points to the stack segment except in TINY model where\r
+; SS is equal to CS\r
+;\r
+_TEXT SEGMENT\r
+IFDEF __TINY__\r
+ ORG 100h\r
+ENDIF\r
+STARTX PROC NEAR\r
+; Save general information, such as :\r
+; DGROUP segment address\r
+; DOS version number\r
+; Program Segment Prefix address\r
+; Environment address\r
+; Top of far heap\r
+\r
+IFDEF __TINY__\r
+ mov dx, cs ; DX = GROUP Segment address\r
+ELSE\r
+ mov dx, DGROUP ; DX = GROUP Segment address\r
+ENDIF\r
+IFNDEF __BOSS__\r
+ mov cs:DGROUP@@, dx ; __BOSS__\r
+ENDIF\r
+ mov ah, 30h\r
+ int 21h ; get DOS version number\r
+ mov bp, ds:[PSPHigh]; BP = Highest Memory Segment Addr\r
+ mov bx, ds:[PSPEnv] ; BX = Environment Segment address\r
+ mov ds, dx\r
+ mov _version@, ax ; Keep major and minor version number\r
+ mov _psp@, es ; Keep Program Segment Prefix address\r
+ mov _envseg@, bx ; Keep Environment Segment address\r
+ mov word ptr _heaptop@ + 2, bp\r
+;\r
+; Save several vectors and install default divide by zero handler.\r
+;\r
+ call SaveVectors\r
+\r
+;===================\r
+;\r
+; IDsoft - Check to make sure that we're running on a 286 or better\r
+\r
+ pushf ; Save original flags\r
+ xor ax,ax ; Clear AX\r
+ push ax\r
+ popf ; Try to pop the 0\r
+ pushf\r
+ pop ax ; Get results of popping 0 into flags\r
+ popf ; Restore original flags\r
+ or ax,ax\r
+ ;begin 8086 hack\r
+ ;jns @@Have286 ; If no sign bit, have a 286\r
+ jmp @@Have286\r
+\r
+ mov cx, lgth_no286MSG\r
+ mov dx, offset DGROUP: no286MSG\r
+ jmp MsgExit3\r
+\r
+@@Have286:\r
+; IDsoft - End of modifications (there's also a code segment string)\r
+;\r
+;===================\r
+\r
+IFDEF __BOSS__\r
+; Determine if in real mode\r
+ mov ax,0FB42h ; find out if DPMI loader is here\r
+ mov bx,1 ; get info function\r
+ int 2fh ;\r
+\r
+ push ax ;\r
+ mov ax, cs ; now, save DGROUP\r
+ add ax, cx ;\r
+ mov es, ax ;\r
+ mov dx, ds ;\r
+ mov es:DGROUP@@, dx ;\r
+ mov es:CSalias@@, ax ;\r
+ pop ax ;\r
+\r
+; cmp ax,0001h ; if not "TRUE"\r
+; JNE InRealMode\r
+\r
+; 8 is the value of the alias selector\r
+; in this system\r
+ MOV _protected@, cx\r
+ MOV _hugeincval@, cx\r
+ clc\r
+ mov ax, cx\r
+ xor cx, cx\r
+ or ax, ax\r
+ je @@gotshift\r
+@@shiftcnt:\r
+ rcr ax,1\r
+ jc @@gotshift\r
+ inc cx\r
+ jmp @@shiftcnt\r
+@@gotshift:\r
+ mov _shiftcount@,cx\r
+\r
+; used by emulator\r
+; PUSH DS\r
+; MOV AX, 0E502H ; prot kernel function, get LDT alias\r
+; INT 21H\r
+; POP DS\r
+; MOV _LDT@, AX\r
+\r
+; cmp _protected@,0001h ; if not "TRUE"\r
+; JNE InRealMode\r
+\r
+ .286P\r
+IFE LDATA\r
+ mov dx, ds ;\r
+; LSL AX, DX ;\r
+; DEC AX ;\r
+ MOV AX, 0FFFEh ;\r
+ MOV SP, AX ;\r
+ MOV SS, DX ;\r
+ENDIF\r
+ .8086\r
+; JMP BossSkip\r
+\r
+InRealMode label near\r
+\r
+ENDIF\r
+\r
+; Count the number of environment variables and compute the size.\r
+; Each variable is ended by a 0 and a zero-length variable stops\r
+; the environment. The environment can NOT be greater than 32k.\r
+\r
+ les di, dword ptr _envLng@\r
+ mov ax, di\r
+ mov bx, ax\r
+ mov cx, 07FFFh ; Environment cannot be > 32 Kbytes\r
+ cld\r
+@@EnvLoop:\r
+ repnz scasb\r
+ jcxz InitFailed ; Bad environment !!!\r
+IFDEF __BOSS__\r
+ jmp InitOK\r
+InitFailed: jmp near ptr _abort\r
+InitOK:\r
+ENDIF\r
+\r
+ inc bx ; BX = Nb environment variables\r
+ cmp es:[di], al\r
+ jne @@EnvLoop ; Next variable ...\r
+ or ch, 10000000b\r
+ neg cx\r
+ mov _envLng@, cx ; Save Environment size\r
+ mov cx, dPtrSize / 2\r
+ shl bx, cl\r
+ add bx, dPtrSize * 4\r
+ and bx, not ((dPtrSize * 4) - 1)\r
+ mov _envSize@, bx ; Save Environment Variables Nb.\r
+\r
+IFNDEF __BOSS__\r
+\r
+; Determine the amount of memory that we need to keep\r
+\r
+IFDEF _DSSTACK_\r
+ mov dx, ds\r
+ELSE\r
+ mov dx, ss\r
+ENDIF\r
+ sub bp, dx ; BP = remaining size in paragraphs\r
+IF LDATA\r
+ mov di, seg __stklen\r
+ mov es, di\r
+ mov di, es:__stklen ; DI = Requested stack size\r
+ELSE\r
+ mov di, __stklen ; DI = Requested stack size\r
+ENDIF\r
+;\r
+; Make sure that the requested stack size is at least MINSTACK words.\r
+;\r
+ cmp di, 2*MINSTACK ; requested stack big enough ?\r
+ jae AskedStackOK\r
+ mov di, 2*MINSTACK ; no --> use minimal value\r
+IF LDATA\r
+ mov es:__stklen, di ; override requested stack size\r
+ELSE\r
+ mov __stklen, di ; override requested stack size\r
+ENDIF\r
+\r
+AskedStackOK label near\r
+IFDEF _DSSTACK_\r
+ add di, offset DGROUP: edata@\r
+ jb InitFailed ; DATA segment can NOT be > 64 Kbytes\r
+ENDIF\r
+IF LDATA EQ false\r
+ add di, __heaplen\r
+ jb InitFailed ; DATA segment can NOT be > 64 Kbytes\r
+ENDIF\r
+ mov cl, 4\r
+ shr di, cl ; $$$ Do not destroy CL $$$\r
+ inc di ; DI = DS size in paragraphs\r
+ cmp bp, di\r
+IF LDATA EQ false\r
+ jb InitFailed ; Not enough memory\r
+ cmp __stklen, 0\r
+ je ExpandDS ; Expand DS up to 64 Kb\r
+ cmp __heaplen, 0\r
+ jne ExcessOfMemory ; Much more available than needed\r
+ExpandDS label near\r
+ mov di, 1000h\r
+ cmp bp, di\r
+ ja ExcessOfMemory ; Enough to run the program\r
+ mov di, bp\r
+ jmp short ExcessOfMemory ; Enough to run the program\r
+ELSE\r
+ jnb ExcessOfMemory ; Much more available than needed\r
+ENDIF\r
+\r
+; All initialization errors arrive here\r
+\r
+InitFailed label near\r
+ jmp near ptr _abort\r
+\r
+; Return to DOS the amount of memory in excess\r
+; Set far heap base and pointer\r
+\r
+ExcessOfMemory label near\r
+ mov bx, di\r
+ add bx, dx\r
+ mov word ptr _heapbase@ + 2, bx\r
+ mov word ptr _brklvl@ + 2, bx\r
+ mov ax, _psp@\r
+ sub bx, ax ; BX = Number of paragraphs to keep\r
+ mov es, ax ; ES = Program Segment Prefix address\r
+ mov ah, 04Ah\r
+ push di ; preserve DI\r
+ int 021h ; this call clobbers SI,DI,BP !!!!!!\r
+ pop di ; restore DI\r
+\r
+ shl di, cl ; $$$ CX is still equal to 4 $$$\r
+\r
+ cli ; req'd for pre-1983 88/86s\r
+ mov ss, dx ; Set the program stack\r
+ mov sp, di\r
+ sti\r
+\r
+IFNDEF _DSSTACK_\r
+ mov ax, seg __stklen\r
+ mov es, ax\r
+ mov es:__stklen, di ; If separate stack segment, save size\r
+ENDIF\r
+\r
+ENDIF ; __BOSS__\r
+\r
+IFNDEF __HUGE__\r
+\r
+; Reset uninitialized data area\r
+\r
+ xor ax, ax\r
+ mov es, cs:DGROUP@@\r
+ mov di, offset DGROUP: bdata@\r
+ mov cx, offset DGROUP: edata@\r
+ sub cx, di\r
+ cld\r
+ rep stosb\r
+ENDIF\r
+\r
+; If default number of file handles have changed then tell DOS\r
+ cmp __nfile, 20\r
+ jbe @@NoChange\r
+\r
+ cmp _osmajor@, 3 ; Check for >= DOS 3.3\r
+ jb @@NoChange\r
+ ja @@DoChange\r
+ cmp _osminor@, 1Eh\r
+ jb @@NoChange\r
+@@DoChange:\r
+ mov ax, 5801h ; Set last fit allocation\r
+ mov bx, 2\r
+ int 21h\r
+ jc @@BadInit\r
+\r
+ mov ah, 67h ; Expand handle table\r
+ mov bx, __nfile\r
+ int 21h\r
+ jc @@BadInit\r
+\r
+ mov ah, 48h ; Allocate 16 bytes to find new\r
+ mov bx, 1 ; top of memory address\r
+ int 21h\r
+ jc @@BadInit\r
+ inc ax ; Adjust address to point after block\r
+ mov word ptr _heaptop@ + 2, ax\r
+\r
+ dec ax ; Change back and release block\r
+ mov es, ax\r
+ mov ah, 49h\r
+ int 21h\r
+ jc @@BadInit\r
+\r
+ mov ax, 5801h ; Set first fit allocation\r
+ mov bx, 0\r
+ int 21h\r
+ jnc @@NoChange\r
+\r
+@@BadInit: jmp near ptr _abort\r
+\r
+@@NoChange:\r
+\r
+; Prepare main arguments\r
+\r
+ mov ah, 0\r
+ int 1ah ; get current BIOS time in ticks\r
+ mov word ptr _StartTime@,dx ; save it for clock() fn\r
+ mov word ptr _StartTime@+2,cx\r
+ or al,al ; was midnight flag set?\r
+ jz @@NotMidnight\r
+ mov ax,40h ; set BIOS midnight flag\r
+ mov es,ax ; at 40:70\r
+ mov bx,70h\r
+ mov byte ptr es:[bx],1\r
+\r
+@@NotMidnight:\r
+ xor bp,bp ; set BP to 0 for overlay mgr\r
+\r
+ mov es, cs:DGROUP@@\r
+ mov si,offset DGROUP:InitStart ;si = start of table\r
+ mov di,offset DGROUP:InitEnd ;di = end of table\r
+ call StartExit\r
+\r
+; ExitCode = main(argc,argv,envp);\r
+\r
+IF LDATA\r
+ push word ptr __C0environ+2\r
+ push word ptr __C0environ\r
+ push word ptr __C0argv+2\r
+ push word ptr __C0argv\r
+ELSE\r
+ push word ptr __C0environ\r
+ push word ptr __C0argv\r
+ENDIF\r
+ push __C0argc\r
+ call _main\r
+\r
+; Flush and close streams and files\r
+\r
+ push ax\r
+ call _exit\r
+\r
+;---------------------------------------------------------------------------\r
+; _cleanup() call all #pragma exit cleanup routines.\r
+; _checknull() check for null pointer zapping copyright message\r
+; _terminate(int) exit program with error code\r
+;\r
+; These functions are called by exit(), _exit(), _cexit(),\r
+; and _c_exit().\r
+;---------------------------------------------------------------------------\r
+\r
+; Call cleanup routines\r
+\r
+__cleanup PROC DIST\r
+ PUBLIC __cleanup\r
+\r
+ mov es, cs:DGROUP@@\r
+ push si\r
+ push di\r
+ mov si,offset DGROUP:ExitStart\r
+ mov di,offset DGROUP:ExitEnd\r
+ call StartExit\r
+ pop di\r
+ pop si\r
+ ret\r
+__cleanup ENDP\r
+\r
+; Check for null pointers before exit\r
+\r
+__checknull PROC DIST\r
+ PUBLIC __checknull\r
+\r
+IF LDATA EQ false\r
+ IFNDEF __TINY__\r
+ push si\r
+ push di\r
+ mov es, cs:DGROUP@@\r
+ xor ax, ax\r
+ mov si, ax\r
+ mov cx, lgth_CopyRight\r
+ComputeChecksum label near\r
+ add al, es:[si]\r
+ adc ah, 0\r
+ inc si\r
+ loop ComputeChecksum\r
+ sub ax, CheckSum\r
+ jz @@SumOk\r
+ mov cx, lgth_NullCheck\r
+ mov dx, offset DGROUP: NullCheck\r
+ call ErrorDisplay\r
+@@SumOK: pop di\r
+ pop si\r
+ ENDIF\r
+ENDIF\r
+ ret\r
+__checknull ENDP\r
+\r
+; Exit to DOS\r
+\r
+__terminate PROC DIST\r
+ PUBLIC __terminate\r
+ mov bp,sp\r
+ mov ah,4Ch\r
+ mov al,[bp+cPtrSize]\r
+ int 21h ; Exit to DOS\r
+__terminate ENDP\r
+\r
+STARTX ENDP\r
+\r
+ SUBTTL Vector save/restore & default Zero divide routines\r
+ PAGE\r
+;[]------------------------------------------------------------[]\r
+;| |\r
+;| Interrupt Save/Restore routines and default divide by zero |\r
+;| handler. |\r
+;| |\r
+;[]------------------------------------------------------------[]\r
+\r
+ZeroDivision PROC FAR\r
+ mov cx, lgth_ZeroDivMSG\r
+ mov dx, offset DGROUP: ZeroDivMSG\r
+ jmp MsgExit3\r
+ZeroDivision ENDP\r
+\r
+;--------------------------------------------------------------------------\r
+; savevectors()\r
+;\r
+; Save vectors for 0, 4, 5 & 6 interrupts. This is for extended\r
+; signal()/raise() support as the signal functions can steal these\r
+; vectors during runtime.\r
+;--------------------------------------------------------------------------\r
+SaveVectors PROC NEAR\r
+ push ds\r
+; Save INT 0\r
+ mov ax, 3500h\r
+ int 021h\r
+ mov word ptr _Int0Vector@, bx\r
+ mov word ptr _Int0Vector@+2, es\r
+; Save INT 4\r
+ mov ax, 3504h\r
+ int 021h\r
+ mov word ptr _Int4Vector@, bx\r
+ mov word ptr _Int4Vector@+2, es\r
+; Save INT 5\r
+ mov ax, 3505h\r
+ int 021h\r
+ mov word ptr _Int5Vector@, bx\r
+ mov word ptr _Int5Vector@+2, es\r
+; Save INT 6\r
+ mov ax, 3506h\r
+ int 021h\r
+ mov word ptr _Int6Vector@, bx\r
+ mov word ptr _Int6Vector@+2, es\r
+;\r
+; Install default divide by zero handler.\r
+;\r
+ mov ax, 2500h\r
+ mov dx, cs\r
+ mov ds, dx\r
+ mov dx, offset ZeroDivision\r
+ int 21h\r
+\r
+ pop ds\r
+ ret\r
+SaveVectors ENDP\r
+\r
+;--------------------------------------------------------------------------\r
+; _restorezero() puts back all the vectors that SaveVectors took.\r
+;\r
+;NOTE : TSRs must BE AWARE that signal() functions which take these\r
+; vectors will be deactivated if the keep() function is executed.\r
+; If a TSR wants to use the signal functions when it is active it\r
+; will have to save/restore these vectors itself when activated and\r
+; deactivated.\r
+;--------------------------------------------------------------------------\r
+__restorezero PROC DIST\r
+ PUBLIC __restorezero\r
+IFDEF __HUGE__\r
+ push ds\r
+ mov ds, cs: DGROUP@@\r
+ENDIF\r
+ push ds\r
+ mov ax, 2500h\r
+ lds dx, _Int0Vector@\r
+ int 21h\r
+ pop ds\r
+\r
+ push ds\r
+ mov ax, 2504h\r
+ lds dx, _Int4Vector@\r
+ int 21h\r
+ pop ds\r
+\r
+ push ds\r
+ mov ax, 2505h\r
+ lds dx, _Int5Vector@\r
+ int 21h\r
+ pop ds\r
+\r
+IFNDEF __HUGE__\r
+ push ds\r
+ENDIF\r
+ mov ax, 2506h\r
+ lds dx, _Int6Vector@\r
+ int 21h\r
+ pop ds\r
+\r
+ ret\r
+ ENDP\r
+\r
+;------------------------------------------------------------------\r
+; Loop through a startup/exit (SE) table,\r
+; calling functions in order of priority.\r
+; ES:SI is assumed to point to the beginning of the SE table\r
+; ES:DI is assumed to point to the end of the SE table\r
+; First 64 priorities are reserved by Borland\r
+;------------------------------------------------------------------\r
+PNEAR EQU 0\r
+PFAR EQU 1\r
+NOTUSED EQU 0ffh\r
+\r
+SE STRUC\r
+calltype db ? ; 0=near,1=far,ff=not used\r
+priority db ? ; 0=highest,ff=lowest\r
+addrlow dw ?\r
+addrhigh dw ?\r
+SE ENDS\r
+\r
+StartExit proc near\r
+@@Start: cmp si,offset DGROUP:InitStart ; startup or exit?\r
+ je @@StartLow ; it's startup\r
+ xor ah,ah ; start with high priority\r
+ jmp short @@SaveEnd\r
+@@StartLow: mov ah,0ffh ;start with lowest priority\r
+@@SaveEnd: mov dx,di ;set sentinel to end of table\r
+ mov bx,si ;bx = start of table\r
+\r
+@@TopOfTable: cmp bx,di ;and the end of the table?\r
+ je @@EndOfTable ;yes, exit the loop\r
+ cmp es:[bx.calltype],NOTUSED;check the call type\r
+ je @@Next\r
+ cmp si,offset DGROUP:InitStart ; startup or exit?\r
+ je @@CompareHigh ; it's startup\r
+ cmp ah,es:[bx.priority] ; it's exit\r
+ jmp short @@CheckPrior ; if priority too low, skip\r
+@@CompareHigh: cmp es:[bx.priority],ah ;check the priority\r
+@@CheckPrior: ja @@Next ;too high? skip\r
+ mov ah,es:[bx.priority] ;keep priority\r
+ mov dx,bx ;keep index in dx\r
+@@Next: add bx,SIZE SE ;bx = next item in table\r
+ jmp @@TopOfTable\r
+\r
+@@EndOfTable: cmp dx,di ;did we exhaust the table?\r
+ je @@Done ;yes, quit\r
+ mov bx,dx ;bx = highest priority item\r
+ cmp es:[bx.calltype],PNEAR ;is it near or far?\r
+ mov es:[bx.calltype],NOTUSED;wipe the call type\r
+ push es ;save es\r
+ je @@NearCall\r
+\r
+@@FarCall: call DWORD PTR es:[bx.addrlow]\r
+ pop es ;restore es\r
+ jmp short @@Start\r
+\r
+@@NearCall: call WORD PTR es:[bx.addrlow]\r
+ pop es ;restore es\r
+ jmp short @@Start\r
+\r
+@@Done: ret\r
+ endp\r
+\r
+;------------------------------------------------------------------\r
+\r
+ErrorDisplay PROC NEAR\r
+ mov ah, 040h\r
+ mov bx, 2\r
+ int 021h\r
+ ret\r
+ErrorDisplay ENDP\r
+\r
+_abort PROC DIST\r
+ PUBLIC _abort\r
+ mov cx, lgth_abortMSG\r
+ mov dx, offset DGROUP: abortMSG\r
+MsgExit3 label near\r
+ mov ds, cs: DGROUP@@\r
+ call ErrorDisplay\r
+CallExit3 label near\r
+ mov ax, 3\r
+ push ax\r
+ call __exit ; _exit(3);\r
+ ENDP\r
+\r
+; The DGROUP@ variable is used to reload DS with DGROUP\r
+\r
+PubSym@ DGROUP@, <dw ?>, __PASCAL__\r
+\r
+IFDEF __BOSS__\r
+PubSym@ CSalias@,<dw ?>, __PASCAL__\r
+ENDIF\r
+\r
+\r
+; __MMODEL is used to determine the memory model or the default\r
+; pointer types at run time.\r
+\r
+ public __MMODEL\r
+__MMODEL dw MMODEL\r
+\r
+_TEXT ENDS\r
+\r
+ SUBTTL Start Up Data Area\r
+ PAGE\r
+;[]------------------------------------------------------------[]\r
+;| Start Up Data Area |\r
+;| |\r
+;| WARNING Do not move any variables in the data |\r
+;| segment unless you're absolutely sure |\r
+;| that it does not matter. |\r
+;[]------------------------------------------------------------[]\r
+\r
+_DATA SEGMENT\r
+\r
+; Magic symbol used by the debug info to locate the data segment\r
+ public DATASEG@\r
+DATASEG@ label byte\r
+\r
+; The CopyRight string must NOT be moved or changed without\r
+; changing the null pointer check logic\r
+\r
+CopyRight db 4 dup(0)\r
+ db 'Borland C++ - Copyright 1991 Borland Intl.',0\r
+lgth_CopyRight equ $ - CopyRight\r
+\r
+IF LDATA EQ false\r
+IFNDEF __TINY__\r
+CheckSum equ 00D5Ch\r
+NullCheck db 'Null pointer assignment', 13, 10\r
+lgth_NullCheck equ $ - NullCheck\r
+ENDIF\r
+ENDIF\r
+\r
+ZeroDivMSG db 'Divide error', 13, 10\r
+lgth_ZeroDivMSG equ $ - ZeroDivMSG\r
+\r
+abortMSG db 'Abnormal program termination', 13, 10\r
+lgth_abortMSG equ $ - abortMSG\r
+\r
+; JAB - Added string for no 286\r
+no286MSG db 'Sorry, this program requires a 286 or better.', 13, 10\r
+lgth_no286MSG equ $ - no286MSG\r
+; JAB - End of modifications\r
+\r
+;\r
+; Interrupt vector save areas\r
+;\r
+; Interrupt vectors 0,4,5 & 6 are saved at startup and then restored\r
+; when the program terminates. The signal/raise functions might\r
+; steal these vectors during execution.\r
+;\r
+; Note: These vectors save area must not be altered\r
+; without changing the save/restore logic.\r
+;\r
+PubSym@ _Int0Vector <dd 0>, __CDECL__\r
+PubSym@ _Int4Vector <dd 0>, __CDECL__\r
+PubSym@ _Int5Vector <dd 0>, __CDECL__\r
+PubSym@ _Int6Vector <dd 0>, __CDECL__\r
+;\r
+; Miscellaneous variables\r
+;\r
+PubSym@ _C0argc, <dw 0>, __CDECL__\r
+dPtrPub@ _C0argv, 0, __CDECL__\r
+dPtrPub@ _C0environ, 0, __CDECL__\r
+PubSym@ _envLng, <dw 0>, __CDECL__\r
+PubSym@ _envseg, <dw 0>, __CDECL__\r
+PubSym@ _envSize, <dw 0>, __CDECL__\r
+PubSym@ _psp, <dw 0>, __CDECL__\r
+PubSym@ _version, <label word>, __CDECL__\r
+PubSym@ _osversion, <label word>, __CDECL__\r
+PubSym@ _osmajor, <db 0>, __CDECL__\r
+PubSym@ _osminor, <db 0>, __CDECL__\r
+PubSym@ errno, <dw 0>, __CDECL__\r
+PubSym@ _StartTime, <dw 0,0>, __CDECL__\r
+\r
+\r
+IFDEF __BOSS__\r
+PubSym@ _protected <dw 0>, __CDECL__\r
+PubSym@ _shiftcount, <dw 12>, __CDECL__\r
+PubSym@ _hugeincval, <dw 1000h>, __CDECL__\r
+ENDIF\r
+\r
+; Memory management variables\r
+\r
+IF LDATA EQ false\r
+PubSym@ __heapbase, <dw DGROUP:edata@>, __CDECL__\r
+ENDIF\r
+IFNDEF __HUGE__\r
+PubSym@ __brklvl, <dw DGROUP:edata@>, __CDECL__\r
+ENDIF\r
+PubSym@ _heapbase, <dd 0>, __CDECL__\r
+PubSym@ _brklvl, <dd 0>, __CDECL__\r
+PubSym@ _heaptop, <dd 0>, __CDECL__\r
+\r
+; If stack in DS and Large data model then override location of __emu\r
+\r
+IFDEF _DSSTACK_\r
+IF LDATA\r
+public __emu\r
+__emu db 044h DUP (0)\r
+ db 0CCh DUP (?)\r
+ENDIF\r
+ENDIF\r
+\r
+_DATA ENDS\r
+\r
+\r
+_CVTSEG SEGMENT\r
+PubSym@ _RealCvtVector, <label word>, __CDECL__\r
+ ENDS\r
+\r
+_SCNSEG SEGMENT\r
+PubSym@ _ScanTodVector, <label word>, __CDECL__\r
+ ENDS\r
+\r
+IFNDEF __HUGE__\r
+_BSS SEGMENT\r
+bdata@ label byte\r
+ ENDS\r
+\r
+_BSSEND SEGMENT\r
+edata@ label byte\r
+ ENDS\r
+ENDIF\r
+\r
+IFNDEF __TINY__\r
+_STACK SEGMENT\r
+IFDEF __BOSS__\r
+ IF LDATA\r
+ db 1400h dup(?)\r
+ ENDIF\r
+ELSE\r
+ db 128 dup(?) ;minimum stack size\r
+ENDIF ; __BOSS__\r
+ ENDS\r
+ENDIF ; __TINY__\r
+ END STARTX\r