home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / modems / modem / cp405src.ark / CP4UTL.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-12-26  |  29.9 KB  |  842 lines

  1. ; CP4UTL.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. ;    Utility routines, pure and impure data.
  20. ;
  21. ; revision history:
  22. ; edit 6: February 6, 1985
  23. ;    Added a storage location for the port value (PORT, just below
  24. ;    SPEED) which is used by the port status routine, and moved the
  25. ;    printer copy flag (PRNFLG:) into the communications area so
  26. ;    that the machine dependant overlay can toggle it. [Hal Hostetler]
  27. ;    Added ffussy flag for filename checking.  Generate the version
  28. ;    string from 'verno', which is set in CP4KER, because CP4KER has the
  29. ;    list of modules and their edit numbers. [Charles Carvalho]
  30. ;
  31. ; edit 5: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
  32. ;
  33. ;pcc002    28-Dec-84    modules:cp4tt,cp4utl
  34. ;    Add connect mode <esc>P command to toggle printer on
  35. ;    and off.  Conflicts with "official" recommended commands
  36. ;    in protocol manual, but I don't think CP/M will ever get
  37. ;    a PUSH command.
  38. ;
  39. ;pcc003-pcc005    2-Jan-85    vjc    modules:cp4mit,cp4tt,cp4utl
  40. ;    These edits must all be installed together and change the way
  41. ;    logging is handled.  The log file spec is moved to a separate
  42. ;    fcb, and not opened until an actual CONNECT command is given.
  43. ;    This takes care of a NASTY bug that if you used any other file
  44. ;    command between the LOG and CONNECT, the log file would get
  45. ;    written over the last file used.  This also allows logging to
  46. ;    be "permanently" enabled until an CLOSE (new command) for all
  47. ;    CONNECT sessions, like most other kermits do.  If a log file
  48. ;    already exists, it will be appended to.  Also add two new
  49. ;    CONNECT mode commands <esc>Q to suspend logging and <esc>R to
  50. ;    resume.  <esc>R means something else during TRANSMIT, but
  51. ;    logging is never on then, so there shouldn't be any conflict.
  52. ;    I also changed the write code, so that it can handle one more
  53. ;    character after the XOFF is send to stop the host.  This allows
  54. ;    a little "slop" for systems that don't stop immediately (such
  55. ;    as TOPS10), but it didn't help much.
  56. ;
  57. ;pcc006    2-jan-85    VJC    modules:cp4cmd,cp4utl
  58. ;    Problems with "?" in filespecs.  On reparse, may cause action
  59. ;    flag to be reset at wrong point, requiring multiple <CR>'s
  60. ;    to terminate the line or other weird stuff.  Also need to
  61. ;    check flag and complain if wild-cards illegal.
  62. ;
  63. ;pcc008    2-Jan-85    vjc    modules:cp4def,cp4tt,cp4utl
  64. ;    Keyboard input during CONNECT mode can get locked out if
  65. ;    there is enough input from the modem port to keep prtchr
  66. ;    busy.  This can happen for example, if the printer is running
  67. ;    at the same speed as the modem line, leaving you helpless to
  68. ;    turn it off or abort the host.  Add a fairness count, so that
  69. ;    at least every prfair characters we look at console input.
  70. ;
  71. ;pcc012    4-Jan-85    vjc    modules:cp4mit,cp4tt,cp4utl
  72. ;    Use the big buffer for the log file.  Move the log file back
  73. ;    into the common fcb and only save the drive, name, and
  74. ;    extension between connects.  Add new routines to cp4utl to
  75. ;    create or append to an existing file, and to conditionally
  76. ;    advance buffers only if in memory.  Remove edit pcc003 that
  77. ;    allows one more character after the xoff, since it didn't
  78. ;    really work very well and does not fit in well with the way
  79. ;    the buffer advancing routines are set up.  If someone still
  80. ;    thinks this would be useful, it could be put back in with a
  81. ;    little more work.
  82. ;    
  83. ;    While testing this edit, I also noticed another bug that
  84. ;    the command parsing routines do not limit or check the
  85. ;    length of command lines or file specs, trashing what ever
  86. ;    comes after them.  Currently because of where the fcb and
  87. ;    command buffer are located, this does not usually cause a
  88. ;    problem, but could if an extremely long line was typed in,
  89. ;    or in the future multiple fcbs defined elsewhere in memory
  90. ;    were used.  Maybe this should be put on the bug list
  91. ;    somewhere.
  92. ;
  93. ;pcc013    8-Jan-85    vjc    modules:cp4mit,cp4utl,cp4typ
  94. ;    Replace CLOSE command to cancel session logging to SET
  95. ;    LOGGING ON/OFF.  This seems to fit in with the command
  96. ;    structure better.  Default the log file to KERMIT.LOG
  97. ;    incase no previous LOG command.  Logging is also enabled
  98. ;    by LOG command, as before.
  99. ;
  100. ; edit 4: September 9, 1984
  101. ;    Move command tables and associated help text to CP4MIT.  Add
  102. ;    makfil/clofil routines and modify outbuf to write files in big
  103. ;    chunks.  Update Kermit's version to 4.03.
  104. ;
  105. ; edit 3: August 21, 1984
  106. ;    Make inbuf read files in big chunks to minimize disk start/stop
  107. ;    delays.  Buffer size and address is specified by system-dependent
  108. ;    overlay.
  109. ;
  110. ; edit 2: August 3, 1984
  111. ;    move "mover" to CP4SYS to allow use of Z80 block move instruction.
  112. ;
  113. ; edit 1: July 27, 1984
  114. ;    extracted from CP4MIT.M80 edit 2, as part of LASM support.  This is
  115. ;    the last file linked for the system-independent code.
  116. ;
  117. utlver:    db    'CP4UTL.ASM (5)  13-Jan-85$'
  118.  
  119. ;    Set the parity for a character in A.
  120. ;    called by: spack, rexmit, logit, vt52, conchr, intchr
  121.  
  122. setpar:    push    h        ;Save HL.
  123.     push    b
  124.     lxi    h,parity
  125.     mov    c,m        ;Get the parity routine.
  126.     mvi    b,0
  127.     lxi    h,parjmp    ;Get the first address.
  128.     dad    b
  129.     pchl
  130.  
  131. parjmp:    jmp    even
  132.     jmp    mark
  133.     jmp    none
  134.     jmp    odd
  135.     jmp    space
  136.  
  137. none:    jmp    parret        ;Don't touch the parity bit.
  138.  
  139. even:    ani    7FH        ;Strip parity.
  140.     jpe    parret        ;Already even, leave it.
  141.     ori    80H        ;Make it even parity.
  142.     jmp    parret
  143.  
  144. mark:    ori    80H        ;Turn on the parity bit.
  145.     jmp    parret
  146.  
  147. odd:    ani    7FH        ;Strip parity.
  148.     jpo    parret        ;Already odd, leave it.
  149.     ori    80H        ;Make it odd parity.
  150.     jmp    parret
  151.  
  152. space:    ani    7FH        ;Turn off the parity bit.
  153.     jmp    parret
  154.  
  155. parret:    pop    b
  156.     pop    h        ;Restore HL.
  157.     ret
  158. ;
  159. ;    Print the escape char.
  160. ;    called by: stat01, xmit, telnet, intchr
  161.  
  162. escpr:    lda    escchr        ;Get the escape char.
  163.     cpi    ' '        ;Is it a control char?
  164.     jp    escpr2
  165.     lxi    d,inms10    ;Output "Control-".
  166.     call    prtstr
  167.     lda    escchr
  168.     ori    100O        ;De-controlify.
  169. escpr2:    mvi    c,conout    ;Output the char
  170.     mov    e,a
  171.     call    bdos
  172.     ret
  173.  
  174. ;    fetch keyword; if unsuccessful, return to command level.
  175. ;    called by: kermit, setcom
  176.  
  177. keycmd:    mvi    a,cmkey
  178.     call    comnd
  179.      jmp    keycm2        ;no match
  180.     ret
  181.  
  182. keycm2:    lxi    d,ermes1    ;"Unrecognized Command"
  183.     call    prtstr
  184.     jmp    kermit        ;Do it again.
  185.  
  186. ;    request confirmation; if unsuccessful, return to command level
  187. ;    called by: bye, exit, help, log, setcom, show, status, send,
  188. ;        finish, logout, xmit, telnet
  189.  
  190. cfmcmd:    mvi    a,cmcfm
  191.     call    comnd
  192.      jmp    kermt3        ;"Not confirmed"
  193.     ret
  194. ;
  195.  
  196. ;    This routine prints the number in HL on the screen in decimal.
  197. ;    Uses all ACs.
  198. ;    called by: cp4sys, read, send, updrtr, dir
  199.  
  200. nout:    lxi    b,-10        ;Get some useful constants.
  201. nout1:    lxi    d,-1
  202.  
  203. nout2:    dad    b        ;Subtract as many 10s as possible.
  204.     inx    d        ;Count them.
  205.     jc    nout2        ;If some left keep going.
  206.     push    h        ;save remainder - 10
  207.     xchg            ;Swap the remainder and the quotient.
  208.     mov    a,h        ;Get the number of 10s found.
  209.     ora    l        ;check for quotient non zero
  210.     cnz    nout1        ;If non zero, recurse.
  211.     pop    h        ;Get the remainder - 10
  212.     mov    a,l        ;in a
  213.     adi    '0'+10        ;Make the number printable and add the 10 back
  214.     mov    e,a        ;Output the digit.
  215.     mvi    c,conout
  216.     jmp    bdos
  217.  
  218. ; prcrlf - print a CR/LF.  (Saves no registers.) [Toad Hall]
  219. ; prtstr - print string pointed to by DE
  220. ;    called by: lots of places.
  221. prcrlf:    lxi    d,crlf        ;Point to the CR/LF
  222. prtstr:    mvi    c,prstr        ; output string
  223.     jmp    bdos        ;a CALL followed by a RET becomes a JMP
  224.  
  225. ;    Jumping to this location is like retskp.  It assumes the instruction
  226. ;    after the call is a jmp addr.
  227. ;    here from: many places.
  228. rskp:    pop    h        ;Get the return address.
  229.     inx    h        ;Increment by three.
  230.     inx    h
  231.     inx    h
  232.     pchl
  233.  
  234. ;    Jumping here is the same as a ret.  'jmp r' is used after routines
  235. ;    that have skip returns, where the non-skip instruction must be 3 bytes.
  236. ;    here from: many places.
  237. r:    ret
  238. ;
  239. ;    Open a file for reading (with inbuf).  The filename is already
  240. ;    in fcb;    upon return, the end of file flag is cleared and chrcnt
  241. ;    is set to zero, so inbuf will be called to get a buffer when we
  242. ;    next attempt to get a character.
  243. ;    called by: sinit, seof, xmit
  244.  
  245. getfil: xra    a
  246.     sta    chrcnt        ;Buffer is empty.
  247.     sta    seccnt        ;No sectors buffered.
  248.     sta    eoflag        ;Not the end of file.
  249.     sta    endsts        ;No EOF/error pending.
  250.     sta    fcb+0CH        ;Zero the extent.
  251.     sta    fcb+0EH        ;Must be zero for MAKEF or OPENF.
  252.     sta    fcb+20H        ;Zero the current record.
  253.     mvi    c,openf        ;Open the file.
  254.     lxi    d,fcb
  255.     call    bdos
  256.     ret
  257.  
  258. ;    Get next sector.  If necessary, read some more from disk.
  259. ;    preserves bc, de, hl
  260. ;    returns nonskip if EOF or error;
  261. ;    returns skip with chrcnt and bufpnt updated if success.
  262. ;    called by: gtchr, xnext
  263.  
  264. inbuf:    lda    eoflag        ;Have we reached the end?
  265.     ora    a
  266.     rnz            ;Return if so.
  267.     push    b
  268.     push    d
  269.     push    h
  270. inbuf1:    lda    seccnt        ; Do we have any sectors left?
  271.     ora    a
  272.     jz    inbuf3        ; If not, go get some more.
  273. inbuf2:    lhld    nxtbuf        ; Yes.  Get address of next sector
  274.     shld    bufpnt        ; Update current buffer pointer
  275.     lxi    b,bufsiz    ; Get number of bytes in sector
  276.     dad    b        ; Update HL to point to next sector
  277.     shld    nxtbuf        ; Save for next time
  278.     dcr    a        ; Decrement count of buffered sectors
  279.     sta    seccnt        ; Put it back
  280.     mvi    a,bufsiz-1    ; Number of bytes in buffer (pre-decremented)
  281.     sta    chrcnt        ; Store for our caller
  282.     pop    h
  283.     pop    d
  284.     pop    b
  285.     jmp    rskp        ; Return success
  286.  
  287. ; We don't have any sectors buffered.  If we've already hit an error or
  288. ; EOF, return that status to the user.
  289.  
  290. inbuf3:    lda    endsts        ; Check status from previous read
  291.     ora    a
  292.     jz    inbuf4        ; It was OK.  Get some more sectors.
  293.     sta    eoflag        ; End of file or error.  Set the flag.
  294.     xra    a
  295.     sta    chrcnt        ; Say no characters in buffer.
  296.     pop    h
  297.     pop    d
  298.     pop    b
  299.     ret            ; Return failure
  300.  
  301. ; Read sectors until we fill the buffer or get an error or EOF, then return
  302. ; the first buffer to the user.  (seccnt is zero)
  303.  
  304. inbuf4:    lhld    bufadr        ; Get address of big buffer
  305.     shld    nxtbuf        ; Store as next buffer address to give user
  306. inbuf5:    shld    bufpnt        ; Store as next buffer address to read into
  307.     xchg            ; Move buffer address to DE
  308.     mvi    c,setdma    ; Tell CP/M where to put the data
  309.     call    bdos        ;  ...
  310.     mvi    c,readf        ; Read a record.
  311.     lxi    d,fcb
  312.     call    bdos
  313.     sta    endsts        ; Save ending status
  314.     ora    a        ; 00H => read O.K
  315.     jnz    inbuf6        ; EOF/error: stop reading.
  316.     lxi    h,seccnt    ; Success.  Get addr of sector count
  317.     inr    m        ; Bump sector count by one
  318.     lda    bufsec        ; Get max number of sectors in buffer
  319.     cmp    m        ; Are we there yet?
  320.     jz    inbuf7        ; Yes, can't read any more.
  321.     lhld    bufpnt        ; No, try for another.  Get buffer address,
  322.     lxi    d,bufsiz    ;  and size of sector,
  323.     dad    d        ;  giving next buffer address in HL
  324.     jmp    inbuf5        ; Go read another sector.
  325.  
  326. ; We hit EOF or got an error.  Put the DMA address back where it belongs,
  327. ; then go see if we have any sectors (before the one that got the error)
  328. ; to return to the caller.  Nxtbuf points to the first good sector, if
  329. ; any; seccnt contains the count of good sectors.
  330.  
  331. inbuf6:    call    rstdma
  332.     jmp    inbuf1        ; Go see if we have some data to return
  333.  
  334. ; We've filled the big buffer.  Reset the DMA address, then go return a
  335. ; sector to the caller.  nxtbuf points to the beginning of the buffer;
  336. ; seccnt contains the number of sectors successfully read (except that
  337. ; if we've read 256 sectors, seccnt contains zero, so we can't just go
  338. ; to inbuf1).
  339.  
  340. inbuf7:    call    rstdma        ;[pcc012]
  341.     lda    seccnt        ; Get sector count again.
  342.     jmp    inbuf2        ; Return a sector.
  343.  
  344. ; ;[pcc012]
  345. ;   appfil - Create or append to an existing file.  File name is in FCB.
  346. ;    Non-skip return if could not be done.  Skip return with file
  347. ;    open and bufpnt pointing to end of file.
  348. ;    called by logopn
  349. appfil:    xra    a        ;[pcc012] zero out stuff for open
  350.     sta    fcb+0CH        ;[pcc012] extent
  351.     sta    fcb+0EH        ;[pcc012] Must be zero for MAKEF or OPENF.
  352.     sta    fcb+20H        ;[pcc012] Zero the current record.
  353.     mvi    c,openf        ;[pcc012] Try to open the file
  354.     lxi    d,fcb        ;[pcc012]
  355.     call    bdos        ;[pcc012]
  356.     cpi    0FFH        ;[pcc012] Did we find it?
  357.     jz    makfi1        ;[pcc012] If not, go create it
  358.     mvi    c,cflsz        ;[pcc012] Compute the file size
  359.     lxi    d,fcb        ;[pcc012]
  360.     call    bdos        ;[pcc012]
  361.     lhld    fcb+21H        ;[pcc012] random record pointer
  362.     mov    a,h        ;[pcc012] See if zero length file
  363.     ora    l        ;[pcc012]
  364.     jz    makfi2        ;[pcc012] set up pointers if null file
  365.     dcx    h        ;[pcc012] backup to last record written
  366.     shld    fcb+21H        ;[pcc012] store rec ptr back
  367.     lhld    bufadr        ;[pcc012] get buffer address
  368.     xchg            ;[pcc012] to DE
  369.     mvi    c,setdma    ;[pcc012] set dma address
  370.     call    bdos        ;[pcc012] for read
  371.     mvi    c,rrand        ;[pcc012] read the last block
  372.     lxi    d,fcb        ;[pcc012]
  373.     call    bdos        ;[pcc012]
  374.     ora    a        ;[pcc012] check results
  375.     jnz    rstdma        ;[pcc012] reset dma and return if error
  376.     lhld    bufadr        ;[pcc012] get address again
  377.     lxi    d,bufsiz    ;[pcc012] and and size
  378.     mvi    a,'Z'-40H    ;[pcc012] control-Z for comparison
  379. appcz:    cmp    m        ;[pcc012] Is this the EOF?
  380.     jz    appxit        ;[pcc012] Jump if yes
  381.     inx    h        ;[pcc012] no, bump
  382.     dcr    e        ;[pcc012] and grind
  383.     jnz    appcz        ;[pcc012] until find or buffer empty
  384. appxit:    shld    bufpnt        ;[pcc012] store buffer pointer
  385.     dad    d        ;[pcc012] compute next buffer adr
  386.     shld    nxtbuf        ;[pcc012] and store
  387.     mov    a,e        ;[pcc012] updated chr count
  388.     sta    chrcnt        ;[pcc012]
  389.     xra    a        ;[pcc012] reset sector count
  390.     sta    seccnt        ;[pcc012]
  391.     call    rstdma        ;[pcc012] reset normal dma
  392.     jmp    rskp        ;[pcc012] and give good return
  393.  
  394. ;    Create a file, deleting any previous version.  The filename is in
  395. ;    fcb.
  396. ;    Returns nonskip if file could not be created.
  397. ;    If successful, takes skip return with bufpnt and chrcnt initialized
  398. ;    for output; buffers should be output via outbuf.
  399. ;    called by: gofil
  400. makfil:    mvi    c,delf        ; delete the file if it exists.
  401.     lxi    d,fcb
  402.     call    bdos
  403.     xra    a
  404.     sta    fcb+0CH        ; zero the extent.
  405.     sta    fcb+0EH        ; must be zero for MAKEF or OPENF.
  406.     sta    fcb+20H        ; zero the current record.
  407. ;[pcc012] here from appfil above if file does not exist
  408. makfi1:    mvi    c,makef        ;[pcc012] now create it.
  409.     lxi    d,fcb
  410.     call    bdos
  411.     cpi    0FFH        ; is the disk full?
  412.     rz            ; take error return if so.
  413. ; success. set up pointers and counters for multisector buffering.
  414. ;[pcc012] also here from appfil if found zero length file
  415. makfi2:    lhld    bufadr        ;[pcc012] find beginning of buffer space.
  416.     shld    bufpnt        ; make it current buffer.
  417.     lxi    d,bufsiz    ; get sector size.
  418.     dad    d        ; find beginning of next buffer.
  419.     shld    nxtbuf        ; store for later.
  420.     mov    a,e        ; store buffer size
  421.     sta    chrcnt        ;  for caller.
  422.     xra    a
  423.     sta    seccnt        ; no sectors stored yet.
  424.     jmp    rskp        ; take success return.
  425.  
  426. ;[pcc012]
  427. ;   outadv - conditionally advance output buffer if disk write not needed.
  428. ;    preserves BC
  429. ;    skip return with with next output buffer set up
  430. ;    non-skip return if memory buffer full and must write to disk.
  431. ;    called by:logit
  432.  
  433. outadv:    push    b        ;[pcc012] save BC as advertised
  434.     lxi    h,seccnt    ;[pcc012] point to sectors buffered
  435.     inr    m        ;[pcc012] count this one
  436.     lda    bufsec        ;[pcc012] how many we can hold
  437.     cmp    m        ;[pcc012] check if full
  438.     jnz    outbf2        ;[pcc012] continue if not
  439.     dcr    m        ;[pcc012] full, un-advance sector count
  440.     pop    b        ;[pcc012] restore bc
  441.     ret            ;[pcc012] and give non-skip return
  442.  
  443. ;    get a fresh output buffer, flushing big buffer if necessary.
  444. ;    returns nonskip if disk full.
  445. ;    if successful, returns skip with bufpnt and chrcnt updated.  Note
  446. ;    that chrcnt holds one less than the buffer size.
  447. ;    preserves BC.
  448. ;    called by: ptchr,logwrt
  449.  
  450. outbuf:    push    b
  451.     lxi    h,seccnt    ; count another buffered sector
  452.     inr    m        ;  ...
  453.     lda    bufsec        ; get number of sectors we can hold
  454.     cmp    m        ; full?
  455.     jnz    outbf2        ; if not, set up pointers and return
  456.     call    outmbf        ; flush the big buffer
  457.      jmp    outbf9        ; disk error.
  458. ;[pcc012] also here from outadv to advance buffer
  459. outbf2:    lhld    nxtbuf        ; get pointer to fresh buffer
  460.     shld    bufpnt        ; store for caller
  461.     lxi    d,bufsiz    ; advance our pointer to next buffer
  462.     dad    d
  463.     shld    nxtbuf
  464.     mvi    a,bufsiz-1    ; get buffer size (pre-decremented)
  465.     sta    chrcnt        ; store for caller
  466.     pop    b
  467.     jmp    rskp        ; return success.
  468.  
  469. outbf9: pop    b        ; clean up stack
  470.     ret            ; and take error return.
  471.  
  472. ;    flush incore output buffers.
  473. ;    returns nonskip if disk full.
  474. ;    if successful, returns skip with nxtbuf reset to start of buffer and
  475. ;    seccnt zero.
  476. ;    destroys all ac's.
  477. ;    called by: outbuf, clofil.
  478.  
  479. outmbf:    lhld    bufadr        ; get start of buffer
  480.     shld    nxtbuf        ; store for next fill cycle
  481.     shld    bufpnt        ; store for empty loop
  482. outmb2:    lhld    bufpnt        ; get address of current sector
  483.     xchg            ;  into DE
  484.     lxi    h,bufsiz    ; advance HL to next sector
  485.     dad    d        ;  ...
  486.     shld    bufpnt        ;  and store for later
  487.     mvi    c,setdma
  488.     call    bdos        ; point CP/M at current sector
  489.     lxi    d,fcb
  490.     mvi    c,writef
  491.     call    bdos        ; output the sector
  492.     ora    a        ; test for error (A non-zero)
  493.     jnz    rstdma        ;[pcc012] reset dma and take nonskip return if so
  494.     lxi    h,seccnt
  495.     dcr    m        ; count down buffered sectors
  496.     jnz    outmb2        ; loop if more saved
  497.     call    rstdma        ;[pcc012] restore normal dma
  498.     jmp    rskp        ; return success.
  499.  
  500. ;    output current buffer, flush incore buffers, and close output file.
  501. ;    returns nonskip if disk full; skip if successful.
  502. ;    called by: rdata
  503.  
  504. clofil:
  505.     lda    chrcnt        ; get the number of chars left in the buffer.
  506.     cpi    bufsiz        ; Virgin buffer?
  507.     jz    clofl3        ; yes, don't output it.
  508.     lhld    bufpnt        ; get the buffer pointer.
  509. clofl1:    dcr    a        ; lower the count.
  510.     jm    clofl2        ; if full then stop.
  511.     mvi    m,'Z'-100O    ; put in a ^Z for EOF.
  512.     inx    h        ; point to the next space.
  513.     jmp    clofl1
  514.  
  515. clofl2:    call    outbuf        ; output the last buffer.
  516.      jmp    r        ; give up if the disk is full.
  517. clofl3:    lda    seccnt        ; any sectors buffered in memory?
  518.     ora    a
  519.     jz    clofl4        ; if not, don't try to flush.
  520.     call    outmbf        ; flush buffers
  521.      jmp    r        ; disk full.
  522. clofl4:    mvi    c,closf        ; close up the file.
  523.     lxi    d,fcb
  524.     call    bdos
  525.     jmp    rskp        ; return success.
  526.  
  527.  
  528. ; Reset DMA address to the default buffer
  529. ; called from inbuf,appfil,outmbf
  530. rstdma:    lxi    d,buff        ;[pcc012]
  531.     mvi    c,setdma    ;[pcc012]
  532.     jmp    bdos        ;[pcc012]
  533.  
  534. ;
  535.  
  536. version:db    'Kermit-80 v4.'
  537.     db    (verno/10) + '0'    ; tenth's digit of version number
  538.     db    (verno MOD 10) + '0'    ; hundredth's digit
  539.     db    ' $'
  540. kerm:    db    'Kermit-80  '
  541. kerm1:    db    'x:>$'        ;'x' filled in at startup with DRIVE name
  542. crlf:    db    cr,lf,'$'
  543. ermes1:    db    cr,lf,'?Unrecognized command$'
  544. ermes3:    db    cr,lf,'?Not confirmed$'
  545. ermes4:    db    '?Unable to receive initiate',cr,lf,'$'
  546. ermes5:    db    '?Unable to receive file name',cr,lf,'$'
  547. ermes6:    db    '?Unable to receive end of file',cr,lf,'$'
  548. erms10:    db    '?Unable to receive data',cr,lf,'$'
  549. erms11:    db    '?Disk full',cr,lf,'$'
  550. erms14:    db    '?Unable to receive an acknowledgement from the host',cr,lf,'$'
  551. erms15:    db    cr,lf,'?Unable to find file',cr,lf,'$'
  552. erms16:    db    '?Unable to rename file$'
  553. erms17: db    cr,lf,'?Disk full$'
  554. erms18: db    cr,lf,'?Unable to tell host that the session is finished$'
  555. erms19: db    cr,lf,'?Unable to tell host to logout$'
  556. erms20: db    cr,lf,'?Kermit has not been configured for a target system$'
  557. erms21: db    cr,lf,'?Consistency check on configuration failed$'
  558. erms22:    db    cr,lf,'?Error writing to log file',cr,lf,'$'    ;[pcc005]
  559.  
  560. infms3:    db    bell,'Completed$'
  561. infms4:    db    bell,'Failed$'
  562. infms5:    db    '%Renaming file to $'
  563. infms6:    db    cr,lf,'[Closing the log file]$'
  564. infms7:    db    cr,lf,'[Connected to remote host.  Type $'
  565. infms8:    db    'C to return;',cr,lf,' type $'
  566. inms8a:    db    '? for command list]',cr,lf,'$'
  567. infms9:    db    cr,lf,'[Connection closed, back at micro]$'
  568. inms10:    db    'Control-$'
  569. inms12:    db    ' (Not implemented)',cr,lf,'$'
  570. inms13:    db    bell,'Interrupted$'
  571. inms14:    db    TAB,TAB,'    Directory for drive '
  572. dnam14:    db    'x:',cr,lf,'$'        ;filled in by dir routine.
  573. inms15:    DB    CR,LF,TAB,TAB,'Drive $'
  574. inms16:    DB    '  has $';filled in by summary code with drive letter
  575. inms17:    DB    'K bytes free',CR,LF,'$'
  576. inms18:    DB    CR,LF,'File(s) erased$',CR,LF
  577. inms19:    db    cr,lf,'[Transmitting file to host:'
  578.     db    cr,lf,' 1. Type any character to send a line.'
  579.     db    cr,lf,' 2. Type RETURN to terminate the line '
  580.     db    'and to get the next line (go back to 1.)'
  581.     db    cr,lf,'    (You may send other characters '
  582.     db    'before RETURN.),'
  583.     db    cr,lf,'   or type $'
  584. inms20:    db    'R to send the same line again,'
  585.     db    cr,lf,'   or type $'
  586. inms21: db    'C to abort transmission.]',cr,lf,'$'
  587. inms22:    db    cr,lf,'[Transmission done. Connected normally '
  588.     db    'to remote host,'
  589.     db    cr,lf,' type $'
  590. inms23:    db    'Sending...$'
  591. inms24:    db    'Receiving...$'
  592. inms25:    db    bell,'Warning: eighth bit cannot be sent$'
  593. inms26:    db    cr,lf,'For help, type ? at any point in a command$'
  594. inms27:    db    cr,lf,'[Logging suspended]',cr,lf,'$'    ;[pcc003]
  595. inms28:    db    cr,lf,'[Logging resumed]',cr,lf,'$'    ;[pcc003]
  596.  
  597. escmes:    db    cr,lf,'Type the new escape character:  $'
  598. tacmes:    db    cr,lf,'Type the new TAC intercept character:  $'
  599.  
  600. xmthlp:    db    cr,lf,'R Send the same line again$'
  601. loghlp:    db    cr,lf,'Q  Suspend logging'        ;[pcc003]
  602.     db    cr,lf,'R  Resume logging$'        ;[pcc003]
  603. inthlp:    db    cr,lf,'?  This message'
  604.     db    cr,lf,'C  Close the connection'
  605.     db    cr,lf,'0  (zero) Transmit a NULL'
  606.     db    cr,lf,'P  Toggle printer on/off'    ;[pcc002]
  607.     db    cr,lf,'S  Status of the connection$'
  608. inhlp1:    db    cr,lf,'Typing another $'
  609. inhlp2:    db    ' will send it to the host'
  610.     db    cr,lf,cr,lf,'Command>$'
  611.  
  612. xmtst:    db    cr,lf,'Transmitting a file$'
  613. locst:    db    cr,lf,'Local echo$'
  614. onstr:    db    ' on$'
  615. offstr:    db    ' off$'
  616. vtemst:    db    cr,lf,'VT52 emulation$'
  617. cpmst:    db    cr,lf,'File Mode$'
  618. defstr: db    ' default$'
  619. ascstr: db    ' ASCII$'
  620. binstr:    db    ' binary$'
  621. ibmst:    db    cr,lf,'IBM flag$'
  622. filst:    db    cr,lf,'File warning$'
  623. prst:    db    cr,lf,'Printer copy$'
  624. logst:    db    cr,lf,'Logging is$'        ;[pcc003]
  625. susstr:    db    ' suspended$'            ;[pcc003]
  626. escst:    db    cr,lf,'Escape char: $'
  627. bckst:    db    cr,lf,'Block check type: $'
  628. bckst1:    db    '-character$'
  629. parst:    db    cr,lf,'Parity: $'
  630. pnonst:    db    'none$'
  631. pmrkst:    db    'mark$'
  632. pspcst:    db    'space$'
  633. poddst:    db    'odd$'
  634. pevnst:    db    'even$'
  635. porst:    db    cr,lf,'Port in use is: $'
  636. spdst:    db    cr,lf,'Current baud rate is: $'
  637. spdust:    db    'indeterminate (not SET)$'
  638. timmsg:    db    'Timer$'
  639. tacst:    db    cr,lf,'Current TACTrap Status/Intercept Character:  $'
  640.  
  641. cmer00:    db    cr,lf,'?Program error:  Invalid COMND call$'
  642. cmer01:    db    cr,lf,'?Ambiguous$'
  643. cmer02:    db    cr,lf,'?Illegal CP/M file specification$'
  644. cmer03:    db    cr,lf,'?Wild-cards not allowed in file specification$'    ;[pcc006]
  645. cmin00:    db    ' Confirm with carriage return$'
  646. ;
  647.     ;Impure data
  648.  
  649. ;COMND storage
  650.  
  651. cmstat:    ds    1        ;What is presently being parsed.
  652. cmaflg:    ds    1        ;Non-zero when an action char has been found.
  653. cmccnt:    ds    1        ;Non-zero if a significant char is found.
  654. cmsflg:    ds    1        ;Non-zero when the last char was a space.
  655. cmostp:    ds    2        ;Old stack pointer for reparse.
  656. cmrprs:    ds    2        ;Address to go to on reparse.
  657. cmprmp:    ds    2        ;Address of prompt.
  658. cmptab:    ds    2        ;Address of present keyword table.
  659. cmhlp:    ds    2        ;Address of present help.
  660. cmdbuf:    ds    80H        ;Buffer for command parsing.
  661. cmfcb:    ds    2        ;Pointer to FCB.
  662. cmfcb2:    ds    2        ;Pointer to position in FCB.
  663. cmfwld:    ds    1        ;Wildcard flag
  664. cmcptr:    ds    2        ;Pointer for next char input.
  665. cmdptr:    ds    2        ;Pointer into the command buffer.
  666. cmkptr:    ds    2        ;Pointer to keyword.
  667. cmsptr:    ds    2        ;Place to save a pointer.
  668. ;
  669. oldsp:    ds    2        ;Room for old system stack.
  670.     ds    40H        ;Room for 32 levels of calls.
  671. stack:    ds    2
  672. eoflag:    ds    1        ;EOF flag;non-zero on EOF.
  673. curdsk:    db    0        ;holds "logged" disk
  674. prtcnt:    db    0        ;[pcc008] prtchr fairness count
  675. timflg:    db    0        ;[jd] timer flag: 0 -> no timer
  676. timval:    dw    0        ;[jd] timer value
  677. wrn8:    db    0        ;[jd] non-zero if 8-bit-lost warning sent
  678. qbchr:    db    '&'        ;[jd] binary quote character.
  679. quot8:    db    0        ;[jd] non-zero if doing 8-bit quoting
  680. logflg:    db    0        ;Flag for a log file.
  681.                 ;[pcc005] 0 = no log
  682.                 ;[pcc005] x1 = logging on
  683.                 ;[pcc005] x2 = suspended
  684.                 ;[pcc005] 8xH (bit 7) = file open
  685. lognam:    db    0        ;[pcc013] File to use for session logging
  686.     db    'KERMIT  '    ;[pcc013]
  687.     db    'LOG'        ;[pcc013]
  688. escflg:    db    0        ;Escape flag (start off).
  689. fileio:    db    0        ;Line-by-line from file (default off).
  690. xofflg:    db    0        ;X-OFF (=^S) received from COMM-line
  691. ;                ;X-ON (=^Q) received resets this
  692. vtyval:    ds    1        ; holds row number for VT52 cursor positioning
  693. chrcnt:    ds    1        ;Number of chars in the file buffer.
  694. filcnt:    ds    1        ;Number of chars left to fill.
  695. outpnt:    ds    2        ;Position in packet.
  696. bufpnt:    ds    2        ;Position in file buffer.
  697. fcbptr:    ds    2        ;Position in FCB.
  698. datptr:    ds    2        ;Position in packet data buffer.
  699. cbfptr:    ds    2        ;Position in character buffer.
  700. pktptr:    ds    2        ;Position in receive packet.
  701. size:    ds    1        ;Size of data from gtchr.
  702. curchk:    ds    1        ;Current checksum type
  703. inichk:    ds    1        ;Agreed upon checksum type
  704. czseen:    ds    1        ;Flag that control-Z was typed
  705. pktnum:    ds    1        ;Packet number.
  706. numpkt:    ds    2        ;Total number of packets sent.
  707. numrtr:    ds    2        ;Total number of retries.
  708. numtry:    ds    1        ;Number of tries on this packet.
  709. oldtry:    ds    1        ;Number of tries on previous packet.
  710. state:    ds    1        ;Present state of the automaton.
  711. packet:    ds    4        ;Packet (data is part of it).
  712. data:    ds    5AH        ;Data and checksum field of packet.
  713. recpkt:    ds    65H        ;Receive packet storage (use the following).
  714. recpkx:    db    cr,'$'        ;=    =    = buffer limit
  715. filbuf:    ds    65H        ;Character buffer.
  716. fnbuf:    ds    20h        ;[jd] file name buffer
  717. ;** Temp 1 & 2 must be in order
  718. temp1:    ds    1        ;Temporary storage.
  719. lstchr    EQU    temp1        ;Last console input character.
  720. temp2:    ds    1
  721. temp3:    ds    1
  722. temp4:    ds    1
  723.  
  724. argblk:    ds    20H        ;Used for subroutine arguments
  725.  
  726. maxfil    EQU    2        ; currently, only two names used.
  727. fcbblk:    ds    maxfil*10H    ;Used for a list of FCB's
  728.  
  729. ; Bookkeeping storage for multiple-sector buffering.  The actual buffer
  730. ; is somewhere in the system-dependent overlay. (at the end, I hope).
  731. nxtbuf:    ds    2        ; Pointer to next sector
  732. seccnt:    ds    1        ; Number of sectors buffered
  733. endsts:    ds    1        ; Status for last read into buffer
  734.  
  735. patch:    ds    100        ; Guarantee some patch space
  736.  
  737.     ORG    ($ + 0ffH) AND 0ff00H    ; move to start of next page
  738. ;
  739. ;    hooks for system-dependent routines:
  740. ;    This area is overwritten by the system-dependent overlay.
  741. ;
  742. lnkflg:    dw    0    ; linkage information for consistency check.
  743. lnkent:    dw    0    ; more of the same.
  744. ovlver:    dw    0    ; pointer to overlay's version string
  745. ;
  746. ; Input/output routines.  Note that outmdm and outcon may actually be the
  747. ;    same routine if selmdm and selcon do anything.  (the same is true
  748. ;    of inpmdm and inpcon).
  749. ;
  750. selmdm:    jmp    $-$    ; select modem for I/O
  751. outmdm:    jmp    $-$    ; output character in E to modem
  752. inpmdm:    jmp    $-$    ; read character from modem. return character or 0 in A.
  753. flsmdm:    jmp    $-$    ; flush pending input from modem
  754. selcon:    jmp    $-$    ; select console for I/O
  755. outcon:    jmp    $-$    ; output character in E to console
  756. inpcon:    jmp    $-$    ; read char from console. return character or 0 in A
  757. outlpt:    jmp    $-$    ; output character in E to printer
  758. ;
  759. ; screen formatting routines
  760. clrlin:    jmp    $-$    ; erase current line
  761. clrspc:    jmp    $-$    ; erase current position (after backspace)
  762. delchr:    jmp    $-$    ; make delete look like backspace
  763. clrtop:    jmp    $-$    ; erase screen and go home
  764. ;
  765. ; these routines are called to display a field on the screen.
  766. scrend:    jmp    $-$    ; move to prompt field
  767. screrr:    jmp    $-$    ; move to error message field
  768. scrfln:    jmp    $-$    ; move to filename field
  769. scrnp:    jmp    $-$    ; move to packet count field
  770. scrnrt:    jmp    $-$    ; move to retry count field
  771. scrst:    jmp    $-$    ; move to status field
  772. rppos:    jmp    $-$    ; move to receive packet field (debug)
  773. sppos:    jmp    $-$    ; move to send packet field (debug)
  774. ;
  775. sysinit: jmp    $-$    ; program initialization
  776. sysexit: jmp    $-$    ; program termination
  777. syscon:    jmp    $-$    ; remote session initialization
  778. syscls:    jmp    $-$    ; return to local command level
  779. sysinh:    jmp    $-$    ; help text for interrupt (escape) extensions
  780. sysint:    jmp    $-$    ; interrupt (escape) extensions, including break
  781. sysflt:    jmp    $-$    ; filter for incoming characters.
  782.             ;  called with character in E.
  783. sysbye:    jmp    $-$    ; terminate remote session
  784. sysspd:    jmp    $-$    ; baud rate change routine.
  785.             ; called with value from table in DE
  786. sysprt:    jmp    $-$    ; port change routine.
  787.             ; called with value from table in DE
  788. sysscr:    jmp    $-$    ; screen setup for file transfer
  789.             ; called with Kermit's version string in DE
  790. csrpos:    jmp    $-$    ; move cursor to row B, column C
  791. sysspc:    jmp    $-$    ; calculate free space for current disk
  792. mover:    jmp    $-$    ; block move
  793. ;
  794. ; Data initialized by system-dependent overlay:
  795. ;
  796. pttab:    ds    2    ; points to local equivalents to VT52 escape sequences
  797. spdtab:    ds    2    ; address of baud rate command table, or zero
  798. spdhlp:    ds    2    ; address of baud rate help table, or zero
  799. prttab:    ds    2    ; address of port command table, or zero
  800. prthlp:    ds    2    ; address of port help table, or zero
  801. timout:    ds    2    ; Initial value for fuzzy timeout
  802. vtflg:    ds    1    ; VT52 emulation flag
  803. escchr:    ds    1    ; Storage for the escape character.
  804. speed:    ds    2    ; storage for the baud rate
  805. port:    ds    2    ; storage for port value
  806. prnflg:    ds    1    ;[hh] printer copy flag (overlay may need it)
  807. dbgflg:    ds    1    ; debugging flag
  808. ecoflg:    ds    1    ; Local echo flag (default off).
  809. flwflg:    ds    1    ; File warning flag (default on).
  810. ibmflg:    ds    1    ; IBM flag (default off).
  811. cpmflg:    ds    1    ; File mode flag (ascii/binary/default)
  812. parity:    ds    1    ; Current parity.
  813. spsiz:    ds    1    ; Send packet size.
  814. rpsiz:    ds    1    ; Receive packet size.
  815. stime:    ds    1    ; Send time out.
  816. rtime:    ds    1    ; Receive time out.
  817. spad:    ds    1    ; Send padding.
  818. rpad:    ds    1    ; Receive padding.
  819. spadch:    ds    1    ; Send padding char.
  820. rpadch:    ds    1    ; Receive padding char.
  821. seol:    ds    1    ; Send EOL char.
  822. reol:    ds    1    ; Receive EOL char.
  823. squote:    ds    1    ; Send quote char.
  824. rquote:    ds    1    ; Receive quote char.
  825. chktyp:    ds    1    ; Checksum type desired
  826. tacflg:    ds    1    ; TACTrap flag (zero=off, nonzero=on; when non-zero,
  827.             ;  contains current TAC intercept character)
  828. tacchr:    ds    1    ; TAC intercept character
  829. bufadr:    ds    2    ; Pointer to big buffer for multiple-sector I/O
  830. bufsec:    ds    1    ; Number of sectors big buffer can hold (0 means 256)
  831. ffussy:    ds    1    ; if nonzero, don't permit <>.,;?*[] in CP/M filespec.
  832. ; space used by directory command; here because space calculation is
  833. ;  (operating) system-dependent
  834. bmax:    ds    2    ; highest block number on drive
  835. bmask:    ds    1    ; (records/block)-1
  836. bshiftf: ds    1    ; number of shifts to multiply by rec/block
  837. nnams:    ds    1    ; counter for filenames per line
  838.  
  839. lnksiz    equ    $-lnkflg ; length of linkage section, for consistency check.
  840.  
  841.     END    START
  842.