SafetyPad       Db 640 dup(0)

Install:


;
;  We want to see if help or the internal stack is being used.
;

      Mov    SI,081
      Call StripBlanks

      ES Cmp B [SI],CR               ; end of inputs?
      Je     Envi                    ; if so then move on

      ES Cmp B [SI],'-'              ; internal stack or not?
      If e Mov StackFlag,0           ; if '-' found no stack

      ES Cmp B [SI],'+'              ; storing help or not ?
      If e Mov HelpFlag,0            ; if '+' found no help

      Push     SI
      Inc      SI
      Call StripBlanks

      ES Cmp B [SI],CR               ; end of inputs?
      Je     Envi                    ; if so then move on

      ES Cmp B [SI],'-'              ; internal stack or not?
      If e Mov StackFlag,0           ; if '-' found no stack

      ES Cmp B [SI],'+'              ; storing help or not ?
      If e Mov HelpFlag,0            ; if '+' found no help

;
;  Now let's see if there is a configuration file on the command line.
;
      Pop    SI

      Cmp    StackFlag,0             ; if no stack then ignore config file
      Je     Envi

      Push   SI

      Mov    DI,SI
      Mov    AL,':'
      Mov    CX,64

      Repne  Scasb
      Jne    WhichOne

      Sub    DI,2
      Mov    SI,DI
      Mov    DI,Offset ConfigBuffer

   CED1:
      Lodsb

      Cmp    AL,CR
      Je     WhichOne

      Cmp    AL,' '
      Je     WhichOne

      Cmp    AL,'a'                  ; lowercase letter?
      If ae Xor AL,020               ; if so make upper case

      Stosb
      Jmp    CED1

WhichOne:
      Pop    SI


;
;  Now we deallocate our environment block and free it up for other programs
;
   Envi:
      Mov    AH,049                  ; release memory call to DOS
      Mov    ES,[02C]                ; set ES to environment
      Int    021                     ; call DOS
      Mov    ES,CS                   ; restore ES
;
;  Based on the variable HelpFlag we determine how much memory to
;  allocate and TSR.  We will begin by assuming help will be installed
;

      Mov    DX,ProgramEndH          ; set DX to include help
      Cmp    HelpFlag,1              ; are we supposed to include help?
      If ne Mov DX,DtaAreaEnd        ; if not change DX

      Mov    StackAddress,DX
      Cmp    StackFlag,1             ; what about the internal stack?
                                     ; if flag set then add 640 bytes for
      Jne    TSR                     ; storage

;
;  We are going to use the internal stack so let's clean it out
;

      Mov    DI,DX
      Mov    CX,640
      Shr    CX,1
      Mov    AX,0
    C1:
      Stosw
      Loop   C1

;
;  Up DX by the size of the buffer. (DX tells DOS how much mem. to TSR)
;

      Cld
      Add    DX,640

;
;  Last thing... if we have a config file read it into stack - if we have
;  a stack .......
;

      Cmp    B [ConfigBuffer],0

      Je     TSR

      Push   DX
      Call ReadConfigFile
      Pop    DX

  TSR:
      Push   DX

        MOV     AX,03521
        INT     021

        MOV     INT_21Off,BX
        MOV     INT_21Seg,ES

        MOV     AX,02521
        MOV     DX,OFFSET New_INT_21
        INT     021

      Cld
      Mov    DX,Offset Version       ; display version.
      Call PrintS

      Pop    DX
      Int    027                     ; terminate and stay resident


;---------------------------------------------------------------------------;
; ReadConfigFile                                                            ;
;                                                                           ;
;     ReadConfigFile checks to see if a config file exits and if it does    ;
;     reads the file and places the data in the internal stack.             ;
;                                                                           ;
;---------------------------------------------------------------------------;

OpenError       Db 'Error opening Config file',CR,LF,Stopper

ReadError       Db 'Error reading Config file.  Check format and size.',CR,LF,Stopper

DataError       Db 'Data error in Config file.  Check format, is it ascii ?',CR,LF,Stopper

ConfigBuffer    db 64 dup(0)

ConfigHandle    Dw ?

;
;  To begin we verify that there is a configuration file in the buffer.  If
;  there is not then we leave.
;

ReadConfigFile:
;
;  We begin by attemptint to open the configuration file.
;
      Mov    AL,0                       ; read access (no sharing)
      Mov    DX,Offset ConfigBuffer     ; file name
      Mov    AH,03D                     ; open file
      Int    021

      Jnc    Opened

;
;  If we get here we have an error opening the config file.
;

      Mov    Errlvl,10
      Mov    DX,Offset OpenError
      Call PrintS
      Jmp    ExitDOS

;
;  With successfull opening we now read the configuration file into memory.
;  We will assume it is less than 2048 bytes long and put it in memory where
;  the TheEND procedure is.
;

Opened:
      Mov    ConfigHandle,AX            ; save handle for closing file

;
;  Read from the config file.
;

      Mov    BX,ConfigHandle            ; read from config file
      Mov    CX,2048                    ; read 2048 bytes
      Mov    DX,Offset TheEND           ; put info at the end
      Mov    AH,03F                     ; read file
      Int    021

;
;  If the carry flag is not set we are ready to go.
;

      Jnc    Close

      Mov    Errlvl,11
      Mov    DX,Offset ReadError
      Call PrintS
      Jmp    ExitDOS

;
;  Now, let's close the file before we go any further
;

Close:
      Mov    BX,ConfigHandle            ; config file
      Mov    AH,03E                     ; close it
      Int    021

;
;  Now we process the configuration information for the internal stack
;

      Mov    SI,Offset TheEND           ; point SI to configuration info

;
;  RCF is the overall loop.  The program comes here at the begining of
;  each stack entry.
;

   RCF:
      Lodsb

      Cmp    AL,26                      ; end of file mark ?
      Je     ExitRCF                    ; yes, leave

      Sub    AL,030                     ; convert ascii
      Cmp    AL,0A                      ; if it's between 0 and 9 we are ok.
      If b Cmp AL,0
      Jae    RCF1

;
;  If the file is not in the proper format - 0=\....CRLF - then ERROR !
;

      Mov    Errlvl,12                  ; error in file format.
      Mov    Dx,Offset DataError
      Call PrintS
      Jmp    ExitDOS

;
;  We have a good format (ie AL contains a stack number) so we find the
;  appropriate offset into the internal stack buffer and make sure the
;  number is followed by an = sign.
;

   RCF1:

      Push   SI                         ; save SI
      Call StackBufferPos               ; get offset into stack buffer
      Mov    DI,SI                      ; point DI to offset
      Pop    SI                         ; get SI back

      Lodsb                             ; get next character in file

      Cmp    AL,'='
      Je     RCF2

;
;  If the number is not followed by an = sign ERROR !
;
      Mov    Errlvl,12                  ; error in file format.
      Mov    Dx,Offset DataError
      Call PrintS
      Jmp    ExitDOS

;
;  Now we process this stack entry.
;

   RCF2:
      Lodsb                          ; get character

      Cmp    AL,CR                   ; is it the end of a line (CR) ?
      Je     RCF3                    ; if so get out of loop

      Cmp    AL,'a'                  ; lowercase letter?
      If ae Xor AL,020               ; if so make upper case

      Stosb                          ; store character

      Jmp    RCF2                    ; go get the next character

   RCF3:

      Inc    SI                      ; move SI past the LF character in the file
      Jmp    RCF                     ; go get the next stack entry from the file

ExitRCF:
      Ret


ExitDOS:
      Mov     AL,Errlvl              ; Return to system
      Mov     AH,04C                 ; via EXIT
      Int     021


TheEND    EQU $
