home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
beehive
/
zcat
/
ldr15.lbr
/
LDR15.MQC
/
LDR15.MAC
Wrap
Text File
|
1991-01-30
|
15KB
|
656 lines
;
; PROGRAM: LDR
; AUTHOR: RICHARD CONN
; VERSION: 1.0
; DATE: 27 FEB 84
; PREVIOUS VERSIONS: 0.1 (3 Feb 84), 0.2 (22 Feb 84), 1.1 (28 Sep 84)
;
VERSION EQU 15 ; Search the path for file to load.
; Joe Wright 2 June 86
;
;VERSION EQU 14 ; V1.4 by steve a. kitahata -- 17-mar-86
; This version modified to correct problem in
; The 'load:' routine when loading a package
; That is too large, specifically the tcap.
; Previous versions cleared the first 128 bytes
; Of the memory buffer, and appended a 3-byte
; Error code routine, resulting in whatever
; Resided after the tcap buffer to be zapped.
;version equ 13 ; This version responds to the quiet flag.
; 11 march 85 joe wright
;VERSION EQU 12 ; Version 1.2 by Dave Lucky 31 Dec 84
; This version modified to correct exit regs from
; Sdload subroutine. the source and destination
; Registers on entry were hl and de, respectively.
; On exit, they were de and hl. the calling routine
; (setdata) went amuck when calculating number of ndr
; Records using bogus de. also, corrected the setdata
; Routine from using the incorrect address of the ndr
; Entry size field as well as its contents acquired
; From the getndr routine.
;VERSION EQU 11 ; Version 1.1 by Joe Wright 28 Sept 84
; This version modified to allow loading the .env
; File the first time, when there is no environment
; Descriptor in memory. the program now takes
; The environment address from the .env file so
; That subsequent files are also loaded correctly.
; Ie. ldr sys.env,sys.rcp,etc. note that .env must
; Be the first declared file until ldr is installed
; To your environment. jww
;VERSION EQU 10 ; Release version
EXTENV EQU 1 ; 1 for external environ, 0 for internal environ
;
; LDR is a general-purpose package loader for ZCPR3. It is
; invoked by the following form:
;
; LDR <list of packages>
;
; For example:
; LDR DEFAULT.RCP,SYSIO.IOP
;
; No default file types are assumed on the list of packages, and
; each package specified must be unambigous and have a type of RCP or IOP
; (for Resident Command Package or Input/Output Package). LDR
; checks to make sure that the files are valid packages and then loads
; them into memory at the correct locations, checking for package boundary
; overflow.
;
;
;
; ZCPR3 Header
;
MACLIB Z3BASE.LIB
;
; System Equates
;
BDOS EQU 5
FCB EQU 5CH
TBUFF EQU 80H
RCPFLG EQU 1 ; Package type is rcp
IOPFLG EQU 2 ; Package type is iop
FCPFLG EQU 3 ; Package type is fcp
NDRFLG EQU 4 ; Package type is ndr
ENVFLG EQU 5 ; Package type is env
TCAPFLG EQU 6 ; Package type is z3t
CR EQU 0DH
LF EQU 0AH
EXT Z3INIT,ENVPTR,GETQUIET
EXT PFIND,RETUD,GETUD,PUTUD,LOGUD
EXT GETRCP,GETFCP,GETIOP,GETNDR
EXT F$OPEN,F$CLOSE,F$READ
EXT PRINT,PFN2
EXT HMOVB,MOVEB,FILLB
EXT CLINE,SKSP,ZFNAME
;
; Environments
;
ORIGIN:
;
IF EXTENV ; If external environment ...
;
; External Environment Definition
;
JMP Z3LDR
DB 'Z3ENV' ; This is an environment
DB 1 ; Class 1 environment (external)
ENVLOC:
DW Z3ENV ; Ptr to environment
Z3LDR:
LHLD ENVLOC ; Hl pts to environment
ELSE ; If internal environment ...
;
; Internal Environment Definition
;
MACLIB SYSENV.LIB
ENVLOC:
JMP Z3LDR
SYSENV ; Define environment
Z3LDR:
LXI H,ENVLOC ; Hl pts to environment
ENDIF
;
; Beginning of LDR
;
CALL Z3INIT ; Initialize environment pointer
CALL BANNER ; Print banner
LXI H,TBUFF ; Pt to command line
CALL CLINE ; Save command line as string
CALL SKSP ; Skip over spaces
MOV A,M ; Get offending char
CPI '/' ; Help?
JZ HELP
ORA A ; Help?
JZ HELP
;
; Main Loop - HL pts to next file name in list
;
Z3LDR1:
LXI D,FCB ; Pt to fcb
CALL ZFNAME ; Extract file name and data
INX D ; Pt to file name
;
CALL GETQUIET
JNZ Q0
CALL PRINT
DB CR,LF,' Loading ',0
CALL PFN2 ; Print file name
Q0: PUSH H ; Save ptr
CALL PKLOAD ; Load file
POP H ; Get ptr
MOV A,M ; Get char
INX H ; Pt to next char
CPI ',' ; Another file in list?
JZ Z3LDR1
RET
;
; Print Help Message
;
HELP:
CALL GETQUIET
RNZ
CALL PRINT
DB CR,LF,' LDR Syntax:'
DB CR,LF,' LDR <list of packages/data files>'
DB CR,LF,' where entries in the list may be any of these types:'
DB CR,LF
DB CR,LF,' FCP - Flow Cmnd Package ENV - Z3 Environ'
DB CR,LF,' IOP - Input/Output Package NDR - Z3 Named Dir'
DB CR,LF,' RCP - Resident Cmnd Package Z3T - Z3TCAP Entry'
DB CR,LF,LF,' The package list may have DU: or DIR: references.'
DB CR,LF,' If they do not, the path is searched for the package.'
DB CR,LF,LF,' The ENV file must be first if LDR is not installed.'
DB CR,LF,0
RET
;
; Load package named in FCB
;
PKLOAD:
CALL SETDATA ; Load data buffers from environment in case of change
CALL CKTYPE ; Check for valid file type
JZ TYPERR ; Abort if error
CALL OPEN ; Open file, read in first block, check for valid
JZ GETUD ; Abort if error
; Check if ENV. If so, get Z3ENV and call z3init
PUSH H ; Save package pointer from cktype
LXI D,FCB+9 ; Fcb type
LXI H,ENVTYP ; Env?
CALL COMPTYP ; Compare types
POP H ; Get package pointer
JNZ PKLD ; Not env, proceed normally
;
; File type is ENV. Get Z3ENV address from file and re-initialize
;
LXI H,TBUFF ; First sector in tbuff
LXI D,1BH ; Offset to z3env
DAD D ; Point hl to it
MOV E,M ; Get z3env
INX H
MOV D,M ; Got it
XCHG ; In hl
CALL Z3INIT ; Set new environment
PKLD: CALL LOAD ; Load package into memory at correct location
CALL CLOSE ; Close up process
CALL GETUD ; Return home
;
; Check for IOP and return if not
;
LDA PKTYPE ; Init package if iop
CPI IOPFLG
RNZ
;
; Init IOP
;
LHLD PACKADR ; Get address
LXI D,9 ; 4th jmp into it
DAD D
PUSH H ; Address on stack
RET ; "call" routine and return to OS
;
; Load Data Buffers from Environment
;
SETDATA:
LHLD ENVPTR ; Get environment descriptor address
SHLD ENVADR
LXI D,80H ; Pt to z3tcap
DAD D
SHLD TCAPADR
CALL GETRCP ; Get rcp data
LXI D,RCPDATA ; Load
CALL SDLOAD
CALL GETIOP ; Get iop data
LXI D,IOPDATA ; Load
CALL SDLOAD
CALL GETFCP ; Get fcp data
LXI D,FCPDATA ; Load
CALL SDLOAD
LXI H,NDRIDAT ; Init ndr data in case no entry
LXI D,NDRDATA
MVI B,9 ; 9 bytes (1-jmp, 5-id, 2-adr, 1-size)
CALL MOVEB
CALL GETNDR ; Get ndr data
MOV B,A ; Save entry count ;1284dl
MOV A,H ; No ndr data?
ORA L
RZ
MOV A,B ; Restore entry count ;1284dl
CALL SDLOAD ; With de -> ndrdata ;1284dl
PUSH D ; Save ptr to entry count ;1284dl
MVI H,0 ; Hl = value
MOV L,A ; A = entry count
DAD H ; *2
MOV D,H ; De = value * 2
MOV E,L
DAD H ; *4
DAD H ; *8
DAD H ; *16
DAD D ; *18
MOV A,H ; /128
RLC
ANI 0FEH
MOV H,A
MOV A,L
RLC
ANI 1
ORA H ; A = value * 18 / 128
INR A ; +1
POP D ; Get ptr
STAX D ; Save value
RET
;
; Load 3 bytes pted to by HL into memory pted to by DE+6
;
; Input Regs: ;1284DL
; HL = Source ;1284DL
; DE = Destination ;1284DL
; ;1284DL
; Output Regs: ;1284DL
; HL = Source ;1284DL
; DE = Destination+8 ;1284DL
; ;1284DL
SDLOAD:
PUSH H ; Save ptr to data
LXI H,6 ; Add 6 to de to pt to proper buffer
DAD D ; Hl pts to buffer
POP D ; De contains address
MOV M,E ; Store address
INX H
MOV M,D
INX H
MOV M,A ; Store size data
XCHG ; Swap source / destination regs ;1284dl
RET
;
; Print Banner
;
BANNER:
CALL GETQUIET
RNZ
CALL PRINT
DB CR,LF,'ZCPR3 LDR, Version '
DB (VERSION/10)+'0','.',(VERSION MOD 10)+'0',0
RET
;
; Check for Valid Package File Type
; Return with Zero Flag Set if error
; If validated, PKTYPE contains package type and HL pts to data
;
CKTYPE:
LXI D,FCB+9 ; Pt to file type
LXI H,RCPTYP ; See if rcp
MVI B,RCPFLG ; Rcp code
CALL COMPTYP ; Compare
JZ CKTOK ; Ok if match
LXI H,IOPTYP ; See if iop
MVI B,IOPFLG ; Iop code
CALL COMPTYP ; Compare
JZ CKTOK ; Ok if match
LXI H,FCPTYP ; See if fcp
MVI B,FCPFLG ; Fcp code
CALL COMPTYP ; Compare
JZ CKTOK ; Ok if match
LXI H,NDRTYP ; See if ndr
MVI B,NDRFLG ; Ndr code
CALL COMPTYP ; Compare
JZ CKTOK ; Ok if match
LXI H,ENVTYP ; See if env
MVI B,ENVFLG ; Env code
CALL COMPTYP ; Compare
JZ CKTOK ; Ok if match
LXI H,TCAPTYP ; See if z3tcap
MVI B,TCAPFLG ; Z3t code
CALL COMPTYP ; Compare
JZ CKTOK
MVI B,0 ; Invalid type
CKTOK:
MOV A,B ; Set package type
STA PKTYPE
ORA A ; Set nz if no error
RET
COMPTYP:
PUSH D ; Save regs
PUSH B
MVI B,3 ; 3 bytes
COMPT1:
LDAX D ; Get fcb char
ANI 7FH ; Mask
CMP M ; Compare
JNZ COMPT2
INX H ; Pt to next
INX D
DCR B ; Count down
JNZ COMPT1
COMPT2:
POP B ; Restore regs
POP D
RET
TYPERR:
CALL GETQUIET
RNZ
CALL PRF ; Print file name and string
DB ' is not a Valid Type',0
RET
;
; If DU reference is explicit, log into it. If not, search path.
; Open File and Load First Block into TBUFF
; Validate Package Structure and Return with Zero Flag Set if Error
; On input, HL pts to data buffer
; If no error, HL points to load address and B is number of 128-byte
; pages allowed in buffer
;
OPEN:
CALL PUTUD ; Save current DU
CALL RETUD ; Get current DU in BC
LDA FCB ; Get disk
ORA A ; Default?
JNZ EXPLICIT ; Explicit reference, do it.
LXI D,FCB
DCR A ; A non-zero
CALL PFIND ; Search current DU, then along path
JZ FNFERR ; Can't find it
JMP LOGIT
EXPLICIT:
MOV B,A ; Disk in b (a=1)
DCR B ; Adjust to a=0
OPEN0:
LDA FCB+13 ; Get user
MOV C,A ; User in c
LOGIT:
CALL LOGUD ; Log into ud
XRA A ; Clear disk
STA FCB
;
; Disallow Ambiguous File Name
;
CALL AMBCHK ; Check for ambiguous file name
JZ AMBERR ; Abort if any ambiguity
;
; Open File
;
LXI D,FCB ; Pt to fcb
CALL F$OPEN ; Open file
JNZ FNFERR ; Abort if file not found
;
; Read First 128-byte Block
;
CALL F$READ ; Read in first block
JNZ FEMPTY ; Abort if file empty
;
; Validate Package
; Package Data Area is structured as follows:
; DB numjmps ; number of jumps at beginning of package
; DB 'Z3xxx' ; package ID (always 5 chars)
; DW address ; address of memory buffer
; DB size ; number of 128-byte blocks in memory buffer
;
XCHG ; De pts to package data
LDAX D ; Get number of jumps
INX D ; Pt to package id
MOV B,A ; Jump count in b
;
; Validate Package - MUST have proper number of JMPs
;
LXI H,TBUFF ; Check jumps
OPEN1:
MOV A,B ; At limit of jumps?
ORA A
JZ OPEN2
DCR B ; Count down
MOV A,M ; Check for jmp
CPI 0C3H ; Jmp?
JNZ STRERR ; Structure error
INX H ; Pt to next
INX H
INX H
JMP OPEN1
;
; Check Package ID - must match
;
OPEN2:
MVI B,5 ; Check package id
OPEN3:
LDAX D ; Get byte
CPI ' ' ; No id if space
JZ OPEN4
CMP M ; Check
JNZ STRERR ; Structure error
OPEN4:
INX D ; Pt to next
INX H
DCR B ; Count down
JNZ OPEN3
;
; Extract Package Address
;
LDAX D ; Get low-order address
MOV L,A ; Put in hl
INX D
LDAX D ; Get high-order address
MOV H,A
INX D
;
; Check for Valid Package Address
;
MOV A,H ; Must not be zero
ORA L
JZ ADRERR
;
; Extract 128-byte Block Count
;
LDAX D ; Get block count
MOV B,A ; Put in b
XRA A ; Set flags
DCR A ; Nz
RET
;
; Ambiguous File Name Check
; Returns with Z Set if Ambiguous
;
AMBCHK:
LXI D,FCB+1 ; Check for ambiguous file name
MVI B,11 ; 11 chars
AMBCHK1:
LDAX D ; Get char
ANI 7FH ; Mask
CPI '?'
RZ
INX D ; Pt to next
DCR B ; Count down
JNZ AMBCHK1
DCR B ; Set nz flag
RET
;
; Error Messages
;
AMBERR:
CALL GETQUIET
JNZ ERRET
CALL PRF ; Print file name and message
DB ' is Ambiguous',0
ERRET:
XRA A ; Set error code
RET
ADRERR:
CALL GETQUIET
JNZ ERRET
CALL PRF ; Print file name and message
DB ' Not Known to Environ',0
JMP ERRET
FNFERR:
CALL GETQUIET
JNZ ERRET
CALL PRF ; Print file name and message
DB ' Not Found',0
JMP ERRET
FEMPTY:
CALL GETQUIET
JNZ ERRET
CALL PRF ; Print file name and message
DB ' Empty',0
JMP ERRET
STRERR:
CALL GETQUIET
JNZ ERRET
CALL PRF ; Print file name and message
DB ' Contains a Format Flaw',0
JMP ERRET
PRF:
CALL PRINT
DB CR,LF,' File ',0
LXI D,FCB+1
CALL PFN2
JMP PRINT
;
; Close File
;
CLOSE:
LXI D,FCB ; Pt to fcb
JMP F$CLOSE ; Close file
;
; Load File Into Buffer
;
LOAD:
SHLD PACKADR ; Save package address in case of error
XCHG ; De pts to buffer, b = max blocks
LOAD1:
PUSH B ; Save count
LXI H,TBUFF ; Pt to buffer
MVI B,128
CALL HMOVB ; Copy tbuff into buffer
PUSH D ; Save ptr to next block in buffer
LXI D,FCB ; Pt to fcb
CALL F$READ ; Read next block
POP D ; Get ptr
POP B ; Get count
RNZ ; Done if nz
DCR B ; Count down
JNZ LOAD1
;
; Buffer Full
;
CALL GETQUIET
JNZ Q1
CALL PRF
DB ' is too Large',0
Q1: LHLD PACKADR ; Clear package
MVI B,128 ; Nops
XRA A
CALL FILLB
; lxi b,128 ; pt to after last NOP [sak]
LXI B,128-ERCSIZ ; [sak]
DAD B
MVI B,3 ; Copy 3 bytes
XCHG ; De pts to empty space
LXI H,ERCODE ; Store error code
JMP MOVEB
;
; Error Code to be Stored if Package Load Fails
;
ERCODE:
XRA A ; 3 bytes
DCR A ; A=0ffh and nz flag set
RET
ERCSIZ EQU $-ERCODE ; [sak]
;
; Buffers
;
NDRIDAT:
DB 0 ; No jmps
DB ' ' ; No id stored
DW 0 ; Address
DB 0 ; (z3ndirs*18)/128+1 size
RCPTYP:
DB 'RCP' ; File type of rcp file
RCPDATA:
DB 0 ; 0 jmps
DB 'Z3RCP' ; Id
DW 0 ; Address
DB 0 ; Size
IOPTYP:
DB 'IOP' ; File type of iop file
IOPDATA:
DB 16 ; 16 jmps
DB 'Z3IOP' ; Id
DW 0 ; Address
DB 0 ; Size
FCPTYP:
DB 'FCP' ; File type of fcp file
FCPDATA:
DB 0 ; 0 jmps
DB 'Z3FCP' ; Id
DW 0 ; Address
DB 0 ; Size
NDRTYP:
DB 'NDR' ; File type of ndr file
NDRDATA:
DB 0 ; No jmps
DB ' ' ; No id stored
DW 0 ; Address
DB 0 ; (z3ndirs*18)/128+1 size
ENVTYP:
DB 'ENV' ; File type of env file
ENVDATA:
DB 1 ; 1 jmp
DB 'Z3ENV' ; Id
ENVADR:
DW 0 ; Address
DB 2 ; 2 128-byte blocks max
TCAPTYP:
DB 'Z3T' ; File type of z3tcap file
TCAPDATA:
DB 0 ; No jmps
DB ' ' ; No id stored
TCAPADR:
DW 0 ; Address
DB 1 ; 1 128-byte block max
PKTYPE:
DS 1 ; Package type (0=error)
PACKADR:
DS 2 ; Package address
END