home *** CD-ROM | disk | FTP | other *** search
- NAME c0
- PAGE 60,132
- LOCALS
- ;[]-------------------------------------------------------------------[]
- ;| C0.ASM -- Start Up Code for MIO |
- ;| |
- ;| Turbo C++ Run Time Library |
- ;| |
- ;| Portions Copyright (c) 1991, Stuart G. Phillips. |
- ;| All rights reserved. |
- ;| |
- ;| Copyright (c) 1987, 1991 by Borland International Inc. |
- ;| All rights reserved. |
- ;| |
- ;| This software is subject to the terms and conditions of the |
- ;| license agreement distributed with Borland C++. |
- ;[]-------------------------------------------------------------------[]
-
- __C0__ = 1
- INCLUDE RULES.ASI
-
- ; Segment and Group declarations
-
- _BOOT SEGMENT BYTE PUBLIC 'CODE' AT 0FFFFh
- ORG 0
- boot_vector LABEL BYTE
- ENDS
-
- _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 __stklen:word
- IF LDATA EQ false
- extrn __heaplen:word
- ENDIF
-
- SUBTTL Start Up Code
- PAGE
- ;/* */
- ;/*-----------------------------------------------------*/
- ;/* */
- ;/* Start Up Code */
- ;/* ------------- */
- ;/* */
- ;/*-----------------------------------------------------*/
- ;/* */
-
- ; public __AHINCR
- ; __AHINCR equ 1000h
- ; public __AHSHIFT
- ; __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__
- ENDIF
- STARTX PROC NEAR
- jmp START
-
- ORG 2000h
-
- START:
- ; Save general information, such as :
- ; DGROUP segment 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 ds,dx ; Set DGROUP as data segment
- mov bp,0c000h ; BP = segment at top of memory
-
- ; Calculate the first free segment value by finding the top of data
- ; in the DGROUP data group - add in the offset of the end and convert
- ; to paragraphs.
-
- mov ax,dx
- mov dx,offset DGROUP:edata@
- add dx,15
- mov cl,4
- shr dx,cl
- add ax,dx
- mov word ptr _heaptop@ + 2, ax
-
- ; Set temporary stack at top of used memory - it gets changed later
-
- cli
- mov ss,ax
- mov sp,100h
- sti
-
- push ax
- ;
- ; Save several vectors and install default divide by zero handler.
- ;
- call SaveVectors
-
- ; Determine the amount of memory that we need to keep
-
- pop ax
-
- IFDEF _DSSTACK_
- mov dx, ds
- ELSE
- mov dx, ax
- 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
- jmp near ptr _abort
-
- ; 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
-
- 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
-
- mov word ptr _first_stack@, di
- mov word ptr _first_stack@ + 2, dx
-
- IFNDEF _DSSTACK_
- ; Set the stack to a known pattern
-
- mov bx,di
- mov es,dx ; ES is stack segment
- mov cx,di
- shr cx,1 ; Convert to words
- mov di,0
- mov ax,'ST'
- cld
- rep stosw
- mov di,bx
- ENDIF
-
- 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
-
- ; Prepare main arguments
-
- xor bp,bp ; set BP to 0 for overlay mgr
-
- IFNDEF __TINY__
- mov ax,DGROUP
- mov ds,ax
- mov si,offset DGROUP:InitStart ;si = start of table
- mov di,offset DGROUP:InitEnd ;di = end of table
- ELSE
- mov si,offset DGROUP:InitStart ;si = start of table
- mov di,offset DGROUP:InitEnd ;di = end of table
- ENDIF
- call StartExit
- mov ds, cs:DGROUP@@
-
- ; OK, to save space we use self-modifying code.
- ; Replace the JA instruction in the startup/exit logic with
- ; a JB instruction. This allows us to scan the table on exit
- ; executing functions in reverse priority. Also change the
- ; immediate which is stored in ah at the first instruction to a 0.
-
- mov byte ptr cs:JA_JB,72h
- mov byte ptr cs:StartExit+1,0
-
- ; MIO main program is called with no parameters - set argc to
- ; a zero count and argv to a null pointer
-
- ; ExitCode = main(argc,argv);
-
- xor ax,ax
-
- IF LDATA
- push ax
- push ax ; Null argv pointer
- ELSE
- push ax ; Null argv pointer
- ENDIF
- push ax ; arc = 0
- call _main
-
- ; Clean up - MIO has no files or streams but clean up the
- ; interrupt vectors and then jump back to the EPROM boot code
- ; ready for the next download
-
- push ax
- jmp far ptr boot_vector
-
- ;---------------------------------------------------------------------------
- ; _exit()
- ;
- ; Restore interrupt vectors taken during startup.
- ;
- ; Jump back to EPROM boot code
- ;
- ;---------------------------------------------------------------------------
- __exitclean PROC NEAR
- PUBLIC __exitclean
- IFNDEF __TINY__
- mov ax,DGROUP
- mov ds,ax
- mov si,offset DGROUP:ExitStart
- mov di,offset DGROUP:ExitEnd
- ELSE
- mov si,offset DGROUP:ExitStart
- mov di,offset DGROUP:ExitEnd
- ENDIF
- call StartExit
-
- mov ds, cs:DGROUP@@
-
- ENDP
-
- __exit PROC DIST
- PUBLIC __exit
- mov ds, cs:DGROUP@@
-
- call DIST ptr __restorezero ; restore captured INT vectors
-
- jmp far ptr boot_vector
- 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
- ret
- ZeroDivision ENDP
-
- ;
- ; Install default divide by zero handler.
- ;
-
- SaveVectors PROC FAR
- mov ax, 0
- push es ; Save current es
- push di ; ... and di
- mov es,ax
- mov di,0
- mov es:[di], cs
- mov dx, offset ZeroDivision
- mov es:[di+2],dx
- pop di
- pop es
- ret
- SaveVectors ENDP
-
- ;--------------------------------------------------------------------------
- ; restorezero() resets the divide by zero interrupt to point to the
- ; boot prom entry point
- ;
- ;--------------------------------------------------------------------------
- __restorezero PROC DIST
- PUBLIC __restorezero
-
- push es ; Save es
- push di ; ...and di
- xor ax,ax
- mov es,ax
- mov di,0
- mov word ptr es:[si],0
- mov word ptr es:[si+2],0ffffh
- pop di
- pop es
- ret
- ENDP
-
- ;------------------------------------------------------------------
- ; Loop through a startup/exit (SE) table,
- ; calling functions in order of priority.
- ; DS:SI is assumed to point to the beginning of the SE table
- ; DS: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
-
- StartExit PROC NEAR
- @@Start: mov ah,0ffh ; 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 [bx.calltype],NOTUSED ; check the call type
- je @@Next
- cmp [bx.priority],ah ; check the priority
- JA_JB: ja @@Next ; too high? skip
- mov ah,[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
- push ds ; save ds
- pop es
- push es ; es = ds
- cmp [bx.calltype],PNEAR ; is it near or far?
- mov [bx.calltype],NOTUSED ; wipe the call type
- mov ds, cs:DGROUP@@
- je @@NearCall
-
- @@FarCall: call DWORD PTR es:[bx.addrlow]
- pop ds ; restore ds
- jmp @@Start
-
- @@NearCall: call WORD PTR es:[bx.addrlow]
- pop ds ; restore ds
- jmp @@Start
-
- @@Done: ret
- StartExit ENDP
-
-
- _abort PROC DIST
- PUBLIC _abort
- mov ax, 3
- push ax
- call __exit ; _exit(3);
- 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
-
-
- CopyRight db 4 dup(0)
- db 'Borland C++ - Copyright 1991 Borland Intl.',0
- ;
- ; 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@ _osmajor, <db 0>, __CDECL__
- PubSym@ _osminor, <db 0>, __CDECL__
- PubSym@ errno, <dw 0>, __CDECL__
- PubSym@ _StartTime, <dw 0,0>, __CDECL__
-
-
- ; Memory management variables
-
- IF LDATA EQ false
- PubSym@ __heapbase, <dw DGROUP:edata@>, __CDECL__
- PubSym@ __brklvl, <dw DGROUP:edata@>, __CDECL__
- ENDIF
- PubSym@ _heapbase, <dd 0>, __CDECL__
- PubSym@ _brklvl, <dd 0>, __CDECL__
- PubSym@ _heaptop, <dd 0>, __CDECL__
- PubSym@ _first_stack <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
- END STARTX
-