;  PROGRAM:  CMD
;  VERSION:  1.0
;  DATE:  19 July 84
;  AUTHOR:  Richard Conn
;  PREVIOUS VERSIONS:  None
;
z3env   equ     0f400h
VERS    EQU     10              ;version number

; CMD is copyright (c) 1984 by Richard Conn
; All Rights Reserved
; CMD may be used freely by the ZCPR3 Community

;
;       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, and VLIB References
;
       ext     z3init
       ext     getcl1,getcl2,puter2,putzex,dutdir
       ext     eprint,pafdc,cout,bline
       ext     retud
       ext     codend

;
;  Basic Definitions
;
TRUE     EQU    0FFH            ;define true and..
FALSE    EQU    0               ;..false.

;
; System Addresses
;
OS$BASE EQU     000H            ;system base..
BDOS    EQU     OS$BASE+05H
FCB     EQU     OS$BASE+5CH
FCB2    EQU     OS$BASE+6CH
TBUFF   EQU     OS$BASE+80H
TPA     EQU     OS$BASE+100H

;
;  ASCII Chars
;
LF      EQU     0AH             ;..linefeed..
CR      EQU     0DH             ;..carriage return..

;
; 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

;
; Mainline
;
       call    z3init          ;initialize the ZCPR3 Env

;
; Check for Help or Prompt
;
       lda     fcb+1           ;check for help request
       cpi     ' '             ;prompted input?
       jz      prompt
       cpi     '/'             ;help?
       jnz     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      0
       ret
;
; Initialize Command Line
;
cinit:
       call    getcl1          ;check for command line buffer
       jz      nocl
;
; HL now points to the command line buffer
;
       call    codend          ;pt to free area
       inx     h               ;skip 2 bytes
       inx     h
       xchg                    ;... in DE
       lxi     h,tbuff+2       ;pt to option input
       call    copystr         ;copy string
       mvi     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:
       mov     a,c             ;get empty flag
       call    puter2          ;set error flag
       call    getcl2          ;get address of command line
       jz      setsh           ;set shell command
       call    copystr         ;copy string
setsh:
       call    getcl1          ;pt to command line buffer
       xchg                    ;... in DE
       lxi     h,4             ;pt to first char position
       dad     d
       shld    lstart          ;save start address in case of abort
       xchg
       mov     m,e             ;store pointer
       inx     h
       mov     m,d
       inx     h               ;pt to buffer size
       mov     b,m             ;get it in B
       call    codend          ;pt to string
       inx     h               ;skip 2 bytes
       inx     h
clcopy:
       mov     a,m             ;get char
       stax    d               ;put char
       inx     h               ;pt to next
       inx     d
       ora     a               ;done?
       rz
       dcr     b               ;count down
       jnz     clcopy
;
; Command Line Too Long
;
       lhld    lstart          ;zero command line
       mvi     m,0
       call    eprint
       db      ' Command Line too Long for Buffer',0
       ret

;
; Print no command line buffer message and exit
;
nocl:
       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:
       mov     a,m             ;get char
       stax    d               ;store it
       ora     a               ;done?
       rz
       inx     h               ;pt to next
       inx     d
       jmp     copystr

;
; Prompt User for Input
;
prompt:
       call    eprint
       db      'CMD ',0
       call    retud           ;get DU
;
; Print DU
;
       mov     a,b             ;output disk
       adi     'A'
       call    cout
       mov     a,c             ;output user
       call    pafdc
       mvi     a,':'           ;separator
       call    cout
;
; Print DIR
;
       call    dutdir          ;convert to name
       jz      prompt2         ;no name input
;
; DIR is defined
;
       mvi     b,8             ;8 chars max
prompt1:
       mov     a,m             ;get char
       cpi     ' '             ;done if space
       jz      promptx
       call    cout            ;echo it
       inx     h               ;pt to next
       dcr     b               ;count down
       jnz     prompt1
       jmp     promptx
;
; DIR is not defined
;
prompt2:
       call    eprint          ;name not found
       db      'Noname',0
;
; Complete prompt and get user input
;
promptx:
       call    eprint
       db      '> ',0
       mvi     a,1             ;tell ZEX that it is prompted
       call    putzex
       call    codend          ;use buffer area
       mvi     m,254           ;set large line size
       mvi     a,0             ;no caps
       call    bline           ;get input line
       xra     a               ;no more prompt
       call    putzex
       call    codend          ;skip to EOL
       inx     h
       inx     h
       xchg                    ;ptr in DE
       ldax    d               ;get first char
       mov     c,a             ;save flag
;
; Skip to end of input line
;
findeol:
       ldax    d               ;get char
       ora     a               ;done?
       jz      checkcl
       inx     d               ;pt to next
       jmp     findeol
;
; Buffers
;
lstart:
       ds      2               ;start of command line

       end