;  PROGRAM:  COMMENT
;  AUTHOR:  Richard Conn
;  VERSION:  2.0
;  DATE:  18 MAY 84
;  PREVIOUS VERSIONS:  1.0 (18 APR 83)

vers    equ     20
z3env   set     0f400h

;
;       COMMENT echoes lines, with simple character editing, to the user's
; console.  This program is designed to facilitate communication between
; two users who see the same console via redirectable I/O.  They can chat
; freely to each other by using this program.
;

llen    equ     65      ;number of chars allowed before auto newline

fcb     equ     5ch     ;FCB

ctrlc   equ     'C'-'@' ;Abort Character
esc     equ     1bh     ;Escape (Abort Character)
cr      equ     0dh     ;New Line
lf      equ     0ah     ;Line Feed
bs      equ     8       ;Back Space
del     equ     7fh     ;Delete Char
ctrlp   equ     'P'-'@' ;^P
ctrlu   equ     'U'-'@' ;^U
ctrlx   equ     'X'-'@' ;^X

;
; Externals
;
       ext     z3init
       ext     cin,cout,crlf,eprint,lout,lcrlf

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

;
; Start of Program -- Initialize ZCPR3 Environment
;
       call    z3init  ;initialize the ZCPR3 Env and the VLIB Env
       call    eprint
       db      'COMMENT, Version '
       db      (vers/10)+'0','.',(vers mod 10)+'0',0
       lda     fcb+1   ;check for help request
       cpi     '/'     ;help?
       jnz     cmt
;
;  Help for COMMENT
;
       call    eprint
       db      cr,lf,'   COMMENT'
       db      cr,lf,'Internal Commands:'
       db      cr,lf,'  ^C or ESC - Abort'
       db      cr,lf,'     ^P     - Toggle Print'
       db      cr,lf,'  BS or DEL - Delete Prev Char'
       db      cr,lf,'  ^U or ^X  - Delete Line'
       db      0
       ret
;
;  Beginning of Comment Routine
;
cmt:
       call    eprint
       db      cr,lf,'Strike ^C or ESC to Abort, ^P to Toggle Print'
       db      cr,lf,0
       xra     a       ;clear print flag
       sta     prflag
       call    comment ;print first prompt and set char count
;
;  Main Character Input Loop
;
loop:
       call    cin     ;input char
       ani     7fh     ;mask MSB
       cpi     ctrlc
       rz
       cpi     esc
       rz
       cpi     ctrlp   ;toggle print flag
       jz      prtog
       cpi     cr      ;new line?
       jz      newline
       cpi     bs      ;back up?
       jz      back
       cpi     del     ;back up?
       jz      back
       cpi     ctrlu   ;erase line?
       jz      eraln
       cpi     ctrlx   ;erase line?
       jz      eraln
       call    cout
       cpi     ' '     ;printable char?
       jc      loop
       mov     b,a     ;save char in B
       lda     prflag  ;print?
       ora     a       ;0=no
       mov     a,b     ;get char to print
       cnz     lout    ;print char if PRFLAG is NZ
       inr     c       ;increment char count
       mvi     a,llen  ;check for nearing end of line
       cmp     c
       cz      comment
       jmp     loop
;
;  Toggle print flag
;
prtog:
       lda     prflag  ;flip flag
       cma
       sta     prflag
       ora     a       ;new line to printer if print flag now off
       cz      lcrlf
       jmp     loop
;
;  Routine to begin a new line
;
newline:
       call    comment ;new line, print prompt, set char count to zero
       jmp     loop
;
;  Back up one character
;
back:
       mov     a,c     ;check for no chars
       ora     a
       jz      loop
       call    back1   ;backup routine
       jmp     loop    ;continue
;
;  General Routine for backing up
;
back1:
       dcr     c       ;count down
       mvi     a,bs    ;backspace
       call    cout
       mvi     a,' '   ;space
       call    cout
       mvi     a,bs    ;backspace
       jmp     cout
;
;  Erase Current Line
;
eraln:
       mov     a,c     ;done?
       ora     a
       jz      loop
       call    back1   ;backup
       jmp     eraln
;
;  Print User Prompt
;
comment:
       call    eprint
       db      cr,lf,'Comment> ',0
       lda     prflag  ;new line to printer if print flag on
       ora     a
       cnz     lcrlf
       mvi     c,0     ;set char count
       ret

;
;  Buffers
;
prflag:
       ds      1       ;print flag (0=off, 0FFH=on)

       end