;
; Program: Z3INS
; Author: Richard Conn
; Version: 1.2
; Date: 9 January 1985
; Previous Versions: 1.0 11 June 84, 1.1 1 Dec 84
;
VERS EQU 12 ; Four times faster.. jww
Z3ENV SET 0F400H
;
; The purpose of Z3INS is to install a group of ZCPR3 System Utilities.
; Z3INS reads in an Environment Descriptor and then reads in a file containing
; the names of the utilities to be installed. It then reads in each file named
; and installs the proper values into it.
;
; Syntax:
; Z3INS Envfile.typ Install.typ
; Default File Types:
; Envfile - ENV
; Install - INS
;
; Added the ability to install one program if the "Install" type
; is "COM".
;
; Customization
; Number of Blocks to Read/Write Per File Access
;
NBLKS EQU 16 ; Must be even (8=1K, 16=2K, etc)
;
; System Equates
;
BASE EQU 0 ; Base address of system
BDOS EQU BASE+05H
FCB EQU BASE+5CH
FCB2 EQU BASE+6CH
TBUFF EQU BASE+80H
TAB EQU 09H
CR EQU 0DH
LF EQU 0AH
CTRLZ EQU 'Z'-'@' ; EOF mark
;
; Environment Definition
;
IF Z3ENV NE 0
;
; External ZCPR3 Environment Descriptor
;
JMP START
DB 'Z3ENV' ; This is a ZCPR3 Utility
DB 1 ; External Environment Descriptor
Z3EADR:
DW Z3ENV
START:
LHLD Z3EADR ; Pt to ZCPR3 environment
;
ELSE
;
; Internal ZCPR3 Environment Descriptor
;
MACLIB Z3BASE.LIB
MACLIB SYSENV.LIB
Z3EADR:
JMP START
SYSENV
START:
LXI H,Z3EADR ; Pt to ZCPR3 environment
ENDIF
;
; Start of Program -- Initialize ZCPR3 Environment
;
CALL Z3INIT ; Initialize the ZCPR3 Env and the VLIB Env
;
; Print Name
;
CALL EPRINT
DB 'Z3INS Version '
DB (VERS/10)+'0','.',(VERS MOD 10)+'0',0
;
; Check for file names
;
LDA FCB+1 ; Get first char
CPI '/' ; Print help
JZ HELP
CPI ' '
JNZ FN2
;
; Print Help Message
;
HELP:
CALL EPRINT
DB CR,LF,'Syntax:'
DB CR,LF,' Z3INS envfile.ENV insfile.INS or'
DB CR,LF,' Z3INS envfile.ENV program.com'
DB 0
RET
;
; Continue file name check
;
FN2:
LDA FCB2+1
CPI ' ' ; Print help if none
JZ HELP
;
; Set Default File Types
;
LXI D,FCB+9 ; Pt to file type
LXI H,DEFENV ; Pt to default
CALL SETTYP
LXI D,FCB2+9 ; Pt to file type
LXI H,DEFINS ; Pt to default
CALL SETTYP
LXI H,FCB2 ; Save 2nd FCB
LXI D,INFILE
MVI B,16 ; 16 bytes
CALL MOVEB
;
; Load Environment Descriptor
;
LXI D,FCB ; Pt to FCB
CALL INITFCB
CALL F$OPEN ; Open file
JZ LOADENV
;
; Print File Not Found Message
; DE pts to FCB
;
PRFNF:
CALL EPRINT
DB CR,LF,'** File ',0
LXI D,FCB+1 ; Pt to file name
CALL PFN1
CALL EPRINT
DB ' NOT Found',0
RET
;
; Load Environment Descriptor
;
LOADENV:
CALL CODEND ; Pt to free space
CALL LOAD ; Load in file
SHLD FLIST ; Save ptr to file list
XCHG ; In DE also
CALL CODEND ; Check for proper amount
MOV A,D
SUB H
CPI 1 ; Must be 1 page
JZ LOADE1
ENVERR:
CALL EPRINT
DB CR,LF,'** Invalid Environment Descriptor',0
RET
LOADE1:
MOV A,L ; Low must be same
SUB E
JNZ ENVERR
LXI D,FCB ; Close environment descriptor
CALL F$CLOSE
;
; Load File List
;
LXI H,INFILE ; Copy into FCB
LXI D,FCB
MVI B,16
CALL MOVEB
; start changes here (Vers 1.1)
LXI H,FCB+9 ; Point to install file type
LXI D,COMNAME ; File type for single Install
MVI B,3 ; Character loop count
COMLP:
LDAX D ; Next character for file type
CMP M ; Next install file type char
JNZ MULT ; Match failed - install multiple
INX H
INX D
DCR B
JNZ COMLP ; Loop for all chars
LXI H,ZZ ; Point to EOF character
SHLD NXTCHR ; To stop install procedure
LHLD FLIST ; Get next avail free storage loc
SHLD FREE ; Place to load installed program
JMP SINGLE ; Process just a single program
; stop changes here (Vers 1.1)
MULT: LXI D,FCB ; Init FCB
CALL INITFCB
CALL F$OPEN ; Open file
JNZ PRFNF ; File not found
LHLD FLIST ; Pt to buffer
CALL LOAD ; Load file
MVI M,CTRLZ ; Ensure EOF mark
ZZ EQU $-1 ; Point to a convenient CTRL-Z (Vers 1.1)
SHLD FREE ; Set ptr to free space
XCHG ; Ptr in DE
LHLD BDOS+1 ; Get address of top of TPA
MOV A,H ; Adjust for CPR
SUI 10
SUB D ; See how many pages left
CPI NBLKS/2 ; Must be at least N/2 pages
JNC FUNCTION ; Perform function if OK
CALL EPRINT
DB CR,LF,'** Not Enough Free Memory for Installation'
DB CR,LF,' Make Installation File Shorter',0
RET
;
; Perform Installation Function
;
FUNCTION:
LHLD FLIST ; Pt to file list
PUSH H ; Save ptr
;
; Set all MSBs to Zero
;
CLEAN:
MOV A,M ; Clear MSB
ANI 7FH
MOV M,A
INX H ; Pt to next
CPI CTRLZ ; Done?
JNZ CLEAN
POP H ; Pt to first line
;
; Process Next Line
;
FCTNXT:
CALL SKSP ; Skip over leading spaces
SHLD NXTCHR ; Set ptr to next char
MOV A,M ; Get char
CPI ';' ; Comment?
JZ FCTCMT ; Process comment line
CPI CTRLZ ; Done?
JZ DONE
LXI D,FCB ; Pt to FCB
CALL FNAME ; Process file name
;
; Check for Non-Ambiguous File Name
;
SINGLE: ; Entry point to install a single program
LXI H,FCB+1 ; Pt to file name
MVI B,11 ; 11 chars
FCTAMB:
MOV A,M ; Check it
CPI '?'
JZ AMBERR
INX H ; Pt to next
DCR B ; Count down
JNZ FCTAMB
LXI D,FCB ; Init FCB and open file
CALL INITFCB
CALL F$OPEN
JZ FCTPRE ; If ok, process preamble
CALL PRFNF ; Print file not found
;
; Continue with Next Line
;
FCTCONT:
LHLD NXTCHR ; Pt to next char
FCTC1:
MOV A,M ; Skip to after LF or EOF
INX H
CPI LF
JZ FCTNXT ; Continue
CPI CTRLZ ; Done?
JNZ FCTC1
RET
;
; Print Ambiguous File Name Error
;
AMBERR:
CALL EPRINT
DB CR,LF,'** Ambiguous File Name Not Allowed: ',0
LXI D,FCB+1 ; Pt to file name
CALL PFN1
JMP FCTCONT ; Continue
;
; Process Comment Line
;
FCTCMT:
CALL CRLF ; New line
MVI C,1 ; Set tab count
FCTCMT1:
MOV A,M ; Get char
INX H ; Pt to next
CPI TAB ; Tabulate?
JZ FCTCMT2
CPI CR ; Done?
JZ FCTCONT
CPI LF ; Done?
JZ FCTCONT
CPI CTRLZ ; Done?
JZ FCTCONT
CPI ' ' ; Don't advance if less than space
JC FCTCMT1
INR C ; Add 1 to col pos
CALL COUT ; Print
JMP FCTCMT1 ; Resume
FCTCMT2:
MVI A,' ' ; Space over
CALL COUT
INR C ; Increment location
MOV A,C
ANI 7 ; Check for every 8
JNZ FCTCMT2
JMP FCTCMT1 ; Resume
;
; Process Preamble
;
FCTPRE:
CALL EPRINT
DB CR,LF,'** Installing File ',0
LXI D,FCB+1 ; Pt to file name
CALL PFN1
LHLD FREE ; Pt to free area
MVI B,2 ; Number of blocks to load
CALL LOADN ; Load them
MOV A,C ; How many blocks loaded?
CPI 2 ; Must be 2
JZ FCTPRE1
;
; Not a ZCPR3 Utility
;
NOTZ3:
CALL EPRINT
DB ' -- NOT a ZCPR3 Utility',0
JMP FCTCONT
;
; Ensure we have a Z3 utility
;
FCTPRE1:
LHLD FREE ; Pt to first byte
MOV A,M ; Get it
CPI 0C3H ; Must be a JMP
JNZ NOTZ3
INX H ; Pt to next key area
INX H
INX H
LXI D,ENVNAM ; Pt to environment name
MVI B,5 ; 5 chars
FCTPRE2:
LDAX D ; Get name char
CMP M ; Check
JNZ NOTZ3
INX H ; Pt to next
INX D
DCR B ; Count down
JNZ FCTPRE2
MOV A,M ; Get class
PUSH PSW
INX H ; Pt to first byte
XCHG ; DE pts to next byte
CALL CODEND ; Pt to environment descriptor
POP PSW
CPI 1 ; Class 1 (external) or 2 (internal)?
JZ CLASS1
;
; Environment Descriptor is Internal
; HL pts to Environment Descriptor and DE pts to next byte
;
LXI B,3+5+1 ; Skip to first valid byte
DAD B
MVI A,0 ; Compute number of bytes to copy
SUB C
MOV B,A ; Result in B
CALL MOVEB ; Copy into buffer
JMP FCTPRE3 ; Complete preamble processing
;
; Environment Descriptor is External
; HL pts to Environment Descriptor and DE pts to next byte
;
CLASS1:
LXI B,1BH ; Offset to environment descriptor address
DAD B
MOV A,M ; Get address
STAX D ; Store it
INX H ; Pt to next
INX D
MOV A,M ; Get high
STAX D ; Store it
;
; Complete Preamble Processing
; Write the new preamble directly to the target file (Vers 1.2)
;
FCTPRE3:
XRA A
STA FCB+32 ; Set current record to zero
LXI B,2 ; Record count
LHLD FREE ; Start at the beginning
CALL WRITEN ; Write 2 records
MOV A,C
ORA A ; Check that 2 records were written
JNZ PRFWE ; Report error and exit, if not.
LXI D,FCB ; Point to current FCB
CALL F$CLOSE ; Close the file
JMP FCTCONT ; Get the next one
;
; File Write Error
;
PRFWE:
CALL EPRINT
DB CR,LF,'** File Write Error',0
RET
;
; Set File Type Pted to by HL into DE if (DE)=' '
;
SETTYP:
LDAX D ; Get dest byte
CPI ' '
RNZ ; Already has type
MVI B,3 ; Copy
JMP MOVEB
;
; Load File Specified in FCB into Memory Starting at HL
; Check for Overflow
;
LOAD:
PUSH H ; Save address of next block
LHLD BDOS+1 ; Check for overflow
XCHG
POP H ; Get address of next block
MOV A,D
SUI 10 ; Adjust for CPR
SUB H
JNZ LOAD1
CALL EPRINT
DB CR,LF,'** Memory Overflow',0
POP PSW ; Clear stack
RET
;
; Load next block - HL pts to location
;
LOAD1:
LXI D,FCB ; Pt to FCB
CALL F$READ ; Read next block
RNZ ; Done if EOF
LXI D,TBUFF ; Pt to buffer area
XCHG ; Flip source and dest
MVI B,128 ; 128 bytes
CALL MOVEB
LXI H,128 ; Pt to next
DAD D
JMP LOAD ; Continue
;
; Load B blocks into Memory Pted to by HL
; Return count in C
;
LOADN:
MVI C,0 ; Set count
LOADN1:
LXI D,FCB ; Pt to fcb
CALL F$READ ; Read next block
RNZ ; Done if EOF
INR C ; Increment count
PUSH B ; Save BC
LXI D,TBUFF ; Pt to buffer area
XCHG ; Flip source and dest
MVI B,128 ; 128 bytes
CALL MOVEB
LXI H,128 ; Pt to next
DAD D
POP B ; Restore BC
DCR B ; Count down
JNZ LOADN1
RET
;
; Store C blocks from Memory Pted to by HL
;
WRITEN:
PUSH B ; Save count
LXI D,TBUFF ; Copy into TBUFF
MVI B,128 ; 128 bytes
CALL MOVEB
LXI B,128 ; Pt to next
DAD B
POP B ; Get count
LXI D,FCB ; Pt to fcb
CALL F$WRITE ; Write next block
RNZ ; Done if EOF
DCR C ; Decrement count
JNZ WRITEN
RET
;
; Write Completion Message
;
DONE:
CALL EPRINT
DB CR,LF,'** Installation Complete **',0
RET
;
; Buffers
;
COMNAME:
DB 'COM' ; File type for COM file
DEFENV:
DB 'ENV' ; Default file type for Environment Descriptor
DEFINS:
DB 'INS' ; Default file type for Installation File
INFILE:
DS 16 ; FCB save area
FLIST:
DS 2 ; Address of file list
FREE:
DS 2 ; Address of scratch area to read into
NXTCHR:
DS 2 ; Ptr to next char to process
ENVNAM:
DB 'Z3ENV' ; Environment Descriptor ID