home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / cpm80 / cpsmit.asm < prev    next >
Assembly Source File  |  2020-01-01  |  30KB  |  835 lines

  1. ; CPSMIT.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 system-independent initialization, the main
  20. ;       loop, and the commands that don't have any place better to go.
  21. ;    All the SET xxx and status routines now in CPSCOM.ASM as CPSMIT.ASM
  22. ;    was getting too big.
  23. ;
  24. ; revision history:
  25. ;
  26. ;edit 30, 29-Mar-1991 by MF. When looking up a TAKE-file in a TAKE command
  27. ;    and the file is not found, complain if it's not the first TAKE of
  28. ;    the current program execution (the automatic TAKE of KERMIT.INI)
  29. ;edit 29, 25-Mar-1991 by MF. Add STAY command as a synonym for SET NO-EXIT
  30. ;    command per Martin J. Carter of Nottingham University in the U.K.
  31. ;edit 28, 21-Mar-1991 by MF. Modify code after "inp2a" in INPUT command
  32. ;    so a ^C will halt TAKE-file processing
  33. ;edit 27, 27-Feb-1991 by MF. Add QUIT as a synonym for EXIT per code of
  34. ;    Dr. Martin J. Carter of Nottingham University, U.K. Recognizing QUIT
  35. ;    helps those who forget they're not in MS-Kermit, C-Kermit,
  36. ;    Kermit-32 etc. Also add commands so that CONNECT, RECEIVE and SEND may
  37. ;    be abbreviated to C,  R and S, respectively.
  38. ;edit 26, 5-Nov-1990 by MF.  Cosmetic changes to main HELP messages for
  39. ;    COPY and RENAME commands.
  40. ;edit 25, 1-Nov-1990 by MF.  Made the following command-name changes in the
  41. ;    interest of uniformity of nomenclature (per suggestions of FDC):
  42. ;    FCOPY to COPY, FRENAME to RENAME and STRING to OUTPUT.
  43. ;    This means we'll have to type "CO" for CONNECT and "REC" for 
  44. ;    RECEIVE but with REMOTE now with us we have to do the latter anyway.
  45. ;edit 24, 18-Sep-1990 by MF.  Implemented FRENAME command to rename a
  46. ;    CP/M file.
  47. ;edit 23, 9-Sep-1990 by MF.  Implemented commands to be sent to a
  48. ;    remote Kermit Server (Remote commands).
  49. ;    Implemented setting of packet sizes for RECEIVE and SEND.
  50. ;    Put DIRECTORY/STRING help texts in proper alphabetical position.
  51. ; edit 22, July 6th, 1987 by OBSchou.  Added a dummy Commandline to be
  52. ;    loaded for debugging purposes as DDT destroys any command line at 80H
  53. ;    Also fixed a bug or two...
  54. ;
  55. ; edit 21, April 8th, 1987.
  56. ;    Various bits, including more SET SENDRECEIVE options, and make 
  57. ;    PADDING and PADCHAR valid options.  Have I wasted my time, or 
  58. ;    there still systems that use padding??  Fixed a bug in the INPUT
  59. ;    command so we know how many characters there are to check for. Also
  60. ;    hived off the SET commands to make a new file, CPSCOM.ASM thereby
  61. ;    reducing the size of CPSMIT.ASM.  Also rename COPY command to FCOPY
  62. ;    hence retaining a single C to imply connect.
  63. ;
  64. ; edit 20, March 30, 1987 by OBSchou.  
  65. ;    added code for no exit to CPM if a command tail is done (optional)
  66. ;    by the SET NO-EXIT command.  Added bits for SET AUTORECEIVE to enable 
  67. ;    or inhibit automatic receive of several files (if something is coming 
  68. ;    along from the remote side, do a receive. Toss first packet away.)  
  69. ;    This is first step to SERVER???
  70. ;    Also added back the INPUT command.
  71. ;
  72. ; edit 19, March 16, 1987.  Moved the code to check for and execute 
  73. ;    command tails (See Richard Russells submission below).  
  74. ;    Added flags to exit to CP/M after executing a command tail.  
  75. ;    The KERMIT.INI file is taken before the command tail is issued.
  76. ;
  77. ; edit 18, March 11, 1987 by OBSchou.
  78. ;    Added in code for TYPE <file> and PRINT <file>.  Hope to add COPY 
  79. ;    later on.  Also added in code submitted by Richard Russel, to accept
  80. ;    a command tail on entry to kermit (eg KERMIT CONNECT).  This facility
  81. ;    if used, will replace the automatic TAKE function on loading Kermit.
  82. ;    Unfortunately, you will not be dropped back to CP/M after the command
  83. ;    In the future, it may be possible to either accept several commands
  84. ;    on the command tail, and possibly accept the automatic TAKE facility
  85. ;    as well.  Low on my list of things to do.
  86. ;
  87. ; edit 17, January 28, 1987 by OBSchou for DJ Roberts of Leicester
  88. ;    Also added a couple of fixes [obs]
  89. ;
  90. ;     DJR  January 1987  David J. Roberts.
  91. ;          USER made a SET option
  92. ;          STATUS output placed in alphabetical order
  93. ;          Report DEBUG mode and default disk 
  94. ;          Name of LOG file on SHOW/STATUS display
  95. ;
  96. ;
  97. ; edit 16 December 1st, OBSchou.  Fixed bug in that if the overlay is not in
  98. ;    place or correct then prtstr is not called to print the error message
  99. ;    (As prtstr has been moved out of the system independent code)
  100. ;
  101. ; edit 15 November 10, 1986 by OBSchou.  Re-inserted Pause and Break 
  102. ;       commands for release.
  103. ;
  104. ; edit 14 August 29, 1986.  Removed PAUSE,BREAK,INPUT and SET CASE as 
  105. ;       these have not been fully coded or debugged.  (For next 
  106. ;       version of Kermit-80...). Also tidied up a bit.
  107. ;
  108. ; 13 by OBSchou for Godfrey Nix.  He writes:
  109. ;       edit August 11,1986      Godfrey Nix, Nottingham University [gnn]
  110. ;       To insert code for setting the packet start character on
  111. ;       both send and receive packets (default is still 01H)
  112. ;       and make GET and RECEIVE to be separate;
  113. ;       use with edits to CP4PKT, CP4UTL
  114. ;
  115. ; edit 12: 19 June, 1986 by OBSchou.  Added PAUSE and BREAK facility.
  116. ;       Breaks simulate a call to sysint which tests for a B being passed.
  117. ;       Note this is only useful if the system dependent code supports breaks,
  118. ;       and an appropriate message is returned if breaks are not possible.
  119. ;       Also added is the command entry for INPUT, which waits for a string
  120. ;       from the host for a given time.  The time is a very variable counter
  121. ;       incremented every BDOS call.  Trial and error will give a reasonable
  122. ;       value.  STRING acceps a string from the use and then sends it on 
  123. ;       to the host.  These new commands allow a user to (almost) set up auto
  124. ;       log on files, where BREAKS/INPUT/STRING/STRING partially emulate a user
  125. ;       (AI LURES OK and all that).  Still could do with a test, eg if not a
  126. ;       correctly returned string go back n steps.  This would make a fairly 
  127. ;       simple TAKE command a lot more complicated.
  128. ;
  129. ;edit 11: 30 May, 1986 OBSchou.  Added in a couple of more routines and such
  130. ;
  131. ;edit 10: 27 May, 1986 OBSchou.  Added in support for USER function
  132. ;       removed XMIT test and routine, but also added SET FLOW-CONTROL
  133. ;       (set for XON/XOFF flow control in both directions) and a 
  134. ;       SET CASE-SENSITIVE ON/OFF (if on => a # A, if ON => a=A)
  135. ;
  136. ;edit 9: 13 May, 1986 OBSchou, Loughborough University, UK
  137. ;       Added in code for SET XMIT character to allow setting of the
  138. ;       character to wait for from the host during TRANSMIT.  It is
  139. ;       a line feed by default.  Also added a TAKE command, to take: commands
  140. ;       from a named disk file.  If a file is TAKEn, then all BDOS calls 
  141. ;       are trapped and tested for console input.  If so, we substitute a 
  142. ;       character (or buffer) from the TAKE file specified.
  143. ;       This may also be used in the future for a CPKERMIT.INI 
  144. ;       to be evaluated during Kermit initialsation.
  145. ;
  146. ; edit 8: February 6, 1895
  147. ;       Add a PORT status/show routine for those machines that have more
  148. ;       than one they can talk to. It also required a port storage variable
  149. ;       a la SPEED and the necessary code to handle it in the SET routine.
  150. ;       [Hal Hostetler]
  151. ;
  152. ; edit 7: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
  153. ;
  154. ;pcc003-pcc005  2-Jan-85        vjc     modules:cp4mit,cp4tt,cp4utl
  155. ;       These edits must all be installed together and change the way
  156. ;       logging is handled.  The log file spec is moved to a separate
  157. ;       fcb, and not opened until an actual CONNECT command is given.
  158. ;       This takes care of a NASTY bug that if you used any other file
  159. ;       command between the LOG and CONNECT, the log file would get
  160. ;       written over the last file used.  This also allows logging to
  161. ;       be "permanently" enabled until an CLOSE (new command) for all
  162. ;       CONNECT sessions, like most other kermits do.  If a log file
  163. ;       already exists, it will be appended to.  Also add two new
  164. ;       CONNECT mode commands <esc>Q to suspend logging and <esc>R to
  165. ;       resume.  <esc>R means something else during TRANSMIT, but
  166. ;       logging is never on then, so there shouldn't be any conflict.
  167. ;       I also changed the write code, so that it can handle one more
  168. ;       character after the XOFF is send to stop the host.  This allows
  169. ;       a little "slop" for systems that don't stop immediately (such
  170. ;       as TOPS10), but it didn't help much.
  171. ;
  172. ;pcc012 4-Jan-85        vjc     modules:cp4mit,cp4tt,cp4utl
  173. ;       Use the big buffer for the log file.  Move the log file back
  174. ;       into the common fcb and only save the drive, name, and
  175. ;       extension between connects.  Add new routines to cp4utl to
  176. ;       create or append to an existing file, and to conditionally
  177. ;       advance buffers only if in memory.  Remove edit pcc003 that
  178. ;       allows one more character after the xoff, since it didn't
  179. ;       really work very well and does not fit in well with the way
  180. ;       the buffer advancing routines are set up.  If someone still
  181. ;       thinks this would be useful, it could be put back in with a
  182. ;       little more work.
  183. ;       
  184. ;       While testing this edit, I also noticed another bug that
  185. ;       the command parsing routines do not limit or check the
  186. ;       length of command lines or file specs, trashing what ever
  187. ;       comes after them.  Currently because of where the fcb and
  188. ;       command buffer are located, this does not usually cause a
  189. ;       problem, but could if an extremely long line was typed in,
  190. ;       or in the future multiple fcbs defined elsewhere in memory
  191. ;       were used.  Maybe this should be put on the bug list
  192. ;       somewhere.
  193. ;
  194. ;pcc013 8-Jan-85        vjc     modules:cp4mit,cp4utl,cp4typ
  195. ;       Replace CLOSE command to cancel session logging to SET
  196. ;       LOGGING ON/OFF.  This seems to fit in with the command
  197. ;       structure better.  Default the log file to KERMIT.LOG
  198. ;       incase no previous LOG command.  Logging is also enabled
  199. ;       by LOG command, as before.
  200. ;
  201. ; edit 6: September 8, 1984
  202. ;       Add VERSION command, to display the internal version strings.
  203. ;       Move command tables here from CP4UTL, and translate string
  204. ;       lengths in them to decimal (how many fingers do YOU got?).
  205. ;       Replace some jump tables with dispatch addresses in tables.
  206. ;       Make help text for SET command consistent with top level help text.
  207. ;
  208. ; edit 5: August 21, 1984
  209. ;       Add word at 0100H to allow us to exit cleanly from DDT (shifting
  210. ;       entry section by two bytes).
  211. ;
  212. ; edit 4: August 3, 1984 (CJC)
  213. ;       Remove "mover" from entry section, as it now lives in CP4SYS.
  214. ;
  215. ; edit 3: July 27, 1984 (CJC)
  216. ;       Merge LASM support from Toad Hall: most of CP4MIT is now in CP4UTL.
  217. ;       When assembling with LASM, CP4MIT is linked by CP4DEF; it links to
  218. ;       CP4PKT.  Add SET TACTRAP command.  Separate out display routines so
  219. ;       we can eventually do "SHOW <parameter>".  Save both bytes of baud
  220. ;       rate in speed, and check both bytes when displaying baud rate.  Move
  221. ;       header info to CP4KER.ASM.  Add onoff and chkkey routines to simplify
  222. ;       SET command (Toad Hall)
  223. ;
  224. ; edit 2: June 8, 1984
  225. ;       formatting and documentation; delete unreferenced variables and some
  226. ;       unnecessary labels; move setpar here from cp4pkt; add module version
  227. ;       string; make this version 4.01.
  228. ;
  229. ; edit 1: May, 1984
  230. ;       extracted from CPMBASE.M80 version 3.9; modifications are described
  231. ;       in the accompanying .UPD file.
  232.  
  233. ;
  234.     ASEG
  235.     ORG    100H
  236.  
  237. ; The CCP invokes programs with a CALL 100H, with the stack pointer set to
  238. ; 100H.  When we exit to CP/M, we do so with a RET, avoiding a warm boot.
  239. ; Unfortunately, DDT starts programs with a jump, not a call, so when we
  240. ; attempt to return to CP/M, we blow the stack and use the word at 100H as
  241. ; the new PC.  Put a 0 there so we reboot instead of dying horribly.
  242. ; (Fortunately, this happens to be two NOP's).
  243.     dw    0
  244.     jmp    start    ; Bypass entry section
  245.  
  246. ;
  247. ;       Entry section for system-independent part.  This contains
  248. ;       jumps to routines needed by the system support module.
  249. ;
  250. entries:
  251.     jmp    kermit        ; reentry address
  252.     jmp    nout        ; output HL in decimal
  253. entsiz    equ    $-entries    ; length of entry section
  254. ;
  255. ;       End of entry section.  As a consistency check, the expected
  256. ;       length of this section is stored by the system-dependent
  257. ;       module in the linkage section at the end of Kermit, and
  258. ;       tested at initialization.
  259.  
  260. mitver:    db    'CPSMIT.ASM (30) 29-Mar-1991$'    ; name, edit number, date
  261. ;
  262. ;
  263. ;       Initialization
  264. ;
  265. start:    lxi    h,0        ; Clear out hl pair
  266.     dad    sp        ; and fetch the system stack pointer
  267.     shld    oldsp        ; and save for later restoral
  268.     lxi    sp,stack    ; move in our own stack.
  269.     lxi    d,version    ; print Kermit version
  270.     call    prtstx        ;  before we do too much (Use fudged prtstr)
  271.     mvi    c,rddrv        ;Get our logged in drive
  272.     call    BDOS
  273.     inr    a        ;relative 1
  274.     sta    CURDSK        ;and save it for later
  275.  
  276.     lda    vtflg        ; [OBS] Hangover from VT52 ems not possible...
  277.     cpi    0ffh        ; ... if 0ff stored, assume terminal = off
  278.     mvi    a,vtdefo
  279.     jnz    start0
  280.     sta    vtflg        ; if 0ffh make it VT52 off
  281. start0:
  282.  
  283.  
  284. IF debug
  285. ;vvvvvvvvvvvvvvvv remove this for run time
  286. ; OBS edit 22 - add in a dummy command line to 80H
  287.     lxi    h,dcomln    ;[22] load up dummy command line
  288.     lxi    d,81h        ;[22] where to put it
  289.     lxi    b,endcoml-dcomln
  290.     mov    a,c        ; get length to a
  291.     sta    80h        ; ... and save as command line length
  292.     call    mover        ; ... and save rest of line
  293.     jmp    starta
  294. dcomln:    db    'set baud 4800',semico
  295.     db    'set dir on',semico
  296.     db    'dir'
  297.     db    0,0    ; just to make up space
  298. endcoml:
  299. ;^^^^^^^^^^^^^^^^ remove this for run time
  300. ENDIF    ;debug
  301.  
  302.  
  303. starta:
  304. ;
  305. ;       Make sure the overlay is in place...
  306. ;
  307.     lhld    lnkflg
  308.     mov    a,h
  309.     ora    l        ; if lnkflg is still zero,
  310.     jz    start1        ;  the configuration overlay is missing.
  311.     lxi    d,-lnksiz    ; if it's not equal to lnksiz,
  312.     dad    d        ;  we've probably got the wrong
  313.     mov    a,h        ;  version of the configuration overlay.
  314.     ora    l
  315.     jnz    start2
  316.     lhld    lnkent        ; make sure the overlay knows how long
  317.     lxi    d,-entsiz    ; our entry section is, so they don't miss.
  318.     dad    d
  319.     mov    a,h
  320.     ora    l
  321.     jnz    start2
  322.                 ; might be ok.
  323.     lxi    h,bdos        ; set xbdos address to bdos trap in our code.
  324.     shld    xbdos+1        ; (they may never use it...)
  325.     call    sysinit        ; do system-dependent initialization
  326.     lda    bufsec        ; get the max no of buffers allowed by system
  327.     sta    maxbsc        ; save for SET BUFFER use to compare
  328.     lxi    d,inms26    ; offer some advice on getting help
  329.     call    prtstr
  330.     lxi    h,buff        ;[19] we copy any potential command tail across
  331.     lxi    d,cbuff
  332.     lxi    b,80h        ;[19] copy all 128 bytes.  May use none.
  333.     call    mover
  334.     lda    80h        ; see if there is a command tail...
  335.  
  336.     ana    a
  337.  
  338.  
  339.  
  340. ; Remove for runtime use
  341. ;    xra    a        ; make out there is no command tail
  342. ; Runtime => no XRA above
  343.  
  344.     jz    startz
  345.     dcr    a
  346.     jz    startz        ; one character tail...
  347.     lda    takflg        ; if more characters, say we are have tail
  348.     ori    10h        ; set bit 4
  349.     sta    takflg
  350.     sta    nexitf        ; exit back to CP/M after command line
  351. startz:
  352.     mvi    a,0ffh        ; when here, system basically initiallised,...
  353.     sta    initflg        ; apart from KERMIT.INI, so say initialised.
  354.  
  355.     call    take1        ;[9] take a KERMIT.INI file
  356.     xra    a        ;[MF] Say we've done it
  357.     sta    initak        ;[MF] ...
  358.     jmp    kermit        ; Start main loop.
  359.  
  360. start1:    lxi    d,erms20    ; "Kermit has not been configured"
  361.     call    prtstx        ; print error message (Use bodge for prtstr)
  362.     jmp    exit2        ;  and exit.
  363.  
  364. start2:    lxi    d,erms21    ; "Consistency check on configuration failed"
  365.     call    prtstx        ; print error message
  366.     jmp    exit2        ;  and exit.
  367. ;
  368. ;This is the main KERMIT loop.  It prompts for and gets the users commands.
  369.  
  370. kermit:    lxi    sp,stack    ; get new stack pointer, old one might be bad.
  371.     call    selcon        ; make sure console is selected.
  372.     xra    a
  373.     sta    mfflg1        ;reset MFNAME
  374.     sta    mfflg2        ;ditto
  375.     sta    mfflg3
  376.     sta    getrxflg    ; clear the get/receive flag
  377.                 ;0=> receive, non 0 => get
  378.     sta    cmbflg        ;[MF]Initial keyword must not be blank
  379.     sta    cmqflg        ;[MF]Allow character-echoing during commands
  380.     sta    remtxt        ;[MF] Clear remote-text-to-screen flag
  381.     lda    curdsk        ; update the prompt
  382.     adi    'A'-1
  383.     sta    kerm1+2
  384.     call    getun        ;[11] get the user number into temp1/2
  385.     lda    temp1+1        ;[11] get ms value of user number
  386.     cpi    '0'        ;[11] less than 10 => do a space
  387.     jnz    kerm4        ;[11] else do MS digit of user number
  388.     mvi    a,' '        ;[11]
  389. kerm4:    sta    kerm1        ;[11]
  390.     lda    temp1        ;[11] get ls digit of user number
  391.     sta    kerm1+1        ;[11] save that
  392.     lda    takflg        ; are we in TAKE or command line??
  393.     ani    11h        ; strip out both bits
  394.     jnz    kerm5        ; still in either or both...
  395.     lda    nexitf        ; if neither, and no-exit-flag set, we quit.
  396.     ana    a
  397.     jnz    exit        ;... back to CP/M, else as you were...
  398. kerm5:
  399.     lxi    d,kerm
  400.     call    prompt        ;Prompt the user.
  401.  
  402. kerm7:    lxi    d,comtab
  403.     lxi    h,tophlp
  404.     call    keycmd        ; Get a keyword
  405.     xchg            ; Get result (dispatch address) into HL
  406.     pchl            ; Dispatch.
  407.  
  408. ;       here from: log, setcom, read, cfmcmd
  409. kermt3:    lxi    d,ermes3    ;"Not confirmed"
  410.     call    prtstr
  411.     jmp    kermit        ;Do it again.
  412.  
  413. ;       Structure of command table:
  414. ;
  415. ;       1) Number of entries.
  416. ;       2) Each entry is arranged as follows:
  417. ;               a) length of command in bytes.
  418. ;               b) 'name of command and $-sign'
  419. ;               c) address of routine to process command
  420. ;
  421. ;       ---> Note this command table is in alphabetic order.
  422. ;
  423.  
  424. comtab:    db    32    ; added remote
  425.             ;[obs] added in COPY command, now called FCOPY
  426.             ;[obs] removed remote simply to issue V4.09
  427.                 ;[MF]Make FCOPY/FRENAME COPY/RENAME for
  428.                 ;[MF]Version 4.10
  429.                 ;[MF]Add QUIT as a synonym for EXIT and
  430.                 ;[MF]C, R and S as abbreviations for
  431.                 ;[MF]CONNECT, RECEIVE and SEND, respectively
  432.                 ;[MF]Add STAY as a synonym for SET NO-EXIT
  433.     db    5, 'BREAK$'
  434.         dw break
  435.     db    3, 'BYE$'
  436.         dw bye
  437.     db    1,'C$'
  438.     dw    telnet        ;[MF]Abbreviation for CONNECT
  439.     db    7, 'CONNECT$'
  440.         dw telnet
  441.     db    4,'COPY$'
  442.         dw copy
  443.     db    9, 'DIRECTORY$'
  444.         dw dir
  445.     db    5, 'ERASE$'
  446.         dw era
  447.     db    4, 'EXIT$'
  448.         dw exit
  449.     db    6, 'FINISH$'
  450.         dw finish
  451.     db    3, 'GET$'
  452.         dw read        ; [gnn] entry for GET
  453.     db    4, 'HELP$'
  454.         dw help
  455.     db      5, 'INPUT$'
  456.         dw input
  457.     db    3, 'LOG$'
  458.         dw log
  459.     db    6, 'LOGOUT$'
  460.         dw logout
  461.     db    6, 'OUTPUT$'
  462.         dw string
  463.     db    5, 'PAUSE$'
  464.         dw pause
  465.     db    5, 'PRINT$'
  466.         dw printf    ;[obs] print a file
  467.     db    4,'QUIT$'
  468.     dw    exit        ;[MF]Synonym for EXIT
  469.     db    1,'R$'
  470.     dw    read0        ;[MF]Abbreviation for RECEIVE
  471.     db    7, 'RECEIVE$'
  472.         dw read0    ; [gnn] not same as GET now
  473.     db    6, 'REMOTE$'
  474.         dw remote
  475.     db    6,'RENAME$'
  476.     dw    rename        ;[MF]
  477.     db    1,'S$'
  478.     dw    send        ;[MF]Abbreviation for SEND
  479.     db    4, 'SEND$'
  480.         dw send
  481.     db    3, 'SET$'
  482.         dw setcom
  483.     db    4, 'SHOW$'
  484.         dw show
  485.     db    6, 'STATUS$'
  486.         dw status
  487.     db    4,'STAY$'
  488.     dw    noexit        ;STAY (SET NO-EXIT)
  489.     db    4, 'TAKE$'            ;[9]
  490.         dw take
  491.     db    8, 'TRANSMIT$'
  492.         dw xmit
  493.     db    4, 'TYPE$'
  494.         dw type        ;[obs] type a file command
  495.     db    7, 'VERSION$'
  496.         dw shover
  497. ;    db    4, 'USER$'            ; removed [DRJ]
  498. ;        dw user                ;[10] removed [DRJ]
  499. ; top-level help message. Caps indicate keywords.
  500. ; this text is also printed by the HELP command.
  501.  
  502. tophlp:    
  503.     db    cr,lf,'BREAK to send a break to the host'
  504.     db    cr,lf,'BYE to host (LOGOUT) and exit to CP/M'
  505.     db    cr,lf,'CONNECT to host on selected port'
  506.     db    cr,lf,'COPY to copy a CP/M file'
  507.     db    cr,lf,'DIRECTORY of current used Micro-disk'
  508.     db    cr,lf,'ERASE a CP/M file'
  509.     db    cr,lf,'EXIT to CP/M'
  510.     db    cr,lf,'FINISH running Kermit on the host'
  511.     db    cr,lf,'GET a file from the host'
  512.     db    cr,lf,'HELP by giving this message'
  513.     db    cr,lf,'INPUT to make the micro wait for a string from the host'
  514.     db    cr,lf,'LOG the terminal sessions to a file'
  515.     db    cr,lf,'LOGOUT the host'
  516.     db    cr,lf,'OUTPUT to send a specified string to the host'
  517.     db    cr,lf,'PAUSE to wait for a little time'
  518.     db    cr,lf,'PRINT a file to the printer'
  519.     db    cr,lf,'QUIT to CP/M'
  520.     db    cr,lf,'RECEIVE file from host'
  521.     db    cr,lf,'REMOTE to send commands to a remote server'
  522.     db    cr,lf,'RENAME to rename a CP/M file'
  523.     db    cr,lf,'SEND file to host'
  524.     db    cr,lf,'SET a parameter'
  525.     db    cr,lf,'SHOW the parameters'
  526.     db    cr,lf,'STATUS of Kermit'
  527.     db    cr,lf,'STAY at Kermit command-level after a command tail'
  528.     db    cr,lf,'TAKE commands from a file'        ;[9]
  529.     db    cr,lf,'TRANSMIT file to host (in connect state)'
  530.     db    cr,lf,'TYPE a file to the console'
  531.     db    cr,lf,'VERSION of Kermit running'        ;[pcc005]
  532. ;    db    cr,lf,'USER to set a different user number' ;removed [DJR]
  533.     db    '$'        ;[obs] added it here to allow for expansion
  534.  
  535. ;
  536. ;       This is the BREAK command.  It sends a 'B' to the system dependent
  537. ;       interrupt routines (test for escape-cokebottle xxx) and do a break
  538. ;       if the overlay can.  Else, we tell user not to be so silly.
  539. break:    call    cfmcmd        ; get return
  540.     mvi    a,'B'        ; were gonna do a break if the overlay can
  541.     call    sysint        ; try doing it..
  542.     jmp    kermit        ; if we can do it, else
  543.     lxi    d,inms12    ;... say not implemented
  544.     jmp    kermit
  545.  
  546. ;
  547. ;
  548. ;       This is the BYE command.  It tells the remote KERSRV to logout,
  549. ;       then exits.
  550.  
  551. bye:    call    cfmcmd
  552.     call    logo        ;Tell the main frame to logout.
  553.     jmp    kermit        ;If it fails, don't exit.
  554.     call    sysbye        ; success. do system-dependent cleanup
  555.     jmp    exit1        ;Exit Kermit.
  556.  
  557. ;       This is the EXIT command.  It leaves KERMIT and returns to CP/M.
  558. ;       alternate entries: exit1, from BYE command;
  559. ;       exit2, from initialization (if it fails)
  560.  
  561. exit:    call    cfmcmd        ; confirm...
  562. exit1:    call    sysexit        ; do system-dependent termination
  563. exit2:    
  564.     jmp    0        ; return to CP/M via JUMP instead of RET.
  565.     
  566. ;    lhld    oldsp        ;Get back the system stack
  567. ;    sphl            ;and restore it.
  568. ;    ret            ;Then return to system.
  569.  
  570. ;       Input command.  Syntax:
  571. ;               INPUT [Wait period] [string]
  572. ;       where
  573. ;               Wait period is a time period to wat for
  574. ;               string is a string to expect back from the host.  Control
  575. ;                       characters are entered as \ and an octal number.
  576. ;
  577. ;       I can see uses for this command from other routines...
  578. ;
  579. input:    mvi    a,cmnum        ; first get the number
  580.     call    comnd        ; get it
  581.     jmp    kermit        ; if we dont understand it...
  582.     lhld    number
  583.     shld    waitp        ; and save as the wait period
  584.     lxi    d,stbuff    ; where to put the string
  585.     mvi    a,cmtxt        ; get text
  586.     call    comnd
  587.     jmp    kermit        ; not quite correct...
  588.     sta    strcnt        ; string count returned in a
  589.     call    cfmcmd        ; get a confirm
  590.  
  591.     lhld    waitp        ; multiply the number by
  592.     dad    h
  593.     dad    h        ; ... 4
  594.     dad    h        ; ... 8
  595.     inx    h        ; but make sure it is at least 1
  596.     shld    waitp        ; and save it away again
  597.     shld    waitp1        ; save in case we need to reset counter
  598.  
  599. ; Right, now wait for characters comming from the line, within the
  600. ;    time allowed (very fuzzy).  Compare with STRING buffer
  601. ;
  602. inp1:    xra    a
  603.     sta    repcnt        ; clear the host prompt chars.counter
  604. inp2:    lhld    waitp        ; have we waited long enough
  605.     dcx    h
  606.     shld    waitp        ; count less one
  607.     mov    a,h        ; test to see if both zero
  608.     ora    l
  609.     jnz    inp20        ; nope
  610.     mvi    a,3        ; error is three ie total failure
  611.     sta    errorc
  612.     jmp    inp5        ; take error exit
  613.  
  614. inp20:    call    rd1chl        ; read a character from the line
  615.     ani    7fh        ; set flags
  616.     jnz    inp4        ; Not zero => we have a character from host
  617.     call    ckchr        ; see if *WE* have a character from console
  618.     push    psw        ; restore to modem
  619.     call    selmdm        ; reselect the modem port
  620.     pop    psw
  621.     ani    7fh        ; strip parity (should not be there)
  622.     jnz    inp2a        ; if a null, try again
  623.     lda    strcnt        ; if the string length is zero, dont wait.
  624.     ana    a
  625.     jnz    inp2        ; so loop back again
  626.     jmp    kermit        ; else drop out
  627.  
  628. inp2a:    cpi    cntlc        ; do we want to abort?
  629. ;[MF]Change following line
  630. ;    jz    kermit        ; in which case exit back to command loop
  631.     jnz    inp2b        ;[MF] No
  632.     lda    takflg        ;[MF] Yes, are we TAKEing
  633.     ani    1        ;[MF] commands from a file?
  634.     cnz    closet        ;[MF] Yes, close and reset to get
  635.                 ;[MF] commands from the command-line
  636.     jmp    kermit        ;[MF] and exit back to command loop
  637. inp2b:    cpi    cntlz        ; if control z exit back to command loop
  638.     jz    kermit        ; else try for other characters [MF]
  639.     jmp    inp2
  640.  
  641. inp4:    mov    e,a        ; save it for a while
  642.     lda    repcnt        ; see if this character matches with one in buffer
  643.     lxi    h,stbuff    ; point to string buffer
  644.     add    l        ; make hl = hl + a
  645.     mov    l,a
  646.     mvi    a,0        ; ie make hl = hl + character count
  647.     adc    h
  648.     mov    h,a        ; not using xra, as that clears the Carry flag
  649.     mov    a,e        ; get the character back again
  650.     cmp    m        ; is it = to what we expect?
  651.     jnz    inp1        ; no, clear counter and try again
  652.     lda    repcnt        ; yes, then update the pointer, and ...
  653.     inr    a        ; ... see if we have received all ...
  654.     sta    repcnt        ; ... we should have received
  655.     lhld    waitp1        ; get original counter
  656.     shld    waitp        ; and reset the loop (timer) counter
  657.     mov    e,a        ; save length into E again
  658.     lda    strcnt        ; get the length to compare
  659.     sub    e        ; if (e) > string length, we have it
  660.     jnz    inp2        ; else wait for a little longer
  661.  
  662.     xra    a        ; no errors
  663.     sta    errorc
  664.     jmp    kermit        ; so say nothing
  665. ;else if error...
  666.  
  667. inp5:    lxi    d,erms30    ; say message not receive in time...
  668.     call    prtstr
  669.     jmp    kermit        ; have string, so exit
  670.  
  671. ;
  672. ;
  673.  
  674. ;       This is the HELP command.  It gives a list of the commands.
  675.  
  676. help:    call    cfmcmd
  677.     lxi    d,tophlp    ;The address of the help message.
  678.     call    p20ln        ;Print at most 20 lines then pause
  679. ;    call    prtstr
  680.     jmp    kermit
  681. ;
  682. ;       This is the LOG command.  It logs a session to a file.
  683.  
  684. log:    mvi    a,cmofi        ;[pcc005] Parse an output file spec.
  685.     lxi    d,fcb        ;[pcc012] where to put it
  686.     call    comnd
  687.     jmp    kermt3
  688.     call    cfmcmd
  689.     lxi    h,fcb        ;[pcc012] copy file name and ext
  690.     lxi    d,lognam    ;[pcc012] to a safe place
  691.     lxi    b,12        ;[pcc012] 12 bytes
  692.     call    mover        ;[pcc012] zap ...
  693.     mvi    a,1        ;[pcc005] set flag for logging
  694.     sta    logflg        ;[pcc005]
  695.     jmp    kermit        ;[pcc005]
  696.  
  697. ;
  698. ;       PAUSE [Wait period]. Just wait for a couple of tics...
  699. pause:    mvi    a,cmnum        ; get the number of the wait period
  700.     call    comnd        ; get it
  701.     jmp    kermit        ; we canna do it, so get next command
  702.     lhld    number
  703.     xchg            ; move to d
  704.     lhld    clkbit+1    ; get clock bits 8 to 23
  705.     mov    a,h        ; strip ms bit so we have space for a possible carry
  706.     ani    7fh
  707.     mov    h,a
  708.     dad    d        ; add the number (ie get the number to wait to
  709.     shld    number        ; save it somewhere
  710. ;
  711. ;       Now, wait for time to be equal to newer NUMBER with Carry
  712. ploop:    
  713.     call    clock        ; increment clock
  714.     lda    takflg        ; test if keyboard interrupt.. not for takes
  715.     ana    a
  716.     jnz    ploop1        ; do nothing for take command files
  717.     mvi    c,dconio    ; get status from console
  718.     mvi    e,0ffh        ; just get the character
  719.     call    bdos
  720.     ana    a        ; if non zero return, then quit
  721.     jnz    kermit        ; we got something, so quit
  722. ploop1:    lhld    number
  723.     xchg
  724.     lhld    clkbit+1    ; get bits 8 to 23
  725.     mov    a,h
  726.     ani    7fh        ; make it 15 bits for a carry...
  727.     mov    h,a
  728.     mov    a,e        ; now, do (DE with carry) - HL
  729.     sub    l
  730.     mov    e,a
  731.     mov    a,d
  732.     sbb    h
  733.     ora    e        ; a = OR of result
  734.     jnz    ploop
  735.     jmp    kermit        ; otherwise we are done.
  736.  
  737. ; PRINT - Print a file to the console and printer.  
  738. ;    This command is active only from the command level, and not 
  739. ;    from the connect state.  Unfortunately, the print command is 
  740. ;    not going to be a background utility.
  741. printf:    mvi    a,0ffh        ; set the print flag on
  742. typent:    sta     prnfl        ; Type file entry.  Common for PRINT and TYPE
  743.     call    type        ; and do the rest of the print via type
  744.     xra    a
  745.     sta    prnfl        ; next clear the print flag
  746.     jmp    kermit
  747.  
  748. ; TYPE - Type a file to the console.
  749. ;    This command is really the same as the print command, but the output
  750. ;    is not copied to the printer.
  751. typef:    xra    a        ; we want to clear the printer on flag
  752.     jmp    typent        ; go to the type entry in printfile above
  753.  
  754.  
  755. ;
  756. ;       This is the TAKE command.  It take input from a file.
  757. ;       TAKE1 is the entry for automatically TAKE-ing KERMIT.INI (or whatever
  758. ;       the file name at taknam is) from the default drive
  759. ;    [18] code added to accept command tails.  See note [18] above
  760. ;
  761. take:    mvi    a,cmifi        ;[9] Get filename from user
  762.     lxi    d,takfcb    ;[9] Take file fcb space
  763.     call    comnd        ;[9] get the file spec
  764.     jmp    kermit        ;[9] User failed to specify a good file spec
  765.     call    take2        ;[MF] Now TAKE the file
  766.     jmp    kermit        ;[MF] Go back to main Kermit command loop
  767. ;
  768. take1:    lxi    b,12        ;[9] copy default drive and file name to take fcb
  769.     lxi    d,takfcb
  770.     lxi    h,taknam
  771.     call    mover        ;[9] and do it (all other extents etc are zero)
  772. ;[MF][30]No longer need the following line
  773. ;    jmp    take2        ; got the file name, now take it.
  774. ;
  775.                 ;[9] get the file name, now lets open it 
  776. ;
  777. take2:
  778.     lda    takflg        ; check to see we have not tak-take
  779.     ani    1        ; if set, we are in a take already
  780. ;[MF]We can do the following test/call more efficiently
  781. ;    jz    take21
  782. ;    call    closet        ; so close current take file
  783.     cnz    closet        ;[MF] So close current take file
  784. take21:
  785.     mvi    c,setdma
  786.     lxi    d,takdma    ;[9] tell bdos where to send data
  787.     call    BDOS
  788.     xra    a        ;[9] clear all these extents etc
  789.     sta    takfcb+14
  790.     sta    takfcb+32
  791.     lxi    d,takfcb    ;[9] open the file
  792.     mvi    c,openf        ;[9] open the file
  793.     call    BDOS
  794.     inr    a        ;[9] if FF returned, problems
  795. ;[MF]Complain if failure and not seeking KERMIT.INI
  796. ;    jz    kermit        ;[9] for now, say nowt if no ini file. Else..
  797.        jz      ntake           ;[9] We'll say file not found
  798.                 ;[MF] unless the initial TAKE (KERMIT.INI)
  799. ;    jmp    take3        ; a test
  800. ;    mvi    c,readf        ;[9] read first bytes from file
  801. ;    lxi    d,takfcb    ;[9]
  802. ;    call    BDOS
  803.  
  804. take3:    lxi    h,0
  805.     shld    takptr        ;[9] point to first byte of take file
  806.     lda    takflg        ; get current flag
  807.     ori    1        ;[9] and set flag to tell Kermit we're taking
  808.     sta    takflg
  809. ;[MF][30]Redo next lines so can flag initial TAKE of KERMIT.INI
  810. ;    call    rnsect        ;[9] read a sector
  811. ;    jmp    kermit        ;(Should use a ret, but this will do)
  812.     jmp    rnsect        ;[9] read a sector and return
  813.  
  814. ntake:    lda    initak        ;[MF]Is this the initial TAKE (KERMIT.INI)?
  815.     ora    a        ;[MF]...
  816.     rnz            ;[MF]Yes, don't complain
  817.     lxi    d,erms15    ;[9] Say file not found
  818.     call    prtstr
  819. ;[MF][30]Make next line a "jmp" since we've called TAKE2
  820. ;    call    rstdma        ;[9] reset the DMA addres for other files
  821. ;    jmp    kermit
  822.     jmp    rstdma        ;[9] reset the DMA addres for other files
  823.                 ;[MF] and return
  824.  
  825.  
  826. ; Little code to allow some expansion of code without changing
  827. ;  every futher address, only up to the end of this file.
  828. ;   TO BE REMOVED FRO RELEASE!
  829.  
  830. ;    org ($+100h) AND 0FF00H
  831.  
  832. IF lasm
  833.     LINK CPSCOM
  834. ENDIF ;lasm
  835.