; PROGRAM: CMD ; VERSION: 1.0 ; DATE: 19 July 84 ; AUTHOR: Richard Conn ; PREVIOUS VERSIONS: None ; z3env equ 0fe00h vers equ 14 ; Version number ; CMD is copyright (c) 1984 by Richard Conn ; All Rights Reserved ; CMD may be used freely by the ZCPR3 Community ; Version 1.4 modifications by Bruce Morgen, March 23, 1991 ; Major change in prompted operation -- CMD now reinvokes ; itself after each command until an empty command line ; (a RETURN alone) or a Control-C is entered. Control-C ; also exits the current shell (if any) as in Version 1.3. ; Version 1.3 - Pre-release tweak to shell name printing code. ; August 16, 1988 Bruce Morgen ; Version 1.2 modifications by Bruce Morgen, March 9, 1988 ; CMD now accepts the "&" substitute command separator and ; aborts the current shell, if any, if a control-C is entered ; in prompted mode. Got rid of silly "Noname" message in the ; prompt, shows current shell instead. Z33 type format with ; safety header, Z80 code with SYSLIB4 and DSEG, etc. ; ; CMD is used to define and run a command line. It either accepts ; the command line (including semicolons) which follow the verb CMD onto ; the command line buffer or, if no input is provided, it prompts the ; user for input and then places this into the command line buffer. ; ; Syntax: ; CMD cmd1&cmd2&... ; or CMD ; ; The sequence of commands "cmd1;cmd2;..." becomes the command line. ; ; ; SYSLIB, Z3LIB, Z33LIB and VLIB References ; extrn z3init,shpop,shpush,getsh1,retcst,getefcb extrn getcl1,getcl2,puter2,putzex,dutdir extrn eprint,pafdc,cout,bline,retud,isgraph ; ; System Addresses ; os$base equ 000h ; System base.. fcb equ os$base+5ch tbuff equ os$base+80h ; ; ASCII Chars ; lf equ 0ah ; ..linefeed.. cr equ 0dh ; ..carriage return.. ; Environment Definition ; TYPE 3 HEADER ; Code modified as suggested by Charles Irvine to function correctly with ; interrupts enabled. Program will abort with an error message when not ; loaded to the correct address (attempt to run it under CP/M or Z30). ; Modified by Bruce Morgen to save a byte and a level of stack from a ; suggestion from Joe Wright via Howard Goldstein. entry: jr start0 ; Must use relative jump nop ; Filler db 'Z3ENV',3 ; Type-3 environment z3eadr: dw z3env ; Filled in by Z33 dw entry ; Intended load address start0: ld hl,0 ; Point to warmboot entry ld a,(hl) ; Save the byte there di ; Protect against interrupts ld (hl),0c9h ; Replace warmboot with a return opcode rst 0 ; Call address 0, pushing RETADDR ; onto stack retaddr: ld (hl),a ; Restore byte at 0 dec sp ; Get stack pointer to point dec sp ; To the value of RETADDR pop hl ; Get it into HL and restore stack ei ; We can allow interrupts again ld de,retaddr ; This is where we should be xor a ; Clear carry flag sbc hl,de ; Subtract -- we should have 0 now jr z,start ; If addresses matched, begin real code add hl,de ; Restore value of RETADDR ld de,notz33msg-retaddr ; Offset to message add hl,de ex de,hl ; Switch pointer to message into DE ld c,9 jp 0005h ; Return via BDOS print string function notz33msg: db 'Not Z33+$' ; Abort message if not Z33-compatible start: ld hl,(z3eadr) ; Pt to ZCPR3 environment ; ; Mainline ; call z3init ; Initialize the ZCPR3 Env ; ; Check for Help or Prompt ; ld hl,(fcb+1) ; Check for help request ld a,l cp ' ' ; Prompted input? jp z,prompt cp '/' ; Help? jp nz,cinit cp h jp nz,cinit ; ; Print Help Message ; help: call eprint db 'CMD, Version ' db (vers/10)+'0','.',(vers mod 10)+'0' db cr,lf,' Syntax: CMD cmd1&cmd2;... or CMD (prompted input)' db cr,lf,' CMD defines the command line in the CL buffer,' db cr,lf,'("&"s are replaced with ";"s. In prompted mode' db cr,lf,'Control-C exits CMD and the current shell, if any,' db cr,lf,'and a RETURN alone exits CMD only.)' db 0 ret ; ; Initialize Command Line ; cinit: call getcl1 ; Check for command line buffer jr z,nocl xor a call puter2 ld de,edbuff+2 ; Working buffer in DE ld hl,tbuff+2 ; Pt to option input call copystr ; Copy string ld c,1 ; Set not empty ; ; Entry point to build rest of command line, where DE=next address ; and C=empty line flag (C=0 means line was empty) ; checkcl: ld a,c ; Get empty flag or a cpl call z,puter2 ; Set error flag call getcl2 ; Get address of command line buffer call nz,copystr ; Copy string if we have one setsh: call getcl1 ; Pt to command line buffer ex de,hl ; ... in DE ld hl,4 ; Pt to first char position add hl,de ld (lstart),hl ; Save start address in case of abort ex de,hl ld (hl),e ; Store pointer inc hl ld (hl),d inc hl ; Pt to buffer size ld b,(hl) ; Get it in B ld hl,edbuff+2 ; Pt to string clcopy: ld a,(hl) ; Get char ld (de),a ; Put char inc hl ; Pt to next inc de or a ; Done? ret z djnz clcopy ; Count down ; ; Command Line Too Long ; ld hl,(lstart) ; Zero command line ld (hl),b call puter2 call eprint db ' Command Line too Long for Buffer',0 ret ; ; Print no command line buffer message and exit ; nocl: ld a,254 call puter2 call eprint db ' No Command Line Buffer',0 ret ; ; Copy string from HL to DE ; Store ending 0 and leave pointer in DE to it ; copystr: ld a,(hl) ; Get char cp '&' jr nz,notsep ld a,';' notsep: ld (de),a ; Store it or a ; Done? ret z inc hl ; Pt to next inc de jr copystr ; ; Prompt User for Input ; prompt: call eprint db 'Cmd,',0 ; ; Complete prompt and get user input ; call getsh1 ld de,shbuff ld (de),a jr z,noshel ld a,(hl) ld (de),a or a jr z,noshel ld c,b push hl shnmlp: ld a,(hl) or a jr nz,notnul ld b,a jr gotnul notnul: call isgraph call z,cout inc hl djnz shnmlp gotnul: pop hl ldir call shpop ld a,'\' call cout ; ; Print DU ; noshel: call retud ; Get DU ld a,b ; Output disk add a,'A' call cout ld a,c ; Output user call pafdc ; ; Print DIR ; call dutdir ; Convert to name jr z,promptx ; No NDR entry defined if Z ; ; DIR is defined ; ld a,':' ; Separator call cout ld b,8 ; 8 chars max prompt1: ld a,(hl) ; Get char cp ' ' ; Done if space call nz,cout ; Echo it inc hl ; Pt to next djnz prompt1 ; Count down promptx: ld a,'>' call cout call retcst ; Command Status to non-shell res 0,(hl) ld a,1 ; Tell ZEX that it is prompted call putzex ld hl,edbuff ; Use buffer area ld a,254 ld (hl),a ; Set large line size, caps call bline ; Get input line xor a ; No more prompt call putzex ld hl,shbuff ld a,(hl) or a jr z,noshp call shpush ex de,hl call getsh1 ex de,hl ld c,b ld b,0 ldir noshp: ld de,edbuff+2 ; Skip to EOL ld a,(de) ; Get first char ld c,a ; Save flag or a jr z,chkclv ; ; Skip to end of input line ; findeol: ld a,(de) ; Get char or a ; Done? jr z,foundeol inc de ; Pt to next jr findeol foundeol: call getefcb jr z,chkclv ld b,9 ld a,';' jr feol1 feollp: inc hl ld a,(hl) and 7fh feol1: ld (de),a sub ' ' jr z,feol2 inc de djnz feollp ld a,b dec de feol2: ld (de),a chkclv: jp checkcl ; ; Buffers ; dseg edbuff: ds 256,0 ; Type 4 requires ",0" (why?) lstart: ds 2 ; Start of command line shbuff: ds 128 end