; ; Program: ALIAS ; Author: Richard Conn ; Version: 1.1 ; Date: 10 June 84 ; Previous Versions: 1.0 (5 Mar 84) ; ;version equ 11 ; Don't know the date ; ; Module: ALIAS0.Z80 ; Author: Joe Wright ; Date: 24 August 90 ; Version: 1.2 ; version equ 12 ; August 24, 1990 ; ; At 1.2, ALIAS has been changed such that the module which ; is written to disk as the alias (this one) is the first module ; in the link order. ; ; Assemble ALIAS0.Z80 and ALIAS1.Z80 to REL with your favorite ; M80, ZMAC or Z80ASM. Then link as follows: ; ; ZML ALIAS=ALIAS0,ALIAS1 ; or SLRNKP ALIAS/N,/A:100/J,ALIAS0,ALIAS1,/E ; ; The purpose of ALIAS0 is to load the Command Line Buffer with ; a command line stored within ALIAS0, extracting parameters using ; the SUBMIT file convention ($n) as they are referenced in the ; new command line. Upon successful build, ALIAS0 runs the new ; command line by simply returning to ZCPR3. ; ; Basic Equates ; no equ 0 yes equ not no ; ; ALIAS0 can be assembled and linked to a COM file creating a ; stand-alone alias for testing or some other purpose. ; alone equ no ; ; We may support Recursive Mode at some later date. ; recursive equ no ; Include VALIAS recursion code ; tbuff equ 80h ; Command tail if not alone public alias0, start, z3eadr extrn alias1 endif ; alias0: if alone jp start ; Execute this module else jp alias1 ; Execute ALIAS1 endif db 'Z3ENV' ; This is a ZCPR3 Utility db 1 ; External Environment Descriptor z3eadr: dw 0 ; Installed by Z33+ if recursive db 'F' recur: db 0 ; Normal Mode (0ffh is Recursive) endif start: ld hl,(z3eadr) ; Pt to ZCPR3 environment ld a,h or a ret z ; Not installed, return jp start1 ; Skip command line buffer ; ; ALIAS ID at START+9 ; db 'Z3 ALIAS' ; ; Internal Command Line Buffer. This buffer address can be ; determined from START+17, where the value of START is ; obtained from the 2nd and 3rd bytes of ALIAS0. ; clbuf: db 0 ; Set to empty ds 256-($-clbuf) ; Allow 256 bytes ; ; Resume ALIAS0 ; start1: ld hl,clbuf ; Pt to buffer ld de,endcod ; Pt to free space in which to build new line ; ; Process Next Char from Target Command Line ; nxtchar: ld a,(hl) ; Get next char or a ; End of line? jp z,done cp '$' ; Possible passed parameter? jr z,param ; Process parameter ld (de),a ; Store next char inc hl ; Pt to next inc de jr nxtchar ; Next character ; ; Process Possible Parameter ; param: ld bc,nxtchar ; Establish return address push bc ; ... on stack ; inc hl ; Get parameter char ld a,(hl) call caps ; Capitalize cp '*' ; Entire tail? jp z,paraml cp 'D' ; Current disk? jp z,paramd cp 'U' ; Current user? jp z,paramu cp 'F' ; System Filename.Typ? jr z,paramf cp 'N' ; System Filename? jr z,paramn cp 'T' ; System Typ? jr z,paramt sub '0' ; Convert to binary jp c,noparam ; Something less than '0' cp 10 jp nc,noparam ; Something greater than '9' or a ; Parameter 0 = original name jp z,oname ld b,a ; Count in B (1 or more) inc hl ; Pt to next char push hl ; Save ptr ld hl,tbuff+1 ; Pt to input line (a Space) ; ; Advance to Desired Parameter ; param1: call skip ; Skip to 'next' parameter or a ; EOL? jr z,paramx ; No more parameters djnz param1 ; Advance HL until B=0 ; ; Extract Parameter Into Target Buffer ; param2: ld a,(hl) ; Get char cp ' '+1 ; Cy if Space or Null jr c,paramx ld (de),a ; Store char inc hl ; Advance inc de jr param2 ; ; Resume Processing of Target Command ; paramx: pop hl ; Restore ptr to next char ret ; Resume at next char ; ; Parameter is for System Filename.typ ; paramf: call getfnum ; Get file number push hl ; Save ptr to next char call ptfn ; Set ptr to file name call putn ; Put file name ld a,'.' ; Dot ld (de),a inc de call putt ; Put file type pop hl ; Restore ptr ret ; ; Parameter is for System Filename ; paramn: call getfnum ; Get file number push hl ; Save ptr to next char call ptfn ; Set ptr to file name call putn ; Put file name pop hl ; Restore ptr ret ; ; Parameter is for System Typ ; paramt: call getfnum ; Get file number push hl ; Save ptr to next char call ptfn ; Set ptr to file name ld a,8 ; Add 8 to get to file type call addah call putt ; Put file type pop hl ; Restore ptr ret ; ; Get File Number (0 to 4) Now includes SH.VAR as File 0. ; If valid number, return with value in A and HL pting to next char ; If not valid, return with Z and HL pting to next char (the number) ; getfnum: inc hl ; Pt to number ld a,(hl) ; Get char sub '0' ; Convert to binary (0..4) jr c,getfne ; Error if less cp 5 ; Range? jr nc,getfne ; Error if more inc hl ; Pt to next char ret ; NZ and Cy from CP 5 (Ok) getfne: pop bc ; Pop this CALL off the stack ret ; 'Return' to NXTCHAR: ; ; Pt to File Name whose Number (0..4) is in A ; ptfn: ld b,a ; Save file number call getfn0 ; Pt to SH.VAR entry ld a,b ; Get file number or a ret z ; File 0 ld bc,11 ; Size of file name and type ptfn1: add hl,bc ; Pt to next dec a ; Count down jr nz,ptfn1 ret ; ; Put File Name pted to by HL ; putn: ld b,8 ; 8 chars jr putc ; ; Put File Type pted to by HL ; putt: ld b,3 ; 3 chars ; ; Copy chars from HL to DE for up to 8 bytes - flush if space ; putc: ld a,(hl) ; Get next char cp ' ' ; Skip spaces jr z,putc1 ld (de),a ; Put next char inc de ; Pt to next putc1: inc hl ; Pt to next djnz putc ret ; ; Parameter is for Disk Letter ; paramd: call retud ; Get DU in BC ld a,b ; Get disk letter add a,'A' ; Convert to ASCII ld (de),a ; Store char inc de ; Pt to next inc hl ; Pt to next char ret ; ; Parameter is for User Number ; paramu: call retud ; Get DU in BC ld a,c ; Get user number ld b,10 ; Compute 10's ld c,'0' pmu1: sub b ; Subtract 10's jr c,pmu2 inc c ; Increment 10's jr pmu1 pmu2: add a,b ; Add B back in add a,'0' ; Convert to ASCII ld b,a ; 10's in C, 1's in B ld a,c cp '0' ; No leading 0's jr z,pmu3 ld (de),a ; Store char inc de ; Pt to next pmu3: ld a,b ; Get 1's ld (de),a ; Store char inc de ; Pt to next inc hl ; Pt to next char ret ; ; Parameter is command line tail ; paraml: inc hl ; Pt to char after parameter letter push hl ; Save ptr to parameter ld hl,tbuff+1 ; Pt to tail ld a,(hl) or a jr z,paramt2 ; No tail, Quit inc hl ; Skip the first space paramt1: ld a,(hl) ; Copy tail into line inc hl ; Pt to next or a ; End of tail? jr z,paramt2 ; Yes ld (de),a ; Store char inc de jr paramt1 paramt2: pop hl ; Pt to next char in script ret ; Continue processing ; ; Form assumed to be '$$', however any unrecognized form after the ; first '$' is placed in the command tail. ; noparam: add a,'0' ; Restore the character ld (de),a inc de ; Pt to next chars inc hl ret ; ; $0 - ALIAS Command Name ; oname: inc hl ; Pt to next char push hl ; Save ptr call getefcb ; Pt to FCB jp z,paramx ; Skip if no external FCB inc hl ; Pt to first char ld b,8 ; At most 8 chars on1: ld a,(hl) ; Copy into output line cp ' ' ; Done if space jp z,paramx ld (de),a ; Store char inc hl ; Pt to next inc de djnz on1 jp paramx ; ; Done -- Buffer is Loaded ; done: xor a ; Store ending 0 ld (de),a ld hl,endcod ; Pt to beginning of buffer ld a,(hl) ; Skip if empty line or a ret z ; Simply return ; ex de,hl ; DE points to Our new line ; ; Get environment from descriptor ; call getmcl ; Get Z3CL pointer ret z ; No Multiple Command Line call putcl ; Store in command line ret nz ; Return to ZCPR3 for processing if OK ld de,ovfl ; Overflow message ld c,9 ; Print string function jp 5 ; Let the BDOS do it ovfl: db 'Ovfl$' ; ; PUTCL stores a command line in the ZCPR3 command line buffer. ; This command line is pted to by DE. CL Buffer is pted to by HL. ; Size in A. On return, A=0 and Zero flag Set if command line ; overflow is possible (no change to command line). ; putcl: inc hl inc hl ; Point to Z3CLS ld b,(hl) ; MCL length (usually 203 characters) ex de,hl ; HL pts to new line push hl ; Save ptr to new line ; ; Go to the end of our line, counting characters as we go. ; We also test the length of each expansion to see that it ; won't overflow TBUFF when it is eventually run. ; ; PCL1 advances HL past the command verb as it is not moved to ; the TBUFF when the command is run. The exit of this seemingly ; interminable loop is through PCL2A when a Null is encountered. ; pcl1: call pcl2a ; Get a character and advance HL semi: dec b ; Decrement MCL count jr z,pclx ; Longer than the MCL cp ' ' jr nz,pcl1 ; Keep going until Space ; ; PCL2 advances HL until the next ';' checking that the tail ; does not exceed 126 characters. ; ld c,126 ; Maximum tail length pcl2: call pcl2a ; Get a character and advance HL dec c ; Tail count jr z,pclx ; Tail is too long cp ';' jr z,semi ; End of tail, start over djnz pcl2 ; Decrement MCL count ; ; Expanded command tail is longer than the MCL. ; pclx: pop hl ; Clear stack ; ; Command Line Buffer Overflow ; nocl: xor a ; Error return ret ; pcl2a: ld a,(hl) ; Get a character inc hl ; Advance HL or a ; Check for Null ret nz ; No ; ; This is the exit from PCL1 or PCL2 when a Null is encountered ; dec hl ; Back up the pointer to the null pop de ; Adjust stack and fall into PCL3 ; ; HL pts to ending 0 of new command line ; B = number of chars remaining before overflow of Z3 command line ; pcl3: push hl ; Save ptr to last byte in case of error call getmcl ; Pt to tail of command line call lhlhl ; Get NXTCHR pointer in HL pop de ; Restore ptr to last byte of command line push de ; Save it again ; ; Check for Recursion and clear existing MCL if so. ; if recursive ld a,(recur) ; Get recursion flag or a jr z,pcl3a ; Normal Mode ld (hl),0 ; Clear the MCL pcl3a: endif ; ld a,(hl) ; Get next character of MCL cp ';' ; Continuation? jr z,pcl4 or a ; Done? jr z,pcl4 ld a,';' ; Set continuation char ld (de),a inc de dec b ; Count down jr z,pcl5 ; Overflow ; ; Copy current MCL onto end of new command line. Enter with B equal ; to the number of bytes remaining free in the MCL after the new ; Command Line. ; pcl4: ld a,(hl) ; Get next char of MCL ld (de),a ; Store it in our line inc hl ; Pt to next inc de or a ; Done? jr z,pcl6 ; Yes djnz pcl4 ; Keep it up ; ; Command Line too Long ; pcl5: pop hl ; Get ptr to end of old line pop af ; Clear stack jr nocl ; Report Ovfl ; ; New Command Line OK ; pcl6: pop af ; Clear stack call getmcl ; Pt to command line buffer ld de,4 ; Pt to first char in buffer ex de,hl ; Swap 'em add hl,de ex de,hl ; Swap 'em again ld (hl),e ; Store Z3CL+4 at Z3CL inc hl ld (hl),d ; DE pts to first char of buffer pop hl ; HL pts to first char of new line ; ; Copy New Command Line into Buffer ; pcl7: ld a,(hl) ; Copy ld (de),a inc hl inc de or a ; EOL? jr nz,pcl7 ; ; Exit with OK Code ; dec a ; Set NZ, Ok ret ; ; ALIAS0 does not use the libraries. Z3LIB and SYSLIB routines ; are emulated here. ; getefcb: ld a,24h ; Offset to EXTFCB jr getenv ; Return HL with EXTFCB address ; ; Get pointer to the Multiple Command Line in HL, A = Z if none. ; getmcl: ld a,18h ; Offset to Z3CL ; ; Given an offset in A, go to the Environment for a segment address ; or other data. Return data in L, the address in HL and H OR L in A. ; getenv: call offenv ; Point HL to the address in Z3ENV ; ; Load HL with the next two bytes it is pointing to. Return A = H OR L. ; lhlhl: ld a,(hl) ; Low order address inc hl ld h,(hl) ; High order address ld l,a or h ; Check HL for Zero ret ; ; Point HL to the prototype SH.VAR system filename in Z3ENV ; getfn0: ld a,47h ; Offset to SH.VAR entry ; ; Given an offset in A, point HL to an item in Z3ENV ; offenv: ld hl,(z3eadr) ; Z3ENV address ; ; Add the value in A to HL ; addah: add a,l ; Add L to A ld l,a ; New L ret nc ; Sum LT 256 inc h ; New H ret ; ; Skip to next token or Null ; skip: ld a,(hl) or a ret z ; Null inc hl cp ' ' jr nz,skip ; ; Skip Spaces - Point HL to first non-Space ; sksp: ld a,(hl) cp ' ' ret nz ; Not a Space inc hl jr sksp ; ; Return current Drive in B (rel 0) and current user in C. ; retud: push hl push de ; Save the registers ld c,25 call 5 ; Current disk push af ld e,255 ld c,32 call 5 ; Current user ld c,a ; User to C pop af ld b,a ; Drive to B pop de pop hl ; Restore the registers ret ; ; Capitalize the character in A, if necessary. ; caps: cp 'a' ret c ; Less than 'a' cp 'z'+1 ret nc ; Greater than 'z' and 5fh ; Force Upper case ret ; ; Buffer ; endcod: ds 128-($-alias0) and 127 ; Record boundary for ALIAS0 end ; ; End of Module 1