]> cloudbase.mooo.com Git - kermit-80.git/blobdiff - cpstt.asm
Convert line endings to CP/M format (cr/lf).
[kermit-80.git] / cpstt.asm
index 41a30af18fa4b45692f0adc0657db00dee4d907a..1e96171272de23f7192ed0eac973ce1d55f735cb 100644 (file)
--- a/cpstt.asm
+++ b/cpstt.asm
-; CPSTT.ASM
-;       KERMIT - (Celtic for "FREE")
-;
-;       This is the CP/M-80 implementation of the Columbia University
-;       KERMIT file transfer protocol.
-;
-;       Version 4.0
-;
-;       Copyright June 1981,1982,1983,1984,1985
-;       Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others. 
-;
-;       This file contains the code for the TRANSMIT and CONNECT commands,
-;       which communicate with a host which is not running KERMIT.
-;
-; revision history:
-;
-;edit 12, 31-Jan-1991 by MF. Delete call to "inbuf" after "xmit1" in
-;      the TRANSMIT command. "getfil" initializes various counters so that
-;      when "in1chr" is first called, "inbuf" will be called immediately
-;      and will read sectors of the file to be transmitted from disk.
-;      This, along with a fix to "in1chr" in CPSUTL.ASM, fixes a bug
-;      discovered by Lance Tagliapietra of the University of Wisconsin at
-;      Platteville wherein the TRANSMIT command was failing to transmit some
-;      characters in files over one sector in length. See CPSUTL.ASM,
-;      edit 29.
-; edit 11, 10 September, a987, by OBSchou.  Modified TRANSMIT command
-;      to TRANSMIT <file> <string>
-;
-; edit 10, 27 August, 1987 by OBSchou.  Fixed bugs in Transmit, but I may
-;      be introducing problems for IBM/CMS or half duplex systems.  What
-;      does this combination do??
-;
-; edit 9 30 March, 1987 by OBSchou to replace the TRANSMIT routine.
-;      Syntax is now TRANSMIT file after a previous 
-;      INPUT <wait time> <string to wait for>
-;
-; edit 8 19 June, 1986 by OBSchou.  Modified the interupt testing routine
-;       to see if the command was a 'D' (Drop the line), in which case also
-;       do a 'C', ie disconnect.  This is really a little too much of a
-;       system dependent thing.
-;       For now, Ill leave it here, and possibly move it later.
-;
-; edit 7 30 May 1986 OBSchou.  Moved xon/xoff control (ie XON/OFF sent to host)
-;       out to CPSUTL so that ther printer routine can use it too.
-;
-; edit 6 30 April, 1986 by OBSchou.
-;       Fixed transmit bug, so as soon as the protocol character is 
-;       received from the host is received then another line is sent.
-;       added in a comchr (ds 1) to save the character read from the comm 
-;       line in prtchr, and is restored in a on return.
-;
-; edit 5 7 March, 1986 by OBSchou Loughborough University.  
-;       Need to save the E register before calling outmdm (in CPSSYS.ASM)
-;       if doing Half duplex.  Push/pop DE should sort this problem
-;
-; edit 4: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
-;
-;pcc002 28-Dec-84       modules:cp4tt,cp4utl
-;       Add connect mode <esc>P command to toggle printer on
-;       and off.  Conflicts with "official" recommended commands
-;       in protocol manual, but I don't think CP/M will ever get
-;       a PUSH command.
-;
-;pcc003-pcc005  2-Jan-85        vjc     modules:cp4mit,cp4tt,cp4utl
-;       These edits must all be installed together and change the way
-;       logging is handled.  The log file spec is moved to a separate
-;       fcb, and not opened until an actual CONNECT command is given.
-;       This takes care of a NASTY bug that if you used any other file
-;       command between the LOG and CONNECT, the log file would get
-;       written over the last file used.  This also allows logging to
-;       be "permanently" enabled until an CLOSE (new command) for all
-;       CONNECT sessions, like most other kermits do.  If a log file
-;       already exists, it will be appended to.  Also add two new
-;       CONNECT mode commands <esc>Q to suspend logging and <esc>R to
-;       resume.  <esc>R means something else during TRANSMIT, but
-;       logging is never on then, so there shouldn't be any conflict.
-;       I also changed the write code, so that it can handle one more
-;       character after the XOFF is send to stop the host.  This allows
-;       a little "slop" for systems that don't stop immediately (such
-;       as TOPS10), but it didn't help much.
-;
-;pcc008 2-Jan-85        vjc     modules:cp4def,cp4tt,cp4utl
-;       Keyboard input during CONNECT mode can get locked out if
-;       there is enough input from the modem port to keep prtchr
-;       busy.  This can happen for example, if the printer is running
-;       at the same speed as the modem line, leaving you helpless to
-;       turn it off or abort the host.  Add a fairness count, so that
-;       at least every prfair characters we look at console input.
-;
-;pcc012 4-Jan-85        vjc     modules:cp4mit,cp4tt,cp4utl
-;       Use the big buffer for the log file.  Move the log file back
-;       into the common fcb and only save the drive, name, and
-;       extension between connects.  Add new routines to cp4utl to
-;       create or append to an existing file, and to conditionally
-;       advance buffers only if in memory.  Remove edit pcc003 that
-;       allows one more character after the xoff, since it didn't
-;       really work very well and does not fit in well with the way
-;       the buffer advancing routines are set up.  If someone still
-;       thinks this would be useful, it could be put back in with a
-;       little more work.
-;       
-;       While testing this edit, I also noticed another bug that
-;       the command parsing routines do not limit or check the
-;       length of command lines or file specs, trashing what ever
-;       comes after them.  Currently because of where the fcb and
-;       command buffer are located, this does not usually cause a
-;       problem, but could if an extremely long line was typed in,
-;       or in the future multiple fcbs defined elsewhere in memory
-;       were used.  Maybe this should be put on the bug list
-;       somewhere.
-;
-; edit 3: July 27, 1984
-;       Allow assembly with LASM: to CP4TT is linked by CP4PKT, and links
-;       to CP4CPM; remove exclamation points so as not to confuse LASM.
-;       Add Toad Hall TACtrap to TRANSMIT command (TAC intercept character
-;       is only doubled if it's data; when typed by the user, they're not
-;       automatically doubled)
-;
-; edit 2: June 7, 1984
-;       formatting and documentation; add module version number; make sure
-;       console is selected when leaving intchr.
-;
-; edit 1: May, 1984
-;       extracted from CPMBASE.M80 version 3.9; modifications are described
-;       in the accompanying .UPD file.
-
-ttver: db      'CPSTT.ASM  (12) 31-Jan-1991$'
-
-;       This is the TRANSMIT command.  It attempts to send a file, even
-;       though there is no KERMIT on the other side.
-;       here from: kermit
-;
-; [OBS] I have replaced the routine, so that TRANSMIT <filename> <wait string>
-; will send a line at a time to the host in a manner similar to MSKERMIT
-;
-;
-xmit:  mvi     a,cmofi         ;Parse an input file spec (non-wild).
-       lxi     d,fcb           ;Give the address for the FCB.
-       call    comnd
-       jmp     kermit          ;Give up on bad parse.
-;
-       lxi     d,stbuff        ; where to put the string
-       mvi     a,cmtxt         ; get text
-       call    comnd
-       jmp     kermit          ; not quite correct...
-       sta     strcnt          ; string count returned in a
-       ana     a               ; if its zero, make it 1 character (CR)
-       jnz     xmit0
-       mvi     a,1
-       sta     strcnt
-       mvi     a,cr
-       sta     stbuff
-;
-xmit0: call    cfmcmd
-       call    getfil          ;Open file.
-       cpi     0FFH            ;Succeed?
-       jnz     xmit1
-       lxi     d,erms15
-       call    prtstr          ;Display error msg.
-       jmp     kermit
-
-;
-; New TRANSMIT routine - transmit a file, line by line, to a remote host
-;      waiting each time for one or more characters to be returned
-;      as a remote host prompt.  It could be as simple as a CR or LF
-;      character.  Repeat until the complete file has been sent, then
-;      close the transmitted file, and drop into the connect state so the
-;      user can tidy up at the host end.
-;get the file to send, open it up, and read first sector from disk
-
-xmit1: lxi     d,inms19        ; say we are send a file to the host
-       call    prtstr
-
-       xra     a
-       sta     repcnt          ; clear the host prompt chars. counter 
-       sta     starc           ; clear star count
-;[MF][12]Delete the following call to "inbuf" as the call to "getfil"
-;[MF][12]above will have initialized counters and flags so that when
-;[MF][12]"in1chr" is called, "inbuf" will be called immediately and will
-;[MF][12]immediately read from disk. Counters and flags will then be
-;[MF][12]properly set up to read all characters of the file to be
-;[MF][12]transmitted.
-;      call    inbuf           ; read one sector from disk
-;      jmp     xmtex           ; exit if error
-
-
-xmt10: xra     a               ; clear retransmit flag and count etc
-       sta     rexbfl          ; retransmit flag (1=> retransmit)
-       sta     rexcnt          ; character counter
-
-xmt1:  call    xmt1ch          ; send a character
-       ani     7fh             ; strip any parity
-       cpi     cr              ; have we reached the end of the line
-       jnz     xmt1            ; nope, loop around again
-
-; Now wait for a string back from the host.  Compare with STRING buffer
-;
-       xra     a               ; clear the character count
-       sta     rexcnt
-;
-       call    selcon          ; sent a line, send a star to console
-       mvi     e,'*'
-       call    outcon
-       lda     starc           ; update star count
-       inr     a
-       sta     starc
-       cpi     60              ; sent 60 stars?
-       jnz     xmt1a           ; nope...
-       xra     a
-       sta     starc
-       call    prcrlf
-xmt1a:
-
-xmt3:  lda     eoflag          ; have we hit end of file?
-       ana     a
-       jnz     xmtex           ; yup, so quit.
-       xra     a
-       sta     repcnt          ; clear the host prompt chars.counter
-xmt2:  call    rd1chl          ; read a character from the line
-       ani     7fh             ; set flags
-       jnz     xmt4            ; Not zero => we have a character from host
-       call    ckchr           ; see if *WE* have a character from console
-       push    psw             ; restore to modem
-       call    selmdm
-       pop     psw
-       ani     7fh             ; stip parity (should not be there)
-       jnz     xmt2a           ; if a null, try again
-       lda     strcnt          ; if the string length is zero, dont wait.
-       ana     a
-       jz      xmt1            ; so loop back again
-       jmp     xmt4            ; else test for xon/off and incomming string
-
-xmt2a: cpi     cntlc           ; do we want to abort?
-       jz      xmtex           ; in which case drop through to connect mode
-       cpi     cntlz           ; if control z exit back to command loop
-       jnz     xmt2b           ; else try for other characters
-       lxi     d,fcb           ; close file before exiting to command loop
-       mvi     c,closf
-       call    bdos
-       jmp     kermit
-
-xmt2b: cpi     cr              ; a cr => resend last line
-       jnz     xmt2            ; nope, then ignore it
-       mvi     a,1
-       sta     rexbfl          ; else we want to resend the line.
-       jmp     xmt1
-
-xmt4:  jmp     xmt6            ; skit xoff test for now...*****************
-
-       cpi     xoff            ; xoff from host?
-       jnz     xmt6
-xmt5:  call    rd1chl          ; else see if XOFF comming
-       ani     7fh
-       jnz     xmt6            ; assume an xoff
-       call    ckchr           ; anything at console?
-       push    psw
-       call    selmdm
-       pop     psw
-       ani     7fh
-       cpi     cntlc           ; control-c == abort & play terminal
-       jz      xmtex
-       ana     a               ; anything else?
-       jz      xmt5            ;loop again
-
-xmt6:  mov     e,a             ; save it for a while
-       lda     repcnt          ; see if this character matches with one in buffer
-       lxi     h,stbuff        ; point to string buffer
-       add     l               ; make hl = hl + a
-       mov     l,a
-       mvi     a,0
-       adc     h
-       mov     h,a             ; not using xra, as that clears the Carry flag
-       mov     a,e             ; get the character back again
-       cmp     m               ; is it = to what we expect?
-       jnz     xmt3            ; no, clear counter and try again
-       lda     repcnt          ; yes, then update the pointer, and ...
-       inr     a               ; ... see if we have received all ...
-       sta     repcnt          ; ... we should have received
-       mov     e,a             ; save length into E again
-       lda     strcnt          ; get the length to compare
-       sub     e               ; if (e) > string length, we have it
-       jz      xmt10           ; so send next line (clear counters etc)
-       jmp     xmt2            ; else wait for a little longer
-
-
-;
-; Routine below sends a character to the line.  It sends up to a CR, and then
-;      it waits for a reply.  This routine is called from xmt1, so if at 
-;      end of file, return.  Then XMT1 will drop through
-;      to connect.
-xmt1ch:        ; send a character from the xmtbuf to the line
-       call    selmdm          ; just in case it uses it
-       lda     eoflag          ; have we hit end of file
-       ana     a               ; set flags
-       jnz     xmt1c1          ; no, so dont...
-       mvi     a,cr            ; load up a carriage return
-xmt1c1:        call    get1xc          ; get the character to send
-       cpi     lf              ; dont send line feeds
-;      jz      xmt1c1
-       cpi     cntlz           ; if control z, then we are at end of the file
-       jz      xmtex           ; so close the file and drop into telcon
-       cpi     20h             ; control character?
-       jp      xmt11           ; no, so ok
-       cpi     cr              ; cr, and tabs ok to send
-       jz      xmt11
-       cpi     tab
-       jz      xmt11
-       jmp     xmt1c1          ; else try for another character
-
-xmt11: call    setpar          ; else set parity etc
-       push    psw             ; we want to keep this for a while
-       mov     e,a             ; we need character in e
-       call    outmdm
-       pop     psw             ; restore the character we sent
-       mov     e,a             ; now, if a TAC is set on..
-       lda     tacflg
-       ana     a               
-       mov     a,e             ; (return must have sent character in a)
-       jz      xmt1c2          ; test for xon/off
-       lda     tacchr          ;... get the tac character
-       cmp     e               ; do we send it again?
-       jnz     xmt1c2          ; test for xon/off
-       push    psw             ; save character for return. Already set E...
-       call    outmdm
-       pop     psw
-
-xmt1c2:        ret
-
-get1xc:        ; get a character from the sector or re-transmit buffer read 
-;      into a.  Read a new sector if we run out.
-;
-; First, see if we do a retransmit
-       lda     rexbfl
-       ana     a               ; if zero, a genuine line
-       jz      get1x1
-; have to retransmit a line
-       lxi     h,rexbuf
-       lda     rexcnt          ; add counter to buffer base
-       mvi     d,0
-       mov     e,a
-       dad     d
-       inr     a               ; update pointer
-       sta     rexcnt
-       mov     a,m             ; get next character to send
-       ret                     ; and exit
-
-get1x1:        call    in1chr          ; get a character from the file. 
-       mov     c,a             ; save it to the retransmit buffer
-       lda     rexcnt
-       mov     e,a
-       mvi     d,0
-       lxi     h,rexbuf
-       dad     d               ; point to next position
-       inr     a
-       sta     rexcnt          ; update the character pointer
-       mov     a,c             ; restore character to a
-       mov     m,c             ; get character to c
-       ret
-
-
-
-; read a character from the line.
-rd1chl:        
-       call    selmdm          ; select the modem
-       call    inpmdm          ; get input from the modem
-       ani     7fh             ; strip parity
-                               ; may UPPERCASE-ify if case sensitivity off
-       ret                     ; return to caller
-
-;  End of transmit routine.  Close input file name, and say we are dropping
-;  throught to telnet.  Note that if eof not found, it is assumed that
-;  this is the ABORT exit.
-
-xmtex:
-       lxi     d,fcb           ; close the transmitted file
-       mvi     c,closf
-       call    bdos
-       call    selcon          ; make sure we are talking to the console
-
-       lda     eoflag          ; end of file or abort exit?
-       lxi     d,inms22        ; assume eof...
-       ana     a
-       jz      xmtex1
-       lxi     d,inms29        ; we were wrong, its an abort.
-xmtex1:        jmp     telnt1          ; and drop through to connect mode
-                               ; telnet does the printing
-
-
-
-;\f
-;   telnet - the CONNECT command.
-;       here from: kermit
-;   telnt1 - entry to connect mode from TRANSMIT command
-;       here from: xend
-
-telnet:        call    cfmcmd
-       lxi     d,infms7        ;Output start of message
-; enter here from TRANSMIT command.
-telnt1:        call    prtstr
-       call    escpr           ;Print the escape char.
-       lxi     d,infms8        ;Output some more of the message
-       call    prtstr
-       call    escpr           ;Print the escape char again.
-       lxi     d,inms8a        ;Print the remainder of the message
-       call    prtstr
-       call    syscon          ;do system-dependent stuff
-       lda     logflg          ;[pcc005] Want a log?
-       ora     a               ;[pcc005]
-       cnz     logopn          ;[pcc005] Open if so
-
-chrlup:        call    prtchr          ;See if char at port (send to console).
-       call    conchr          ;See if char at console (send to port).
-       jmp     kermit          ;requested to end session - go to command loop.
-       jmp     chrlup          ;Go do it again.
-;\f
-;
-;       prtchr - copy characters from comm line to console
-;       returns: nonskip, console selected.
-;       called by: xnext, rexmit, telnet
-;
-
-prtchr:        call    selmdm          ; select modem port
-       call    inpmdm          ; try to get a character from it
-       push    psw             ; restore to console
-       call    selcon          ; select console
-       pop     psw             ; restore the (possible character) read
-       ora     a               ; test character
-       jnz     prtch0          ; if non-zero, process it.
-       sta     prtcnt          ;[pcc008] zero out prt fairness count
-       ret                     ; return.
-
-prtch0:        ani     7FH             ; drop parity bit.
-       sta     comchr          ;[6] save it in case we need it again
-       lda     vtflg           ;[9] get the vt52 emulation flag
-       cpi     vtdefe          ;[9] are we doing external emulation?
-       lda     comchr          ;[9] collect character again
-       jz      extern          ;[9] jup, go do it.
-
-       ana     a               ; set flags.  it may be a null
-       jz      prtchr          ; ignore null (filler)
-       cpi     del             ; ignore delete, too
-       jz      prtchr
-       cpi     xon             ;Is it an XON?
-       jz      prtxon          ;yes
-       cpi     xoff            ;Is it an XOFF?
-       jz      prtxof          ;yes
-       mov     e,a             ;Set the char aside.
-       lda     vtflg           ;Get the VT52 emulation flag.
-       cpi     vtdefv          ;Is the flag set for VT52 (ie 1)
-                               ;0 = none
-                               ;1 = VT52
-                               ;2 = external
-                               ;3 = dumb (traps non printing chars)
-                               ;0ffh not possible by local code (Will change)
-       jnz     prtch1          ;If not, don't do this stuff.
-       lda     escflg          ;Get the escape flag.
-       ora     a               ;Are we working on an escape sequence?
-       jz      prtch2          ;If not, continue.
-       call    vt52            ;If so, work on it some more
-       jmp     prtchr          ;try for more characters.
-
-prtch2:        mov     a,e             ;normal text.
-       cpi     esc             ;Is the char an escape?
-       jnz     prtch1          ;If not skip on.
-       mvi     a,1
-       sta     escflg          ;Set the escape flag: escape seen.
-       jmp     prtchr          ;Get another char...
-
-prtch1:        cpi     vtdefe          ; are we doing external emulation?
-       jnz     prtch3          ; assume we continue on
-       lxi     h,extern+1      ; get address of external emulator
-       mov     a,h             ; se if address = 0 (not implemented)
-       ora     l
-       jz      prtch3          ; not external, assume we just carry on
-       pchl                    ; go do external emulation.  RET back to caller
-
-prtch3:        cpi     vtdefd          ; are we trapping all non printing characters?
-       jnz     prtch4          ; nope, something else
-       lda     comchr          ; Dumb terminal.  Lets test the character
-       cpi     cr              ; cr then ok
-       jz      prtch4          ; its ok
-       cpi     lf              ; lf then ok
-       jz      prtch4
-       cpi     tab
-       jz      prtch4          ; assume tabs are expanded
-       cpi     space           ; if less than 20H ignore it
-       rm                      ; return if a control character
-
-prtch4:        call    sysflt          ; ok to print this character (in E)?
-       ora     a
-       jz      prtchr          ; no, skip it.
-       lda     logflg          ;Get the log flag.
-       cpi     81H             ;[pcc003] Are we logging
-       cz      logit           ;[pcc003] Do so if needed
-       call    selcon          ; select console
-       lda     prnflg          ;Get Print parallel flag
-       ora     a
-       cnz     outlpt          ; output to printer if flag set
-       call    outcon          ; output to console.
-       lxi     h,prtcnt        ;[pcc008] point to prt fairness count
-       inr     m               ;[pcc008] bump
-       mov     a,m             ;[pcc008] get it in a
-       cpi     prfair+1        ;[pcc008] time to be fair?
-       jm      prtchr          ;[pcc008] no, go around again.
-       mvi     m,0             ;[pcc008] reset count
-       lda     comchr          ;[6] restore that character read from comm line
-       ret                     ;[pcc008] and return
-
-; I don't think we want to print xon/xoff - this should be
-; flow control only across the link between us and the host.
-; (besides, IBM host xon's don't make sense to most micros)
-; remember xon/xoff state in xofflg (zero = xon, non-zero = xoff)
-prtxon:        xra     a               ;Yes, reset XOFF flag
-prtxof:        sta     xofflg
-       jmp     prtchr          ; look for another character
-;\f;[pcc005] Log file routines
-
-;[pcc005]
-;    logopn - open the log file
-;       Open the log file and append to it if it already exists
-;       or create one if not.
-
-logopn:        
-       mvi     a,ctrlz         ;[9] ignore control-z in log files
-       cmp     e               ;[9] well, was it?
-       rz                      ;[9] yes, to ignore it.
-       lxi     h,lognam        ;[pcc012] copy name
-       lxi     d,fcb           ;[pcc012] to fcb
-       lxi     b,12            ;[pcc012] 12 bytes
-       call    mover           ;[pcc012] copy it
-       call    appfil          ;[pcc012] open file for appending
-       jmp     logerr          ;[pcc012] error
-       lxi     h,logflg        ;[pcc005] point to log flag
-       mvi     a,80H           ;[pcc005] file open flag
-       ora     m               ;[pcc005] or in contents of logflg
-       mov     m,a             ;[pcc005] and store back
-       lxi     d,inms28        ;[pcc005] assume logging is on
-       cpi     81H             ;[pcc005] check
-       jz      prtstr          ;[pcc005] print msg if true
-       lxi     d,inms27        ;[pcc005] no, must be suspended
-       jmp     prtstr          ;[pcc005] print and return
-
-;
-;       logit - output character in E to log file.
-;       we assume the host recognizes xon/xoff. (we probably shouldn't)
-;       modem port is selected.
-;       preserves de
-;       called by: prtchr
-
-logit: lxi     h,chrcnt        ;[pcc012] point to buffer count
-       dcr     m               ;[pcc012] and decrement
-       jp      logit1          ;[pcc012] continue if ok
-       push    d               ;[pcc012] save de
-       call    outadv          ;[pcc012] advance buffer if in memory
-       call    logwrt          ;[pcc012] sigh, time to write to disk
-       pop     d               ;[pcc012] restore de
-       lda     logflg          ;[pcc012] get logging flag
-       ora     a               ;[pcc012] Did we quit because of an error
-       rz                      ;[pcc012] return now if so
-logit1:        lhld    bufpnt          ;[pcc012] get buffer pointer
-       mov     m,e             ;Store the char.
-       inx     h
-       shld    bufpnt
-       ret                     ;[pcc012] and return
-
-;[pcc012]
-;  logwrt - write to log file with XON/XOFF since it may take a while.
-
-logwrt:        call    sndxoff         ;[7] send and xoff to host
-       call    outbuf          ;[pcc012] output the buffer and advance
-       call    logerr          ;[pcc005] quit if error
-       call    sndxon          ;[send an xon to host
-       ret                     ;[pcc012]
-
-;[pcc005]
-;       logcls - Close the log file and reset the flag
-
-logcls:        lxi     d,infms6        ;[pcc005] Tell user we are closing file.
-       call    prtstr          ;[pcc005]
-       call    clofil          ;[pcc012] and do it
-       jmp     logerr          ;[pcc005] jump if error
-       lxi     h,logflg        ;[pcc005] point to flag
-       mov     a,m             ;[pcc005] get it
-       ani     7FH             ;[pcc005] clear the open bit
-       mov     m,a             ;[pcc005] and store back
-       ret                     ;[pcc005]
-
-;[pcc005]
-;    logerr - here on a variety of logging errors
-;       just close the file and disable logging
-;       called from logopn,logptr,logcls
-
-logerr:        lxi     d,erms22        ;[pcc005] Error message
-       call    prtstr          ;[pcc005] print it
-       mvi     c,closf         ;[pcc005] Close the file.
-       lxi     d,fcb           ;[pcc012]
-       call    bdos            ;[pcc005] 
-       xra     a               ;[pcc005] clear logflg
-       sta     logflg          ;[pcc005] so don't try again
-       ret                     ;[pcc005]
-;\f
-;
-;       VT52 emulation.
-;       called by: prtchr
-;       A/ contents of escflg (guaranteed non-zero)
-;       E/ current character
-;       modem is selected.
-;
-vt52:  cpi     1               ; first character after escape?
-       jnz     vt52y           ; no, must be doing cursor positioning.
-;
-;       E contains the character that followed the escape.
-;       valid characters are:
-;       A - cursor up
-;       B - cursor down
-;       C - cursor right
-;       D - cursor left
-;       F - enter graphics mode (hard to do on a non-vt52)
-;       G - exit graphics mode
-;       H - home
-;       I - reverse linefeed
-;       J - erase to end of screen
-;       K - erase to end of line
-;       Y - cursor positioning leadin
-;       Z - identify terminal as VT52
-;       [ - enter hold-screen mode (not supported)
-;       \ - exit hold-screen mode (not supported)
-;       > - enter alternate-keypad mode? (not supported)
-;       = - exit alternate-keypad mode? (not supported)
-;
-;       Invalid sequences are handled as the VT52 does - the escape and
-;       the following character are swallowed, never to be seen again.
-;       For <esc>E, the translation table may contain just '$' (no action),
-;       or may be used as clear-and-home, as in the Heath/Zenith H19.
-;
-       mov     a,e             ; get the second character of the sequence.
-       cpi     'Y'             ; if cursor lead-in handle it.
-       jnz     vt52a           ; if not, go on.
-       mvi     a,2             ; state = 2: row follows.
-       sta     escflg          ; update the flag.
-       ret                     ; back for another character
-
-vt52a: cpi     'Z'             ; VT52 ID query?
-       jz      vt52id          ; yes. claim to be one.
-       cpi     'A'             ;Less than an 'A'?
-       jm      vtig            ;Yes - ignore.
-       cpi     'K'+1           ;Greater than 'K'?
-       jp      vtig            ;Yes - ignore.
-       sui     'A'             ;Else make into index.
-       rlc                     ;Multiply by four.
-       rlc                     ;(Shift left twice.)
-       lhld    pttab           ;Load base addr of table.
-       mov     e,a             ;Move a into de pair.
-       mvi     d,00H           ;Zero out high byte.
-       dad     d               ;Double add index+offset.
-       xchg                    ;Exchange de with hl.
-       call    selcon          ; select console
-       call    prtstr          ;and syscall.
-vtig:                          ;Ignore escape sequence.
-       xra     a               ;Reset the ol' escape flag.
-       sta     escflg
-       ret                     ;Return home.
-
-; here for <esc>Z.  Tell the host we're a VT52. (Sure we are...)
-vt52id:        mvi     a,esc           ; response is escape...
-       call    setpar          ; (need correct parity)
-       mov     e,a
-       call    outmdm          ; (console already selected)
-       mvi     a,'/'           ; ... slash ...
-       call    setpar          ; (with parity)
-       mov     e,a
-       call    outmdm
-       mvi     a,'K'           ; ... K.
-       call    setpar
-       mov     e,a
-       call    outmdm
-       jmp     vtig            ; clear escape-sequence flag and return.
-
-; here when escflg isn't 0 or 1 - processing cursor positioning sequence.
-vt52y: cpi     2               ; looking for row? (y-coordinate)
-       jnz     vt52x           ; no, must be column.
-       mov     a,e             ; yes. get coordinate
-       sui     (' '-1)         ; convert from ascii (1 = top line)
-       sta     vtyval          ; store for later
-       mvi     a,3             ; advance to next state (x coord)
-       sta     escflg          ; store it
-       ret                     ; try for another character
-
-; here when escflag isn't 0, 1, or 2 - it must be 3. (right?)
-; E holds the last character of the cursor positioning sequence.
-vt52x: xra     a               ; end of escape sequence, reset state.
-       sta     escflg
-       mov     a,e             ; get column (' ' is left margin)
-       sui     (' '-1)         ; make left margin be one
-       mov     c,a             ; stash column in c
-       lda     vtyval          ; get row number
-       mov     b,a             ;  in b
-       call    selcon          ; select console
-       call    csrpos          ; call system-dependent cursor positioner
-       ret                     ; all through.
-;\f
-;
-;       conchr - copy character from console to comm line, processing
-;       (kermit's) escape sequences.
-;       Enter and exit with console selected.
-;       nonskip return: transparent mode terminated.
-;       skip return:    still in transparent mode.
-;       called by: rexmit, telnet
-
-conchr:        call    inpcon          ;Try to get a character from the console
-       ani     07FH            ;Keep only 7 bits
-       jz      rskp            ;Null means nothing there.
-       mov     e,a             ;Move the char for comparison.
-       sta     lstchr          ;Save it
-       lda     escchr          ;Get the escape char.
-       cmp     e               ;Is it an escape char?
-       jz      intchr          ;If so go process it.
-       call    selmdm          ; select the modem
-       mov     a,e             ;Get the char.
-       call    setpar          ;Set parity (if any).
-       mov     e,a             ;Restore it.
-       push    d               ; need to save e in case we are half dplx [5]
-       call    outmdm          ;Output the char to the port.
-       pop     d               ; Just in case we are half dplx [5]
-       call    selcon          ; reselect console
-       lda     ecoflg          ;Get the echo flag.
-       ora     a               ;Is it turned on?
-       jz      rskp            ;If not we're done here.
-       mov     a,e             ;Get the char.
-       ani     7FH             ;Turn off the parity bit.
-       mov     e,a
-       call    outcon          ; echo the character.
-       jmp     rskp            ; use skip return
-;\f
-;       transparent escape character has been typed. dispatch on second
-;       character. (console is still selected)
-;       here from: conchr
-
-intchr:        call    inpcon          ; get another character from the console
-       ora     a               ; zero means no character available yet.
-       jz      intchr          ; If so, loop until we get a char.
-       mov     b,a             ;Save the actual char.
-       cpi     ctrlc           ;is it Control-C?
-       jz      contc           ;yes
-       ani     137O            ;Convert to upper case.
-       cpi     'C'             ;Is it close?
-       jnz     intch0          ;If not proceed.
-contc: lxi     d,infms9        ;Say we are back.
-       call    prtstr
-       call    syscls          ; call system-dependent close routine
-       lda     logflg          ;Get the log flag.
-       ora     a               ;[pcc005] Check if open
-       cm      logcls          ;[pcc005] Close if needed
-       ret
-
-;Here if not a 'C' or '^C'
-
-intch0:        cpi     'S'             ;Is it status?
-       jnz     inch01          ;If not, proceed.
-       call    stat01          ;Print out the status stuff.
-       call    prcrlf          ;[pcc011] add a crlf
-       jmp     rskp            ;return from conchr
-
-inch01:
-inch03:        mov     a,b             ;Get the char.
-       cpi     '?'             ;Is it a help request?
-       jnz     intch1          ;If not, go to the next check.
-inch3a:        lda     logflg          ;[pcc003] Logging flag
-       ora     a               ;[pcc003] see if active
-       jp      inch04          ;[pcc005] jump if no file open
-       lxi     d,loghlp        ;[pcc003] yes, tell about R AND Q
-       call    prtstr          ;[pcc003]
-inch04:        lxi     d,inthlp        ;If so, get the address of the help message.
-       call    prtstr
-       call    sysinh          ; print system-dependent help message
-       lxi     d,inhlp1        ; Tell about doubling the escape character
-       call    prtstr
-       call    escpr           ;Print escape character
-       lxi     d,inhlp2        ;Print the rest
-       call    prtstr
-       jmp     intchr          ;Get another char.
-
-intch1:        mov     a,b             ;Get the character.
-       cpi     '0'             ;Is it '0', to send a null?
-       jnz     intch3          ;No.
-       xra     a               ;Yes, send an ASCII zero.
-       call    setpar          ; with the correct parity
-       mov     e,a
-       call    selmdm          ; (to the modem...)
-       call    outmdm
-       call    selcon          ; return with console selected
-       jmp     rskp
-
-intch3:        lda     escchr          ;Get the escape char.
-       cmp     b               ;Is it the escape char?
-       jnz     intch4          ;[pcc002] jump if not
-       mov     a,b             ;Get the char.
-       call    setpar
-       mov     e,a             ;Restore it.
-       call    selmdm
-       call    outmdm          ;Output it.
-       call    selcon          ;We promised console would be selected...
-       jmp     rskp            ;Return, we are done here.
-intch4:        mov     a,b             ;[pcc002] get it again
-       ani     137o            ;[pcc002] in upper case
-       cpi     'P'             ;[pcc002] toggle printer?
-       jnz     intch5          ;[pcc003] nope
-       lda     prnflg          ;[pcc002] get printer flag
-       xri     01h             ;[pcc002] complement it
-       sta     prnflg          ;[pcc002] and put back
-       jmp     rskp            ;[pcc002]
-intch5:        lda     logflg          ;[pcc003] get log flag
-       ora     a               ;[pcc003] See if open
-       jp      intch7          ;[pcc003] no, skip R and Q
-       mov     a,b             ;[pcc003] get back chr
-       ani     137o            ;[pcc003] make upper case
-       cpi     'R'             ;[pcc003] Is it R
-       jnz     intch6          ;[pcc003] Jump if not
-       mvi     a,81H           ;[pcc003] set flag for logging
-       sta     logflg          ;[pcc003] put it back
-       lxi     d,inms28        ;[pcc003] message
-       call    prtstr          ;[pcc003]
-       jmp     rskp            ;[pcc003] done
-intch6:        cpi     'Q'             ;[pcc003] Quit logging?
-       jnz     intch7          ;[pcc003] no
-       mvi     a,82H           ;[pcc003] flag for open, but suspended
-       sta     logflg          ;[pcc003] store away
-       lxi     d,inms27        ;[pcc003] keep them informed
-       call    prtstr          ;[pcc003]
-       jmp     rskp            ;[pcc003]
-intch7:                                ;[pcc003]
-
-intchz:        mov     a,b             ; not recognized. get saved copy back.
-       push    psw             ;[8] save as we will want to test for 'D'
-       call    sysint          ; interpret system-dependent sequences
-       jmp     intchy          ;  done. [10] Now see if D.  If so, do a C.
-       pop     psw             ;[10] tidy stack
-       mvi     e,'G'-100O      ;Otherwise send a beep.
-       call    outcon          ; to the console.
-       jmp     rskp
-
-intchy:        pop     psw             ;[10] adjust stack
-       ani     5fh             ;[10] strip parity, make it upper case
-       cpi     'D'             ;[10] was it a D?
-       jz      contc           ;[10] yup, so to the equivalent of an escape-C
-       jmp     rskp
-;\f
-; Little code to allow some expansion of code without changing
-;  every futher address, only up to the end of this file.
-;   TO BE REMOVED FOR RELEASE!
-
-;      org ($+100h) AND 0FF00H
-IF lasm
-       LINK    CPSCPM
-ENDIF;lasm
+; CPSTT.ASM\r
+;       KERMIT - (Celtic for "FREE")\r
+;\r
+;       This is the CP/M-80 implementation of the Columbia University\r
+;       KERMIT file transfer protocol.\r
+;\r
+;       Version 4.0\r
+;\r
+;       Copyright June 1981,1982,1983,1984,1985\r
+;       Columbia University\r
+;\r
+; Originally written by Bill Catchings of the Columbia University Center for\r
+; Computing Activities, 612 W. 115th St., New York, NY 10025.\r
+;\r
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,\r
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many\r
+; others. \r
+;\r
+;       This file contains the code for the TRANSMIT and CONNECT commands,\r
+;       which communicate with a host which is not running KERMIT.\r
+;\r
+; revision history:\r
+;\r
+;edit 12, 31-Jan-1991 by MF. Delete call to "inbuf" after "xmit1" in\r
+;      the TRANSMIT command. "getfil" initializes various counters so that\r
+;      when "in1chr" is first called, "inbuf" will be called immediately\r
+;      and will read sectors of the file to be transmitted from disk.\r
+;      This, along with a fix to "in1chr" in CPSUTL.ASM, fixes a bug\r
+;      discovered by Lance Tagliapietra of the University of Wisconsin at\r
+;      Platteville wherein the TRANSMIT command was failing to transmit some\r
+;      characters in files over one sector in length. See CPSUTL.ASM,\r
+;      edit 29.\r
+; edit 11, 10 September, a987, by OBSchou.  Modified TRANSMIT command\r
+;      to TRANSMIT <file> <string>\r
+;\r
+; edit 10, 27 August, 1987 by OBSchou.  Fixed bugs in Transmit, but I may\r
+;      be introducing problems for IBM/CMS or half duplex systems.  What\r
+;      does this combination do??\r
+;\r
+; edit 9 30 March, 1987 by OBSchou to replace the TRANSMIT routine.\r
+;      Syntax is now TRANSMIT file after a previous \r
+;      INPUT <wait time> <string to wait for>\r
+;\r
+; edit 8 19 June, 1986 by OBSchou.  Modified the interupt testing routine\r
+;       to see if the command was a 'D' (Drop the line), in which case also\r
+;       do a 'C', ie disconnect.  This is really a little too much of a\r
+;       system dependent thing.\r
+;       For now, Ill leave it here, and possibly move it later.\r
+;\r
+; edit 7 30 May 1986 OBSchou.  Moved xon/xoff control (ie XON/OFF sent to host)\r
+;       out to CPSUTL so that ther printer routine can use it too.\r
+;\r
+; edit 6 30 April, 1986 by OBSchou.\r
+;       Fixed transmit bug, so as soon as the protocol character is \r
+;       received from the host is received then another line is sent.\r
+;       added in a comchr (ds 1) to save the character read from the comm \r
+;       line in prtchr, and is restored in a on return.\r
+;\r
+; edit 5 7 March, 1986 by OBSchou Loughborough University.  \r
+;       Need to save the E register before calling outmdm (in CPSSYS.ASM)\r
+;       if doing Half duplex.  Push/pop DE should sort this problem\r
+;\r
+; edit 4: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809\r
+;\r
+;pcc002 28-Dec-84       modules:cp4tt,cp4utl\r
+;       Add connect mode <esc>P command to toggle printer on\r
+;       and off.  Conflicts with "official" recommended commands\r
+;       in protocol manual, but I don't think CP/M will ever get\r
+;       a PUSH command.\r
+;\r
+;pcc003-pcc005  2-Jan-85        vjc     modules:cp4mit,cp4tt,cp4utl\r
+;       These edits must all be installed together and change the way\r
+;       logging is handled.  The log file spec is moved to a separate\r
+;       fcb, and not opened until an actual CONNECT command is given.\r
+;       This takes care of a NASTY bug that if you used any other file\r
+;       command between the LOG and CONNECT, the log file would get\r
+;       written over the last file used.  This also allows logging to\r
+;       be "permanently" enabled until an CLOSE (new command) for all\r
+;       CONNECT sessions, like most other kermits do.  If a log file\r
+;       already exists, it will be appended to.  Also add two new\r
+;       CONNECT mode commands <esc>Q to suspend logging and <esc>R to\r
+;       resume.  <esc>R means something else during TRANSMIT, but\r
+;       logging is never on then, so there shouldn't be any conflict.\r
+;       I also changed the write code, so that it can handle one more\r
+;       character after the XOFF is send to stop the host.  This allows\r
+;       a little "slop" for systems that don't stop immediately (such\r
+;       as TOPS10), but it didn't help much.\r
+;\r
+;pcc008 2-Jan-85        vjc     modules:cp4def,cp4tt,cp4utl\r
+;       Keyboard input during CONNECT mode can get locked out if\r
+;       there is enough input from the modem port to keep prtchr\r
+;       busy.  This can happen for example, if the printer is running\r
+;       at the same speed as the modem line, leaving you helpless to\r
+;       turn it off or abort the host.  Add a fairness count, so that\r
+;       at least every prfair characters we look at console input.\r
+;\r
+;pcc012 4-Jan-85        vjc     modules:cp4mit,cp4tt,cp4utl\r
+;       Use the big buffer for the log file.  Move the log file back\r
+;       into the common fcb and only save the drive, name, and\r
+;       extension between connects.  Add new routines to cp4utl to\r
+;       create or append to an existing file, and to conditionally\r
+;       advance buffers only if in memory.  Remove edit pcc003 that\r
+;       allows one more character after the xoff, since it didn't\r
+;       really work very well and does not fit in well with the way\r
+;       the buffer advancing routines are set up.  If someone still\r
+;       thinks this would be useful, it could be put back in with a\r
+;       little more work.\r
+;       \r
+;       While testing this edit, I also noticed another bug that\r
+;       the command parsing routines do not limit or check the\r
+;       length of command lines or file specs, trashing what ever\r
+;       comes after them.  Currently because of where the fcb and\r
+;       command buffer are located, this does not usually cause a\r
+;       problem, but could if an extremely long line was typed in,\r
+;       or in the future multiple fcbs defined elsewhere in memory\r
+;       were used.  Maybe this should be put on the bug list\r
+;       somewhere.\r
+;\r
+; edit 3: July 27, 1984\r
+;       Allow assembly with LASM: to CP4TT is linked by CP4PKT, and links\r
+;       to CP4CPM; remove exclamation points so as not to confuse LASM.\r
+;       Add Toad Hall TACtrap to TRANSMIT command (TAC intercept character\r
+;       is only doubled if it's data; when typed by the user, they're not\r
+;       automatically doubled)\r
+;\r
+; edit 2: June 7, 1984\r
+;       formatting and documentation; add module version number; make sure\r
+;       console is selected when leaving intchr.\r
+;\r
+; edit 1: May, 1984\r
+;       extracted from CPMBASE.M80 version 3.9; modifications are described\r
+;       in the accompanying .UPD file.\r
+\r
+ttver: db      'CPSTT.ASM  (12) 31-Jan-1991$'\r
+\r
+;       This is the TRANSMIT command.  It attempts to send a file, even\r
+;       though there is no KERMIT on the other side.\r
+;       here from: kermit\r
+;\r
+; [OBS] I have replaced the routine, so that TRANSMIT <filename> <wait string>\r
+; will send a line at a time to the host in a manner similar to MSKERMIT\r
+;\r
+;\r
+xmit:  mvi     a,cmofi         ;Parse an input file spec (non-wild).\r
+       lxi     d,fcb           ;Give the address for the FCB.\r
+       call    comnd\r
+       jmp     kermit          ;Give up on bad parse.\r
+;\r
+       lxi     d,stbuff        ; where to put the string\r
+       mvi     a,cmtxt         ; get text\r
+       call    comnd\r
+       jmp     kermit          ; not quite correct...\r
+       sta     strcnt          ; string count returned in a\r
+       ana     a               ; if its zero, make it 1 character (CR)\r
+       jnz     xmit0\r
+       mvi     a,1\r
+       sta     strcnt\r
+       mvi     a,cr\r
+       sta     stbuff\r
+;\r
+xmit0: call    cfmcmd\r
+       call    getfil          ;Open file.\r
+       cpi     0FFH            ;Succeed?\r
+       jnz     xmit1\r
+       lxi     d,erms15\r
+       call    prtstr          ;Display error msg.\r
+       jmp     kermit\r
+\r
+;\r
+; New TRANSMIT routine - transmit a file, line by line, to a remote host\r
+;      waiting each time for one or more characters to be returned\r
+;      as a remote host prompt.  It could be as simple as a CR or LF\r
+;      character.  Repeat until the complete file has been sent, then\r
+;      close the transmitted file, and drop into the connect state so the\r
+;      user can tidy up at the host end.\r
+;get the file to send, open it up, and read first sector from disk\r
+\r
+xmit1: lxi     d,inms19        ; say we are send a file to the host\r
+       call    prtstr\r
+\r
+       xra     a\r
+       sta     repcnt          ; clear the host prompt chars. counter \r
+       sta     starc           ; clear star count\r
+;[MF][12]Delete the following call to "inbuf" as the call to "getfil"\r
+;[MF][12]above will have initialized counters and flags so that when\r
+;[MF][12]"in1chr" is called, "inbuf" will be called immediately and will\r
+;[MF][12]immediately read from disk. Counters and flags will then be\r
+;[MF][12]properly set up to read all characters of the file to be\r
+;[MF][12]transmitted.\r
+;      call    inbuf           ; read one sector from disk\r
+;      jmp     xmtex           ; exit if error\r
+\r
+\r
+xmt10: xra     a               ; clear retransmit flag and count etc\r
+       sta     rexbfl          ; retransmit flag (1=> retransmit)\r
+       sta     rexcnt          ; character counter\r
+\r
+xmt1:  call    xmt1ch          ; send a character\r
+       ani     7fh             ; strip any parity\r
+       cpi     cr              ; have we reached the end of the line\r
+       jnz     xmt1            ; nope, loop around again\r
+\r
+; Now wait for a string back from the host.  Compare with STRING buffer\r
+;\r
+       xra     a               ; clear the character count\r
+       sta     rexcnt\r
+;\r
+       call    selcon          ; sent a line, send a star to console\r
+       mvi     e,'*'\r
+       call    outcon\r
+       lda     starc           ; update star count\r
+       inr     a\r
+       sta     starc\r
+       cpi     60              ; sent 60 stars?\r
+       jnz     xmt1a           ; nope...\r
+       xra     a\r
+       sta     starc\r
+       call    prcrlf\r
+xmt1a:\r
+\r
+xmt3:  lda     eoflag          ; have we hit end of file?\r
+       ana     a\r
+       jnz     xmtex           ; yup, so quit.\r
+       xra     a\r
+       sta     repcnt          ; clear the host prompt chars.counter\r
+xmt2:  call    rd1chl          ; read a character from the line\r
+       ani     7fh             ; set flags\r
+       jnz     xmt4            ; Not zero => we have a character from host\r
+       call    ckchr           ; see if *WE* have a character from console\r
+       push    psw             ; restore to modem\r
+       call    selmdm\r
+       pop     psw\r
+       ani     7fh             ; stip parity (should not be there)\r
+       jnz     xmt2a           ; if a null, try again\r
+       lda     strcnt          ; if the string length is zero, dont wait.\r
+       ana     a\r
+       jz      xmt1            ; so loop back again\r
+       jmp     xmt4            ; else test for xon/off and incomming string\r
+\r
+xmt2a: cpi     cntlc           ; do we want to abort?\r
+       jz      xmtex           ; in which case drop through to connect mode\r
+       cpi     cntlz           ; if control z exit back to command loop\r
+       jnz     xmt2b           ; else try for other characters\r
+       lxi     d,fcb           ; close file before exiting to command loop\r
+       mvi     c,closf\r
+       call    bdos\r
+       jmp     kermit\r
+\r
+xmt2b: cpi     cr              ; a cr => resend last line\r
+       jnz     xmt2            ; nope, then ignore it\r
+       mvi     a,1\r
+       sta     rexbfl          ; else we want to resend the line.\r
+       jmp     xmt1\r
+\r
+xmt4:  jmp     xmt6            ; skit xoff test for now...*****************\r
+\r
+       cpi     xoff            ; xoff from host?\r
+       jnz     xmt6\r
+xmt5:  call    rd1chl          ; else see if XOFF comming\r
+       ani     7fh\r
+       jnz     xmt6            ; assume an xoff\r
+       call    ckchr           ; anything at console?\r
+       push    psw\r
+       call    selmdm\r
+       pop     psw\r
+       ani     7fh\r
+       cpi     cntlc           ; control-c == abort & play terminal\r
+       jz      xmtex\r
+       ana     a               ; anything else?\r
+       jz      xmt5            ;loop again\r
+\r
+xmt6:  mov     e,a             ; save it for a while\r
+       lda     repcnt          ; see if this character matches with one in buffer\r
+       lxi     h,stbuff        ; point to string buffer\r
+       add     l               ; make hl = hl + a\r
+       mov     l,a\r
+       mvi     a,0\r
+       adc     h\r
+       mov     h,a             ; not using xra, as that clears the Carry flag\r
+       mov     a,e             ; get the character back again\r
+       cmp     m               ; is it = to what we expect?\r
+       jnz     xmt3            ; no, clear counter and try again\r
+       lda     repcnt          ; yes, then update the pointer, and ...\r
+       inr     a               ; ... see if we have received all ...\r
+       sta     repcnt          ; ... we should have received\r
+       mov     e,a             ; save length into E again\r
+       lda     strcnt          ; get the length to compare\r
+       sub     e               ; if (e) > string length, we have it\r
+       jz      xmt10           ; so send next line (clear counters etc)\r
+       jmp     xmt2            ; else wait for a little longer\r
+\r
+\r
+;\r
+; Routine below sends a character to the line.  It sends up to a CR, and then\r
+;      it waits for a reply.  This routine is called from xmt1, so if at \r
+;      end of file, return.  Then XMT1 will drop through\r
+;      to connect.\r
+xmt1ch:        ; send a character from the xmtbuf to the line\r
+       call    selmdm          ; just in case it uses it\r
+       lda     eoflag          ; have we hit end of file\r
+       ana     a               ; set flags\r
+       jnz     xmt1c1          ; no, so dont...\r
+       mvi     a,cr            ; load up a carriage return\r
+xmt1c1:        call    get1xc          ; get the character to send\r
+       cpi     lf              ; dont send line feeds\r
+;      jz      xmt1c1\r
+       cpi     cntlz           ; if control z, then we are at end of the file\r
+       jz      xmtex           ; so close the file and drop into telcon\r
+       cpi     20h             ; control character?\r
+       jp      xmt11           ; no, so ok\r
+       cpi     cr              ; cr, and tabs ok to send\r
+       jz      xmt11\r
+       cpi     tab\r
+       jz      xmt11\r
+       jmp     xmt1c1          ; else try for another character\r
+\r
+xmt11: call    setpar          ; else set parity etc\r
+       push    psw             ; we want to keep this for a while\r
+       mov     e,a             ; we need character in e\r
+       call    outmdm\r
+       pop     psw             ; restore the character we sent\r
+       mov     e,a             ; now, if a TAC is set on..\r
+       lda     tacflg\r
+       ana     a               \r
+       mov     a,e             ; (return must have sent character in a)\r
+       jz      xmt1c2          ; test for xon/off\r
+       lda     tacchr          ;... get the tac character\r
+       cmp     e               ; do we send it again?\r
+       jnz     xmt1c2          ; test for xon/off\r
+       push    psw             ; save character for return. Already set E...\r
+       call    outmdm\r
+       pop     psw\r
+\r
+xmt1c2:        ret\r
+\r
+get1xc:        ; get a character from the sector or re-transmit buffer read \r
+;      into a.  Read a new sector if we run out.\r
+;\r
+; First, see if we do a retransmit\r
+       lda     rexbfl\r
+       ana     a               ; if zero, a genuine line\r
+       jz      get1x1\r
+; have to retransmit a line\r
+       lxi     h,rexbuf\r
+       lda     rexcnt          ; add counter to buffer base\r
+       mvi     d,0\r
+       mov     e,a\r
+       dad     d\r
+       inr     a               ; update pointer\r
+       sta     rexcnt\r
+       mov     a,m             ; get next character to send\r
+       ret                     ; and exit\r
+\r
+get1x1:        call    in1chr          ; get a character from the file. \r
+       mov     c,a             ; save it to the retransmit buffer\r
+       lda     rexcnt\r
+       mov     e,a\r
+       mvi     d,0\r
+       lxi     h,rexbuf\r
+       dad     d               ; point to next position\r
+       inr     a\r
+       sta     rexcnt          ; update the character pointer\r
+       mov     a,c             ; restore character to a\r
+       mov     m,c             ; get character to c\r
+       ret\r
+\r
+\r
+\r
+; read a character from the line.\r
+rd1chl:        \r
+       call    selmdm          ; select the modem\r
+       call    inpmdm          ; get input from the modem\r
+       ani     7fh             ; strip parity\r
+                               ; may UPPERCASE-ify if case sensitivity off\r
+       ret                     ; return to caller\r
+\r
+;  End of transmit routine.  Close input file name, and say we are dropping\r
+;  throught to telnet.  Note that if eof not found, it is assumed that\r
+;  this is the ABORT exit.\r
+\r
+xmtex:\r
+       lxi     d,fcb           ; close the transmitted file\r
+       mvi     c,closf\r
+       call    bdos\r
+       call    selcon          ; make sure we are talking to the console\r
+\r
+       lda     eoflag          ; end of file or abort exit?\r
+       lxi     d,inms22        ; assume eof...\r
+       ana     a\r
+       jz      xmtex1\r
+       lxi     d,inms29        ; we were wrong, its an abort.\r
+xmtex1:        jmp     telnt1          ; and drop through to connect mode\r
+                               ; telnet does the printing\r
+\r
+\r
+\r
+;\f\r
+;   telnet - the CONNECT command.\r
+;       here from: kermit\r
+;   telnt1 - entry to connect mode from TRANSMIT command\r
+;       here from: xend\r
+\r
+telnet:        call    cfmcmd\r
+       lxi     d,infms7        ;Output start of message\r
+; enter here from TRANSMIT command.\r
+telnt1:        call    prtstr\r
+       call    escpr           ;Print the escape char.\r
+       lxi     d,infms8        ;Output some more of the message\r
+       call    prtstr\r
+       call    escpr           ;Print the escape char again.\r
+       lxi     d,inms8a        ;Print the remainder of the message\r
+       call    prtstr\r
+       call    syscon          ;do system-dependent stuff\r
+       lda     logflg          ;[pcc005] Want a log?\r
+       ora     a               ;[pcc005]\r
+       cnz     logopn          ;[pcc005] Open if so\r
+\r
+chrlup:        call    prtchr          ;See if char at port (send to console).\r
+       call    conchr          ;See if char at console (send to port).\r
+       jmp     kermit          ;requested to end session - go to command loop.\r
+       jmp     chrlup          ;Go do it again.\r
+;\f\r
+;\r
+;       prtchr - copy characters from comm line to console\r
+;       returns: nonskip, console selected.\r
+;       called by: xnext, rexmit, telnet\r
+;\r
+\r
+prtchr:        call    selmdm          ; select modem port\r
+       call    inpmdm          ; try to get a character from it\r
+       push    psw             ; restore to console\r
+       call    selcon          ; select console\r
+       pop     psw             ; restore the (possible character) read\r
+       ora     a               ; test character\r
+       jnz     prtch0          ; if non-zero, process it.\r
+       sta     prtcnt          ;[pcc008] zero out prt fairness count\r
+       ret                     ; return.\r
+\r
+prtch0:        ani     7FH             ; drop parity bit.\r
+       sta     comchr          ;[6] save it in case we need it again\r
+       lda     vtflg           ;[9] get the vt52 emulation flag\r
+       cpi     vtdefe          ;[9] are we doing external emulation?\r
+       lda     comchr          ;[9] collect character again\r
+       jz      extern          ;[9] jup, go do it.\r
+\r
+       ana     a               ; set flags.  it may be a null\r
+       jz      prtchr          ; ignore null (filler)\r
+       cpi     del             ; ignore delete, too\r
+       jz      prtchr\r
+       cpi     xon             ;Is it an XON?\r
+       jz      prtxon          ;yes\r
+       cpi     xoff            ;Is it an XOFF?\r
+       jz      prtxof          ;yes\r
+       mov     e,a             ;Set the char aside.\r
+       lda     vtflg           ;Get the VT52 emulation flag.\r
+       cpi     vtdefv          ;Is the flag set for VT52 (ie 1)\r
+                               ;0 = none\r
+                               ;1 = VT52\r
+                               ;2 = external\r
+                               ;3 = dumb (traps non printing chars)\r
+                               ;0ffh not possible by local code (Will change)\r
+       jnz     prtch1          ;If not, don't do this stuff.\r
+       lda     escflg          ;Get the escape flag.\r
+       ora     a               ;Are we working on an escape sequence?\r
+       jz      prtch2          ;If not, continue.\r
+       call    vt52            ;If so, work on it some more\r
+       jmp     prtchr          ;try for more characters.\r
+\r
+prtch2:        mov     a,e             ;normal text.\r
+       cpi     esc             ;Is the char an escape?\r
+       jnz     prtch1          ;If not skip on.\r
+       mvi     a,1\r
+       sta     escflg          ;Set the escape flag: escape seen.\r
+       jmp     prtchr          ;Get another char...\r
+\r
+prtch1:        cpi     vtdefe          ; are we doing external emulation?\r
+       jnz     prtch3          ; assume we continue on\r
+       lxi     h,extern+1      ; get address of external emulator\r
+       mov     a,h             ; se if address = 0 (not implemented)\r
+       ora     l\r
+       jz      prtch3          ; not external, assume we just carry on\r
+       pchl                    ; go do external emulation.  RET back to caller\r
+\r
+prtch3:        cpi     vtdefd          ; are we trapping all non printing characters?\r
+       jnz     prtch4          ; nope, something else\r
+       lda     comchr          ; Dumb terminal.  Lets test the character\r
+       cpi     cr              ; cr then ok\r
+       jz      prtch4          ; its ok\r
+       cpi     lf              ; lf then ok\r
+       jz      prtch4\r
+       cpi     tab\r
+       jz      prtch4          ; assume tabs are expanded\r
+       cpi     space           ; if less than 20H ignore it\r
+       rm                      ; return if a control character\r
+\r
+prtch4:        call    sysflt          ; ok to print this character (in E)?\r
+       ora     a\r
+       jz      prtchr          ; no, skip it.\r
+       lda     logflg          ;Get the log flag.\r
+       cpi     81H             ;[pcc003] Are we logging\r
+       cz      logit           ;[pcc003] Do so if needed\r
+       call    selcon          ; select console\r
+       lda     prnflg          ;Get Print parallel flag\r
+       ora     a\r
+       cnz     outlpt          ; output to printer if flag set\r
+       call    outcon          ; output to console.\r
+       lxi     h,prtcnt        ;[pcc008] point to prt fairness count\r
+       inr     m               ;[pcc008] bump\r
+       mov     a,m             ;[pcc008] get it in a\r
+       cpi     prfair+1        ;[pcc008] time to be fair?\r
+       jm      prtchr          ;[pcc008] no, go around again.\r
+       mvi     m,0             ;[pcc008] reset count\r
+       lda     comchr          ;[6] restore that character read from comm line\r
+       ret                     ;[pcc008] and return\r
+\r
+; I don't think we want to print xon/xoff - this should be\r
+; flow control only across the link between us and the host.\r
+; (besides, IBM host xon's don't make sense to most micros)\r
+; remember xon/xoff state in xofflg (zero = xon, non-zero = xoff)\r
+prtxon:        xra     a               ;Yes, reset XOFF flag\r
+prtxof:        sta     xofflg\r
+       jmp     prtchr          ; look for another character\r
+;\f;[pcc005] Log file routines\r
+\r
+;[pcc005]\r
+;    logopn - open the log file\r
+;       Open the log file and append to it if it already exists\r
+;       or create one if not.\r
+\r
+logopn:        \r
+       mvi     a,ctrlz         ;[9] ignore control-z in log files\r
+       cmp     e               ;[9] well, was it?\r
+       rz                      ;[9] yes, to ignore it.\r
+       lxi     h,lognam        ;[pcc012] copy name\r
+       lxi     d,fcb           ;[pcc012] to fcb\r
+       lxi     b,12            ;[pcc012] 12 bytes\r
+       call    mover           ;[pcc012] copy it\r
+       call    appfil          ;[pcc012] open file for appending\r
+       jmp     logerr          ;[pcc012] error\r
+       lxi     h,logflg        ;[pcc005] point to log flag\r
+       mvi     a,80H           ;[pcc005] file open flag\r
+       ora     m               ;[pcc005] or in contents of logflg\r
+       mov     m,a             ;[pcc005] and store back\r
+       lxi     d,inms28        ;[pcc005] assume logging is on\r
+       cpi     81H             ;[pcc005] check\r
+       jz      prtstr          ;[pcc005] print msg if true\r
+       lxi     d,inms27        ;[pcc005] no, must be suspended\r
+       jmp     prtstr          ;[pcc005] print and return\r
+\r
+;\r
+;       logit - output character in E to log file.\r
+;       we assume the host recognizes xon/xoff. (we probably shouldn't)\r
+;       modem port is selected.\r
+;       preserves de\r
+;       called by: prtchr\r
+\r
+logit: lxi     h,chrcnt        ;[pcc012] point to buffer count\r
+       dcr     m               ;[pcc012] and decrement\r
+       jp      logit1          ;[pcc012] continue if ok\r
+       push    d               ;[pcc012] save de\r
+       call    outadv          ;[pcc012] advance buffer if in memory\r
+       call    logwrt          ;[pcc012] sigh, time to write to disk\r
+       pop     d               ;[pcc012] restore de\r
+       lda     logflg          ;[pcc012] get logging flag\r
+       ora     a               ;[pcc012] Did we quit because of an error\r
+       rz                      ;[pcc012] return now if so\r
+logit1:        lhld    bufpnt          ;[pcc012] get buffer pointer\r
+       mov     m,e             ;Store the char.\r
+       inx     h\r
+       shld    bufpnt\r
+       ret                     ;[pcc012] and return\r
+\r
+;[pcc012]\r
+;  logwrt - write to log file with XON/XOFF since it may take a while.\r
+\r
+logwrt:        call    sndxoff         ;[7] send and xoff to host\r
+       call    outbuf          ;[pcc012] output the buffer and advance\r
+       call    logerr          ;[pcc005] quit if error\r
+       call    sndxon          ;[send an xon to host\r
+       ret                     ;[pcc012]\r
+\r
+;[pcc005]\r
+;       logcls - Close the log file and reset the flag\r
+\r
+logcls:        lxi     d,infms6        ;[pcc005] Tell user we are closing file.\r
+       call    prtstr          ;[pcc005]\r
+       call    clofil          ;[pcc012] and do it\r
+       jmp     logerr          ;[pcc005] jump if error\r
+       lxi     h,logflg        ;[pcc005] point to flag\r
+       mov     a,m             ;[pcc005] get it\r
+       ani     7FH             ;[pcc005] clear the open bit\r
+       mov     m,a             ;[pcc005] and store back\r
+       ret                     ;[pcc005]\r
+\r
+;[pcc005]\r
+;    logerr - here on a variety of logging errors\r
+;       just close the file and disable logging\r
+;       called from logopn,logptr,logcls\r
+\r
+logerr:        lxi     d,erms22        ;[pcc005] Error message\r
+       call    prtstr          ;[pcc005] print it\r
+       mvi     c,closf         ;[pcc005] Close the file.\r
+       lxi     d,fcb           ;[pcc012]\r
+       call    bdos            ;[pcc005] \r
+       xra     a               ;[pcc005] clear logflg\r
+       sta     logflg          ;[pcc005] so don't try again\r
+       ret                     ;[pcc005]\r
+;\f\r
+;\r
+;       VT52 emulation.\r
+;       called by: prtchr\r
+;       A/ contents of escflg (guaranteed non-zero)\r
+;       E/ current character\r
+;       modem is selected.\r
+;\r
+vt52:  cpi     1               ; first character after escape?\r
+       jnz     vt52y           ; no, must be doing cursor positioning.\r
+;\r
+;       E contains the character that followed the escape.\r
+;       valid characters are:\r
+;       A - cursor up\r
+;       B - cursor down\r
+;       C - cursor right\r
+;       D - cursor left\r
+;       F - enter graphics mode (hard to do on a non-vt52)\r
+;       G - exit graphics mode\r
+;       H - home\r
+;       I - reverse linefeed\r
+;       J - erase to end of screen\r
+;       K - erase to end of line\r
+;       Y - cursor positioning leadin\r
+;       Z - identify terminal as VT52\r
+;       [ - enter hold-screen mode (not supported)\r
+;       \ - exit hold-screen mode (not supported)\r
+;       > - enter alternate-keypad mode? (not supported)\r
+;       = - exit alternate-keypad mode? (not supported)\r
+;\r
+;       Invalid sequences are handled as the VT52 does - the escape and\r
+;       the following character are swallowed, never to be seen again.\r
+;       For <esc>E, the translation table may contain just '$' (no action),\r
+;       or may be used as clear-and-home, as in the Heath/Zenith H19.\r
+;\r
+       mov     a,e             ; get the second character of the sequence.\r
+       cpi     'Y'             ; if cursor lead-in handle it.\r
+       jnz     vt52a           ; if not, go on.\r
+       mvi     a,2             ; state = 2: row follows.\r
+       sta     escflg          ; update the flag.\r
+       ret                     ; back for another character\r
+\r
+vt52a: cpi     'Z'             ; VT52 ID query?\r
+       jz      vt52id          ; yes. claim to be one.\r
+       cpi     'A'             ;Less than an 'A'?\r
+       jm      vtig            ;Yes - ignore.\r
+       cpi     'K'+1           ;Greater than 'K'?\r
+       jp      vtig            ;Yes - ignore.\r
+       sui     'A'             ;Else make into index.\r
+       rlc                     ;Multiply by four.\r
+       rlc                     ;(Shift left twice.)\r
+       lhld    pttab           ;Load base addr of table.\r
+       mov     e,a             ;Move a into de pair.\r
+       mvi     d,00H           ;Zero out high byte.\r
+       dad     d               ;Double add index+offset.\r
+       xchg                    ;Exchange de with hl.\r
+       call    selcon          ; select console\r
+       call    prtstr          ;and syscall.\r
+vtig:                          ;Ignore escape sequence.\r
+       xra     a               ;Reset the ol' escape flag.\r
+       sta     escflg\r
+       ret                     ;Return home.\r
+\r
+; here for <esc>Z.  Tell the host we're a VT52. (Sure we are...)\r
+vt52id:        mvi     a,esc           ; response is escape...\r
+       call    setpar          ; (need correct parity)\r
+       mov     e,a\r
+       call    outmdm          ; (console already selected)\r
+       mvi     a,'/'           ; ... slash ...\r
+       call    setpar          ; (with parity)\r
+       mov     e,a\r
+       call    outmdm\r
+       mvi     a,'K'           ; ... K.\r
+       call    setpar\r
+       mov     e,a\r
+       call    outmdm\r
+       jmp     vtig            ; clear escape-sequence flag and return.\r
+\r
+; here when escflg isn't 0 or 1 - processing cursor positioning sequence.\r
+vt52y: cpi     2               ; looking for row? (y-coordinate)\r
+       jnz     vt52x           ; no, must be column.\r
+       mov     a,e             ; yes. get coordinate\r
+       sui     (' '-1)         ; convert from ascii (1 = top line)\r
+       sta     vtyval          ; store for later\r
+       mvi     a,3             ; advance to next state (x coord)\r
+       sta     escflg          ; store it\r
+       ret                     ; try for another character\r
+\r
+; here when escflag isn't 0, 1, or 2 - it must be 3. (right?)\r
+; E holds the last character of the cursor positioning sequence.\r
+vt52x: xra     a               ; end of escape sequence, reset state.\r
+       sta     escflg\r
+       mov     a,e             ; get column (' ' is left margin)\r
+       sui     (' '-1)         ; make left margin be one\r
+       mov     c,a             ; stash column in c\r
+       lda     vtyval          ; get row number\r
+       mov     b,a             ;  in b\r
+       call    selcon          ; select console\r
+       call    csrpos          ; call system-dependent cursor positioner\r
+       ret                     ; all through.\r
+;\f\r
+;\r
+;       conchr - copy character from console to comm line, processing\r
+;       (kermit's) escape sequences.\r
+;       Enter and exit with console selected.\r
+;       nonskip return: transparent mode terminated.\r
+;       skip return:    still in transparent mode.\r
+;       called by: rexmit, telnet\r
+\r
+conchr:        call    inpcon          ;Try to get a character from the console\r
+       ani     07FH            ;Keep only 7 bits\r
+       jz      rskp            ;Null means nothing there.\r
+       mov     e,a             ;Move the char for comparison.\r
+       sta     lstchr          ;Save it\r
+       lda     escchr          ;Get the escape char.\r
+       cmp     e               ;Is it an escape char?\r
+       jz      intchr          ;If so go process it.\r
+       call    selmdm          ; select the modem\r
+       mov     a,e             ;Get the char.\r
+       call    setpar          ;Set parity (if any).\r
+       mov     e,a             ;Restore it.\r
+       push    d               ; need to save e in case we are half dplx [5]\r
+       call    outmdm          ;Output the char to the port.\r
+       pop     d               ; Just in case we are half dplx [5]\r
+       call    selcon          ; reselect console\r
+       lda     ecoflg          ;Get the echo flag.\r
+       ora     a               ;Is it turned on?\r
+       jz      rskp            ;If not we're done here.\r
+       mov     a,e             ;Get the char.\r
+       ani     7FH             ;Turn off the parity bit.\r
+       mov     e,a\r
+       call    outcon          ; echo the character.\r
+       jmp     rskp            ; use skip return\r
+;\f\r
+;       transparent escape character has been typed. dispatch on second\r
+;       character. (console is still selected)\r
+;       here from: conchr\r
+\r
+intchr:        call    inpcon          ; get another character from the console\r
+       ora     a               ; zero means no character available yet.\r
+       jz      intchr          ; If so, loop until we get a char.\r
+       mov     b,a             ;Save the actual char.\r
+       cpi     ctrlc           ;is it Control-C?\r
+       jz      contc           ;yes\r
+       ani     137O            ;Convert to upper case.\r
+       cpi     'C'             ;Is it close?\r
+       jnz     intch0          ;If not proceed.\r
+contc: lxi     d,infms9        ;Say we are back.\r
+       call    prtstr\r
+       call    syscls          ; call system-dependent close routine\r
+       lda     logflg          ;Get the log flag.\r
+       ora     a               ;[pcc005] Check if open\r
+       cm      logcls          ;[pcc005] Close if needed\r
+       ret\r
+\r
+;Here if not a 'C' or '^C'\r
+\r
+intch0:        cpi     'S'             ;Is it status?\r
+       jnz     inch01          ;If not, proceed.\r
+       call    stat01          ;Print out the status stuff.\r
+       call    prcrlf          ;[pcc011] add a crlf\r
+       jmp     rskp            ;return from conchr\r
+\r
+inch01:\r
+inch03:        mov     a,b             ;Get the char.\r
+       cpi     '?'             ;Is it a help request?\r
+       jnz     intch1          ;If not, go to the next check.\r
+inch3a:        lda     logflg          ;[pcc003] Logging flag\r
+       ora     a               ;[pcc003] see if active\r
+       jp      inch04          ;[pcc005] jump if no file open\r
+       lxi     d,loghlp        ;[pcc003] yes, tell about R AND Q\r
+       call    prtstr          ;[pcc003]\r
+inch04:        lxi     d,inthlp        ;If so, get the address of the help message.\r
+       call    prtstr\r
+       call    sysinh          ; print system-dependent help message\r
+       lxi     d,inhlp1        ; Tell about doubling the escape character\r
+       call    prtstr\r
+       call    escpr           ;Print escape character\r
+       lxi     d,inhlp2        ;Print the rest\r
+       call    prtstr\r
+       jmp     intchr          ;Get another char.\r
+\r
+intch1:        mov     a,b             ;Get the character.\r
+       cpi     '0'             ;Is it '0', to send a null?\r
+       jnz     intch3          ;No.\r
+       xra     a               ;Yes, send an ASCII zero.\r
+       call    setpar          ; with the correct parity\r
+       mov     e,a\r
+       call    selmdm          ; (to the modem...)\r
+       call    outmdm\r
+       call    selcon          ; return with console selected\r
+       jmp     rskp\r
+\r
+intch3:        lda     escchr          ;Get the escape char.\r
+       cmp     b               ;Is it the escape char?\r
+       jnz     intch4          ;[pcc002] jump if not\r
+       mov     a,b             ;Get the char.\r
+       call    setpar\r
+       mov     e,a             ;Restore it.\r
+       call    selmdm\r
+       call    outmdm          ;Output it.\r
+       call    selcon          ;We promised console would be selected...\r
+       jmp     rskp            ;Return, we are done here.\r
+intch4:        mov     a,b             ;[pcc002] get it again\r
+       ani     137o            ;[pcc002] in upper case\r
+       cpi     'P'             ;[pcc002] toggle printer?\r
+       jnz     intch5          ;[pcc003] nope\r
+       lda     prnflg          ;[pcc002] get printer flag\r
+       xri     01h             ;[pcc002] complement it\r
+       sta     prnflg          ;[pcc002] and put back\r
+       jmp     rskp            ;[pcc002]\r
+intch5:        lda     logflg          ;[pcc003] get log flag\r
+       ora     a               ;[pcc003] See if open\r
+       jp      intch7          ;[pcc003] no, skip R and Q\r
+       mov     a,b             ;[pcc003] get back chr\r
+       ani     137o            ;[pcc003] make upper case\r
+       cpi     'R'             ;[pcc003] Is it R\r
+       jnz     intch6          ;[pcc003] Jump if not\r
+       mvi     a,81H           ;[pcc003] set flag for logging\r
+       sta     logflg          ;[pcc003] put it back\r
+       lxi     d,inms28        ;[pcc003] message\r
+       call    prtstr          ;[pcc003]\r
+       jmp     rskp            ;[pcc003] done\r
+intch6:        cpi     'Q'             ;[pcc003] Quit logging?\r
+       jnz     intch7          ;[pcc003] no\r
+       mvi     a,82H           ;[pcc003] flag for open, but suspended\r
+       sta     logflg          ;[pcc003] store away\r
+       lxi     d,inms27        ;[pcc003] keep them informed\r
+       call    prtstr          ;[pcc003]\r
+       jmp     rskp            ;[pcc003]\r
+intch7:                                ;[pcc003]\r
+\r
+intchz:        mov     a,b             ; not recognized. get saved copy back.\r
+       push    psw             ;[8] save as we will want to test for 'D'\r
+       call    sysint          ; interpret system-dependent sequences\r
+       jmp     intchy          ;  done. [10] Now see if D.  If so, do a C.\r
+       pop     psw             ;[10] tidy stack\r
+       mvi     e,'G'-100O      ;Otherwise send a beep.\r
+       call    outcon          ; to the console.\r
+       jmp     rskp\r
+\r
+intchy:        pop     psw             ;[10] adjust stack\r
+       ani     5fh             ;[10] strip parity, make it upper case\r
+       cpi     'D'             ;[10] was it a D?\r
+       jz      contc           ;[10] yup, so to the equivalent of an escape-C\r
+       jmp     rskp\r
+;\f\r
+; Little code to allow some expansion of code without changing\r
+;  every futher address, only up to the end of this file.\r
+;   TO BE REMOVED FOR RELEASE!\r
+\r
+;      org ($+100h) AND 0FF00H\r
+IF lasm\r
+       LINK    CPSCPM\r
+ENDIF;lasm\r