;
;  PROGRAM:  ECHO
;  AUTHOR:  RICHARD CONN
;  VERSION:  1.3
;  DATE:  17 AUG 83
;  PREVIOUS VERSIONS:  1.2 (21 JUN 83), 1.1 (6 JAN 83), 1.0 (10 DEC 82)
;
VERS    EQU     13

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


;
;       ECHO is used to echo the command line to the screen.  It is invoked
; in the following ways:
;               ECHO                    <-- print Help Message
;               ECHO //                 <-- print Help Message
;               ECHO text               <-- print text
;               ECHO /po text           <-- print text on printer
;
;       This seems like a trivial program, but it buys the user one key thing:
; for ZCPR2 use, a message may be stored in the multiple command line buffer
; by using ECHO, so that programs like STARTUP can print a welcome message
; after they have run.  For STARTUP in particular, a sample command line
; would be:
;
;               ioloader;ld ld;tinit;echo WELCOME TO ZCPR II
;
;       This line runs IOLOADER, which loads the redirectable I/O devices,
; followed by LD LD, which loads a named directory into memory, and TINIT,
; which initializes a TVI 950 terminal (function keys, user line, etc).
; When all is done, TINIT will have cleared the screen and ECHO will have
; printed its message.
;
;       A second noted use for ECHO is in performing miscellaneous printer
; functions.  The /P option allows the user to send any text to the printer,
; and this text can include control characters.  This can be used to set
; printer controls for those printers which respond to commands from the
; user.  If the letter following the P is an N, then NO new line is printed
; following the text (otherwise, the text is followed by a CRLF).
;
;       Finally, a third noted use for ECHO is to set attributes of the
; user's terminal if he has a programmable terminal.  By passing control
; characters, ECHO allows any control sequence to be sent to a terminal.
;

;
;  Externals
;
       ext     crlf    ; new line on console
       ext     lcrlf   ; new line on printer
       ext     print   ; print string pted to by return address
       ext     cout    ; output to console
       ext     lout    ; output to printer

;
;  CP/M Constants
;
tbuff   equ     80h     ; console line buffer
cr      equ     0dh
lf      equ     0ah

;
;  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      000H    ; EXTERNAL PATH?
MCREQD:
       DB      000H    ; MULTIPLE COMMAND LINE?
MXREQD:
       DB      000H    ; MAX USER/DISK?
UDREQD:
       DB      000H    ; ALLOW USER/DISK CHANGE?
PUREQD:
       DB      000H    ; PRIVILEGED USER?
CDREQD:
       DB      000H    ; CURRENT INDIC AND DMA?
NDREQD:
       DB      000H    ; NAMED DIRECTORIES?
Z2CLASS:
       DB      0       ; CLASS 0
       DB      'ZCPR2'
       DS      10      ; RESERVED

;
;  END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
;
;******************************************************************
;

;
;  Start of Program
;
start:
       xra     a
       sta     pflag   ; clear print flag
       sta     nflag   ; clear new line flag
       lxi     h,tbuff ; place zero at end of command line
       mov     a,m     ; get char count
       inx     h       ; pt to first char
       push    h       ; save ptr
       add     l       ; HL=HL+A
       mov     l,a
       mov     a,h
       aci     0
       mov     h,a
       mvi     m,0     ; store ending zero
       pop     h       ; pt to first char
       call    sblank  ; skip to first non-blank
       ora     a       ; EOL means print Help Message
       jz      phelp
       cpi     '/'     ; slash means print Help Message also
       jnz     echo    ; if not slash, print buffer contents
       inx     h       ; pt to next character
       mov     a,m     ; get next char
       cpi     'P'     ; printer?
       jnz     phelp
       mvi     a,0ffh  ; set print flag
       sta     pflag
       inx     h       ; pt to after the P
       mov     a,m     ; get option letter
       cpi     'N'     ; new line?
       jnz     echo
       inx     h       ; pt to after option letter
       mvi     a,0ffh  ; set new line flag
       sta     nflag
       jmp     echo    ; perform function

;
;  Print Help Message
;
phelp:
       call    print
       db      'ECHO  Version '
       db      (vers/10)+'0','.',(vers mod 10)+'0'
       db      cr,lf,' ECHO prints the command line on the user''s console'
       db      cr,lf,'or printer.  It is invoked by the following forms:'
       db      cr,lf
       db      cr,lf,'         ECHO or ECHO //         <-- Print this Help'
       db      cr,lf,'         ECHO text               <-- Print text'
       db      cr,lf,'         ECHO /po text           <-- Print text on LST:'
       db      cr,lf
       db      cr,lf,' In the last form, the significant text begins'
       db      cr,lf,'immediately after the option letter.  If this option'
       db      cr,lf,'letter is N, then the text is NOT followed by a new'
       db      cr,lf,'line.  With no option letter, the text is followed by'
       db      cr,lf,'a carriage return/line feed pair.  This way, ECHO /P'
       db      cr,lf,'simply outputs a new line to the printer.'
       db      cr,lf,' ECHO performs NO control character interpretation'
       db      cr,lf,'(such as tab expansion).'
       db      cr,lf,0
       ret
;
;  Echo Command Line
;
echo:
       lda     pflag   ; printing?
       ora     a       ; 0=no
       cz      crlf    ; new line
       call    pstr    ; simply print string starting at HL
       lda     pflag   ; printing?
       ora     a       ; 0=no
       rz
       lda     nflag   ; new line?
       ora     a       ; 0=yes (reverse logic)
       cz      lcrlf   ; new line
       ret
;
;  Print string (with no interpretation) pointed to by HL
;
pstr:
       mov     a,m     ; get next char
       ora     a       ; done?
       rz
       inx     h       ; pt to next
       mov     b,a     ; save char
       lda     pflag   ; con or lst?
       ora     a       ; 0=con
       jz      pstrc
       mov     a,b     ; get char
       call    lout    ; list
       jmp     pstr
pstrc:
       mov     a,b     ; get char
       call    cout    ; console
       jmp     pstr
;
;  Skip to Non-Blank
;
sblank:
       mov     a,m     ; get char
       inx     h       ; pt to next
       cpi     ' '     ; skip if space
       jz      sblank
       dcx     h       ; back up to non-space
       ret

;
;  Buffers
;
pflag:  ds      1       ; print flag
nflag:  ds      1       ; new line flag


       end