home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / KERMIT / CP411SRC.ARK / cpstt.asm < prev    next >
Assembly Source File  |  1991-04-23  |  30KB  |  863 lines

  1. ; CPSTT.ASM
  2. ;       KERMIT - (Celtic for "FREE")
  3. ;
  4. ;       This is the CP/M-80 implementation of the Columbia University
  5. ;       KERMIT file transfer protocol.
  6. ;
  7. ;       Version 4.0
  8. ;
  9. ;       Copyright June 1981,1982,1983,1984,1985
  10. ;       Columbia University
  11. ;
  12. ; Originally written by Bill Catchings of the Columbia University Center for
  13. ; Computing Activities, 612 W. 115th St., New York, NY 10025.
  14. ;
  15. ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
  16. ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
  17. ; others. 
  18. ;
  19. ;       This file contains the code for the TRANSMIT and CONNECT commands,
  20. ;       which communicate with a host which is not running KERMIT.
  21. ;
  22. ; revision history:
  23. ;
  24. ;edit 12, 31-Jan-1991 by MF. Delete call to "inbuf" after "xmit1" in
  25. ;    the TRANSMIT command. "getfil" initializes various counters so that
  26. ;    when "in1chr" is first called, "inbuf" will be called immediately
  27. ;    and will read sectors of the file to be transmitted from disk.
  28. ;    This, along with a fix to "in1chr" in CPSUTL.ASM, fixes a bug
  29. ;    discovered by Lance Tagliapietra of the University of Wisconsin at
  30. ;    Platteville wherein the TRANSMIT command was failing to transmit some
  31. ;    characters in files over one sector in length. See CPSUTL.ASM,
  32. ;    edit 29.
  33. ; edit 11, 10 September, a987, by OBSchou.  Modified TRANSMIT command
  34. ;    to TRANSMIT <file> <string>
  35. ;
  36. ; edit 10, 27 August, 1987 by OBSchou.  Fixed bugs in Transmit, but I may
  37. ;    be introducing problems for IBM/CMS or half duplex systems.  What
  38. ;    does this combination do??
  39. ;
  40. ; edit 9 30 March, 1987 by OBSchou to replace the TRANSMIT routine.
  41. ;    Syntax is now TRANSMIT file after a previous 
  42. ;    INPUT <wait time> <string to wait for>
  43. ;
  44. ; edit 8 19 June, 1986 by OBSchou.  Modified the interupt testing routine
  45. ;       to see if the command was a 'D' (Drop the line), in which case also
  46. ;       do a 'C', ie disconnect.  This is really a little too much of a
  47. ;       system dependent thing.
  48. ;       For now, Ill leave it here, and possibly move it later.
  49. ;
  50. ; edit 7 30 May 1986 OBSchou.  Moved xon/xoff control (ie XON/OFF sent to host)
  51. ;       out to CPSUTL so that ther printer routine can use it too.
  52. ;
  53. ; edit 6 30 April, 1986 by OBSchou.
  54. ;       Fixed transmit bug, so as soon as the protocol character is 
  55. ;       received from the host is received then another line is sent.
  56. ;       added in a comchr (ds 1) to save the character read from the comm 
  57. ;       line in prtchr, and is restored in a on return.
  58. ;
  59. ; edit 5 7 March, 1986 by OBSchou Loughborough University.  
  60. ;       Need to save the E register before calling outmdm (in CPSSYS.ASM)
  61. ;       if doing Half duplex.  Push/pop DE should sort this problem
  62. ;
  63. ; edit 4: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
  64. ;
  65. ;pcc002 28-Dec-84       modules:cp4tt,cp4utl
  66. ;       Add connect mode <esc>P command to toggle printer on
  67. ;       and off.  Conflicts with "official" recommended commands
  68. ;       in protocol manual, but I don't think CP/M will ever get
  69. ;       a PUSH command.
  70. ;
  71. ;pcc003-pcc005  2-Jan-85        vjc     modules:cp4mit,cp4tt,cp4utl
  72. ;       These edits must all be installed together and change the way
  73. ;       logging is handled.  The log file spec is moved to a separate
  74. ;       fcb, and not opened until an actual CONNECT command is given.
  75. ;       This takes care of a NASTY bug that if you used any other file
  76. ;       command between the LOG and CONNECT, the log file would get
  77. ;       written over the last file used.  This also allows logging to
  78. ;       be "permanently" enabled until an CLOSE (new command) for all
  79. ;       CONNECT sessions, like most other kermits do.  If a log file
  80. ;       already exists, it will be appended to.  Also add two new
  81. ;       CONNECT mode commands <esc>Q to suspend logging and <esc>R to
  82. ;       resume.  <esc>R means something else during TRANSMIT, but
  83. ;       logging is never on then, so there shouldn't be any conflict.
  84. ;       I also changed the write code, so that it can handle one more
  85. ;       character after the XOFF is send to stop the host.  This allows
  86. ;       a little "slop" for systems that don't stop immediately (such
  87. ;       as TOPS10), but it didn't help much.
  88. ;
  89. ;pcc008 2-Jan-85        vjc     modules:cp4def,cp4tt,cp4utl
  90. ;       Keyboard input during CONNECT mode can get locked out if
  91. ;       there is enough input from the modem port to keep prtchr
  92. ;       busy.  This can happen for example, if the printer is running
  93. ;       at the same speed as the modem line, leaving you helpless to
  94. ;       turn it off or abort the host.  Add a fairness count, so that
  95. ;       at least every prfair characters we look at console input.
  96. ;
  97. ;pcc012 4-Jan-85        vjc     modules:cp4mit,cp4tt,cp4utl
  98. ;       Use the big buffer for the log file.  Move the log file back
  99. ;       into the common fcb and only save the drive, name, and
  100. ;       extension between connects.  Add new routines to cp4utl to
  101. ;       create or append to an existing file, and to conditionally
  102. ;       advance buffers only if in memory.  Remove edit pcc003 that
  103. ;       allows one more character after the xoff, since it didn't
  104. ;       really work very well and does not fit in well with the way
  105. ;       the buffer advancing routines are set up.  If someone still
  106. ;       thinks this would be useful, it could be put back in with a
  107. ;       little more work.
  108. ;       
  109. ;       While testing this edit, I also noticed another bug that
  110. ;       the command parsing routines do not limit or check the
  111. ;       length of command lines or file specs, trashing what ever
  112. ;       comes after them.  Currently because of where the fcb and
  113. ;       command buffer are located, this does not usually cause a
  114. ;       problem, but could if an extremely long line was typed in,
  115. ;       or in the future multiple fcbs defined elsewhere in memory
  116. ;       were used.  Maybe this should be put on the bug list
  117. ;       somewhere.
  118. ;
  119. ; edit 3: July 27, 1984
  120. ;       Allow assembly with LASM: to CP4TT is linked by CP4PKT, and links
  121. ;       to CP4CPM; remove exclamation points so as not to confuse LASM.
  122. ;       Add Toad Hall TACtrap to TRANSMIT command (TAC intercept character
  123. ;       is only doubled if it's data; when typed by the user, they're not
  124. ;       automatically doubled)
  125. ;
  126. ; edit 2: June 7, 1984
  127. ;       formatting and documentation; add module version number; make sure
  128. ;       console is selected when leaving intchr.
  129. ;
  130. ; edit 1: May, 1984
  131. ;       extracted from CPMBASE.M80 version 3.9; modifications are described
  132. ;       in the accompanying .UPD file.
  133.  
  134. ttver:    db    'CPSTT.ASM  (12) 31-Jan-1991$'
  135.  
  136. ;       This is the TRANSMIT command.  It attempts to send a file, even
  137. ;       though there is no KERMIT on the other side.
  138. ;       here from: kermit
  139. ;
  140. ; [OBS] I have replaced the routine, so that TRANSMIT <filename> <wait string>
  141. ; will send a line at a time to the host in a manner similar to MSKERMIT
  142. ;
  143. ;
  144. xmit:    mvi    a,cmofi        ;Parse an input file spec (non-wild).
  145.     lxi    d,fcb        ;Give the address for the FCB.
  146.     call    comnd
  147.     jmp    kermit        ;Give up on bad parse.
  148. ;
  149.     lxi    d,stbuff    ; where to put the string
  150.     mvi    a,cmtxt        ; get text
  151.     call    comnd
  152.     jmp    kermit        ; not quite correct...
  153.     sta    strcnt        ; string count returned in a
  154.     ana    a        ; if its zero, make it 1 character (CR)
  155.     jnz    xmit0
  156.     mvi    a,1
  157.     sta    strcnt
  158.     mvi    a,cr
  159.     sta    stbuff
  160. ;
  161. xmit0:    call    cfmcmd
  162.     call    getfil        ;Open file.
  163.     cpi    0FFH        ;Succeed?
  164.     jnz    xmit1
  165.     lxi    d,erms15
  166.     call    prtstr        ;Display error msg.
  167.     jmp    kermit
  168.  
  169. ;
  170. ; New TRANSMIT routine - transmit a file, line by line, to a remote host
  171. ;    waiting each time for one or more characters to be returned
  172. ;    as a remote host prompt.  It could be as simple as a CR or LF
  173. ;    character.  Repeat until the complete file has been sent, then
  174. ;    close the transmitted file, and drop into the connect state so the
  175. ;    user can tidy up at the host end.
  176. ;get the file to send, open it up, and read first sector from disk
  177.  
  178. xmit1:    lxi    d,inms19    ; say we are send a file to the host
  179.     call    prtstr
  180.  
  181.     xra    a
  182.     sta    repcnt        ; clear the host prompt chars. counter 
  183.     sta    starc        ; clear star count
  184. ;[MF][12]Delete the following call to "inbuf" as the call to "getfil"
  185. ;[MF][12]above will have initialized counters and flags so that when
  186. ;[MF][12]"in1chr" is called, "inbuf" will be called immediately and will
  187. ;[MF][12]immediately read from disk. Counters and flags will then be
  188. ;[MF][12]properly set up to read all characters of the file to be
  189. ;[MF][12]transmitted.
  190. ;    call    inbuf        ; read one sector from disk
  191. ;    jmp    xmtex        ; exit if error
  192.  
  193.  
  194. xmt10:    xra    a        ; clear retransmit flag and count etc
  195.     sta    rexbfl        ; retransmit flag (1=> retransmit)
  196.     sta    rexcnt        ; character counter
  197.  
  198. xmt1:    call    xmt1ch        ; send a character
  199.     ani    7fh        ; strip any parity
  200.     cpi    cr        ; have we reached the end of the line
  201.     jnz    xmt1        ; nope, loop around again
  202.  
  203. ; Now wait for a string back from the host.  Compare with STRING buffer
  204. ;
  205.     xra    a        ; clear the character count
  206.     sta    rexcnt
  207. ;
  208.     call    selcon        ; sent a line, send a star to console
  209.     mvi    e,'*'
  210.     call    outcon
  211.     lda    starc        ; update star count
  212.     inr    a
  213.     sta    starc
  214.     cpi    60        ; sent 60 stars?
  215.     jnz    xmt1a        ; nope...
  216.     xra    a
  217.     sta    starc
  218.     call    prcrlf
  219. xmt1a:
  220.  
  221. xmt3:    lda    eoflag        ; have we hit end of file?
  222.     ana    a
  223.     jnz    xmtex        ; yup, so quit.
  224.     xra    a
  225.     sta    repcnt        ; clear the host prompt chars.counter
  226. xmt2:    call    rd1chl        ; read a character from the line
  227.     ani    7fh        ; set flags
  228.     jnz    xmt4        ; Not zero => we have a character from host
  229.     call    ckchr        ; see if *WE* have a character from console
  230.     push    psw        ; restore to modem
  231.     call    selmdm
  232.     pop    psw
  233.     ani    7fh        ; stip parity (should not be there)
  234.     jnz    xmt2a        ; if a null, try again
  235.     lda    strcnt        ; if the string length is zero, dont wait.
  236.     ana    a
  237.     jz    xmt1        ; so loop back again
  238.     jmp    xmt4        ; else test for xon/off and incomming string
  239.  
  240. xmt2a:    cpi    cntlc        ; do we want to abort?
  241.     jz    xmtex        ; in which case drop through to connect mode
  242.     cpi    cntlz        ; if control z exit back to command loop
  243.     jnz    xmt2b        ; else try for other characters
  244.     lxi    d,fcb        ; close file before exiting to command loop
  245.     mvi    c,closf
  246.     call    bdos
  247.     jmp    kermit
  248.  
  249. xmt2b:    cpi    cr        ; a cr => resend last line
  250.     jnz    xmt2        ; nope, then ignore it
  251.     mvi    a,1
  252.     sta    rexbfl        ; else we want to resend the line.
  253.     jmp    xmt1
  254.  
  255. xmt4:    jmp    xmt6        ; skit xoff test for now...*****************
  256.  
  257.     cpi    xoff        ; xoff from host?
  258.     jnz    xmt6
  259. xmt5:    call    rd1chl        ; else see if XOFF comming
  260.     ani    7fh
  261.     jnz    xmt6        ; assume an xoff
  262.     call    ckchr        ; anything at console?
  263.     push    psw
  264.     call    selmdm
  265.     pop    psw
  266.     ani    7fh
  267.     cpi    cntlc        ; control-c == abort & play terminal
  268.     jz    xmtex
  269.     ana    a        ; anything else?
  270.     jz    xmt5        ;loop again
  271.  
  272. xmt6:    mov    e,a        ; save it for a while
  273.     lda    repcnt        ; see if this character matches with one in buffer
  274.     lxi    h,stbuff    ; point to string buffer
  275.     add    l        ; make hl = hl + a
  276.     mov    l,a
  277.     mvi    a,0
  278.     adc    h
  279.     mov    h,a        ; not using xra, as that clears the Carry flag
  280.     mov    a,e        ; get the character back again
  281.     cmp    m        ; is it = to what we expect?
  282.     jnz    xmt3        ; no, clear counter and try again
  283.     lda    repcnt        ; yes, then update the pointer, and ...
  284.     inr    a        ; ... see if we have received all ...
  285.     sta    repcnt        ; ... we should have received
  286.     mov    e,a        ; save length into E again
  287.     lda    strcnt        ; get the length to compare
  288.     sub    e        ; if (e) > string length, we have it
  289.     jz    xmt10        ; so send next line (clear counters etc)
  290.     jmp    xmt2        ; else wait for a little longer
  291.  
  292.  
  293. ;
  294. ; Routine below sends a character to the line.  It sends up to a CR, and then
  295. ;    it waits for a reply.  This routine is called from xmt1, so if at 
  296. ;    end of file, return.  Then XMT1 will drop through
  297. ;    to connect.
  298. xmt1ch:    ; send a character from the xmtbuf to the line
  299.     call    selmdm        ; just in case it uses it
  300.     lda    eoflag        ; have we hit end of file
  301.     ana    a        ; set flags
  302.     jnz    xmt1c1        ; no, so dont...
  303.     mvi    a,cr        ; load up a carriage return
  304. xmt1c1:    call    get1xc        ; get the character to send
  305.     cpi    lf        ; dont send line feeds
  306. ;    jz    xmt1c1
  307.     cpi    cntlz        ; if control z, then we are at end of the file
  308.     jz    xmtex        ; so close the file and drop into telcon
  309.     cpi    20h        ; control character?
  310.     jp    xmt11        ; no, so ok
  311.     cpi    cr        ; cr, and tabs ok to send
  312.     jz    xmt11
  313.     cpi    tab
  314.     jz    xmt11
  315.     jmp    xmt1c1        ; else try for another character
  316.  
  317. xmt11:    call    setpar        ; else set parity etc
  318.     push    psw        ; we want to keep this for a while
  319.     mov    e,a        ; we need character in e
  320.     call    outmdm
  321.     pop    psw        ; restore the character we sent
  322.     mov    e,a        ; now, if a TAC is set on..
  323.     lda    tacflg
  324.     ana    a        
  325.     mov    a,e        ; (return must have sent character in a)
  326.     jz    xmt1c2        ; test for xon/off
  327.     lda    tacchr        ;... get the tac character
  328.     cmp    e        ; do we send it again?
  329.     jnz    xmt1c2        ; test for xon/off
  330.     push    psw        ; save character for return. Already set E...
  331.     call    outmdm
  332.     pop    psw
  333.  
  334. xmt1c2:    ret
  335.  
  336. get1xc:    ; get a character from the sector or re-transmit buffer read 
  337. ;    into a.  Read a new sector if we run out.
  338. ;
  339. ; First, see if we do a retransmit
  340.     lda    rexbfl
  341.     ana    a        ; if zero, a genuine line
  342.     jz    get1x1
  343. ; have to retransmit a line
  344.     lxi    h,rexbuf
  345.     lda    rexcnt        ; add counter to buffer base
  346.     mvi    d,0
  347.     mov    e,a
  348.     dad    d
  349.     inr    a        ; update pointer
  350.     sta    rexcnt
  351.     mov    a,m        ; get next character to send
  352.     ret            ; and exit
  353.  
  354. get1x1:    call    in1chr        ; get a character from the file. 
  355.     mov    c,a        ; save it to the retransmit buffer
  356.     lda    rexcnt
  357.     mov    e,a
  358.     mvi    d,0
  359.     lxi    h,rexbuf
  360.     dad    d        ; point to next position
  361.     inr    a
  362.     sta    rexcnt        ; update the character pointer
  363.     mov    a,c        ; restore character to a
  364.     mov    m,c        ; get character to c
  365.     ret
  366.  
  367.  
  368.  
  369. ; read a character from the line.
  370. rd1chl:    
  371.     call    selmdm        ; select the modem
  372.     call    inpmdm        ; get input from the modem
  373.     ani    7fh        ; strip parity
  374.                 ; may UPPERCASE-ify if case sensitivity off
  375.     ret            ; return to caller
  376.  
  377. ;  End of transmit routine.  Close input file name, and say we are dropping
  378. ;  throught to telnet.  Note that if eof not found, it is assumed that
  379. ;  this is the ABORT exit.
  380.  
  381. xmtex:
  382.     lxi    d,fcb        ; close the transmitted file
  383.     mvi    c,closf
  384.     call    bdos
  385.     call    selcon        ; make sure we are talking to the console
  386.  
  387.     lda    eoflag        ; end of file or abort exit?
  388.     lxi    d,inms22    ; assume eof...
  389.     ana    a
  390.     jz    xmtex1
  391.     lxi    d,inms29    ; we were wrong, its an abort.
  392. xmtex1:    jmp    telnt1        ; and drop through to connect mode
  393.                 ; telnet does the printing
  394.  
  395.  
  396.  
  397. ;
  398. ;   telnet - the CONNECT command.
  399. ;       here from: kermit
  400. ;   telnt1 - entry to connect mode from TRANSMIT command
  401. ;       here from: xend
  402.  
  403. telnet:    call    cfmcmd
  404.     lxi    d,infms7    ;Output start of message
  405. ; enter here from TRANSMIT command.
  406. telnt1:    call    prtstr
  407.     call    escpr        ;Print the escape char.
  408.     lxi    d,infms8    ;Output some more of the message
  409.     call    prtstr
  410.     call    escpr        ;Print the escape char again.
  411.     lxi    d,inms8a    ;Print the remainder of the message
  412.     call    prtstr
  413.     call    syscon        ;do system-dependent stuff
  414.     lda    logflg        ;[pcc005] Want a log?
  415.     ora    a        ;[pcc005]
  416.     cnz    logopn        ;[pcc005] Open if so
  417.  
  418. chrlup:    call    prtchr        ;See if char at port (send to console).
  419.     call    conchr        ;See if char at console (send to port).
  420.     jmp    kermit        ;requested to end session - go to command loop.
  421.     jmp    chrlup        ;Go do it again.
  422. ;
  423. ;
  424. ;       prtchr - copy characters from comm line to console
  425. ;       returns: nonskip, console selected.
  426. ;       called by: xnext, rexmit, telnet
  427. ;
  428.  
  429. prtchr:    call    selmdm        ; select modem port
  430.     call    inpmdm        ; try to get a character from it
  431.     push    psw        ; restore to console
  432.     call    selcon        ; select console
  433.     pop    psw        ; restore the (possible character) read
  434.     ora    a        ; test character
  435.     jnz    prtch0        ; if non-zero, process it.
  436.     sta    prtcnt        ;[pcc008] zero out prt fairness count
  437.     ret            ; return.
  438.  
  439. prtch0:    ani    7FH        ; drop parity bit.
  440.     sta    comchr        ;[6] save it in case we need it again
  441.     lda    vtflg        ;[9] get the vt52 emulation flag
  442.     cpi    vtdefe        ;[9] are we doing external emulation?
  443.     lda    comchr        ;[9] collect character again
  444.     jz    extern        ;[9] jup, go do it.
  445.  
  446.     ana    a        ; set flags.  it may be a null
  447.     jz    prtchr        ; ignore null (filler)
  448.     cpi    del        ; ignore delete, too
  449.     jz    prtchr
  450.     cpi    xon        ;Is it an XON?
  451.     jz    prtxon        ;yes
  452.     cpi    xoff        ;Is it an XOFF?
  453.     jz    prtxof        ;yes
  454.     mov    e,a        ;Set the char aside.
  455.     lda    vtflg        ;Get the VT52 emulation flag.
  456.     cpi    vtdefv        ;Is the flag set for VT52 (ie 1)
  457.                 ;0 = none
  458.                 ;1 = VT52
  459.                 ;2 = external
  460.                 ;3 = dumb (traps non printing chars)
  461.                 ;0ffh not possible by local code (Will change)
  462.     jnz    prtch1        ;If not, don't do this stuff.
  463.     lda    escflg        ;Get the escape flag.
  464.     ora    a        ;Are we working on an escape sequence?
  465.     jz    prtch2        ;If not, continue.
  466.     call    vt52        ;If so, work on it some more
  467.     jmp    prtchr        ;try for more characters.
  468.  
  469. prtch2:    mov    a,e        ;normal text.
  470.     cpi    esc        ;Is the char an escape?
  471.     jnz    prtch1        ;If not skip on.
  472.     mvi    a,1
  473.     sta    escflg        ;Set the escape flag: escape seen.
  474.     jmp    prtchr        ;Get another char...
  475.  
  476. prtch1:    cpi    vtdefe        ; are we doing external emulation?
  477.     jnz    prtch3        ; assume we continue on
  478.     lxi    h,extern+1    ; get address of external emulator
  479.     mov    a,h        ; se if address = 0 (not implemented)
  480.     ora    l
  481.     jz    prtch3        ; not external, assume we just carry on
  482.     pchl            ; go do external emulation.  RET back to caller
  483.  
  484. prtch3:    cpi    vtdefd        ; are we trapping all non printing characters?
  485.     jnz    prtch4        ; nope, something else
  486.     lda    comchr        ; Dumb terminal.  Lets test the character
  487.     cpi    cr        ; cr then ok
  488.     jz     prtch4        ; its ok
  489.     cpi    lf        ; lf then ok
  490.     jz    prtch4
  491.     cpi    tab
  492.     jz    prtch4        ; assume tabs are expanded
  493.     cpi    space        ; if less than 20H ignore it
  494.     rm            ; return if a control character
  495.  
  496. prtch4:    call    sysflt        ; ok to print this character (in E)?
  497.     ora    a
  498.     jz    prtchr        ; no, skip it.
  499.     lda    logflg        ;Get the log flag.
  500.     cpi    81H        ;[pcc003] Are we logging
  501.     cz    logit        ;[pcc003] Do so if needed
  502.     call    selcon        ; select console
  503.     lda    prnflg        ;Get Print parallel flag
  504.     ora    a
  505.     cnz    outlpt        ; output to printer if flag set
  506.     call    outcon        ; output to console.
  507.     lxi    h,prtcnt    ;[pcc008] point to prt fairness count
  508.     inr    m        ;[pcc008] bump
  509.     mov    a,m        ;[pcc008] get it in a
  510.     cpi    prfair+1    ;[pcc008] time to be fair?
  511.     jm    prtchr        ;[pcc008] no, go around again.
  512.     mvi    m,0        ;[pcc008] reset count
  513.     lda    comchr        ;[6] restore that character read from comm line
  514.     ret            ;[pcc008] and return
  515.  
  516. ; I don't think we want to print xon/xoff - this should be
  517. ; flow control only across the link between us and the host.
  518. ; (besides, IBM host xon's don't make sense to most micros)
  519. ; remember xon/xoff state in xofflg (zero = xon, non-zero = xoff)
  520. prtxon:    xra    a        ;Yes, reset XOFF flag
  521. prtxof:    sta    xofflg
  522.     jmp    prtchr        ; look for another character
  523. ; ;[pcc005] Log file routines
  524.  
  525. ;[pcc005]
  526. ;    logopn - open the log file
  527. ;       Open the log file and append to it if it already exists
  528. ;       or create one if not.
  529.  
  530. logopn:    
  531.     mvi    a,ctrlz        ;[9] ignore control-z in log files
  532.     cmp    e        ;[9] well, was it?
  533.     rz            ;[9] yes, to ignore it.
  534.     lxi    h,lognam    ;[pcc012] copy name
  535.     lxi    d,fcb        ;[pcc012] to fcb
  536.     lxi    b,12        ;[pcc012] 12 bytes
  537.     call    mover        ;[pcc012] copy it
  538.     call    appfil        ;[pcc012] open file for appending
  539.     jmp    logerr        ;[pcc012] error
  540.     lxi    h,logflg    ;[pcc005] point to log flag
  541.     mvi    a,80H        ;[pcc005] file open flag
  542.     ora    m        ;[pcc005] or in contents of logflg
  543.     mov    m,a        ;[pcc005] and store back
  544.     lxi    d,inms28    ;[pcc005] assume logging is on
  545.     cpi    81H        ;[pcc005] check
  546.     jz    prtstr        ;[pcc005] print msg if true
  547.     lxi    d,inms27    ;[pcc005] no, must be suspended
  548.     jmp    prtstr        ;[pcc005] print and return
  549.  
  550. ;
  551. ;       logit - output character in E to log file.
  552. ;       we assume the host recognizes xon/xoff. (we probably shouldn't)
  553. ;       modem port is selected.
  554. ;       preserves de
  555. ;       called by: prtchr
  556.  
  557. logit:    lxi    h,chrcnt    ;[pcc012] point to buffer count
  558.     dcr    m        ;[pcc012] and decrement
  559.     jp    logit1        ;[pcc012] continue if ok
  560.     push    d        ;[pcc012] save de
  561.     call    outadv        ;[pcc012] advance buffer if in memory
  562.     call    logwrt        ;[pcc012] sigh, time to write to disk
  563.     pop    d        ;[pcc012] restore de
  564.     lda    logflg        ;[pcc012] get logging flag
  565.     ora    a        ;[pcc012] Did we quit because of an error
  566.     rz            ;[pcc012] return now if so
  567. logit1:    lhld    bufpnt        ;[pcc012] get buffer pointer
  568.     mov    m,e        ;Store the char.
  569.     inx    h
  570.     shld    bufpnt
  571.     ret            ;[pcc012] and return
  572.  
  573. ;[pcc012]
  574. ;  logwrt - write to log file with XON/XOFF since it may take a while.
  575.  
  576. logwrt:    call    sndxoff        ;[7] send and xoff to host
  577.     call    outbuf        ;[pcc012] output the buffer and advance
  578.     call    logerr        ;[pcc005] quit if error
  579.     call    sndxon        ;[send an xon to host
  580.     ret            ;[pcc012]
  581.  
  582. ;[pcc005]
  583. ;       logcls - Close the log file and reset the flag
  584.  
  585. logcls:    lxi    d,infms6    ;[pcc005] Tell user we are closing file.
  586.     call    prtstr        ;[pcc005]
  587.     call    clofil        ;[pcc012] and do it
  588.     jmp    logerr        ;[pcc005] jump if error
  589.     lxi    h,logflg    ;[pcc005] point to flag
  590.     mov    a,m        ;[pcc005] get it
  591.     ani    7FH        ;[pcc005] clear the open bit
  592.     mov    m,a        ;[pcc005] and store back
  593.     ret            ;[pcc005]
  594.  
  595. ;[pcc005]
  596. ;    logerr - here on a variety of logging errors
  597. ;       just close the file and disable logging
  598. ;       called from logopn,logptr,logcls
  599.  
  600. logerr:    lxi    d,erms22    ;[pcc005] Error message
  601.     call    prtstr        ;[pcc005] print it
  602.     mvi    c,closf        ;[pcc005] Close the file.
  603.     lxi    d,fcb        ;[pcc012]
  604.     call    bdos        ;[pcc005] 
  605.     xra    a        ;[pcc005] clear logflg
  606.     sta    logflg        ;[pcc005] so don't try again
  607.     ret            ;[pcc005]
  608. ;
  609. ;
  610. ;       VT52 emulation.
  611. ;       called by: prtchr
  612. ;       A/ contents of escflg (guaranteed non-zero)
  613. ;       E/ current character
  614. ;       modem is selected.
  615. ;
  616. vt52:    cpi    1        ; first character after escape?
  617.     jnz    vt52y        ; no, must be doing cursor positioning.
  618. ;
  619. ;       E contains the character that followed the escape.
  620. ;       valid characters are:
  621. ;       A - cursor up
  622. ;       B - cursor down
  623. ;       C - cursor right
  624. ;       D - cursor left
  625. ;       F - enter graphics mode (hard to do on a non-vt52)
  626. ;       G - exit graphics mode
  627. ;       H - home
  628. ;       I - reverse linefeed
  629. ;       J - erase to end of screen
  630. ;       K - erase to end of line
  631. ;       Y - cursor positioning leadin
  632. ;       Z - identify terminal as VT52
  633. ;       [ - enter hold-screen mode (not supported)
  634. ;       \ - exit hold-screen mode (not supported)
  635. ;       > - enter alternate-keypad mode? (not supported)
  636. ;       = - exit alternate-keypad mode? (not supported)
  637. ;
  638. ;       Invalid sequences are handled as the VT52 does - the escape and
  639. ;       the following character are swallowed, never to be seen again.
  640. ;       For <esc>E, the translation table may contain just '$' (no action),
  641. ;       or may be used as clear-and-home, as in the Heath/Zenith H19.
  642. ;
  643.     mov    a,e        ; get the second character of the sequence.
  644.     cpi    'Y'             ; if cursor lead-in handle it.
  645.     jnz    vt52a        ; if not, go on.
  646.     mvi    a,2        ; state = 2: row follows.
  647.     sta    escflg        ; update the flag.
  648.     ret            ; back for another character
  649.  
  650. vt52a:    cpi    'Z'             ; VT52 ID query?
  651.     jz    vt52id        ; yes. claim to be one.
  652.     cpi    'A'             ;Less than an 'A'?
  653.     jm    vtig        ;Yes - ignore.
  654.     cpi    'K'+1           ;Greater than 'K'?
  655.     jp    vtig        ;Yes - ignore.
  656.     sui    'A'             ;Else make into index.
  657.     rlc            ;Multiply by four.
  658.     rlc            ;(Shift left twice.)
  659.     lhld    pttab        ;Load base addr of table.
  660.     mov    e,a        ;Move a into de pair.
  661.     mvi    d,00H        ;Zero out high byte.
  662.     dad    d        ;Double add index+offset.
  663.     xchg            ;Exchange de with hl.
  664.     call    selcon        ; select console
  665.     call    prtstr        ;and syscall.
  666. vtig:                ;Ignore escape sequence.
  667.     xra    a        ;Reset the ol' escape flag.
  668.     sta    escflg
  669.     ret            ;Return home.
  670.  
  671. ; here for <esc>Z.  Tell the host we're a VT52. (Sure we are...)
  672. vt52id:    mvi    a,esc        ; response is escape...
  673.     call    setpar        ; (need correct parity)
  674.     mov    e,a
  675.     call    outmdm        ; (console already selected)
  676.     mvi    a,'/'           ; ... slash ...
  677.     call    setpar        ; (with parity)
  678.     mov    e,a
  679.     call    outmdm
  680.     mvi    a,'K'           ; ... K.
  681.     call    setpar
  682.     mov    e,a
  683.     call    outmdm
  684.     jmp    vtig        ; clear escape-sequence flag and return.
  685.  
  686. ; here when escflg isn't 0 or 1 - processing cursor positioning sequence.
  687. vt52y:    cpi    2        ; looking for row? (y-coordinate)
  688.     jnz    vt52x        ; no, must be column.
  689.     mov    a,e        ; yes. get coordinate
  690.     sui    (' '-1)         ; convert from ascii (1 = top line)
  691.     sta    vtyval        ; store for later
  692.     mvi    a,3        ; advance to next state (x coord)
  693.     sta    escflg        ; store it
  694.     ret            ; try for another character
  695.  
  696. ; here when escflag isn't 0, 1, or 2 - it must be 3. (right?)
  697. ; E holds the last character of the cursor positioning sequence.
  698. vt52x:    xra    a        ; end of escape sequence, reset state.
  699.     sta    escflg
  700.     mov    a,e        ; get column (' ' is left margin)
  701.     sui    (' '-1)         ; make left margin be one
  702.     mov    c,a        ; stash column in c
  703.     lda    vtyval        ; get row number
  704.     mov    b,a        ;  in b
  705.     call    selcon        ; select console
  706.     call    csrpos        ; call system-dependent cursor positioner
  707.     ret            ; all through.
  708. ;
  709. ;
  710. ;       conchr - copy character from console to comm line, processing
  711. ;       (kermit's) escape sequences.
  712. ;       Enter and exit with console selected.
  713. ;       nonskip return: transparent mode terminated.
  714. ;       skip return:    still in transparent mode.
  715. ;       called by: rexmit, telnet
  716.  
  717. conchr:    call    inpcon        ;Try to get a character from the console
  718.     ani    07FH        ;Keep only 7 bits
  719.     jz    rskp        ;Null means nothing there.
  720.     mov    e,a        ;Move the char for comparison.
  721.     sta    lstchr        ;Save it
  722.     lda    escchr        ;Get the escape char.
  723.     cmp    e        ;Is it an escape char?
  724.     jz    intchr        ;If so go process it.
  725.     call    selmdm        ; select the modem
  726.     mov    a,e        ;Get the char.
  727.     call    setpar        ;Set parity (if any).
  728.     mov    e,a        ;Restore it.
  729.     push    d        ; need to save e in case we are half dplx [5]
  730.     call    outmdm        ;Output the char to the port.
  731.     pop    d        ; Just in case we are half dplx [5]
  732.     call    selcon        ; reselect console
  733.     lda    ecoflg        ;Get the echo flag.
  734.     ora    a        ;Is it turned on?
  735.     jz    rskp        ;If not we're done here.
  736.     mov    a,e        ;Get the char.
  737.     ani    7FH        ;Turn off the parity bit.
  738.     mov    e,a
  739.     call    outcon        ; echo the character.
  740.     jmp    rskp        ; use skip return
  741. ;
  742. ;       transparent escape character has been typed. dispatch on second
  743. ;       character. (console is still selected)
  744. ;       here from: conchr
  745.  
  746. intchr:    call    inpcon        ; get another character from the console
  747.     ora    a        ; zero means no character available yet.
  748.     jz    intchr        ; If so, loop until we get a char.
  749.     mov    b,a        ;Save the actual char.
  750.     cpi    ctrlc        ;is it Control-C?
  751.     jz    contc        ;yes
  752.     ani    137O        ;Convert to upper case.
  753.     cpi    'C'             ;Is it close?
  754.     jnz    intch0        ;If not proceed.
  755. contc:    lxi    d,infms9    ;Say we are back.
  756.     call    prtstr
  757.     call    syscls        ; call system-dependent close routine
  758.     lda    logflg        ;Get the log flag.
  759.     ora    a        ;[pcc005] Check if open
  760.     cm    logcls        ;[pcc005] Close if needed
  761.     ret
  762.  
  763. ;Here if not a 'C' or '^C'
  764.  
  765. intch0:    cpi    'S'             ;Is it status?
  766.     jnz    inch01        ;If not, proceed.
  767.     call    stat01        ;Print out the status stuff.
  768.     call    prcrlf        ;[pcc011] add a crlf
  769.     jmp    rskp        ;return from conchr
  770.  
  771. inch01:
  772. inch03:    mov    a,b        ;Get the char.
  773.     cpi    '?'             ;Is it a help request?
  774.     jnz    intch1        ;If not, go to the next check.
  775. inch3a:    lda    logflg        ;[pcc003] Logging flag
  776.     ora    a        ;[pcc003] see if active
  777.     jp    inch04        ;[pcc005] jump if no file open
  778.     lxi    d,loghlp    ;[pcc003] yes, tell about R AND Q
  779.     call    prtstr        ;[pcc003]
  780. inch04:    lxi    d,inthlp    ;If so, get the address of the help message.
  781.     call    prtstr
  782.     call    sysinh        ; print system-dependent help message
  783.     lxi    d,inhlp1    ; Tell about doubling the escape character
  784.     call    prtstr
  785.     call    escpr        ;Print escape character
  786.     lxi    d,inhlp2    ;Print the rest
  787.     call    prtstr
  788.     jmp    intchr        ;Get another char.
  789.  
  790. intch1:    mov    a,b        ;Get the character.
  791.     cpi    '0'             ;Is it '0', to send a null?
  792.     jnz    intch3        ;No.
  793.     xra    a        ;Yes, send an ASCII zero.
  794.     call    setpar        ; with the correct parity
  795.     mov    e,a
  796.     call    selmdm        ; (to the modem...)
  797.     call    outmdm
  798.     call    selcon        ; return with console selected
  799.     jmp    rskp
  800.  
  801. intch3:    lda    escchr        ;Get the escape char.
  802.     cmp    b        ;Is it the escape char?
  803.     jnz    intch4        ;[pcc002] jump if not
  804.     mov    a,b        ;Get the char.
  805.     call    setpar
  806.     mov    e,a        ;Restore it.
  807.     call    selmdm
  808.     call    outmdm        ;Output it.
  809.     call    selcon        ;We promised console would be selected...
  810.     jmp    rskp        ;Return, we are done here.
  811. intch4:    mov    a,b        ;[pcc002] get it again
  812.     ani    137o        ;[pcc002] in upper case
  813.     cpi    'P'             ;[pcc002] toggle printer?
  814.     jnz    intch5        ;[pcc003] nope
  815.     lda    prnflg        ;[pcc002] get printer flag
  816.     xri    01h        ;[pcc002] complement it
  817.     sta    prnflg        ;[pcc002] and put back
  818.     jmp    rskp        ;[pcc002]
  819. intch5:    lda    logflg        ;[pcc003] get log flag
  820.     ora    a        ;[pcc003] See if open
  821.     jp    intch7        ;[pcc003] no, skip R and Q
  822.     mov    a,b        ;[pcc003] get back chr
  823.     ani    137o        ;[pcc003] make upper case
  824.     cpi    'R'             ;[pcc003] Is it R
  825.     jnz    intch6        ;[pcc003] Jump if not
  826.     mvi    a,81H        ;[pcc003] set flag for logging
  827.     sta    logflg        ;[pcc003] put it back
  828.     lxi    d,inms28    ;[pcc003] message
  829.     call    prtstr        ;[pcc003]
  830.     jmp    rskp        ;[pcc003] done
  831. intch6:    cpi    'Q'             ;[pcc003] Quit logging?
  832.     jnz    intch7        ;[pcc003] no
  833.     mvi    a,82H        ;[pcc003] flag for open, but suspended
  834.     sta    logflg        ;[pcc003] store away
  835.     lxi    d,inms27    ;[pcc003] keep them informed
  836.     call    prtstr        ;[pcc003]
  837.     jmp    rskp        ;[pcc003]
  838. intch7:                ;[pcc003]
  839.  
  840. intchz:    mov    a,b        ; not recognized. get saved copy back.
  841.     push    psw        ;[8] save as we will want to test for 'D'
  842.     call    sysint        ; interpret system-dependent sequences
  843.     jmp    intchy        ;  done. [10] Now see if D.  If so, do a C.
  844.     pop    psw        ;[10] tidy stack
  845.     mvi    e,'G'-100O      ;Otherwise send a beep.
  846.     call    outcon        ; to the console.
  847.     jmp    rskp
  848.  
  849. intchy:    pop    psw        ;[10] adjust stack
  850.     ani    5fh        ;[10] strip parity, make it upper case
  851.     cpi    'D'             ;[10] was it a D?
  852.     jz    contc        ;[10] yup, so to the equivalent of an escape-C
  853.     jmp    rskp
  854. ;
  855. ; Little code to allow some expansion of code without changing
  856. ;  every futher address, only up to the end of this file.
  857. ;   TO BE REMOVED FOR RELEASE!
  858.  
  859. ;    org ($+100h) AND 0FF00H
  860. IF lasm
  861.     LINK    CPSCPM
  862. ENDIF;lasm
  863.