Listing 2

              page    60,132
              title   start1 - simple start-up code
;**************************************************************;
;                                                              ;
;                         start1.asm                           ;
;                                                              ;
;   start-up for stand-alone C code - Turbo C/C++ version      ;
;                                                              ;
;                   created: November 17, 1990                 ;
;                                                              ;
;                      Copyright (c) 1990                      ;
;                      Pasquale J. Villani                     ;
;                      All Rights Reserved                     ;
;                                                              ;
;**************************************************************;

_TEXT           segment byte public 'CODE'
              assume  cs:_TEXT                  ; small model
_TEXT           ends

_DATA           segment word public 'DATA'
DGROUP          group   _DATA,_BSS,_BSSEND         ; small model
              assume  ds:DGROUP,ss:DGROUP
_DATA           ends

_BSS            segment word public 'BSS'
_BSS            ends

_BSSEND         segment byte public 'STACK'
_BSSEND         ends

_TEXT           segment byte public 'CODE'
              
              extrn    _main:near           ; C entry point
              extrn    _hdw_init:near       ; Hardware init (asm or C)

;
; entry:
;    Our ROM madule's entry point. This should be used as the
;    'jmp far ptr entry' at the top of ROM.
;
entry      proc     far
         public   entry;
       
       ;
       ; First order of business is the initialization of the
       ; machine itself. This is basically the initialization
       ; of any segment registers that the processor needs for
       ; proper operation. On an 80X86 class processor, this is
       ; usually initializing the segmentation registers, going
       ; to the proper mode (i. e. protected, etc.) for
       ; 80[234]86 processors, etc. This file is for an 8086 or
       ; 8088 machine (or any other in real mode). Segment
       ; registers are the only processor initialization.
       ;
       ; NOTE: the cs register is not initialized because the
       ; processor itself initializes the first cs, followed
       ; by the far jump changing it to point to segment entry.
       ;
       cli                     ; prevent interrupts while starting
       mov     ax,DGROUP       ; initialize the segment registers
       mov     ds,ax
       mov     ss,ax
       mov     es,ax
       ;
       ; Once the processor is initialized, it usually requires
       ; the proper setting of the stack pointer(s). For the
       ; 8086 case, all we need is to initialize the sp and bp
       ; registers.
       ;
       mov     sp,offset DGROUP:tos
       mov     bp,sp
       ;
       ; We are now ready to make any special hardware
       ; initialization. This includes initializing the interrupt
       ; vector table, moving the data segment to RAM and
       ; initializing the BSS to zero to match C programming
       ; conventions. This should end with a call to __hdw_init
       ; to initialize I/O, etc.
       call  near ptr __hdw_init; initialize the system without ints
       sti                   ;now enable them
       ;
       ; After the hardware is initialized, we wish to enter
       ; main(). This is accomplished by building the stack for
       ; envp, argv and argc. This is a convienent mechanism
       ; for passing system configuration, dip switch settings,
       ; etc. to our C code.
       ;
       mov     ax,offset env   ; envp for this example
       push    ax
       mov     ax,offset args  ; argv for this example
       push    ax
       mov     ax,2            ; argc = 2
       push    ax
       call    near ptr _main  ; finally enter C code
       add     sp,6            ; clean stack
       ;
       ; If main should return, we need a mechanism to catch this
       ; condition. Depending on the system design, we should
       ; alarm, restart, etc., therefore, the following code
       ; is very implementation dependant. In our case, all we
       ; want to do is call exit with a special -1 exit code.
       ;
       mov     ax,-1
       push    ax
       call    near ptr _exit
       jmp     $               ; belt and suspenders

entry       endp

;
; exit:
;    Where to go for error conditions (typically) or shutdown
;    conditions. This code is very implementaion sensitive, since
;    we may want to light LEDs and sound alarms. In this case, we'll
;    only silently stop. In certain cases, we may want to only
;    display a message and restart. This should be decided upon
;    during system design.
;
_exit           proc    near
             public  _exit
             
             cli
             hlt
             jmp     _exit

_exit           endp

T_EXT           ends

_DATA           segment  word public 'DATA'
env0    label   byte
             db       'ENV=ROM',0
arg0    label   byte
             db               'ex0s', 0
arg1    label   byte
             db               'rom', 0
env     label   word
       dw      DGROUP:env0
       dw      0
args    label   word
       dw      DGROUP:arg0
       dw      DGROUP:arg1
       dw      0
_DATA           ends

;
; The stack segment. This size should be adjusted to fit
; any particular system requirements.
;
_STACK          SEGMENT
              dw      512 dup (?)
tos             label    byte
              dd      (?)           ; safety area
last            label    word          ; must always be end of stack area
_STACK  ENDS

_BSS            segment  word public 'BSS'
_errno          label    word          ; c lib errno
              public  _errno
              dw      (?)
_BSS            ends

_BSSEND segment  byte    public 'STACK'
_BSSEND ends

       end