; ; Program: CD ; Version: 2.4 ; Author: Richard Conn ; Date: 18 Aug 83 ; Previous Versions: 2.3 (6 Jan 83), 2.2 (19 Dec 82), 2.1 (7 Dec 82) ; Derivation: CD.MAC was derived in concept from CD.C, Version 1.2 ; vers equ 24 ; ; This program is Copyright (c) 1982, 1983 by Richard Conn ; All Rights Reserved ; ; ZCPR2 and its utilities, including this one, are released ; to the public domain. Anyone who wishes to USE them may do so with ; no strings attached. The author assumes no responsibility or ; liability for the use of ZCPR2 and its utilities. ; ; The author, Richard Conn, has sole rights to this program. ; ZCPR2 and its utilities may not be sold without the express, ; written permission of the author. ; ; ; CD is designed to allow the user to quickly change to another ; working directory (CD=Change Directory). ; Intended to be small in size, CD accepts a command of the ; following forms: ; ; CD // <-- Print Help Message ; CD dir or CD dir: <-- Log Into Directory ; ; ; CP/M Constants ; cpm equ 0 ; Warm Boot Address udflag equ cpm+4 ; User/Disk Flag fcb equ 5ch ; Location of Default FCB tbuff equ 80h ; Temporary Input Line Buffer cr equ 0dh lf equ 0ah ; ; Externals ; ext zgpins ; init ZCPR2 buffers ext zdnfind ; used to determine directory user/disk ext zmcptr ; MC buffer ptr ext logud ; log in user/disk ext retud ; return current user/disk ext initfcb ; init FCB ext f$exist ; file exist test ext print ; print routine ext cout ; char output ext crlf ; new line ext inline ; input line editor, external buffer ext cin ; char input ext codend ; end of code ; ; Branch to Start of Program ; jmp start ; ;****************************************************************** ; ; SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format ; ; This data block precisely defines the data format for ; initial features of a ZCPR2 system which are required for proper ; initialization of the ZCPR2-Specific Routines in SYSLIB. ; ; ; EXTERNAL PATH DATA ; EPAVAIL: DB 0FFH ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES) EPADR: DW 40H ; ADDRESS OF EXTERNAL PATH IF AVAILABLE ; ; INTERNAL PATH DATA ; INTPATH: DB 0,0 ; DISK, USER FOR FIRST PATH ELEMENT ; DISK = 1 FOR A, '$' FOR CURRENT ; USER = NUMBER, '$' FOR CURRENT DB 0,0 DB 0,0 DB 0,0 DB 0,0 DB 0,0 DB 0,0 DB 0,0 ; DISK, USER FOR 8TH PATH ELEMENT DB 0 ; END OF PATH ; ; MULTIPLE COMMAND LINE BUFFER DATA ; MCAVAIL: DB 0FFH ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE? MCADR: DW 0FF00H ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE ; ; DISK/USER LIMITS ; MDISK: DB 4 ; MAXIMUM NUMBER OF DISKS MUSER: DB 31 ; MAXIMUM USER NUMBER ; ; FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK ; DOK: DB 0FFH ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES) UOK: DB 0FFH ; ALLOW USER CHANGE? (0=NO, 0FFH=YES) ; ; PRIVILEGED USER DATA ; PUSER: DB 10 ; BEGINNING OF PRIVILEGED USER AREAS PPASS: DB 'chdir',0 ; PASSWORD FOR MOVING INTO PRIV USER AREAS DS 41-($-PPASS) ; 40 CHARS MAX IN BUFFER + 1 for ending NULL ; ; CURRENT USER/DISK INDICATOR ; CINDIC: DB '$' ; USUAL VALUE (FOR PATH EXPRESSIONS) ; ; DMA ADDRESS FOR DISK TRANSFERS ; DMADR: DW 80H ; TBUFF AREA ; ; NAMED DIRECTORY INFORMATION ; NDRADR: DW 00000H ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY NDNAMES: DB 64 ; MAX NUMBER OF DIRECTORY NAMES DNFILE: DB 'NAMES ' ; NAME OF DISK NAME FILE DB 'DIR' ; TYPE OF DISK NAME FILE ; ; REQUIREMENTS FLAGS ; EPREQD: DB 0FFH ; EXTERNAL PATH? MCREQD: DB 0FFH ; MULTIPLE COMMAND LINE? MXREQD: DB 0FFH ; MAX USER/DISK? UDREQD: DB 0FFH ; ALLOW USER/DISK CHANGE? PUREQD: DB 0FFH ; PRIVILEGED USER? CDREQD: DB 0FFH ; CURRENT INDIC AND DMA? NDREQD: DB 0FFH ; NAMED DIRECTORIES? Z2CLASS: DB 0 ; CLASS 0 DB 'ZCPR2' DS 10 ; RESERVED ; ; END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA ; ;****************************************************************** ; stfile: db 0 db 'ST ' ; file name db 'COM' ; file type ds 4 ds 16 ds 4 ; 36 bytes total ; ; Start of Program ; start: call zgpins ; install ZCPR2 variables call print ; print banner db 'CD, Version ' db vers/10+'0','.',(vers mod 10)+'0',0 lxi h,tbuff ; pt to input line mov a,m ; get input line size inx h ; pt to first char push h ; save ptr to first char add l ; pt to after last char mov l,a mov a,h aci 0 mov h,a ; hl pts to after last char mvi m,0 ; store ending zero pop h ; pt to first char lxi d,cbuff ; temp storage for line ; ; Copy input line into temporary buffer ; start0: mov a,m ; get byte stax d ; put byte inx h ; pt to next inx d ora a ; end of line? jnz start0 ; ; Skip to first non-blank and process if Help requested ; lxi h,cbuff ; pt to first char sblank: mov a,m ; pt to char inx h ; pt to next cpi ' ' ; ? jz sblank dcx h ; pt to first non-blank ora a ; print directory info? jz help cpi '/' ; help option? jnz cd ; change dir processing if not help ; ; Print Help Message ; help: call print db cr,lf,' CD is a ZCPR2 named directory move utility' db cr,lf,'(CD=Change Directory). Command Forms are:' db cr,lf,' CD or CD // <-- Print Help Message' db cr,lf,' CD dir or CD dir: <-- Log Into Dir' db cr,lf,0 ret ; ; Scan Line for Colon and append Colon if none present ; cd: push h ; save ptr to first char for later scolon: mov a,m ; get char ora a ; eol? jz pcolon ; append colon cpi ' ' ; ? jz pcolon ; append colon cpi ':' ; colon? jz cd2 ; continue processing inx h ; pt to next char jmp scolon pcolon: mvi m,':' ; place colon at end of token inx h ; pt to next char mvi m,0 ; place ending zero ; ; Extract User/Disk Numbers ; cd2: call retud ; get current user/disk mov a,b ; store disk sta cdisk mov a,c ; store user sta cuser pop h ; get ptr to first char xra a ; do not allow du: form call zdnfind ; extract user/disk info jnz cd3 call print db cr,lf,'Dir Name Not Found',0 ret ; ; Set Current User/Disk ; cd3: mov a,b ; get disk number cpi 0ffh ; current? jnz setd ; set disk if not lda cdisk ; get current disk inr a ; increment because of ZDNFIND offset setd: mov b,a ; disk in B lda mdisk ; max disk number cmp b ; must be less jnc setd1 ; error if selected > max uderr: call print db cr,lf,'Dir Range Error -- Abort',0 ret setd1: mov a,c ; get user number cpi 0ffh ; current? jnz setu ; set user if not lda cuser ; get current user setu: mov c,a ; user in C lda muser ; max user number cmp c ; must be less jc uderr ; error if selected > max call pass ; ask for password if not priv cding into priv dcr b ; adjust disk to 0 to n-1 lda mcavail ; multiple commands available? ora a ; 0=no jz login call logud ; log into new directory lxi d,stfile ; check for presence of startup file call initfcb ; init FCB call f$exist ; does it exist? jz login call zmcptr ; get ptr to next char in MC line dcx h ; back up two chars lda stfile+2 mov m,a dcx h lda stfile+1 ; store new file name mov m,a lhld mcadr ; get address of line mov a,m ; get low-order byte dcr a ; back up 2 chars dcr a mov m,a ; set new count login: mov a,c ; user in A ora a ; clear carry rlc ; move user into high nybble rlc rlc rlc ora b ; mask in new disk sta udflag ; set loc 4 jmp cpm ; ; Ask for password if non-priveleged user (cuser) is trying to CD into ; a priveleged user area (=>puser) ; pass: push b ; save desired user/disk lda puser ; get priv user number mov b,a ; ... in B lda cuser ; get current user cmp b ; is current user priveleged? pop b rnc ; done if so lda puser ; see if desired to move into priveleged user area dcr a ; just under priveleged user area cmp c ; is C >= puser? rnc ; done if PUSER-1 >= desired user ; ; Non-priv wants to CD into Priv ... ask password ; push b ; save desired user/disk call print db cr,lf,'Access Password? ',0 call codend ; pt to scratch area xra a ; no echo call inline ; input line editor lxi d,ppass ; pt to password stored scomp: ldax d ; get byte cmp m ; compare jnz nomatch inx h ; pt to next inx d ora a ; end of strings? jnz scomp call print db cr,lf,'** Access Granted **',0 pop b ; match -- return normally ret nomatch: pop b ; clear BC pop h ; clear stack call print db cr,lf,'** Invalid Password -- Access Denied **',0 ret ; ; Buffers ; cuser: ds 1 ; current user cdisk: ds 1 ; current disk cbuff: ds 250 ; command line buffer end