home *** CD-ROM | disk | FTP | other *** search
- page 60,132
- title STARTUP0 -- Simple Start Up Code for .EXE Programs
- name STARTUP0
- comment ÷
- STARTUP0 V1.05
- --------------------------------------------------------------------------
- NAME
- STARTUP0 Simple start up code for .exe programs
-
- SYNOPSIS
- extern START_UP0
-
- DESCRIPTION
- This is the startup code for all .exe and .com assembly language
- programs. Just use the SYNOPSIS above in the main function to
- include the startup code in the .exe file from a .lib. For .com
- assembly language programs, this source code must be the first
- assembled so that this code is the linked first.
-
- This procedure performs the following functions:
- - Initializes the following global variables:
- -- DGRP, segment address of DGROUP
- -- STACK_BOTTOM, offset to stack bottom in DGROUP
- -- PSP, segment address of PSP
- -- ENVIRON, segment address of passed copy of the ENVIRONMENT
- -- OSMAJOR, integer part of OS system
- -- OSMINOR, decimal part of OS system
- - Initializes DS and ES segment registers to DGROUP
- - Shrinks memory down to size of program by releasing all memory
- above the program
-
- RETURNS
- If main returns to the startup code. The program terminiates with
- the return code in AL.
-
- PROGRAMING NOTES
- Assembled with Microsoft MASM V6.11d with options: /Cp /W3 /Wx
- /memmod={see below}. Do not use the /NOI switch with linker.
-
- Written to link with any memory model
-
- Assemble with the following command line options to get the desired
- memory models:
-
- Use MEMMOD to specify the memory model.
- /dMEMMOD=TINY|SMALL|COMPACT|MEDIUM|LARGE|HUGE
-
- Written using the FORTRAN/PASCAL/BASIC calling convention so passed
- parameters are pushed in the order of appearance in the proc
- declaration.
-
- MEMORY REQUIREMENTS (in bytes using the .286 processor directive)
- Tiny Small Compact Medium Large Huge
- Code: 74 84 84 86 86 86
- _Data: 0 0 0 0 0 0
- Const: 0 0 0 0 0 0
- _BBS: 12 12 12 12 12 12
- Stack: 2 2 2 4 4 4
-
- Note: _BBS data is defined in sudata.asm so that all startup
- procedures can reside in the same .lib file.
-
- CAUTION
- Startup0 defines a 512 byte stack. This should be enough for programs
- who make moderate use of the stack. If automatic variables are used
- extensively, more stack space should be defined in the main module
- unless using the tiny memory model. In this case, the startup code
- must be the first souce file in the build, change the size of the
- STACK_SIZE define.
-
- EXTERNAL LIBRARIES
- sudata alib?
-
- EXTERNAL PROCEDURES
- main user defined
-
- INTERUPTS CALLED
- Int 21h 30h - Get Version Number
- Int 21h 4ah - Set Memory Block Size
- Int 21h 4ch - Terminate program with return code
-
- GLOBAL NAMES
- Startup_0
-
- AUTHOR
- Raymond Moon - 7 Sep 87
-
- Copyright (c) 1987, 1988, 1995, 1996 - MoonWare
- ALL RIGHTS RESERVED
-
- VERSION
- Version - Date - Remarks
- 1.00 - 7 Sep 87 - Original
- 1.01 - 8 Aug 88 - Updated to MASM V5.1
- 1.02 - 9 Oct 88 - Added Stack_Bottom & ZZ_PRGM_TOP segment
- to determine end of data.
- 1.03 - 30 Oct 94 - Moved ZZ_PRGM_TOP segment position in file.
- - Removed increment in program size in paras
- as ZZ_PRGM_TOP is aligned on a para.
- 1.04 - 6 Oct 95 - Added TINY Model capability
- - Converted to .dosseg using __end vice
- ZZ_PRGM_TOP for end of data
- - Removed DOS 1.0 checking and termination
- 1.05 - 29 Dec 96 - Optimized the .com coding
- ==========================================================================
- ÷ Comment End
-
- ;-----------------------------
- ; A Make the small memory model the default
-
- ifndef memmod
- memmod equ <small>
- endif
-
- ;-----------------------------
- ; B Include the processor, memory model, associate ES register with
- ; DGROUP, and specify DOS segment order.
-
- include procesor.inc
- % .MODEL memmod, FORTRAN
- assume es:DGROUP
- .dosseg
-
- ;----------------------------
- ; C Required includes
-
- include startup.inc
-
- ;----------------------------
- ; D Define any required equates
-
- STACK_SIZE equ 512
-
- ;=========================================================================
- ; DATA
- ;=========================================================================
-
- ;----------------------------
- ; E Define __end
-
- externdef __end:byte
-
- ;=========================================================================
- ; STACK
- ;=========================================================================
- ; F Define the stack if memory model is not TINY
-
- if @Model NE 1
-
- .STACK STACK_SIZE ; Define a nominal stack
- endif
-
- ;=========================================================================
- ; PSP
- ;=========================================================================
- ; G Define segment for addressing information in the PSP
-
- PSP_SEG segment at 00h
-
- org 2h
- NEXTPARA_PTR dw ? ; Segment address of next memory para
- org 2ch
- ENVIRON_PTR dw ? ; Segment address of Environment
-
- ;=========================================================================
- ; CODE
- ;=========================================================================
- ; H Put the called main procedure in the proper relationship to the
- ; startup code.
-
- if @CodeSize
- extrn Main:far
- .CODE
- else
- .CODE
- extrn Main:near
- endif
-
- ;-----------------------------
- ; I Include org statement if tiny model
-
- if @Model EQ 1
-
- org 100h
- endif
-
- ;-----------------------------
- ; J Start the START_UP0 code. Make it a far procedure so error return
- ; will work.
-
- Start_Up0 proc far
-
- ;-----------------------------
- ; K First, initialize global variables. Set DS to DGROUP.
- ; Skip DGROUP code for .com(Tiny) memory models
-
- if @Model NE 1
-
- mov ax, DGROUP ; Get seg address of DGROUP
- mov ds, ax ; Initialize DS segment register
- mov DGRP, ax ; Initialize DGRP
- assume es:PSP_SEG
- else
- mov DGRP, ds ; Initialize DGRP
- endif
- mov PSP, es ; Initialize PSP
- if @Model eq 1
- assume ds:PSP_SEG
- endif
- mov bx, ENVIRON_PTR ; Get segment address of environment
- mov cx, NEXTPARA_PTR ; Get segment address of next memory
- if @Model eq 1
- assume ds:DGROUP
- endif
- mov ENVIRON, bx ; Initialize ENVIRON
- mov NEXTPARA, cx ; Initialize NEXTPARA
- mov ah, 30h ; Get DOS version number
- int 21h ; Call DOS
- mov OSMAJOR, al ; Save major version number
- mov OSMINOR, ah ; Save minor version number
-
- ;----------------------------
- ; L Combine the stack into DGROUP so that it is addressable from DGROUP.
- ; Initialize STACK_BOTTOM.
-
- lea bx, __end ; Get pointer to end of data
-
- if @Model eq 1 ; Ensure that Stack bottom at paragraph
- add bx, 15 ; Add to ensure next para if necessary
- and bx, 0fff0h ; Truncate to a paragraph boundary
- endif
-
- mov STACK_BOTTOM, bx ; Save it
-
- if @Model eq 1 ; Get stack size
- add bx, STACK_SIZE ; DI = stack size
- else
- add bx, sp ; DI = stack size
- endif
-
- mov dx, ds ; Get DGROUP segment address
- mov ss, dx ; Reset SS
- mov sp, bx ; Reset SP
-
- ;----------------------------
- ; M Release all memory above program. Calculate the size of the program
- ; in paragraphs (16 bits). BX starts with Stack Top
-
- mov cl, 4 ; Convert to #para by dividing by 16
- shr bx, cl ; Do division by bit shifting
-
- if @Model ne 1 ; Needed in non-Tiny memory models
- mov ax, ds ; AX => DGROUP
- sub ax, PSP ; AX = # para for code
- add bx, ax ; BX = # para in program
- endif
-
- mov ah, 4ah ; Request DOS set block
- int 21h ; Call DOS
-
- if @Model ne 1
- ;-----------------------------
- ; N Initialize ES to DGROUP
-
- mov es, DGRP
- endif
-
- ;-----------------------------
- ; O call MAIN
-
- call Main ; Call MAIN procedure
-
- ;----------------------------
- ; P If main returns, the program is to terminate with the return code
- ; in AL
-
- mov ah, 4ch ; End process
- int 21h ; Call DOS
-
- Start_Up0 endp
-
- end Start_Up0 ; Indicate that START_UP0 is the start
- ; of the program
-