home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / d / k20mit-264.mac < prev    next >
Text File  |  2020-01-01  |  398KB  |  12,533 lines

  1. $verno==^d5            ; Major version number.
  2. $mnver==^d1            ; Minor version number (minimum: 1).
  3. $edno==^d180             ; Edit number increases independent of version.
  4. $who==^d0            ; Who edited, 0=Columbia.
  5. ;
  6. ; Copyright (C) 1981, 2001,
  7. ; The Trustees of Columbia University in the City of New York.
  8. ;
  9. ; RECENT EDIT HISTORY (more at end):
  10. ;
  11. ;/w/fdc/timrek/kermit.mac, Mon Aug  6 14:28:27 2001, Frank (fdc@columbia.edu)
  12. ;[180] Buffered packet input instead per-character BIN% + better statistics.
  13. ;/w/fdc/timrek/kermit.mac, Sun Jan 28 17:33:20 2001, Frank (fdc@columbia.edu)
  14. ;[179] Added Long packets:
  15. ; . Added new symbol MAXBUF (10KB)
  16. ; . Increased packet buffer sizes to MAXBUF
  17. ; . Changed .setpk to allow sizes up to 9000 (near theoretical max)
  18. ; . Added CAPAS, WINDO, MAXLX1, MAXLX2 field support to rpar and spar.
  19. ; . Added long-packet sending/reading to spack/rpack.
  20. ; . Removed hardwired ^d94 packet-length references.
  21. ; . Speed improvements by up to a factor of 20.
  22. ; Changed default delay to 1 sec.
  23. ; Increased version number from 4.2 to 5.1.
  24. ; All long-packet related lines are marked "[179]".
  25. ;
  26. ;******************** Version 5.1 ************************
  27. ;PK:<TIMREK>KERMIT.MAC.259, 26-Jan-88 10:28:51, Frank (SY.FDC@CU20B)
  28. ;[178] Allow passwords to come from TAKE files.
  29. ;PK:<TIMREK>KERMIT.MAC.259, 25-Jan-88 18:38:14, Frank (SY.FDC@CU20B)
  30. ;[177] Fix [176].  It wasn't conditioning the line correctly.
  31. ;PK:<TIMREK>KERMIT.MAC.258, 11-Dec-87 14:16:09, Frank (SY.FDC@CU20B)
  32. ;[176] Allow commands to servers to be issued from TAKE file.
  33. ; Also, pass capabilities down to inferior process correctly.
  34. ;PS:<TIMREK>KERMIT.MAC.6,  6-May-85 17:39:44, Frank (SY.FDC@CU20B)
  35. ;[175] Delete any dot at the end of outbound file names (like 'makefile.').
  36. ;PS:<KERMIT>20KERMIT.MAC.256,  2-May-85 12:21:34, Frank (SY.FDC@CU20B)
  37. ;[174] Several things:
  38. ;. Don't ACK a Z packet if the file can't be closed.
  39. ;. Fix server interpretation of remote directory command with no args.
  40. ;. Fix "push" command message to not assume connected to remote.
  41. ;. Give appropriate messages for local/remote mode server entry.
  42. ;. Recover from i/o errors in debug log writing.
  43. ;. Recover from incoming filenames that start with dot.
  44. ;PS:<TIMREK>KERMIT.MAC.1028, 11-Dec-84 19:00:29, Frank (SY.FDC@CU20B)
  45. ;[173] Display contents of any incoming X packet.
  46. ;PS:<TIMREK>KERMIT.MAC.1028, 11-Dec-84 18:37:05, Frank (SY.FDC@CU20B)
  47. ;[172] Don't use "*" for default file type in SEND command.
  48. ;PS:<TIMREK>KERMIT.MAC.1021, 15-Nov-84 15:28:26, Frank (SY.FDC@CU20B)
  49. ;[171] Fix LOCAL CWD not to ask for password unless it has to.
  50. ;PS:<TIMREK>KERMIT.MAC.1018, 15-Nov-84 11:39:00, Frank (SY.FDC@CU20B)
  51. ;[170] Don't send 4 null bytes at end of ITS binary file.
  52. ;PS:<TIMREK>KERMIT.MAC.1012, 18-Oct-84 13:20:42, Frank (SY.FDC@CU20B)
  53. ;[169] Misc small fixes:
  54. ;. Make $XHOST allow ^C interrupt to work during SINFO.
  55. ;. Allow ^C interrupt in LOCAL TYPE.
  56. ;. REMOTE CWD Password: input was erroneously saying "?Too long"
  57. ;. In RUN command, don't let inferior log out.
  58. ;PS:<TIMREK>KERMIT.MAC.1012, 18-Oct-84 13:20:42, Frank (SY.FDC@CU20B)
  59. ;[168] Fix SPAR not to overrule SET commands when entering server mode.
  60. ;PS:<TIMREK>KERMIT.MAC.1004,  3-Oct-84 15:30:24, Frank (SY.FDC@CU20B)
  61. ;[167] Add ECHO command.
  62. ;PS:<TIMREK>KERMIT.MAC.1000,  3-Oct-84 12:13:10, Frank (SY.FDC@CU20B)
  63. ;[166] Add ^M and ^P interrupts for getting unstuck from TRANSMIT
  64. ;PS:<TIMREK>KERMIT.MAC.980,  2-Oct-84 19:36:41, Frank (SY.FDC@CU20B)
  65. ;[165] Add TRANSMIT command.
  66. ;PS:<TIMREK>KERMIT.MAC.972,  1-Oct-84 22:00:43, Frank (SY.FDC@CU20B)
  67. ;[164] Make session logging work during script execution.
  68. ;PS:<TIMREK>KERMIT.MAC.966, 30-Sep-84 13:27:04, Frank (SY.FDC@CU20B)
  69. ;[163] Add PC typeout to %JSERR
  70. ;PS:<TIMREK>KERMIT.MAC.962, 28-Sep-84 16:37:25, Frank (SY.FDC@CU20B)
  71. ;[162] Add CLEAR command.
  72. ;PS:<TIMREK>KERMIT.MAC.961, 28-Sep-84 08:37:26, Frank (SY.FDC@CU20B)
  73. ;[161] If SET SPEED done, remember it!
  74. ;PS:<TIMREK>KERMIT.MAC.946, 27-Sep-84 15:15:23, Frank (SY.FDC@CU20B)
  75. ;[160] Refinements of previous edit, add SET/SHOW INPUT.
  76. ;PS:<TIMREK>KERMIT.MAC.924, 26-Sep-84 16:35:53, Frank (SY.FDC@CU20B)
  77. ;[159] INPUT, OUTPUT, and PAUSE commands to provide a simple script facility.
  78. ;******************** Version 4.2 ************************
  79. ;
  80. ;PS:<TIMREK>KERMIT.MAC.918, 18-Jul-84 13:50:17, Frank
  81. ;[158] Clear up any XOFF condition when leaving protocol mode.
  82. ;PS:<TIMREK>KERMIT.MAC.916, 13-Jul-84 17:57:24, Frank
  83. ;[157] Don't get stuck if XOFF'd while typing out server message (thanks Jeff).
  84. ;PS:<TIMREK>KERMIT.MAC.914, 11-Jul-84 19:51:24, Frank
  85. ;[156] Debug previous edits.
  86. ;PS:<TIMREK>KERMIT.MAC.899, 10-Jul-84 18:52:39, Frank
  87. ;[155] Fix recently introduced bug in INILIN that broke handshake code.
  88. ;PS:<TIMREK>KERMIT.MAC.896, 10-Jul-84 17:12:04, Frank
  89. ;[154] Fix up session logging - avoid loss of nonopen JFN.  Add CLOSE command.
  90. ;PS:<TIMREK>KERMIT.MAC.893,  9-Jul-84 18:48:42, Frank
  91. ;[153] Always convert lc letters in incoming filenames to uc (for Bernie).
  92. ;PS:<TIMREK>KERMIT.MAC.888,  6-Jul-84 16:41:26, Frank
  93. ;[152] Add PUSH, SET SPEED, and SET BREAK.
  94. ;PS:<TIMREK>KERMIT.MAC.879,  5-Jul-84 12:53:06, Frank
  95. ;[151] Integrate connect code into this program, rather than running TTLINK
  96. ; in a lower fork.  Use TELNET-style separate input & output forks with no
  97. ; interrupts.  This was done for several reasons:
  98. ; . Release 6.0 of TOPS-20 doesn't allow multiple JFNs on a single TTY.
  99. ; . TTLINK did interrupt-driven i/o in a single fork, so would not work under
  100. ;   batch, where BATCON feeds i/o depending on whether "pty hungry".
  101. ; . Fewer source files to keep track of.
  102. ;******************** Version 4.1 ************************
  103. ;
  104. ;PS:<TIMREK>KERMIT.MAC.871,  3-Jul-84 10:50:55, Frank
  105. ;[150] Add dispatch tables for server and generic commands, to force us
  106. ; to think about every case -- e.g. server shouldn't complain about NAKs.
  107. ;PS:<TIMREK>KERMIT.MAC.870, 29-Jun-84 13:28:08, Frank
  108. ;[149] Fix bug in SET SEND/RECEIVE PADCHAR parsing (thanks, Daphne)
  109. ;PS:<TIMREK>KERMIT.MAC.859, 26-Jun-84 14:26:37, Frank
  110. ;[148] Allow source & destination filespecs for GET to be given separately.
  111. ;
  112. ;PS:<TIMREK>KERMIT.MAC.855, 26-Jun-84 12:38:18, Frank
  113. ;[147] Fix various problems reported by Ken Harrenstien (KLH@SRI-NIC):
  114. ; . Allow user to include !,?,@,;, etc in GET filespec with ^V quote.
  115. ; . Refuse links on file-transfer tty, not controlling tty!
  116. ; . Restore advice and links to tty after file transfer.
  117. ;
  118. ;PS:<TIMREK>KERMIT.MAC.840, 28-May-84 17:33:56, Frank
  119. ;[146] Get monitor version number at startup.  Under V6 or later, we can tell
  120. ; the real speed of the communication line (after all these years!). Also, we
  121. ; know speed of a local line.  Account for all this in CHKLIN, and report the
  122. ; percent efficiency in STATISTICS command when baud rate is known.
  123. ;
  124. ;PS:<TIMREK>KERMIT.MAC.820, 28-May-84 14:23:45, Frank
  125. ;[145] Allow LOCAL commands to be issued without the "LOCAL" prefix.
  126. ; Change LOCAL/REMOTE "DISK" to "SPACE".  Fill in local TYPE and RUN commands.
  127. ;
  128. ;PS:<TIMREK>KERMIT.MAC.810, 28-May-84 10:06:30, Frank
  129. ;[144] Misc bugs fixed:
  130. ; . In ENCODE, fix problem when exactly two consecutive repeat prefix
  131. ;    characters appear in data.
  132. ; . In SRVCMD, decode contents of ACK (it was being displayed "bare").
  133. ; . Remove test for remote at $SERVE, let server work over asg'd tty line.
  134. ; . In DOSRV, don't allow an I packet to cause a state transition.
  135. ; . Don't create empty debugging log files.
  136. ; . Fix bytesize in OPENF in RFIL3K (cosmetic)
  137. ; . Allow SET HANDSHAKE to also accept an octal number.
  138. ;
  139. ;PS:<TIMREK>KERMIT.MAC.804, 28-May-84 09:55:50, Frank
  140. ;[143] Add SET FLOW-CONTROL, SET EXPUNGE.
  141. ; Change SET DEBUGGING LOG to LOG DEBUGGING (like other Kermits).
  142. ;PS:<TIMREK>KERMIT.MAC.803, 19-Apr-84 12:16:59, Frank
  143. ;[142] Fix broken FILCNV for normal-form (from George Boyce, Cornell).
  144. ;PS:<TIMREK>KERMIT.MAC.799, 12-Apr-84 16:29:05, Frank
  145. ;[141] Decode filename in R packet instead of taking it literally.
  146. ; Also, allow ERMSG and KERMSG macros to take addresses, like %JSERR and
  147. ; %JSKER, and make their message formats nicer and more consistent.
  148. ;PS:<TIMREK>KERMIT.MAC.792,  5-Apr-84 13:23:38, Frank
  149. ;[140] Make ^X = ^Z if we're sending a directory (or deleted file) listing.
  150. ;PS:<TIMREK>KERMIT.MAC.791,  3-Apr-84 16:40:01, Frank
  151. ;[139] Fix "help receive" (table out of order).  Fix problem where server was
  152. ; sending a directory listing, interrupted, then asked to delete files, and
  153. ; sent rest of directory listing before deleting files.
  154. ;PS:<TIMREK>KERMIT.MAC.788, 26-Mar-84 13:11:11, Frank
  155. ;[138] Make sure any logs are closed after server FIN command.
  156. ;
  157. ;PS:<TIMREK>KERMIT.MAC.783, 23-Mar-84 11:00:06, Frank
  158. ;[137] When server gets a FINISH command, exit from program rather than
  159. ; going back to KERMIT command level, as we used to before.  Also:
  160. ; . Add SET PROMPT
  161. ; . Add SET RECEIVE SERVER-TIMEOUT (for Bernie)
  162. ; . Fix password delimitation in server CWD command.
  163. ; . Fill in LOCAL CWD command.
  164. ;
  165. ;PS:<TIMREK>KERMIT.MAC.778, 19-Mar-84 19:27:57, Frank
  166. ;[136] Fix mistake in CRC calculation when parity being used.
  167. ;
  168. ;PS:<TIMREK>KERMIT.MAC.767, 15-Mar-84 16:31:22, Frank
  169. ;[135] Move handshake code from beginning of SPACK to end of RPACK.
  170. ; This allows IBM communication to work again.
  171. ; Also, handle carrier drop a little better in SPACK.
  172. ; Also, make sure we close any open file after ^C out of file transfer.
  173. ;
  174. ;PS:<TIMREK>KERMIT.MAC.752, 14-Mar-84 11:50:47, Frank
  175. ;[134] Make SHOW LINE really test carrier, rather than possibly old flag.
  176. ; Put modem/carrier checking stuff in CHKLIN routine.  Also:
  177. ; . Be more defensive about terminal modes after running TTLINK.
  178. ; . Make sure file gets closed if in cAncel state.
  179. ; . Don't assign device if own controlling TTY (even if it is a TVT).
  180. ; . In GIVEUP, obey setting of INCOMPLETE FILE DISPOSITION for incoming
  181. ;   files that ask to be discarded.
  182. ;
  183. ;PS:<SY.FDC>KERMIT.MAC.736, 13-Mar-84 16:27:08, Frank
  184. ;[133] When sending an I packet, keep trying till retry limit exceeded.
  185. ; Also, include byte count and byte size in directory listing.
  186. ;
  187. ;PS:<TIMREK>KERMIT.MAC.735,  9-Mar-84 09:49:03, Frank
  188. ;[132] In STATISTICS, only show last JSYS error if debugging.  Also:
  189. ; . QCTL field in S/I packets and their ACKs was backwards!  Fix in SPAR, RPAR.
  190. ; . Fix a couple details with timers, clear all pending before setting.
  191. ; . In the unlikely event that an incoming filename can't be dealt with, store
  192. ;   the file as -UNTRANSLATABLE-FILENAME-.KERMIT.-1 to avoid sending an error
  193. ;   packet & terminating the transfer.
  194. ;
  195. ;PS:<TIMREK>KERMIT.MAC.726,  7-Mar-84 11:52:31, Frank
  196. ;[131] Add time stamps to debugging-packets log (suggested by BillW).  Also:
  197. ; . When logging incoming data, include current load-adjusted timeout interval.
  198. ; . Try to use different timeouts for sending & receiving.
  199. ; . Double outgoing IAC bytes in SPACK if TVT-BINARY is set.
  200. ;
  201. ;PS:<TIMREK>KERMIT.MAC.716,  5-Mar-84 12:15:09, Frank
  202. ;[130] Rename SET TAC to SET TVT, because it really applies to all ARPANET
  203. ; TVTs.  If TVT, must still OPENF line in 8 bit mode.  Also:
  204. ; . In INCHAR, detect carrier loss and close, deassign line when it happens.
  205. ; . Take class scheduler into account when getting load averages.
  206. ;
  207. ;PS:<TIMREK>KERMIT.MAC.705,  2-Mar-84 10:31:44, Frank
  208. ;[129] Install ARPANET TAC support changes from Dale Chase, ISI.
  209. ; Code mostly adapted from the TOPS-20 MODEM program (Bill Westfield, SRI).
  210. ; Dale's code modified at Columbia to operate through SET TAC rather than by
  211. ; determining TVT status through a site-dependent JSYS (DEC vs BBN vs...).
  212. ;
  213. ; Important installation note from Dale:
  214. ;
  215. ; Some TOPS-20s may need a patch or two to allow user programs to send the
  216. ; necessary telnet protocol negotiations.  The monitor cell NVTDOD must contain
  217. ; "400000,,RSKP" so that TOPS-20 will accept the negotiation.  And some sites
  218. ; may have code that "doubles" any IAC (octal 377) characters sent from a
  219. ; network terminal.  We turned that off here by putting a "RET" in CHKIAC.  If
  220. ; TOPS-20 doubles IACs, this program will not be able to negotiate telnet
  221. ; binary mode.
  222. ;
  223. ;PS:<TIMREK>KERMIT.MAC.691, 29-Feb-84 17:00:05, Frank
  224. ;[128] Several final things before field-test:
  225. ; . Accept null data field in server commands.
  226. ; . In RPAR, ask other side to time us out based on our 15-min ldav rather
  227. ;   than hardwired constant, DRTIM.  New routine ADJTIM does this.
  228. ;   Also, raise DRTIM from 8 to 15 seconds, since we're probably in better
  229. ;   control of the timeouts than the KERMIT on the other side.
  230. ; . In local mode, don't mix up blips with debugging output.
  231. ; . When starting to send, check for incoming NAKs to cut short any delay.
  232. ; . Add support for LOG SESSION command.
  233. ; . Fix mistake in setting file size by clearing RCHR before entering RD state.
  234. ; . Ditto for SCHR when entering SD state.
  235. ; . Exchange parameters before sending file related commands to a server.
  236. ; . Don't send garbage in X headers after a timeout.
  237. ; . Allow RECEIVE when local, for talking to a remote non-server (undo [94]).
  238. ;PS:<TIMREK>KERMIT.MAC.659, 24-Feb-84 18:53:47, Frank
  239. ;[127] Don't assign or open comm line if it's the controlling terminal, don't
  240. ; reset line between transactions if a server.  This prevents a server that got
  241. ; detached (e.g. when carrier dropped) from making the line unavailable for
  242. ; further use.
  243. ;PS:<TIMREK>KERMIT.MAC.653, 24-Feb-84 17:14:45, Frank
  244. ;[126] Put in all the transaction logging code, show status of it in SHOW.
  245. ;PS:<TIMREK>KERMIT.MAC.641, 23-Feb-84 19:01:24, Frank
  246. ;[125] LOG command, parsing only.
  247. ;PS:<TIMREK>KERMIT.MAC.638, 23-Feb-84 17:36:40, Frank
  248. ;[124] When sending a multipacket response to a server command, start with
  249. ; an S packet unless using type 1 block check, in which case start with X.
  250. ;PS:<TIMREK>KERMIT.MAC.636, 23-Feb-84 17:10:52, Frank
  251. ;[123] Add S and N packet heuristics to RPACK to help resync when fancy
  252. ; block check types are being used, but the two sides lose track.
  253. ;PS:<TIMREK>KERMIT.MAC.631, 23-Feb-84 14:38:50, Frank
  254. ;[122] Make directory listing neater.
  255. ;PS:<TIMREK>KERMIT.MAC.629, 23-Feb-84 10:41:34, Frank
  256. ;[121] Fix turning off ^C trap after FINISH, again.
  257. ; Don't try to CLOSF or GNJFN if sending generated text rather than files.
  258. ; Restore normal i/o after sending server help message.
  259. ; Fix SRVCMD to actually do what it says it does.
  260. ; Fix problem with spurious repeat counts appearing in file headers.
  261. ;PS:<TIMREK>KERMIT.MAC.627, 24-Jan-84 18:45:56, Frank
  262. ;[120] Add REMOTE HELP and server support for it.
  263. ;PS:<TIMREK>KERMIT.MAC.617, 24-Jan-84 13:11:20, Frank
  264. ;[119] Decode incoming filenames and validate them more completely.
  265. ;PS:<TIMREK>KERMIT.MAC.613, 23-Jan-84 19:28:23, Frank
  266. ;[118] Server does file deletions.
  267. ;PS:<TIMREK>KERMIT.MAC.612, 23-Jan-84 18:01:33, Frank
  268. ;[117] Fix bugs: SEND x (INITIAL) was broken, and check for receive-packet
  269. ; buffer overflow, to prevent writing over other data (thanks to Greg Small
  270. ; of Berkeley for uncovering that one).
  271. ;PS:<TIMREK>KERMIT.MAC.603, 19-Jan-84 17:08:00, Frank
  272. ;[116] Server sends directory listings.
  273. ;PS:<TIMREK>KERMIT.MAC.570, 18-Jan-84 10:30:07, Frank
  274. ;[115] Rewrite directory listing code to allow for i/o redirection.
  275. ;PS:<TIMREK>KERMIT.MAC.566, 17-Jan-84 11:03:38, Frank
  276. ;[114] Rewrite DIAMSG to give more informative message.
  277. ; When logging packets, precede received packets by "R:", sent by "S:".
  278. ;PS:<SY.FDC>KERMIT.MAC.31, 16-Jan-84 16:31:57, Frank
  279. ;[113] Add LOCAL DELETE command.
  280. ;PS:<SY.FDC>KERMIT.MAC.30, 16-Jan-84 16:15:25, Frank
  281. ;[112] Fix server command business of ACK vs Text Header; get/send one or the
  282. ; other, but not both.
  283. ;PS:<SY.FDC>KERMIT.MAC.18, 16-Jan-84 12:15:04, Frank
  284. ;[111] Make file stepping mechanism do 1-file lookahead.  Add LOCAL DIRECTORY.
  285. ;PS:<TIMREK>KERMIT.MAC.551, 13-Jan-84 19:16:44, Frank
  286. ;[110] Release TTY JFN when ^C'd out of server mode.
  287. ; Thanks to Kimmo Laaksonen (Helsinki), Norm Kincl (HP Labs) for reporting
  288. ; this bug, which surfaced when user detached after ^C out of server mode,
  289. ; leaving TTY assigned and unavailable for new jobs.
  290. ;PS:<TIMREK>KERMIT.MAC.550, 13-Jan-84 17:36:32, Frank
  291. ;[109] Fix bad bug in 8th-bit prefixing.  Also bug in SET PARITY command that
  292. ; prevented SET PARITY NONE from ever working.
  293. ;PS:<TIMREK>KERMIT.MAC.542, 11-Jan-84 09:28:05, Frank
  294. ;[108] Add REMOTE DELETE, REMOTE DIRECTORY.  Misc cleanups, minor fixes.
  295. ; Merge SDEBUG and DIAMSG.  Better recovery from SPACK failures.
  296. ;PS:<TIMREK>KERMIT.MAC.540, 10-Jan-84 17:40:57, Frank
  297. ;[107] Added server support for remote CWD command.
  298. ;PS:<TIMREK>KERMIT.MAC.521,  9-Jan-84 18:26:43, Frank
  299. ;[106] Added REMOTE CWD command.
  300. ;PS:<TIMREK>KERMIT.MAC.512,  9-Jan-84 12:44:11, Frank
  301. ;[105] Debug [104], add REMOTE HOST command.
  302. ;PS:<TIMREK>KERMIT.MAC.500,  6-Jan-84 19:40:33, Frank
  303. ;[104] Add server and user TYPE command.
  304. ; Collapse a lot of redundant code into routines like SRVCMD and DOSRV.
  305. ;PS:<TIMREK>KERMIT.MAC.499,  6-Jan-84 11:50:51, Frank
  306. ;[103] Provide disk quota query service in server mode.
  307. ;*************** Major Version 4.0 ****************
  308. ;
  309. ;(Old Edit History moved to end of file, after END statement)
  310.  
  311. ; THINGS TO DO...
  312. ;
  313. ; * Internal cleanup -- do state transition, packet input & ACK/NAK, etc
  314. ;   globally like C-Kermit, instead of replicating the same code all over.
  315. ;
  316. ; * Check/fix bugs:
  317. ;   . Page mode on/off on assigned line (got some complaints, not verified).
  318. ;   . ^A in local mode sometimes gets lost.
  319. ;   . ^A sometimes not turned off (e.g. after ^C out of f.t., then connect)
  320. ;
  321. ; * Move receive-file opening code to RDATA (& REOF); don't open file until
  322. ;   first data packet (or EOF if null file) arrives, to prepare for attributes.
  323. ;
  324. ; * Finish adding server functions: COPY, RENAME, WHO, MESSAGE, STATUS, RUN,
  325. ;   KERMIT (e.g. "remote kermit set file bytesize 8").
  326. ;
  327. ; * Do something with the REMOTE ERROR command (like think of a better name,
  328. ;   make it visible, and document it, maybe put it on ^E).
  329. ;
  330. ; * When local and receiving a file, if ^Z has no effect, send an error packet
  331. ;   to shut down the transaction.
  332. ;
  333. ; * Add host commands.  Fork an Exec, pass commands to it in rescan, somehow
  334. ;   pipe the Exec's typeout back, packetized.  Too bad TOPS-20 isn't UNIX...
  335. ;   Maybe use LOTS's new pipe device?
  336. ;
  337. ; * Add some support for file attribute packets.
  338. ;
  339. ; * Integrate %JSERR etc with the debugging log mechanism?
  340. ;
  341. ; * When receiving a file, put the name I open the file under in the data field
  342. ;   of the ACK to the File Header.  When receiving File Headers in local mode,
  343. ;   print the contents of the data field instead of doing a JFNS if the data
  344. ;   field is not empty.
  345. ;
  346. ; * In local mode, allow running as a background fork. Or use ^P as an
  347. ;   interrupt character during file transfer to Push to an inferior exec while
  348. ;   the transfer continues above.  ^A should still give progress report.
  349. ;
  350. ; * Separate out the routines according to ISO levels.  In particular, make the
  351. ;   transport-level routines available to any other application (like mail,
  352. ;   e.g. SMTP) that may want to use them.
  353. ;
  354. ; * For various reasons, it might be nice to allow KERMIT-20 to send its
  355. ;   packets to a file, without another KERMIT to talk to.  This will translate
  356. ;   a file into all printable characters (with data compaction, etc) suitable
  357. ;   for transmission over an RJE link or other picky communication media.
  358. ;
  359. ; * Parse single characters in nicer ways, like CONTROL X, or "^X", as well
  360. ;   as octal numbers (in all the SET commands).
  361.  
  362.     Title Kermit -- That's Celtic for "free".
  363.  
  364. ; Needs only standard DEC-distributed external files MONSYM, MACSYM, CMD.
  365.  
  366.     search monsym,macsym,cmd
  367.     .require sys:macrel,sys:cmd
  368.  
  369. ; Originally written by Bill Catchings, Columbia University, April 1981.
  370. ; Taken over by Frank da Cruz, Columbia University, March 1983.
  371. ;
  372. ; This program is the DEC-20 implementation of Columbia University's KERMIT
  373. ; file transfer protocol for use over serial asynchronous communication lines.
  374. ; See the KERMIT user and protocol manuals for the specifications.
  375. ;
  376. ; Version 1,  1981-82:  Basic service (Bill)
  377. ;
  378. ; Version 2,   Feb 83:  Basic server service (Bill)
  379. ;
  380. ; Version 3,   Mar 83:  Local mode, TTLINK, talk to server (Frank)
  381. ;
  382. ; Version 3B,  Oct 83:  I packets, ^X,^Z interrupts, TAKE, DEFINE, etc (Frank)
  383. ;         3C,  Nov 83:  8th-bit prefixing, repeat counts.
  384. ;         3.4, Dec 83:  2- and 3-character block checks.
  385. ;
  386. ; Version 4,   Jan 84:  Advanced server functions, LOG, ARPAnet support (Frank)
  387. ;
  388. ; Version 4.1, Jul 84:  Integrated CONNECT code, no more TTLINK (Frank)
  389. ;
  390. ; Version 4.2, Oct 84:  Non-Protocol upload/download, login scripts (Frank)
  391.  
  392.     subttl Help Text.    ;[18] Lengthy help messages added in edit [18].
  393.  
  394. ; Overall summary, more detailed help text is with each command.
  395. ;
  396. hkermi:    asciz |
  397. KERMIT is a file transfer protocol for use over an asynchronous serial
  398. telecommunication line.  Files are broken up into "packets" with checksums and
  399. other control information to promote error-free and complete transmission.
  400.  
  401. KERMIT-20 is the KERMIT implementation for the DECSYSTEM-20.  KERMIT-20 can be
  402. run "remotely" from another computer (e.g. a microcomputer), or "locally" with
  403. a remote Kermit on the other end of an assigned TTY line (e.g. over an
  404. autodialer connection)
  405.  
  406. You can run Kermit interactively by typing repeated commands in response to
  407. its "Kermit-20>" prompt, or you can invoke it from the TOPS-20 Exec with a
  408. single command line argument (e.g. "kermit receive"), or you can run it as a
  409. remote server.
  410.  
  411. KERMIT-20 command summary -- optional parts are in [brackets]:
  412.  
  413. * For exchanging files using KERMIT protocol:
  414.     SEND file(s) [(INITIAL) file]
  415.     RECEIVE [file]
  416.     GET remote-file(s)
  417.     SERVER
  418.  
  419. * For acting as local Kermit:
  420.     CONNECT [line], INPUT, OUTPUT, CLEAR
  421.     SET: LINE, FLOW, PARITY, DUPLEX, HANDSHAKE, ESCAPE, BREAK, SPEED
  422.  
  423. * For talking to a server:
  424.     BYE, FINISH, GET remote-file(s), SEND file(s);
  425.     REMOTE: DISK-USAGE, TYPE, CWD, DIRECTORY, DELETE, HELP, HOST
  426.  
  427. * Setting nonstandard transmission and file parameters:
  428.     SET: DEBUG, DELAY, FILE, INCOMPLETE, INPUT, ITS, PROMPT, RETRY, TVT;
  429.     SET SEND (or RECEIVE): END-OF-LINE, START-OF-PACKET, PACKET-LENGTH,
  430.         PAUSE, PADDING, TIMEOUT, SERVER-TIMEOUT
  431.     DEFINE a macro for a combination of SET commands.
  432.  
  433. * For non-protocol data transfer:
  434.     INPUT, OUTPUT, PAUSE, CLEAR, TRANSMIT, LOG SESSION
  435.  
  436. * For interrupting transmission: Control-X (^X), ^Z, ^C
  437.  
  438. * Getting information:        HELP [topic], STATISTICS, SHOW, ^A
  439. * Recording information:    LOG or CLOSE TRANSACTIONS, SESSION, DEBUGGING
  440. * Executing command files:      TAKE
  441. * Leaving the program:        EXIT, QUIT, BYE, PUSH
  442.  
  443. If you have a file called KERMIT.INI in your login directory, KERMIT-20 will
  444. execute an implicit TAKE command on it upon initial startup.  KERMIT.INI may
  445. contain any KERMIT-20 commands; DEFINE and SET commands are the most useful.
  446.  
  447. For further information, type "help" for any of the above, e.g. "help set",
  448. or see the "Kermit Users Guide" and the "Kermit Protocol Manual" for complete
  449. details.
  450. |
  451.  
  452.     subttl Definitions
  453.  
  454. pdlsiz==^d200            ; Stack size, be generous.
  455. takel==^d20            ;[78] TAKE command JFN stack size.
  456.  
  457. f=0                ; AC definitions:  flag AC (not used),
  458. t4=<t3=<t2=<t1=1>+1>+1>+1    ;  temporary AC's,
  459. q4=<q3=<q2=<q1=t4+1>+1>+1>+1    ;  and preserved AC's.
  460. state=q4+1            ; State of the automaton.
  461. rchr=state+1            ; Total file characters received.
  462. schr=rchr+1            ; Total file characters sent.
  463. debug=schr+1            ;[22] Debugging (0=none, 1=states, 2=packets)
  464.  
  465. mappag==200            ; Single page window for mapping files.
  466.  
  467. SOH==^o001            ; ASCII Start of header character.
  468. XON==^o021            ; XON is defined to be Control-Q (ASCII DC1).
  469. MAXBUF==^d10240            ; Packet buffer size [179]
  470. MAXPKT==^d94            ; Packet buffer size [179]
  471. IOBUF==^d1024            ; Communications i/o buffer [180]
  472.  
  473. maxpkt=="~"-" "+2        ; Maximum size of a packet.
  474. dmxtry==5            ; Default number of retries on a packet.
  475. dimxtr==20            ; Default number of retries send initiate.
  476. drpsiz==^d80            ; Default receive packet size.
  477. dspsiz==^d80            ; Default send packet size.
  478. spmin==^d10            ;[47] Minimum size packet we want to send.
  479. spmax==^d9000            ;[47] Maximum ...
  480. dstim==^d8            ; Default send time out interval.
  481. drtim==^d13            ;[128] Default receive time out interval.
  482. dsrvtm==^d30            ;[20] Def timout when awaiting server commands.
  483. drpaus==0.0            ;[35] Default pause before ACKing packets.
  484. dspaus==0.0            ;[36] Default pause before sending packets.
  485. dspad==^o0            ; Default send padding char.
  486. drpad==^d0            ; Default receive padding char.
  487. dspadn==^d0            ; Default number of send padding chars.
  488. drpadn==^d0            ; Default number of receive padding chars.
  489. dseol==.chcrt            ; Default send EOL char.
  490. dreol==.chcrt            ; Default receive EOL char.
  491. dsquot=="#"            ; Default outbound control prefix.
  492. drquot=="#"            ; Default incoming control prefix.
  493. dqbin=="&"            ; Default 8th-bit prefix.
  494. drept=="~"            ; Default repeat count prefix.
  495. ddelay==^d1            ; Default delay before the first packet, secs.
  496. dxfull==0            ;[18] Full duplex.
  497. dxhalf==1            ;[18] Half duplex.
  498. defesc==34            ; Default CONNECT escape character is ^\.
  499. defpar==none            ; Default parity.
  500. defits==-1            ;[75] Handle ITS binary files by default.
  501. defics==0            ;[160] Default case search for INPUT commands.
  502. defita==0            ;[160] Default timeout action for INPUTs.
  503. defito==5            ;[160] Default timeout interval for INPUTs.
  504. maxtim=^d94            ;[2] Maximum timeout interval to set, secs.
  505. minlod=4.0            ;[2] Minimum ldav to consider for timeout.
  506. maxlod=50.0            ;[2] Maximum ldav to consider for timeout.
  507. blip=^d5            ;[4] Every this many packets, print a blip.
  508.  
  509. mnblen==^d200            ;[77] Macro name buffer length (words).
  510. mtblen==^d1000            ;[77] Macro text buffer length (words).
  511. macmax==^d100            ;[77] Maximum number of macros.
  512.  
  513. ;[129] ARPA definitions
  514.  
  515. ifndef STAT%,<opdef STAT% [JSYS 745]> ; So this will assemble
  516. ifndef TCP%NT,<TCP%NT==40000000> ; without symbols from BBN TCP monitor.
  517.  
  518. iac==377            ; arpanet telnet IAC
  519. will==373            ; telnet will <option>
  520. wont==374            ; telnet wont <option>
  521. do==375                ; telnet do <option>
  522. dont==376            ; telnet don't <option>
  523. trnbin==0            ; transmit binary
  524.  
  525.     subttl Macros
  526.  
  527.  
  528. ; ERMSG -- Type error message on local terminal, and save a pointer to the
  529. ;  error string, that can be used when querying most recent error.
  530.  
  531. define ermsg (msg,label) <
  532.      jrst [    tmsg <
  533. >
  534.         hrroi t1, [asciz/?KERMIT-20: 'msg/]
  535.         movem t1, errptr ;; Save pointer to error msg for stats.
  536.         PSOUT%
  537.         tmsg <
  538. >
  539. ifb <label>,<    jrst .+1>
  540. ifnb <label>,<    jrst label>
  541.         ]
  542. >;ermsg
  543.  
  544.  
  545. ; KERMSG -- Like ERMSG, but also send the message to the other KERMIT in
  546. ;  an error packet, which cancels the current transfer.
  547.  
  548. define kermsg (msg,label) <
  549.     $count=0
  550.     irpc msg, <$count=$count+1>
  551.      jrst [    movei t1, "E"    ;; Send an error packet to the other side.
  552.         move t2, pktnum    ;; Packet number.
  553.         movei t3, $count+^d11 ;; The count.
  554.         move t4, [point 7, [asciz/KERMIT-20: 'msg/]] ;; The msg.
  555.         movem t4, errptr ;; Save pointer to error msg for status.
  556.         call spack    ;; Send the error packet.
  557.          nop
  558.         tmsg <
  559. ?KERMIT-20: 'msg
  560. >
  561. ifb <label>,<    jrst .+1>
  562. ifnb <label>,<    jrst label>
  563.         ]
  564. >
  565.  
  566. ; Error handling macros, cont'd
  567.  
  568.  
  569. ; %JSERR -- Invoked by ERJMP after a JSYS call.  Prints the given message,
  570. ;  if any, then the JSYS error message, and then jumps to the address given
  571. ;  or else halts (continuably) if no jump address given.
  572. ;[163] Make it include the address of the failing JSYS at end of message.
  573.  
  574. define %jserr (msg, label) <    ;; Use this immediately following a JSYS.
  575.     ercal [ ttcrlf        ;; Output a crlf if necessary
  576.         tmsg <?KERMIT-20: 'msg> ;; Type given msg with our prefix,
  577. ifnb <msg>,<    call jserr0>    ;;  if given, put JSYS error after dash,
  578. ifb <msg>,<    call jsmsg0>    ;;  else right after "?KERMIT-20:  "
  579.         tmsg < at PC >    ;; Say where it happened.
  580.         pop p, t2    ;; Pop the return address off the stack.
  581.         hrrzs t2    ;; Clear out junk from left half.
  582.         subi t2, 2    ;; Adjust to point at offending JSYS.
  583.         numout t2, ^d8    ;; Type JSYS PC in octal.
  584.         tmsg <
  585. >                ;; And a trailing CR.
  586. ifb <label>,<    HALTF%        ;; Then, if no label was specified, halt
  587.         jrst .+1    ;; continuably,
  588. >;ifb
  589. ifnb <label>,<    jrst label>    ;; or if there was, go there.
  590.           ]
  591. >;%jserr
  592.  
  593.  
  594. define %ermsg (msg, label) <    ;; Use this in any skipping context.
  595.     jrst [    ttcrlf
  596.         tmsg <?KERMIT-20: 'msg> ;; Otherwise, just like %JSERR.
  597. ifnb <msg>,<    call jserr0>    ;; Except no PC typeout.
  598. ifb <msg>,<    call jsmsg0>
  599.         tmsg <
  600. >
  601. ifb <label>,<    HALTF%
  602.         jrst .+1
  603. >;ifb
  604. ifnb <label>,<    jrst label>
  605.           ]
  606. >;%ermsg
  607.  
  608. ; %JSKER -- Like %JSERR, but also sends message to other KERMIT in an error
  609. ; packet, as KERMSG does.
  610.  
  611. define %jsker (msg, label) <    ;; Use this immediately following a JSYS.
  612.     erjmp [
  613. ifb <msg>,<    move t1, [point 7, [asciz/KERMIT-20: /]] >
  614. ifnb <msg>,<    move t1, [point 7, [asciz/KERMIT-20: 'msg - /]] >
  615.         movem t1, errptr ;; Save pointer to error msg for status.
  616.         call %%krms
  617.         ttcrlf
  618.         tmsg <?KERMIT-20: 'msg> ;; Type given msg with our prefix,
  619. ifnb <msg>,<    call jserr0>    ;;  if given, put JSYS error after dash,
  620. ifb <msg>,<    call jsmsg0>    ;;  else right after "?Kermit:  "
  621.         tmsg <
  622. >                ;; And a trailing CR.
  623. ifb <label>,<    HALTF%        ;; then if no label was specified, halt,
  624.         jrst .+1    ;; continuably,
  625. >;ifb
  626. ifnb <label>,<    jrst label>    ;; or if there was, go there.
  627.           ]
  628. >;%jsker
  629.  
  630. ; Support routines for error handling macros.
  631.  
  632.  
  633. ; JSERR0 synchronizes with terminal i/o in progress before typing the
  634. ;  JSYS error message.
  635. ;
  636. ; JSMSG0 just types the JSYS error message.
  637. ;
  638. jserr0:    movei t1,.priin
  639.     CFIBF%            ; Clear typeahead.
  640.     movei t1,.priou
  641.     DOBE%            ; Wait for previous output to finish.
  642.     tmsg < - >        ; Type a dash.
  643. jsmsg0:    movei t1,.priou
  644.     hrloi t2,.fhslf        ; This fork ,, last error.
  645.     setz t3,
  646.     ERSTR%
  647.      jfcl
  648.      jfcl
  649.     ret
  650.  
  651.  
  652. ; KERMSG -- Send an error message to the KERMIT on the other side in an
  653. ;  error packet.  Invoked from %JSKER, with T1 pointing at the user-provided
  654. ;  prefix (if any), to which the JSYS error message is appended.
  655.  
  656. blanks:    repeat <maxpkt/4>,<ascii/     />
  657.  
  658. %%krms: move t3, [blanks,,%%krbf] ;[40] Fill up the msg buffer with blanks.
  659.     blt t3, <%%krbf+<maxpkt/4>-1> ;[40]
  660.     move t3, [point 7, %%krbf] ; Get a pointer to the buffer.
  661.     setz t4,        ; Zero the counter.
  662. %%krm1:    ildb t2, t1        ; Get the byte.
  663.     jumpe t2, %%krm2    ; Is it a null?
  664.     idpb t2, t3        ; Deposit the byte.
  665.     aoja t4, %%krm1
  666. %%krm2:    move t1, t3        ; Put the information into the buffer.
  667.     hrloi t2, .fhslf    ; Say:  this fork ,, last error.
  668.     movn t3, spsiz        ; Specify the maximum to send as a negative
  669.     add t3, t4        ;  number
  670.     hrlzs t3        ;[74] (ERSTR wants -n,,0)
  671.     skipge t3        ;[50] (don't bother if not negative).
  672.      ERSTR%
  673.      trn
  674.      trn
  675.     move t2, t1        ; Set up to get the new length.
  676.     move t1, [point 7, %%krbf] ; ...
  677.     call subbp        ; Subtract byte pointers.
  678.      skipa            ;[40] If there is an error assume this count.
  679.     camle t3, spsiz        ;[40] Longer than we're supposed to send?
  680.      move t3, spsiz        ;[40] If so, truncate it.
  681.     movei t1, "E"        ; An error packet.
  682.     move t2, pktnum        ; Packet number.
  683.     move t4, [point 7, %%krbf] ; Pointer to string.
  684.     call spack        ; Send the error packet.
  685.      nop
  686.     ret
  687.  
  688. ; Misc macros
  689.  
  690.  
  691. ; NUMOUT - Type a number in the desired base (decimal by default), free format.
  692.  
  693. define numout(num,base<^d10>) <
  694.     call [    saveac <t1,t2,t3>
  695.         move t2, num
  696.         movei t1, .PRIOU
  697.         movei t3, base
  698.         NOUT%
  699.          nop
  700.         ret ]    
  701. >;numout
  702.  
  703.  
  704. ; OUTCHR - Type a character at the terminal without disturbing any registers.
  705.  
  706. define    OUTCHR(char) <
  707.     jrst [    exch t1, char
  708.         PBOUT
  709.         exch t1, char
  710.         jrst .+1 ]
  711. >;OUTCHR
  712.  
  713.  
  714. ;[126] Write time-stamped file message to the transaction log file.
  715. ;
  716. ; Macro arguments are a message string and the address of a JFN
  717. ; of the filename to write, e.g.
  718. ;
  719. ;    wtlog (<Sending >,filjfn)
  720. ;
  721. define wtlog(..msg,..file) <
  722.     call [ skipn t1, tlgjfn ;; Transaction log open?
  723.          ret          ;; No, skip this.
  724.         saveac <t2,t3,t4> ;; Yes, save these AC's
  725.         seto t2,    ;; Start with time stamp, current date/time.
  726.         movx t3, ot%nda    ;; No date.
  727.         ODTIM
  728.         hrroi t2, [asciz/: /] ;; Punctuation.
  729.         setzb t3, t4
  730.         SOUT
  731.         hrroi t2, [asciz/..msg/] ;; The given message.
  732.         SOUT
  733. ifnb <..file>,<
  734.         move t3, [111110,,js%paf]
  735.         skiple t2, ..file ; File name.
  736.          JFNS
  737. >;ifnb
  738.         setz t3,
  739.         hrroi t2, crlf
  740.         SOUT
  741.         ret ]
  742. >;wtlog
  743.  
  744. ; %TABLE - Beginning of COMND/TBLUK keyword table.
  745. ;
  746. define %table <
  747.     %%tbst== .        ;; Plant start of table
  748.     exp 0            ;;  and leave a hole for %tbend to fill
  749. >
  750.  
  751. ; %TBEND - End of COMND/TBLUK keyword table.
  752. ;
  753. define %tbend <
  754.     %%tbnd==.-1        ;; Get address of last entry in table
  755.     .org %%tbst        ;; Move back to start
  756.     xwd %%tbnd-%%tbst, %%tbnd-%%tbst;;  and build table header
  757.     .org            ;; Finally, get back to the way we were
  758. >
  759.  
  760. ; %KEY - COMND or TBLUK keyword definition
  761. ;
  762. ; This macro takes three arguments: an (alphanumerics only!) keyword, the
  763. ; data to be associated with the keyword, and an (optional) flag value.  It
  764. ; creates either a flagless keyword (the normal case), or, if any flags are
  765. ; given, a keyword with flags in the first word and CM%FW set.  Thus,
  766. ; the result is a TBLUK table entry, suitable for use by the .CMKEY COMND
  767. ; JSYS function.  Note that all %KEY words in a table must be bracketed
  768. ; by %TABLE and %TBEND macros (see above).
  769. ;
  770. define %key (name, data, flags) < ;; Flags are optional
  771.    ifb <flags>, <
  772.     xwd [asciz\name\],data    ;; No-flags case
  773.    >
  774.    ifnb<flags>, <
  775.     xwd [<flags>!cm%fw    ;; Flags: first word holds them,
  776.          asciz\name\], data    ;;  second is start of name
  777.    >
  778. >
  779.  
  780. define ttcrlf <             ;; Output a CRLF if not at left margin.
  781.     call [    saveac <t1,t2>
  782.         movei t1, .priou
  783.         RFPOS%    
  784.         hrroi t1, crlf
  785.         trne t2, -1
  786.          PSOUT
  787.         ret ]
  788. >;;ttcrlf
  789.  
  790.  
  791.     subttl Command Line Processing
  792.  
  793. ;  RESCAN - Routine to check for command line arguments.
  794. ;
  795. ;[85] Returns +1 always, with F$EXIT = 0 if no args, nonzero if some args.
  796. ;
  797. rescan:    setzm f$exit        ;[85] Assume no rescan arguments.
  798.     movx t1, .rsini        ; Now check.
  799.     RSCAN%            ;  ...
  800.      erjmp r        ;[85]  If none return.
  801.  
  802.     movx t1, .rscnt        ; Get the size of the rescan.
  803.     RSCAN%            ;  ...
  804.      erjmp r        ;[85]  Return if unsucessful.
  805.     jumpe t1, r        ;[85] If the size is zero return.
  806.     
  807.     prompt <>        ; Null prompt.
  808.     movei t1, r+1        ; Get the address we want to go to on reparse.
  809.     movem t1, repara    ; Fudge it.  This is to prevent looping back
  810.                 ;  to prompt <> for ever on an error on the
  811.                 ;  rescan line.
  812.     movei t1, [flddb. (.cmkey,,<[exp <1,,1>,<[asciz/Kermit/],,0>]>)]
  813.     call rflde        ; Parse it.
  814.      ret            ;[85]  If we don't find it return.
  815.     setom f$exit        ;[85] Assume we have command line arguments.
  816.     movei t1, [flddb. (.cmcfm,cm%sdh)] ; See if we can parse a confirm.
  817.     call rflde        ;  ...
  818.      ret            ;  If not, we have a rescan argument.
  819.     setzm f$exit        ;[85] Parsed confirmation, so no arguments.
  820.     ret            ;[85] Done.
  821.  
  822.     subttl KERMIT Program entry, initialization, and exit.
  823.  
  824. kermit:    jrst start        ; Start entry.
  825.     jrst reen        ; Re-entry.
  826. versio:    byte (3)$who(9)$verno(6)$mnver(18)$edno    ; Program version.
  827. evlen==.-kermit
  828.  
  829. reen:    jrst start        ; Nothing special for now...
  830.  
  831. start:    RESET%            ; Normal startup: reset everything
  832.     setzm monv        ; See what monitor version.
  833.     move t1, [sixbit/MONVER/] ; This only works in V6 or later.
  834.     SYSGT
  835.      erjmp .+1
  836.     skipe t2        ; Got anything?
  837.      movem t1, monv        ; Yes, save it.
  838.  
  839.     move p, [iowd pdlsiz,pdl] ;  and set up a stack.
  840.     setzm ttfork        ; Clear connect receive fork handle
  841.     setzm netjfn        ; and communication line JFN
  842.     setzm f$exit        ; and exit flag, so we re-init if restarted.
  843.  
  844. ;[78] Set up a JFN stack for 'take' commands.
  845.  
  846.     move t2, [iowd takel, takpdl] ;[78] Construct TAKE jfn stack pointer.
  847.     movem t2, takep        ;[78]
  848.     setzm takdep        ;[78] Start 'take depth' out at 0.
  849.     setzm takjfn        ;[78] And no TAKE file jfn.
  850.  
  851. ; Run KERMIT...
  852.  
  853.     call main        ; The actual program.
  854. halt:    HALTF%            ; Upon return, just halt.
  855.  
  856. ; If continued, fall thru to here...
  857.  
  858. cont:    setzm f$exit        ; Turn off the exit flag.
  859.     move t1, ttynum        ;[87] Reassign the line we were using.
  860.     movem t1, pars3        ;[87] (this is the calling convention...)
  861.     call $setln        ;[85]
  862.     call prsint        ; Go to command level.
  863.     jrst halt
  864.  
  865.     subttl  KERMIT main program
  866.  
  867. main:    setzm local        ; Start off running remotely.
  868.     call pinit        ; Initialize interrupt system.
  869.     movei t1, .fhslf    ;[176] Read current process capabilities.
  870.     RPCAP%            ;[176]
  871.     movem t2, capas        ;[176]
  872.     seto t1,        ; Get job info for this job.
  873.     move t2, [-20,,jobtab]    ; Into this job table.
  874.     setzb t3, t4
  875.     GETJI
  876.      %jserr (,.+1)
  877.     dmove t3, jobtab    ; Get job & terminal numbers.
  878.     movem t3, myjob        ; Job number of my job.
  879.     movem t4, mytty        ; Remember this is my controlling terminal.
  880.     movem t4, pars3        ; Make believe we parsed terminal number
  881.     setz debug,        ; And no debugging
  882.     call $setln        ; Set the line to our own.
  883.     call cmdini        ; Initialize the command package.
  884.     call inifil        ;[79] Execute commands from KERMIT.INI, if any.
  885. ccl:     call rescan        ;[85] If no .INI file, look for rescan now.
  886.     skipe f$exit        ;[85] If there was a rescan argument,
  887.      jrst parse        ;[85] go do that.
  888.     jrst @dfstrt        ; No rescan go to default: PROMPT or SERVER.
  889.  
  890. server:    jrst getcom        ; Here if starting as server by default.
  891.  
  892. ; Here if starting in command mode by default.
  893.  
  894. promp:    skipe iniflg        ;[83] Doing init file?
  895.      jrst prsint        ;[83]  Yes, don't print herald yet.
  896.     move q1, [ret]        ;[39] Hokey calling convention for routine
  897.     call $shver        ;[39]  to print current program version.
  898.  
  899. prsint:    setzm rcving        ; Indicate neither receiving nor sending.
  900.     skipe f$exit        ; Exit flag set by EXIT command or CCL entry?
  901.      jrst clenup        ;  If so, go clean up and return.
  902.     hrroi t1, prompx    ;[137] Otherwise, point to prompt text.
  903.     call dpromp        ;[137] Issue prompt.
  904.  
  905. parse:    setzm pars1        ;[40] Clean out old parse values.
  906.     move t1, [pars1,,pars2] ;[40]
  907.     blt t1, parsx        ;[40]
  908.     setzm cjfnbk+.gjgen    ; Clear the JFN bits.
  909.     movei t1, [flddb. .cmkey,,cmdtab] ; Point to command keyword table.
  910.     skipe local        ;[68] Running in local mode?
  911.      movei t1, [flddb. .cmkey,,cmdtb2] ;[68] Yes, use that table instead.
  912.     call rflde        ;[78] Parse a keyword.
  913.      jrst eoftst        ;[78] If error, test for EOF on command file.
  914.     hrrz t2, (t2)        ; Get the command routine addresses.
  915.     movem t2, pars1        ; Save into pars1.
  916.     hlrz t1, (t2)        ; Get the next level routine.
  917.     call (t1)        ; Call it.
  918.  
  919. eval:    move t2, pars1        ; Get back data value.
  920.     hrrz t1, (t2)        ; Get evaluation routine.
  921.     call (t1)        ; Call it.
  922.     jrst prsint        ; Go round again.
  923.  
  924. ;[78] EOFTST:  Command file EOF handler.
  925. ;
  926. eoftst:    push p, t2        ; Save this in case we can resume.
  927.     movei t1, .fhslf    ; Get last process error.
  928.     GETER%            ; Test for eof on COMND input file.
  929.     move t1, t2        ; Move error code from t2 to t1
  930.     pop p, t2        ;  and restore t2.
  931.     hrrzs t1        ; Erase fork handle from this.
  932.     caie t1, iox4        ; Was error EOF?
  933.      cain t1, comnx9    ; Or this kind of EOF?
  934.      jrst eofts2        ;[85] Yes, some kind of EOF.
  935.  
  936.     skipe f$exit        ;[85] Parsing rescan line?
  937.      jrst [    tmsg <?Not a KERMIT command - > ;[85] Yes, print message
  938.         hrroi t1, atmbuf ;[85]
  939.         PSOUT        ;[85]
  940.         ret ]        ;[85] And quit.
  941.  
  942. ; Not EOF, and not parsing rescan line, just enter normal parse error handler.
  943.  
  944.     jrst cmderr        ; Complain, then resume parsing.
  945.  
  946. ; EOF on command file.
  947.  
  948. eofts2:    call popjfn        ; It was EOF.  Pop the command file JFN.
  949.      jrst [    movei t1, .priin ; On any error, revert parsing to TTY.    
  950.         call setcsb    ;  ...
  951.         jrst .+1 ]
  952.     skipn iniflg        ;[83] Just closed init file?
  953.      jrst prsint        ;[83]  No, don't bother with rescan stuff.
  954.  
  955. ;[83] Just closed init file, check for command line (rescan) arguments.
  956.  
  957.     setzm iniflg        ;[83] Flag that we're done with init file.
  958.     jrst ccl        ;[85] And go check for rescan arguments.
  959.  
  960. ; Top-Level command tables.
  961.  
  962. ; Commands available to remote KERMIT.
  963.  
  964. cmdtab:    %table
  965.     %key <bye>, [xwd .bye,$bye], cm%inv ;[11]
  966.     %key <c>, %conn, cm%inv+cm%abr
  967.     %key <clear>, [xwd .clear,$clear], cm%inv ;[162]
  968.     %key <close>, [xwd .close,$close]
  969. %conn:    %key <connect>, [xwd .conne,$conne]
  970.     %key <cwd>, [xwd .ycwd,$ycwd] ;[145]
  971.     %key <define>, [xwd .defin,$defin] ;[77]
  972.     %key <delete>, [xwd .ydele,$ydele] ;[145]
  973.     %key <directory>, [xwd .ydire,$ydire] ;[145]
  974.     %key <e>, %exit, cm%inv+cm%abr
  975.     %key <echo>, [xwd .echo,$echo]
  976. %exit:    %key <exit>, [xwd .exit,$exit]
  977.     %key <finish>, [xwd .finis,$finis], cm%inv ;[28]
  978.     %key <get>,  [xwd .get,$get], cm%inv ;[11]
  979.     %key <help>, [xwd .help,$help]
  980.     %key <input>, [xwd .input,$input], cm%inv ;[159]
  981.     %key <local>, [xwd .local,$local] ;[56]
  982.     %key <log>, [xwd .log,$log] ;[125]
  983.     %key <output>, [xwd .outpu,$outpu], cm%inv ;[159]
  984.     %key <pause>, [xwd .pause,$pause], cm%inv ;[159]
  985.     %key <prompt>, [xwd .promp,$promp], cm%inv
  986.     %key <push>, [xwd .push,$push] ;[152]
  987.     %key <quit>, [xwd .exit,$exit]
  988.     %key <r>, %recv, cm%inv+cm%abr ;[56]
  989. %recv:    %key <receive>, [xwd .recv,$recv]
  990.     %key <remote>, [xwd .remot,$remot], cm%inv ;[56]
  991.     %key <run>, [xwd .yrun,$yrun] ;[145]
  992.     %key <s>, %send, cm%inv+cm%abr
  993. %send:    %key <send>, [xwd .send,$send]
  994.     %key <server>, [xwd .serve,$serve]
  995.     %key <set>, [xwd .set,$set]
  996.     %key <show>, [xwd .show,$show]
  997.     %key <space>, [xwd .ydisk,$ydisk] ;[145]
  998.     %key <statistics>, [xwd .stat,$stat]
  999.     %key <take>, [xwd .take,$take] ;[78]
  1000.     %key <transmit>, [xwd .trans,$trans],cm%inv ;[165]
  1001.     %key <type>, [xwd .ytype,$ytype] ;[145]
  1002.     %tbend
  1003.  
  1004. ; Commands available to local KERMIT.
  1005.  
  1006. cmdtb2:    %table
  1007.     %key <bye>, [xwd .bye,$bye] ;[11]
  1008.     %key <c>, %conn2, cm%inv+cm%abr
  1009.     %key <clear>, [xwd .clear,$clear] ;[162]
  1010.     %key <close>, [xwd .close,$close]
  1011. %conn2:    %key <connect>, [xwd .conne,$conne]
  1012.     %key <cwd>, [xwd .ycwd,$ycwd] ;[145]
  1013.     %key <define>, [xwd .defin,$defin] ;[77]
  1014.     %key <delete>, [xwd .ydele,$ydele] ;[145]
  1015.     %key <directory>, [xwd .ydire,$ydire] ;[145]
  1016.     %key <e>, %exit2, cm%inv+cm%abr
  1017.     %key <echo>, [xwd .echo,$echo]
  1018. %exit2:    %key <exit>, [xwd .exit,$exit]
  1019.     %key <finish>, [xwd .finis,$finis] ;[28]
  1020.     %key <get>,  [xwd .get,$get]    ;[11]
  1021.     %key <help>, [xwd .help,$help]
  1022.     %key <input>, [xwd .input,$input] ;[159]
  1023.     %key <local>, [xwd .local,$local] ;[56]
  1024.     %key <log>, [xwd .log,$log] ;[125]
  1025.     %key <output>, [xwd .outpu,$outpu] ;[159]
  1026.     %key <pause>, [xwd .pause,$pause] ;[159]
  1027.     %key <prompt>, [xwd .promp,$promp], cm%inv
  1028.     %key <push>, [xwd .push,$push] ;[152]
  1029.     %key <quit>, [xwd .exit,$exit]
  1030.     %key <r>, %recv2, cm%inv+cm%abr ;[56]
  1031. %recv2:    %key <receive>, [xwd .recv,$recv]
  1032.     %key <remote>, [xwd .remot,$remot] ;[56]
  1033.     %key <run>, [xwd .yrun,$yrun] ;[145]
  1034.     %key <s>, %send2, cm%inv+cm%abr
  1035. %send2:    %key <send>, [xwd .send,$send]
  1036.     %key <server>, [xwd .serve,$serve], cm%inv
  1037.     %key <set>, [xwd .set,$set]
  1038.     %key <show>, [xwd .show,$show]
  1039.     %key <space>, [xwd .ydisk,$ydisk] ;[145]
  1040.     %key <statistics>, [xwd .stat,$stat]
  1041.     %key <take>, [xwd .take,$take] ;[78]
  1042.     %key <transmit>, [xwd .trans,$trans] ;[165]
  1043.     %key <type>, [xwd .ytype,$ytype] ;[145]
  1044.     %tbend
  1045.  
  1046.     subttl    ECHO command [167]
  1047.  
  1048. ; Help text for ECHO
  1049.  
  1050. hecho:    asciz |
  1051. ECHO text-string
  1052.  
  1053. Echoes the given text string at your terminal.  Useful in TAKE command files
  1054. and with login scripts for reporting progress or telling you what to do.
  1055. |
  1056. .echo:    noise <text at terminal> ; Issue noise words
  1057.     movei t1, [flddb. .cmtxt] ; Get the string into the atom buffer.
  1058.     call cfield
  1059.     ret
  1060.  
  1061. $echo:    hrroi t1, atmbuf    ; Point at the atom buffer.
  1062.     PSOUT            ; Type the string.
  1063.     hrroi t1, crlf        ; And a CRLF.
  1064.     PSOUT    
  1065.     ret
  1066.  
  1067.     subttl    EXIT and QUIT commands (which are the same)
  1068.  
  1069. ; Help text for QUIT.
  1070.  
  1071. hquit:    asciz |
  1072. QUIT
  1073.  
  1074. Synonym for EXIT.
  1075. |
  1076.  
  1077. ; Help text for EXIT...
  1078.  
  1079. hexit:    asciz |
  1080. EXIT
  1081.  
  1082. Exit from KERMIT-20.  You can CONTINUE the program from the TOPS-20 Exec,
  1083. provided you haven't run another program on top of it.  You can also exit from
  1084. KERMIT-20 by typing one or more control-C's, even if it's in the middle of
  1085. transferring a file.  KERMIT-20 will always restore your terminal to its
  1086. original condition, and you will be able to CONTINUE the program to get back
  1087. to KERMIT-20> command level.  When you EXIT from KERMIT-20, any open files,
  1088. including logs, will be closed.
  1089. |
  1090.  
  1091. ; Parse the rest of the EXIT or QUIT command.
  1092.  
  1093. .exit:    noise <from Kermit>
  1094.     confrm            ; Confirm.
  1095.     ret
  1096.  
  1097. ; Execute the EXIT or QUIT command.
  1098.  
  1099. $exit:    setom f$exit        ; Set exit flag.
  1100.     ret            ; (that's all)
  1101.  
  1102. ; Routine to clean up any open files or devices.
  1103.  
  1104. clenup:    move t1, netjfn        ;[127] Get communication line JFN.
  1105.     setzm netjfn
  1106.     setzm local
  1107.     caie t1, .cttrm        ;[127] Previous one was controlling terminal?
  1108.      skipn t1        ;[127] Close any assigned TTY.
  1109.      jrst clenu2
  1110.     CLOSF
  1111.      erjmp .+1        ; Ignore any error (silently).
  1112. clenu2:    skipn asgflg        ; Did I also assign the TTY?
  1113.      jrst clenu3        ; No.
  1114.     move t1, ttynum        ; Yes, so I should deassign it.
  1115.     movei t1, .ttdes(t1)
  1116.     RELD%
  1117.      erjmp .+1
  1118.     setzm asgflg
  1119.  
  1120. clenu3:    skipn t1, logjfn    ; Do we have a debugging log?
  1121.      jrst clenu4        ;  No.
  1122.     setz t2,        ;[144] Yes, any bytes written?
  1123.     RFPTR            ;[144]
  1124.      nop            ;[144]
  1125.     skipg t2        ;[144]
  1126.      txo t1, cz%abt        ;[144] None, don't bother keeping the log.
  1127.     setzm logjfn        ; Yes, forget about it,
  1128.     CLOSF            ; Close it.
  1129.      erjmp .+1
  1130.  
  1131. clenu4:    skipn t1, tlgjfn    ;[126] Transaction log was open?
  1132.      jrst clenu5
  1133.     wtlog <Closed Transaction Log>
  1134.      setzm tlgjfn
  1135.     CLOSF
  1136.      erjmp .+1
  1137.  
  1138. clenu5:    skipn t1, filjfn    ; Any file transfer JFNs hanging around?
  1139.      jrst clenu6
  1140.     setzm filjfn
  1141.     CLOSF
  1142.      erjmp .+1
  1143.  
  1144. clenu6:    skipn t1, sesjfn    ; How about a session log?
  1145.      jrst clenuz
  1146.     setzm sesjfn
  1147.     CLOSF
  1148.      erjmp .+1
  1149.  
  1150. clenuz:    ret            ; Note, we DON'T turn off interrupt system.
  1151.  
  1152.     subttl    HELP command
  1153.  
  1154. hsfdb1: flddb. .cmkey,,mactab,<SET macro,>,<summary>,hsfdb2
  1155. hsfdb2:    flddb. .cmkey,,sethlp,<SET option,>,<summary>
  1156.  
  1157. .help:    noise <about>        ;[18] HELP
  1158.     movei t1, [flddb. .cmkey,,hlptab,,<kermit>]
  1159.     call rfield        ;[67]
  1160.     move t2, (t2)        ; Get help text address.
  1161.     movem t2, pars3
  1162.     hrrzs t2        ;[67]
  1163.     caie t2, hset        ;[67] They want help for SET?
  1164.      jrst .helpx        ;[67]  No.
  1165.     noise <parameter>    ;[67] Yes, give guide word.
  1166.     movei t1, hsfdb1    ;[77] Parse from macro or SET keyword table.
  1167.     call rfield        ;[67] Get SET option they want help for.
  1168.     hrrzs t3        ;[77] Which function descriptor block was used?
  1169.     caie t3, hsfdb1        ;[77] The macro table?
  1170.      move t2, (t2)        ;[67]  Yes, don't do indirection
  1171.     movem t2, pars3        ;[67] SET...
  1172. .helpx:    confrm            ;[67]
  1173.     ret
  1174.  
  1175. hlptab:    %table            ;[18] Table of help commands.
  1176.     %key <bye>,hbye
  1177.     %key <clear>,hclear    ;[162]
  1178.     %key <close>,hclose
  1179.     %key <connect>,hconne
  1180.     %key <CWD>,hcwd
  1181.     %key <define>,hdefin    ;[77]
  1182.     %key <delete>,hdele
  1183.     %key <directory>,hdire
  1184.     %key <echo>,hecho
  1185.     %key <exit>,hexit
  1186.     %key <finish>,hfinis
  1187.     %key <get>,hget
  1188.     %key <help>,hhelp
  1189.     %key <input>,hinput    ;[159]
  1190.     %key <kermit>,hkermi
  1191.     %key <local>,hlocal
  1192.     %key <log>,hlog
  1193.     %key <output>,houtpu    ;[159]
  1194.     %key <pause>,hpause    ;[159]
  1195.     %key <prompt>,hpromp
  1196.     %key <push>,hpush
  1197.     %key <quit>,hquit
  1198.     %key <receive>,hrecei
  1199.     %key <remote>,hremot
  1200.     %key <run>,hrun
  1201.     %key <send>,hsend
  1202.     %key <server>,hserve
  1203.     %key <set>,hset
  1204.     %key <show>,hshow
  1205.     %key <space>,hspace
  1206.     %key <statistics>,hstatu
  1207.     %key <take>,htake
  1208.     %key <transmit>,htrans
  1209.     %key <type>,htype
  1210.     %tbend
  1211.  
  1212. sethlp:    %table            ;[67] Table of HELP SET commands.
  1213.     %key <break>, hsbrea
  1214.     %key <block-check>, hsbc
  1215.     %key <debugging>, hsdeb
  1216.     %key <delay>, hsdel
  1217.     %key <duplex>, hsdup
  1218.     %key <escape>, hsesc
  1219.     %key <file>, hsfil
  1220.     %key <flow-control>, hsflo ;[143]
  1221.     %key <handshake>, hshan    ;[76]
  1222.     %key <incomplete>, hsabf
  1223.     %key <input>, hsetin    ;[160]
  1224.     %key <ITS-binary>, hsits ;[75]
  1225.     %key <line>, hslin
  1226.     %key <parity>, hspar
  1227.     %key <prompt>, hsprom    ;[137]
  1228.     %key <receive>, hsrcv
  1229.     %key <retry>, hsrty
  1230.     %key <send>, hssnd
  1231.     %key <speed>, hspeed
  1232.     %key <summary>, hset
  1233.     %key <TVT-Binary>, hstac ;[129]
  1234.     %tbend
  1235.     
  1236.     ;...
  1237.  
  1238. ;...HELP command, cont'd
  1239.  
  1240.  
  1241. ; Help text for HELP command...
  1242.  
  1243. hhelp:    asciz |
  1244. HELP [topic]
  1245.  
  1246. Typing HELP alone prints a brief summary of KERMIT-20 and its commands.
  1247. You can also type
  1248.  
  1249.    HELP command
  1250.  
  1251. for any Kermit-20 command, e.g. "help send", to get more detailed information
  1252. about a specific command.  To see a list of all the available help commands,
  1253. type
  1254.  
  1255.    HELP ?
  1256.  
  1257. or consult the Kermit User Guide.
  1258. |
  1259.  
  1260. ; Execute the help command.
  1261.  
  1262. $help:    hrrz t3, pars3        ;[77] Special case for help about macro.
  1263.     cail t3, mactab+1
  1264.      caile t3, mactbx
  1265.      jrst $help2    
  1266.     tmsg <
  1267. ">
  1268.     hlro t1, (t3)
  1269.     PSOUT
  1270.     tmsg <" is a SET macro defined to be:
  1271.    >
  1272.     hrro t1, (t3)
  1273.     PSOUT
  1274.     tmsg <
  1275. >
  1276.     ret
  1277.  
  1278. $help2:    hrro t1, pars3        ;[18] Normal help text.
  1279.     PSOUT
  1280.     hrroi t1, crlf
  1281.     PSOUT
  1282.     ret
  1283.  
  1284.     subttl    INPUT, OUTPUT, and PAUSE added as edit [159].
  1285.  
  1286. hinput:    asciz |
  1287. INPUT interval string
  1288.  
  1289. INPUT is useful with OUTPUT and PAUSE for sending connect and login
  1290. sequences to a remote host, e.g. over a dialout connection.
  1291.  
  1292. On the currently selected communication line, look for the given string
  1293. for the specified time interval.  If no interval is specified, then wait
  1294. for the default interval, which is 2 seconds unless changed by SET INPUT
  1295. DEFAULT-TIMEOUT.  An interval of 0 or less means no timeout (wait
  1296. forever).
  1297.  
  1298. Characters coming in from the line will be scanned for the search string,
  1299. and when a match is found, the command will terminate successfully; if
  1300. the string is not found within the given interval, the command will
  1301. terminate unsuccessfully.  While the INPUT command is active, all
  1302. incoming characters will appear on your screen.
  1303.  
  1304. The search string may contain any printable characters.  Control or other
  1305. special characters may be included by preceding their octal ASCII value
  1306. with a backslash, for instance foo\15 is "foo" followed by a carriage
  1307. return, \100 is an atsign (@).  Alphabetic case is ignored ("a" = "A")
  1308. unless you have SET INPUT CASE OBSERVE.  If no search string is given,
  1309. then the INPUT command will keep operating until it times out.
  1310.  
  1311. If the INPUT command fails to find the requested string within the given
  1312. interval, it will "fail"; if the INPUT command was issued from a command
  1313. file (see TAKE), then the next command will be executed, unless you have
  1314. SET INPUT TIMEOUT-ACTION to QUIT, in which case the command file will be
  1315. terminated.  An INPUT command can by interrupted by typing two ^C's.
  1316.  
  1317. Type HELP SET INPUT for further information.
  1318. |
  1319. .input:    noise <interval>
  1320.     setzm buffer        ; Make dynamic default string.
  1321.     setzm buffer+1
  1322.     move t1, [point 7, buffer]
  1323.     move t2, indeft
  1324.     movei t3, ^d10
  1325.     NOUT
  1326.      erjmp .+1
  1327.     movei t1, [flddb. .cmnum,,^d10,<Number of seconds to wait,>,<5>]
  1328.     move t2, [point 7, buffer] ; The above default will be overridden
  1329.     skipe buffer        ; if there's anything in this buffer.
  1330.      movem t2, .cmdef(t1)    ; Stuff the pointer into the fdb.
  1331.     call rfield
  1332.     setzm buffer
  1333.     setzm buffer+1
  1334.     movem t2, pars2
  1335.     movei t1, [flddb. .cmtxt,cm%sdh,,<Text string to look for,
  1336. use \ooo (backslash followed by octal digits) to include control characters,
  1337. \\ to include a single backslash>]
  1338.     call cfield
  1339.     ret
  1340.  
  1341. ; INPUT command.
  1342.  
  1343. $input:    call getss        ; Get & decode search string from atom buffer.
  1344.     skipg pars2
  1345.      jrst $inpu5        ; Skip timer if interval 0 or negative.
  1346.  
  1347. ; Set the desired timeout.
  1348.  
  1349.     movei t1, .fhslf
  1350.     movx t2, 1b0        ; Turn on channel 0.
  1351.     AIC
  1352.      %jserr <Can't turn on timer channel>, <.+1>
  1353.  
  1354.     move t1, [.fhslf,,.timal] ; Remove all pending timer requests.
  1355.     setzb t2, t3
  1356.     TIMER
  1357.      %jserr <Can't clear pending timers>, <.+1>
  1358.  
  1359.     movem p, intstk        ; The timer interrupt routine needs this.
  1360.     movei t1, $inpu9    ; Where to go upon timeout
  1361.     movem t1, intpc        ;  ...
  1362.  
  1363.     move t1, [.fhslf,,.timel] ; Our process and time from now.
  1364.     move t2, pars2        ; The interval we parsed.
  1365.     imuli t2, ^d1000    ; Make time into milliseconds.
  1366.     setz t3,        ; Channel zero.
  1367.     TIMER
  1368.      %jserr <Can't set timer>, <.+1>
  1369.  
  1370. ; Try to get string from the communication line.
  1371.  
  1372. $inp4a:    call dobits        ; Condition the line for i/o.
  1373.      ret            ;  Pass along any failure.
  1374.     call ttyob        ; Put TTY in binary mode for output only.
  1375.     call ccon        ; Turn on ^C trap.
  1376.      jrst $inpuy        ; If ^C typed, go to this place.
  1377.  
  1378. $inpu5:    move t4, [point 7, strbuf] ; Point to the search string.
  1379.  
  1380. $inpu6:    skipn strc        ; Is there a search string?
  1381.      jrst $inpu7        ;  No, just go forever.
  1382.     ildb t3, t4        ; Get a character from search string.
  1383.     jumpe t3, $inpux    ; If no more, then success.
  1384.     ;...
  1385.     
  1386. ;...$INPUT, cont'd
  1387.  
  1388.  
  1389. ; Get & echo a character, compare with current position in search string.
  1390.  
  1391. $inpu7:    move t1, netjfn        ; Now get a character from the line.
  1392.     setz t2,
  1393.     BIN
  1394.      %jserr (,$inpux)
  1395.     andi t2, ^o177        ; Strip any parity.
  1396.     move t1, t2        ; Echo the character.
  1397.     PBOUT
  1398.     skiple t1, sesjfn    ; Session logging?
  1399.      jrst [    BOUT        ; Yes, record the character in the log.
  1400.          erjmp .+1
  1401.         jrst .+1 ]        
  1402.     skipn incase        ; Case-sensitive compare?
  1403.      jrst [    cail t2, "a"    ; No, is this a lower case letter?
  1404.          caile t2, "z"
  1405.          skipa        ; No.
  1406.          txz t2, 40    ; Yes, convert to upper.
  1407.         jrst .+1 ]
  1408.  
  1409.     camn t2, t3        ; Compare OK?
  1410.      jrst $inpu6        ;  Yes, get next from string and comm line.
  1411.     jrst $inpu5        ; No, rewind search string, get next from line.
  1412.  
  1413. ; Come here upon input timeout.
  1414.  
  1415. $inpu9:    hrroi t1, [asciz/
  1416. %/]                ; % message if proceeding
  1417.     skipe intima
  1418.      hrroi t1, [asciz/
  1419. ?/]                ; ? message if quitting (for batch)
  1420.     PSOUT
  1421.     hrroi t1, [asciz/KERMIT-20: INPUT timed out looking for "/]
  1422.     PSOUT
  1423.     hrroi t1, strbuf    ; Tell what string we couldn't find.
  1424.     PSOUT
  1425.     hrroi t1, [asciz/", proceeding...
  1426. /]                ; Say what we're doing, proceeding
  1427.     skipe intima
  1428.      hrroi t1, [asciz/", quitting /] ; ...or quitting.
  1429.     PSOUT
  1430.     skipn intima
  1431.      jrst $inpux        ; Proceeding, just exit from the INPUT command.
  1432.     movei t1, .priou    ; Quitting, tell which file we're quitting from
  1433.     move t2, takjfn        ;  (if any).
  1434.     setz t3,
  1435.     JFNS            ; If no TAKJFN, this will print nothing.
  1436.      erjmp .+1
  1437.     tmsg <
  1438. >
  1439.  
  1440. $inpuy:    call popjfn        ; Pop the TAKE file JFN from the TAKE stack.
  1441.     ;...
  1442.  
  1443. ;...$INPUT, cont'd
  1444.  
  1445.  
  1446. ; Exit thru here, turning off timer, restore line to previous condition.
  1447.  
  1448. $inpux:    call ccoff2        ; Turn off ^C trap.
  1449.     call unbits        ; Restore the line
  1450.     call ttyou        ; Restore controlling tty output.
  1451.     skipg pars2        ; Skip timer stuff if interval 0 or negative.
  1452.      ret
  1453.     move t1, [.fhslf,,.timbf] ; Turn off timer interrupts for this fork.
  1454.     hrloi t2, 377777    ; For all times before this (far in future).
  1455.     TIMER            ;
  1456.      erjmp .+1
  1457.     movx t1, .fhslf        ; Deactivate the channel.
  1458.     movx t2, 1b0
  1459.     DIC
  1460.      %jserr <Can't DIC>,<.+1>
  1461.     setzm strbuf        ; Leave the string buffer cleanup up
  1462.     setzm strbuf+1        ;  a bit...
  1463.     setzm strptr
  1464.     ret    
  1465.  
  1466. ; GETSS - Get & Decode a backslash-decoded search string from the atom buffer.
  1467. ; Returns +1 with 7-bit ASCIZ string in STRBUF, STRC 0 if null, else nonzero.
  1468. ;
  1469. getss:    move t1, [point 7, atmbuf] ; Copy search string from here
  1470.     move t2, [point 7, strbuf] ; ... to here
  1471.     movem t2, strptr    ; Use this pointer
  1472.     setzm strc        ;  and this counter.
  1473.  
  1474. getss2:    ildb t4, t1        ; Get a character.
  1475.  
  1476. getss3:    jumpe t4, getssx    ; If null, then done.
  1477.     aos strc        ; Got one, count it.
  1478.     cain t4, "\"        ; Backslash?
  1479.      jrst [    movei t3, ^d8    ; Yes, try to read a number.
  1480.         NIN
  1481.          nop        ; If error, just keep the backslash.
  1482.         idpb t2, strptr    ; OK, deposit ascii value of number.
  1483.         ldb t4, t1    ; Account for how NIN overshoots the pointer.
  1484.         jrst getss3 ]
  1485. getss4:    skipn incase        ; Case-sensitive compare?
  1486.      jrst [    cail t4, "a"    ; No, is this a lower case letter?
  1487.          caile t4, "z"
  1488.          skipa        ; No.
  1489.          txz t4, 40    ; Yes, convert to upper.
  1490.         jrst .+1 ]
  1491. getss5:    idpb t4, strptr        ; Deposit the result of all this.
  1492.     jrst getss2
  1493.  
  1494. getssx:    idpb t4, strptr        ; Deposit a null at the end.
  1495.     ret
  1496.  
  1497. houtpu:    asciz |
  1498. OUTPUT string
  1499.  
  1500. The given string is sent out the currently selected communication line.
  1501. Control characters may be included in \ooo format (backslash followed by
  1502. octal representation of ASCII value).  Currently selected settings for
  1503. DUPLEX, PARITY, and FLOW are used.
  1504.  
  1505. Type HELP INPUT for further information.
  1506. |
  1507. .outpu:    noise (string)        ; Parse OUTPUT command.
  1508.     movei t1, [flddb. .cmtxt,cm%sdh,,<Text string to send,
  1509. use \ooo (backslash followed by octal digits) to include control characters,
  1510. \\ to include a single backslash>]
  1511.     call cfield
  1512.     ret
  1513.  
  1514. $outpu:    move t1, [point 7, atmbuf] ; Do OUTPUT; move chars from here...
  1515.     move t2, [point 8, strbuf] ;  to here.
  1516.     movem t2, strptr
  1517.  
  1518. $outp3:    ildb t4, t1        ; Copy them
  1519. $out3x:    jumpe t4, $outp4    ;  up to a null.
  1520.     cain t4, "\"        ; Backslash?
  1521.      jrst [    movei t3, ^d8    ; Yes, read a number
  1522.         NIN
  1523.          movei t2, "\"    ; If error, keep the backslash.
  1524.         move t4, t2    ; Get ascii value into t4.
  1525.         seto t2,    ; Decrement the source byte pointer.
  1526.         adjbp t2, t1
  1527.         move t1, t2
  1528.         jrst .+1 ]
  1529.  
  1530. out3a:    exch t1, t4        ; Put character in t1, preserve source pointer.
  1531.     call @parity        ; Tack on desired parity.
  1532.     idpb t1, strptr        ; Deposit the result in the output buffer.
  1533.     move t1, t4        ; Restore the source pointer.
  1534.     jrst $outp3        ; Go back for next.
  1535.  
  1536. $outp4:    idpb t4, strptr        ; Done, deposit a null.
  1537.     move t1, netjfn        ; Comm line designator.
  1538.     move t2, [point 8, strbuf] ; Point to string.
  1539.     setzb t3, t4        ; It's null-terminated.
  1540.     SOUT            ; Send it.
  1541.      %jserr (<Can't send the string>,<.+1>)
  1542.     skipn duplex        ; Half duplex connection?
  1543.      ret            ;  No, host will echo.
  1544.     movei t1, .priou    ; Yes, do it ourselves.
  1545.     move t2, [point 8, strbuf] ; Point to string again.
  1546.     setzb t3, t4
  1547.     SOUT
  1548.      erjmp .+1
  1549.     skipn t1, sesjfn    ; Session logging?
  1550.      jrst $outpx        ; No.
  1551.     move t2, [point 8, strbuf] ; Yes, point again.
  1552.     setzb t3, t4
  1553.     SOUT
  1554.      erjmp .+1
  1555. $outpx:    ret            ; Done.
  1556.  
  1557. ; PAUSE command.
  1558.  
  1559. hpause:    asciz |
  1560. PAUSE interval
  1561.  
  1562. Pause for the given number of seconds.  Useful with INPUT and OUTPUT.
  1563. |
  1564. .pause:    noise (seconds)
  1565.     movei t1, [flddb. .cmnum,,^d10,<Number of seconds to pause>,<1>]
  1566.     call cfield
  1567.     movem t2, pars2
  1568.     ret
  1569.  
  1570. $pause:    move t1, pars2        ; Get the number that was parsed.
  1571.     imuli t1, ^d1000    ; Convert to millisecs.
  1572.     DISMS            ; Sleep.
  1573.      erjmp .+1
  1574.     ret
  1575.  
  1576.     subttl    TAKE command, added as edit 78.
  1577.  
  1578. htake:    asciz |
  1579. TAKE filespec
  1580.  
  1581. Execute KERMIT-20 commands from the specified file.  The file may contain
  1582. contain TAKE commands.  Command files may be nested up to a depth of 20.
  1583. |
  1584.  
  1585. ; Parse the rest of the TAKE command.
  1586.  
  1587. .take:    movx t1, cz%ncl!.fhslf    ; Release non-open jfn's.
  1588.     CLZFF
  1589.     noise <commands from file>
  1590.     move t1, [defbk,,cjfnbk] ; Insert our file parsing defaults.    
  1591.     blt t1, cjfnbk+defbkl
  1592.     movei t1, [flddb. .cmfil]
  1593.     call cfield
  1594.     movem t2, pars2        ; Here's the JFN just parsed.
  1595.     ret
  1596.  
  1597. ; Execute the TAKE command.
  1598.  
  1599. $take:    move t1, takdep        ; How deep are we?
  1600.     caile t1, takel        ; Too deep?
  1601.      jrst [    tmsg <?TAKE command file stack overflow> ; Yes, don't do it.
  1602.         ret ]
  1603.     move t1, takjfn        ; There's room, get current TAKE file jfn.
  1604.     move t2, takep        ; Push it on the stack
  1605.     push t2, t1        ; ...
  1606.     movem t2, takep        ; ...
  1607.     aos takdep        ; Remember what level we're on.
  1608.  
  1609.     move t1, pars2        ; Get JFN that was parsed
  1610.     movem t1, takjfn    ;  ...
  1611.     movx t2, fld(7,of%bsz)!of%rd ; 7-bit i/o, read access.
  1612.     OPENF
  1613.      %jserr (,$takex)
  1614.     callret setcsb        ; Opened OK, go set up command state block.
  1615.  
  1616. ; Error opening command file.
  1617.  
  1618. $takex: call popjfn        ; Remove offending JFN from TAKE stack.
  1619.      jrst [ tmsg <?TAKE file stack underflow>
  1620.         ret ]
  1621.  
  1622.     movx t1, cz%ncl!.fhslf    ; Release extraneous JFNs.
  1623.     CLZFF
  1624.      erjmp .+1
  1625.     ret
  1626.  
  1627. ; Default command filespec fields for .CMFIL:
  1628.  
  1629. defbk:    gj%old            ; Must be existing file.
  1630.     repeat 4,<0>        ; Normal defaults for dev:<dir>name.
  1631.     point 7, [asciz/CMD/]    ; Default extension is .CMD.
  1632.     0            ; Default protection,
  1633.     0            ;  and account.
  1634. defbkl==<.-defbk>        ; Length of this GTJFN argument block.
  1635.     
  1636. ; SETCSB - Set up Command State Block to parse from JFN in t1.
  1637. ;
  1638. setcsb:    skipg t1        ; Make sure there's a real JFN.
  1639.      movei t1, .priin    ; If not, revert.
  1640.     hrlm t1, sbk+.cmioj    ; Put the input JFN into the CSB.
  1641.     movei t2, .priou    ; Assume JFN is primary input.
  1642.     caie t1, .priin        ; Is it?
  1643.      movx t2, .nulio    ; No, it's a file, so nullify COMND output.
  1644.     hrrm t2, sbk+.cmioj    ; Put output JFN in CSB.
  1645.     ret
  1646.  
  1647.  
  1648. ; POPJFN
  1649. ; Routine to pop a command file JFN off the JFN stack.
  1650. ;
  1651. ; Enter with current command file jfn in TAKJFN.
  1652. ;
  1653. ; Returns:
  1654. ;  +1 if stack empty,
  1655. ;  +2 otherwise, with popped jfn in TAKJFN.
  1656. ;
  1657. popjfn:    skipg takdep        ; Back at top level?
  1658.      ret            ;  Yes, return silently.
  1659.  
  1660. ; Close current command file.
  1661.  
  1662.     hrrz t1, takjfn        ; No, close the current file
  1663.     CLOSF            ;  ...
  1664.      %jserr (,.+1)        ; Just print message on error.
  1665.  
  1666. ; Return to previous one.
  1667.  
  1668.     move t2, takep        ; Get the TAKE stack pointer
  1669.     pop t2, t1        ;  and the previous TAKE file JFN,
  1670.     movem t2, takep        ;  restore them,
  1671.     movem t1, takjfn    ;  ...
  1672.     call setcsb        ;  and also restore the command state block.
  1673.     sos takdep        ; Decrement the depth indicator
  1674.     retskp            ; Return successfully.
  1675.  
  1676. ;[79] INIFIL -- Process initialization file.
  1677. ;
  1678. ;[85] Returns +1 if there was no init file, +2 if there was.
  1679. ;
  1680. inifil:    move t2, jobtab+.jiuno
  1681.     move t1, [point 7, dirbuf, 27] ; Put string here.
  1682.     DIRST    
  1683.      erjmp r
  1684.     movei t3, 76        ; Right angle bracket.
  1685.     idpb t3, t1
  1686.     move t2, [point 7, [asciz/KERMIT.INI/]]    ; File name.
  1687.  
  1688. inif2:    ildb t3, t2        ; Copy file name.
  1689.     idpb t3, t1
  1690.     jumpn t3, inif2
  1691.  
  1692. inif3:    movx t1, gj%old+gj%sht    ; Get JFN on it.
  1693.     hrroi t2, dirbuf
  1694.     GTJFN
  1695.      erjmp r        ; If we can't, return silently.
  1696.     hrrzm t1, pars2        ; Got one, pretend we parsed it.
  1697.     setom iniflg        ;[83] Flag that we're doing init file.
  1698.     call $take        ; Go TAKE the file.
  1699.     retskp            ;[85]
  1700.  
  1701.     subttl    LOCAL and REMOTE commands.
  1702.  
  1703. ;[56] LOCAL and REMOTE commands added as edit 56
  1704.  
  1705. .local:    setom lcflg        ; -1 = local
  1706.     movei t1, [flddb. .cmkey,,loctab] ; LOCAL what?
  1707.     jrst .remo2        ; Go parse the rest.
  1708.  
  1709. loctab:    %table
  1710.     %key <cwd>, [xwd .ycwd,$ycwd]
  1711.     %key <delete>, [xwd .ydele,$ydele]
  1712.     %key <directory>, [xwd .ydire,$ydire]
  1713.     %key <run>, [xwd .yrun,$yrun]
  1714.     %key <space>, [xwd .ydisk,$ydisk]
  1715.     %key <type>, [xwd .ytype,$ytype]
  1716.     %tbend
  1717.  
  1718. .remot:    setzm lcflg        ; 0 = remote
  1719.     movei t1, [flddb. .cmkey,,remtab] ; REMOTE what?
  1720. .remo2:    call rfield        ; Parse a keyword.
  1721.     hrrz t2, (t2)        ; Get the command routine addresses.
  1722.     movem t2, pars2        ; Save into pars2.
  1723.     hlrz t1, (t2)        ; Get the next level routine.
  1724.     call (t1)        ; Call it.
  1725.     ret
  1726.  
  1727. remtab:    %table
  1728.     %key <cwd>, [xwd .xcwd,$xcwd]
  1729.     %key <delete>, [xwd .rmfil,$xdele]
  1730.     %key <directory>, [xwd .rmfil,$xdire]
  1731.     %key <error>, [xwd .xerr,$xerr], cm%inv
  1732.     %key <help>, [xwd .xhelp,$xhelp] ;[120]
  1733.     %key <host>, [xwd .xhost,$xhost] ;[105]
  1734. ;;;*    %key <run>, [xwd .???, $???]
  1735.     %key <space>, [xwd .xdisk,$xdisk]
  1736.     %key <type>, [xwd .rmfil,$xtype]
  1737.     %tbend
  1738.  
  1739. ; LOCAL command help text.
  1740.  
  1741. hlocal:    asciz |
  1742. LOCAL option
  1743.  
  1744. Execute a command locally.  Options include:
  1745.  
  1746.  CWD            Change Working Directory (connect to directory).
  1747.  DELETE filespec    Delete a file or file group.
  1748.  DIRECTORY filespec    Print a directory listing.
  1749.  HOST command        A command to be executed by the TOPS-20 Exec.
  1750.  RUN program            Run the specified program.
  1751.  SPACE area        Disk usage query.
  1752.  TYPE filesec        Type a local file or file group at the terminal.
  1753.  
  1754. For further information, type HELP CWD, HELP DELETE, etc.
  1755. |
  1756.  
  1757. ;[137] LOCAL CWD command parsing.
  1758. ;
  1759. hcwd:    asciz |
  1760. CWD means CHANGE WORKING DIRECTORY.  It is the same as LOCAL CWD, i.e. it is
  1761. executed on the local system.  The operation is the same as the DEC-20
  1762. CONNECT command.
  1763. |
  1764. .ycwd:    setzm pasbuf        ; Zero this out.
  1765.     setzm pasbuf+1        ;  ...
  1766.     noise <to directory>    ; Issue guide words.
  1767.     movei t1, [
  1768.         flddb. .cmdir,cm%sdh,,<directory name or logical name,
  1769.  or carriage return to connect back to your login directory>,,[
  1770.         flddb. .cmcfm,cm%sdh ]]
  1771.     call rfield        ; Parse a directory specification.
  1772.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  1773.     cain t3, .cmcfm        ; Confirmation?
  1774.      jrst [    move t2, jobtab+.jilno ; Yes, then use own logged in dir no.
  1775.         movem t2, pars3
  1776.         ret ]
  1777.  
  1778.     movem t2, pars3        ; No, directory number, save it.
  1779.     confrm            ; Get confirmation.
  1780.     ret
  1781.  
  1782. ; Execute the LOCAL CWD command.
  1783. ;
  1784. ;[171] Rewritten to only prompt for the password when necessary, as
  1785. ; the Exec CONNECT command does, and to print the name of the directory
  1786. ; connected to.
  1787. ;
  1788. ; First try to connect with no password.  This returns immediately on error.
  1789. ;
  1790. $ycwd:    move t1, [ac%con!<3>]    ; Ask for connect function, arg block length 3.
  1791.     movei t2, pars3        ; Point to argument block.
  1792.     setom pars5        ; Specify "this job".
  1793.     ACCES            ; Try to connect.
  1794.      erjmp $ycwdx        ;  If error, go prompt for password.
  1795.     jrst $ycwdz        ; Connected OK, exit.
  1796.  
  1797. ; Handle error by prompting for password and then trying to connect again.
  1798.  
  1799. $ycwdx:    setzm pars4        ; Assume no password will be given.
  1800.     call getpas        ; Ask for password.
  1801.     movem t1, pars4        ; Save pointer to (possibly null) string.
  1802.     move t1, [ac%con!<3>]    ; Try to connect again.
  1803.     movei t2, pars3        ; If this fails, monitor won't return
  1804.     ACCES            ;  for about 3 seconds.
  1805.      %jserr (,.+1)        ; On failure, give message and exit.
  1806.  
  1807. ; Done either way, exit.
  1808.  
  1809. $ycwdz:    setzm pasbuf        ; Connected, clear this out for security.
  1810.     setzm pasbuf+1
  1811.  
  1812.     tmsg <[Connected to >    ; Print what we're connected to.
  1813.     seto t1,        ; Get this job's connected directory number.
  1814.     hrroi t2, t3
  1815.     movei t3, .jidno
  1816.     GETJI
  1817.      erjmp r
  1818.     move t2, t3        ; Convert to string.
  1819.     movem t2, jobtab+.jidno    ; Remember for future reference.
  1820.     movei t1, .priou
  1821.     DIRST
  1822.      erjmp r
  1823.     movei t1, "]"
  1824.     PBOUT
  1825.     ret
  1826.  
  1827. ; GETPAS -- Get a password from the terminal
  1828. ;
  1829. ; Prompts for password, turns off echoing during typein, leaves result in
  1830. ; PASBUF, with t1 pointing to it.
  1831. ;
  1832. ; Uses t1-t4.
  1833. ;
  1834. getpas:    skipn takdep        ;[178] Do specially for TAKE files
  1835.      jrst getpa2        ;[178]  (here thru ret)
  1836.     setzm pasbuf
  1837.     move t1, takjfn        ; Read line from the TAKE file
  1838.     hrroi t2, pasbuf    ; Into here
  1839.     movei t3, pasbfl    ; This many chars, max
  1840.     movei t4, .CHLFD    ; terminate on linefeed.
  1841.     SIN
  1842.      erjmp getpax
  1843.     seto t3,        ; Decrement the returned byte pointer.
  1844.     adjbp t3, t2
  1845.     setz t4,        ; Write a zero over the terminating CR.
  1846.     dpb t4, t3
  1847.     idpb t4, t3        ; And linefeed.
  1848. getpax:    move t1, [point 7, pasbuf] ; Return pointer to password.
  1849.     ret            ;[178]
  1850.  
  1851. getpa2:    hrroi t1, [asciz/ Password: /] ; Issue first prompt.
  1852.     PSOUT    
  1853.     movei t1, .priin    ; Get TTY mode word
  1854.     setz t2,
  1855.     RFMOD
  1856.      erjmp .+1
  1857.     call [    saveac <t1,t2>    ; Save TTY info.
  1858.         txz t2, tt%eco    ; Turn off echoing.
  1859.         SFMOD
  1860.          erjmp r
  1861.         hrroi t1, pasbuf ; Ask for password.
  1862.         move t2, [rd%crf+rd%bel+pasbfl]
  1863.         hrroi t3, [asciz/ Password: /]
  1864.         RDTTY
  1865.          %jserr (,r)
  1866.         move t4, t2    ;[169] Remember flag bits that were returned.
  1867.         setz t2,    ; Write a zero over the terminating linefeed.
  1868.         dpb t2, t1
  1869.         ret ]        ; Restore TTY info.
  1870.     SFMOD            ; Restore TTY to normal echoing.
  1871.      erjmp .+1    
  1872.     tmsg <
  1873. >                ; Echo the crlf that wasn't echoed.
  1874.     txnn t4, rd%btm        ; Too long?
  1875.      jrst [    tmsg <
  1876. ?Password too long>        ;* This doesn't help, must do something better
  1877.         jrst .+1 ]    ;* later on...
  1878.     move t1, [point 7, pasbuf] ; Return pointer to result.
  1879.     ret
  1880.  
  1881. ;[111] LOCAL DIRECTORY
  1882.  
  1883. hdire:    asciz |
  1884. DIRECTORY is the same as LOCAL directory.  It produces a directory listing of
  1885. the specified files at your terminal.
  1886. |
  1887.  
  1888. ; Default wildcard filespec fields for .CMFIL:
  1889.  
  1890. dirbk:    gj%old!gj%ifg!gj%flg!.gjall ; Flag bits,,generation number.
  1891.     .priin,,.priou        ; COMND i/o.
  1892.     repeat 2,<0>        ; Normal defaults for dev:<dir> and gen.
  1893.     repeat    2,<point 7, [asciz/*/]>    ; *.* for name and type.
  1894.     0            ; Default protection,
  1895.     0            ;  and account.
  1896. dirbkl==<.-dirbk>        ; Length of this GTJFN argument block.
  1897.  
  1898. .ydire:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  1899.     CLZFF
  1900.     noise <of files>    ; Issue guide words.
  1901.     move t1, [dirbk,,cjfnbk] ; Insert our file parsing defaults.    
  1902.     blt t1, cjfnbk+dirbkl
  1903.     movei t1, [flddb. .cmfil]
  1904.     call cfield
  1905.     movem t2, pars3        ; Here's the JFN just parsed.
  1906.     ret
  1907.  
  1908. ; LOCAL DIRECTORY command execution.
  1909.  
  1910.  
  1911. ; Set up.
  1912.  
  1913. $ydire:    setzm ffunc        ; Function is "directory".
  1914. $ydir1:    move t2, pars3        ; Here's the JFN.
  1915.     setzm filjfn        ; Make sure no one thinks this is in use.
  1916.     call dirhdr        ; Do the header first.
  1917.  
  1918. ; File-listing loop
  1919.  
  1920. $ydir2:    call dmpbuf        ; Get some directory listing.
  1921.     call dirlst        ; Print it.
  1922.      jumpn t1, $ydir2    ; Go back for more.
  1923.  
  1924.     ret            ; Till done.
  1925.  
  1926. ; DIRHDR
  1927. ;
  1928. ; Put directory listing header in string buffer.
  1929. ; Initializes buffer pointers, counters, etc.
  1930. ; Call with t2/ JFN of files to list.
  1931. ; Returns +1 always.
  1932. ;
  1933. dirhdr:    movem t2, ndxjfn    ; Save wildcard bits.
  1934.     hrrzm t2, nxtjfn    ; Initialize lookahead
  1935.     setzm filcnt        ; File counter
  1936.     setom dirfin        ; Initialize directory finished flag.
  1937.  
  1938.     move t1, [point 7, srvbuf] ; Put the listing in the srving buffer.
  1939.     skipe ffunc        ; Directory listing?
  1940.      jrst dirhdx        ;  No, skip printing the heading.
  1941.  
  1942.     setom dirfin        ; Assume some error.
  1943.     move t3, [111110,,js%paf] ; dev:<dir>name.typ.gen
  1944.     JFNS
  1945.      erjmp r
  1946.     
  1947.     hrroi t2, [asciz/
  1948. Name                Pages Bytes(Size)        Creation Date
  1949. /]
  1950.     setzb t3, t4        ; Print heading.
  1951.     SOUT
  1952.  
  1953. dirhdx:    setzm dirfin        ; No error, so not finished.
  1954.     movem t1, srvptr    ; Preserve string buffer pointer.
  1955.     ret
  1956.     
  1957. ; DIRLST
  1958. ;
  1959. ; Builds a directory listing in a chunk of memory starting at
  1960. ; SRVBUF and ending at (or slightly after) SRVBZ, with pointer in SRVPTR.
  1961. ;
  1962. ; Returns +1 always, with t1/ -1 if we got some data, t1/ 0 if done.
  1963. ;
  1964. ; Keeps global file counter in FILCNT.
  1965. ;
  1966. dirlst:    setz t1,
  1967.     skipe dirfin        ; Finished?
  1968.      ret            ;  Yes.
  1969.     move t1, srvptr        ; No, there's more to do.
  1970.     hrroi t2, crlf        ; Issue a line break.
  1971.     setzb t3, t4
  1972.     SOUT
  1973.     movem t1, srvptr    ; Save the buffer pointer.
  1974.     call gtnfil        ; Get next file.
  1975.      jrst dirlsz        ;  If none, done.
  1976.     aos filcnt        ; Got one, count it.
  1977.  
  1978. ;[133] Get detailed size info from FDB.
  1979.  
  1980.     hrrzs t1, t1        ; Get rid of any flags.
  1981.     move t2, [3,,.fbbyv]    ; Get size info from FDB.
  1982.     movei t3, pagcnt    ; Put info in PAGCNT,BYTCNT,CRDATE
  1983.     GTFDB            ; which are adjacent in the data area.
  1984.      erjmp dirlsz
  1985.     move t2, t1        ; Put JFN in t2 for JFNS below.
  1986.  
  1987. ;[122] The rest of this routine rewritten to provide nice columnar listing.
  1988.  
  1989.     move t1, [ascii/     /]    ; Fill the filename buffer with blanks.
  1990.     movem t1, filbuf
  1991.     move t1, [filbuf,,filbuf+1]
  1992.     blt t1, filbfz-1
  1993.  
  1994.     move t1, [point 7, filbuf] ; Now start filling in the fields.
  1995.     move t3, [001110,,<js%tmp!js%paf>] ; First the filename.
  1996.     JFNS
  1997.      erjmp dirlsz
  1998.     skipe ffunc        ; What was the file function?
  1999.      jrst dirls2        ;  Not directory, so skip the rest.
  2000.     ;...
  2001.  
  2002. ;...DIRLST, cont'd
  2003.  
  2004.  
  2005. ; For real directory listing, include file size and creation date.
  2006.  
  2007. dirlsm:    move t4, t2        ; Save file JFN in t4 for a while...
  2008.     movei t3, 40        ; Put a blank over the null left by JFNS.
  2009.     idpb t3, t1
  2010.     hrrz t2, t1        ; Get address from updated pointer.
  2011.     caige t2, filbuf+4    ; Name stayed within its field?
  2012.      jrst [    move t1, [point 7, filbuf+4] ; Yes, advance to next field.
  2013.         movx t3, <no%lfl!no%ast!fld(5,no%col)!fld(^d10,no%rdx)>
  2014.         jrst dirlsa ]    ;  Use right-adjusted number format.
  2015.     movei t2, 40        ; No, do free format.
  2016.     idpb t2, t1        ; Deposit a blank, advance pointer.
  2017.     movei t3, ^d10        ; No fixed-field stuff on page count.
  2018.  
  2019. ;[133] More detailed info about size: pages, byte count, byte size.
  2020.  
  2021. dirlsa:    hrrz t2, pagcnt        ; Number of pages in file.
  2022.     NOUT
  2023.      erjmp dirlsz
  2024.     movei t3, 40        ; A blank
  2025.     idpb t3, t1
  2026.     move t2, bytcnt        ; Byte count, free format.
  2027.     movei t3, ^d10
  2028.     NOUT
  2029.      erjmp dirlsz
  2030.     movei t3, "("        ; Byte size, in parens.
  2031.     idpb t3, t1
  2032.     ldb t2, [pointr (pagcnt,fb%bsz)]
  2033.     movei t3, ^d10
  2034.     NOUT
  2035.      erjmp dirlsz
  2036.     movei t3, ")"
  2037.     idpb t3, t1        ;[133](end) Closing parens.
  2038.  
  2039.     hrrz t3, t1        ; Same deal to advance to date field.
  2040.     caige t3, filbuf+11
  2041.      jrst [    move t1, [point 7, filbuf+11]
  2042.         jrst dirlsb ]
  2043.     movei t2, 40        ; Put in a blank to separate.
  2044.     idpb t2, t1
  2045.  
  2046. dirlsb:    move t2, t4        ; File JFN again.
  2047.     movei t3, js%cdr    ; Get the creation date.
  2048.     JFNS
  2049.      erjmp dirlsz
  2050.  
  2051. dirls2:    setz t3,        ; Done with this line, make it asciz.
  2052.     idpb t3, t1    
  2053.     ;...
  2054.  
  2055. ; DIRLST, cont'd
  2056.  
  2057.  
  2058. ; Copy the result into the server sending buffer.
  2059.  
  2060.     move t4, [point 7, filbuf] ; Source pointer
  2061.  
  2062. dirlsc:    ildb t3, t4        ; Copy loop
  2063.     jumpe t3, dirlsx
  2064.     idpb t3, srvptr
  2065.     jrst dirlsc
  2066.  
  2067. ; Still expect to have file jfn in t2 when we get here.
  2068.  
  2069. dirlsx:    skipe t1, ffunc        ; What is the function?
  2070.      call (t1)        ;  Not directory, so go do selected function.
  2071.     move t1, srvptr
  2072.     hrrz t2, t1        ; See if buffer full.
  2073.     cail t2, srvbz
  2074.      jrst [ seto t1,    ; Return indicating we have data.
  2075.         ret ]
  2076.     jrst dirlst        ; Loop
  2077.  
  2078. ; Done, print summary.
  2079.  
  2080. dirlsz:    move t1, srvptr        ; Get the buffer pointer.
  2081.     movei t2, " "        ; Summary.  First a space.
  2082.     BOUT
  2083.     move t2, filcnt        ; Then the number of files.
  2084.     movei t3, ^d10
  2085.     NOUT
  2086.      erjmp .+1
  2087.     setzb t3, t4
  2088.     hrroi t2, [asciz/ files
  2089. /]
  2090.     sosn filcnt        ; Do singular or plural right.
  2091.      hrroi t2, [asciz/ file
  2092. /]
  2093.     SOUT
  2094.     movem t1, srvptr    ; Save pointer.
  2095.     seto t1,        ; Say we're returning data.
  2096.     setom dirfin        ; Set finished flag for next time through.
  2097.     ret
  2098.  
  2099. ;[115] DMPBUF
  2100. ;
  2101. ; Dump the buffer.
  2102. ;
  2103. ; Call with SRVPTR/ current pointer (to end of string to be dumped)
  2104. ; Returns +1 with t1/ new pointer.  Uses t2.
  2105. ;
  2106. ; Dumps the buffer starting from SRVBUF thru present position,
  2107. ; resets pointer SRVPTR to beginning of SRVBUF.
  2108. ;
  2109. dmpbuf:    move t1, srvptr        ; Get current pointer.
  2110.     setz t2,
  2111.     idpb t2, t1        ; Make sure string is asciz.
  2112.     move t1, [point 7, srvbuf] ; Point to buffer
  2113.     movem t1, srvptr    ; Save new pointer.
  2114.     skipn srvflg        ; Am I a server?
  2115.      PSOUT            ;  If not, print it.
  2116.     setzm srvbuf        ; Clear it.
  2117.     move t1, [srvbuf,,srvbuf+1]
  2118.     blt t1, srvbzz
  2119.     move t1, srvptr        ; Return pointer in t1.
  2120.     ret
  2121.  
  2122. ;[113] LOCAL DELETE
  2123. ;
  2124. ; LOCAL DELETE
  2125. ;
  2126. hdele:    asciz |
  2127. DELETE filespec
  2128.  
  2129.   DELETE is the same as LOCAL DELETE.  It works like the DEC-20 DELETE command,
  2130.   except that if you SET EXPUNGE ON, then all files that you delete with
  2131.   KERMIT, whether with interactive DELETE commands, or via REMOTE DELETE
  2132.   commands when KERMIT-20 is running as a server, will also be automatically
  2133.   expunged.
  2134. |
  2135. ; Default filespec fields for .CMFIL:
  2136.  
  2137. delbk:    gj%old!gj%ifg!gj%flg!.gjall ; Flag bits,,generation number.
  2138.     .priin,,.priou        ; COMND i/o.
  2139.     repeat 6,<0>        ; No defaults, except all generations.
  2140. delbkl==<.-delbk>        ; Length of this GTJFN argument block.
  2141.  
  2142. .ydele:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  2143.     CLZFF
  2144.     noise <files>        ; Issue guide words.
  2145.     move t1, [delbk,,cjfnbk] ; Insert our file parsing defaults.    
  2146.     blt t1, cjfnbk+delbkl
  2147.     movei t1, [flddb. .cmfil]
  2148.     call cfield
  2149.     movem t2, pars3        ; Here's the JFN just parsed.
  2150.     ret
  2151.  
  2152. ;[118] LOCAL DELETE command execution.
  2153.  
  2154. $ydele:    movei t2, delfil    ; Address of delete-file code.
  2155.     movem t2, ffunc        ; Make it the file function.
  2156.     callret $ydir1        ; Go do it like a directory.
  2157.  
  2158. ;[118] DELFIL - Routine to delete a file.
  2159.  
  2160. delfil:    move t1, t2        ; Put the JFN in the right place.
  2161.     skipe expung        ;[143] Expunging automatically?
  2162.      txo t1, df%exp        ;[143] Yes, set the bit.
  2163.     DELF            ; Try to delete it.
  2164.      jrst [    move t1, srvptr ; Error, record the message
  2165.         hrroi t2, [asciz/: /]
  2166.         setzb t3, t4
  2167.         SOUT
  2168.          erjmp .+1
  2169.         hrloi t2,.fhslf    ; This fork ,, last error.
  2170.         setz t3,
  2171.         ERSTR
  2172.          nop
  2173.          nop
  2174.         sos filcnt    ; "Uncount" this file, it wasn't deleted.
  2175.         jrst delf2 ]
  2176.     
  2177.     move t1, srvptr        ; Confirmation message.
  2178.     hrroi t2, [asciz/ [OK]/]
  2179. delf2:    setzb t3, t4
  2180.     SOUT
  2181.      erjmp r
  2182.     movem t1, srvptr    ; Update the string pointer.
  2183.     ret            ; Done
  2184.  
  2185. ; LOCAL SPACE
  2186. hspace:    asciz |
  2187. SPACE is the same as LOCAL SPACE.  It tells the number of disk pages allowed
  2188. and used in the current local directory.
  2189. |
  2190.  
  2191. .ydisk:    noise <usage query>
  2192.     confrm
  2193.     ret
  2194.  
  2195. $ydisk:    seto t1,        ; local disk usage query.
  2196.     GTDAL%
  2197.      %jserr (,r)
  2198.     dmove q1, t1
  2199.     cail t1, [^d100000000]
  2200.      jrst [    tmsg <
  2201.  Quota: +Inf>
  2202.         jrst $ydsk3 ]
  2203.  
  2204. $ydsk2:    tmsg <
  2205.  Quota: >
  2206.     numout q1
  2207.  
  2208. $ydsk3:    tmsg <, used: >
  2209.     numout q2
  2210.     tmsg < (pages)>
  2211.     ret
  2212.  
  2213. ; LOCAL RUN
  2214.  
  2215. hrun:    asciz |
  2216. RUN [filespec]
  2217.  
  2218.   RUN is the same as LOCAL RUN.  It runs the specified file as a program in a
  2219.   fork underneath KERMIT-20.  The default file type is .EXE.  When the program
  2220.   terminates, you will be back at KERMIT-20 prompt level.  If you want to issue
  2221.   Exec commands without leaving KERMIT-20, you can RUN SYSTEM:EXEC.EXE, and
  2222.   then type POP to get back to KERMIT.  If you have already RUN a program once,
  2223.   you can run it again without the overhead of fork creation by typing the RUN
  2224.   command without an argument.
  2225. |
  2226.  
  2227. ; JFN block for RUN command.
  2228.  
  2229. runbk:    gj%old!gj%ifg!gj%flg    ; Flag bits,,most recent generation.
  2230.     .priin,,.priou        ; COMND i/o.
  2231.     repeat 3,<0>        ; No defaults, except
  2232.     -1,,[asciz/EXE/]    ;  file type.
  2233.     repeat 2,<0>        ; No defaults, except
  2234. runbkl==<.-runbk>        ; Length of this GTJFN argument block.
  2235.  
  2236. ; Parse local RUN command.
  2237.  
  2238. .yrun:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  2239.     CLZFF
  2240.     noise <file>        ; Issue guide word.
  2241.     move t1, [runbk,,cjfnbk] ; Insert our file parsing defaults.    
  2242.     blt t1, cjfnbk+runbkl    ; Same as for DELETE.
  2243.     movei t1, [flddb. .cmfil]
  2244.     skipe rufork        ; Already have a fork?
  2245.      movei t1, [        ;  Yes, let them rerun it.
  2246.         flddb. .cmfil,cm%sdh,,<name of program to run,
  2247.  or carriage return to re-run the program you ran last time>,,[
  2248.         flddb. .cmcfm,cm%sdh ]]
  2249.     call rfield        ; Parse a directory specification.
  2250.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  2251.     cain t3, .cmcfm        ; Confirmation?
  2252.      jrst [    setom pars3    ; Yes, set "jfn" to -1.
  2253.         ret ]
  2254.  
  2255.     hrrzm t2, pars3        ; No, real JFN, save it.
  2256.     confrm            ; Get confirmation.
  2257.     ret
  2258.  
  2259. ; Execute local RUN command.
  2260.  
  2261. $yrun:    skipg pars3        ; Re-run current fork?
  2262.      jrst $yrun2        ;  Yes, do do that.
  2263.     skiple t1, rufork    ; No, do we have a current fork to kill?
  2264.      KFORK            ;  Yes, try to kill it.
  2265.      erjmp .+1
  2266.     setz t1,        ; Take care of capabilities below.
  2267.     setzm t2
  2268.     CFORK            ; Make a fork.
  2269.      %jserr <Can't create run fork>,r
  2270.     movem t1, rufork    ; Remember the fork handle.
  2271.     move t2, capas        ;[169] Get our capabilities.
  2272.     txz t2, sc%log        ;[169] Inferior has same ones,
  2273.     txo t2, sc%gtb        ;[169] but with GETAB capability (for Exec),
  2274.     move t3, t2        ;[169] and no logout!
  2275.     EPCAP            ;[169]  ...
  2276.      erjmp .+1        ;[169]  ...
  2277.     hrlzs t1        ; Move handle into left half.
  2278.     hrr t1, pars3        ; JFN in right half.
  2279.     setzm t2        ; Nothing special.
  2280.     GET            ; Get the file to run.
  2281.      %jserr <Can't GET program to run>,r
  2282.     move t1, pars3        ; Got the file, now can release its JFN.
  2283.     RLJFN
  2284.      erjmp .+1
  2285.  
  2286. ; Can come straight here to re-run current fork.
  2287.  
  2288. $yrun2:    skipg t1, rufork    ; Get fork handle.
  2289.      ermsg <No fork to run>,r ; Make sure it's ok.
  2290.     setz t2,        ; Primary start address.
  2291.     SFRKV            ;  Start it up.
  2292.      %jserr <Can't start run fork>,r
  2293.     WFORK            ; wait for the fork to halt.
  2294.      %jserr <Can't wait for run fork>,r
  2295.  
  2296.     ret
  2297.  
  2298. ;[165] TRANSMIT
  2299. htrans:    asciz |
  2300.  
  2301. TRANSMIT filespec [prompt]
  2302.  
  2303.   For use in local mode only.  Sends the specified text file a line at a time
  2304.   to the remote system, waiting for the specified prompt for each line.  Kermit
  2305.   protocol is not used; the file is sent "raw".  The prompt is any string, for
  2306.   instance the prompt of a line editor in text insertion mode.  The prompt
  2307.   string may include special characters by preceding their octal ASCII values
  2308.   with a backslash, e.g. \15 for carriage return.  Only a single file may be
  2309.   sent, no wildcards allowed in the filespec.
  2310.  
  2311.   If a prompt string is supplied, alphabetic case will be ignored in searching
  2312.   for it unless you SET INPUT CASE OBSERVE.  If a prompt string is not
  2313.   supplied, then linefeed will be used by default, unless you have performed
  2314.   a SET HANDSHAKE command, in which case the handshake character will be used.
  2315.   If you really want to send the entire file without looking for any prompts,
  2316.   specify a prompt of "\0" (ASCII zero, null) (not recommended).
  2317.  
  2318.   The file will be sent using the current settings for duplex, parity, and flow
  2319.   control.  There are no timeouts on input, as there are with the INPUT
  2320.   command.  The TRANSMIT command waits forever for each prompt to appear.  You
  2321.   may use the following controls during TRANSMIT:
  2322.  
  2323.   Carriage Return - Send the next line immediately, even if the prompt hasn't
  2324.             appeared.
  2325.   Control-P       - Resend the previous line.
  2326.   Control-C       - Typed two or three times will cancel the TRANSMIT command
  2327.                      and return you to the Kermit-20> prompt.
  2328. |
  2329. .trans:    noise <file>        ; Prompt for file name.
  2330.     movei t1, [flddb. .cmifi]
  2331.     call rfield
  2332.     movem t2, pars2        ; Save the JFN
  2333.     noise <using prompt>    ; Prompt for prompt...
  2334.     movei t1, [flddb. .cmtxt,cm%sdh,,<Remote system's line input prompt,
  2335. use \ooo (backslash followed by octal digits) to include control characters,
  2336. \\ to include a single backslash>] ; No default, supplied in action routine.
  2337.     call cfield        ; Get prompt string into atom buffer.
  2338.     ret
  2339.  
  2340. ; TRANSMIT command execution.
  2341.  
  2342.  
  2343. $trans:    move t1, pars2        ; First make sure we can open the file.
  2344.     movem t1, filjfn
  2345.     movx t2, fld(7,of%bsz)!of%rd ; 7-bit read access.
  2346.     OPENF
  2347.      %jserr (,r)
  2348.     call getss        ; Get & decode prompt (search) string.
  2349.     skipe strc        ; Was there one?
  2350.      jrst $tran2        ;  Yes, use it.
  2351.     setzm strbuf        ; No, then supply an appropriate default.
  2352.     move t2, [point 7, strbuf]
  2353.     skipn t1, handsh    ; Handshaking?
  2354.      movei t1, .chlfd    ;  No, then use linefeed.
  2355.     idpb t1, t2        ; Deposit what we have
  2356.  
  2357. $tran2:    call dobits        ; Condition the line.
  2358.      jrst $tranx
  2359.     call ccon        ; Turn on ^C trap
  2360.      jrst $tranx        ; Where to go upon ^C.
  2361.     call ttyob        ; Let controlling tty output binary.
  2362.     movei t1, $tran3    ; Where to go if ^M typed (send next)
  2363.     movem t1, cmloc        ;  ...
  2364.     movei t1, $tran4    ; Where to go if ^P typed (resend previous)
  2365.     movem t1, cploc        ;  ...
  2366.     call cmpon        ; Enable interrupts on ^M, ^P.
  2367.     tmsg <
  2368. [KERMIT-20: Transmitting >    ; Tell user we're starting.
  2369.     movei t1, .priou
  2370.     move t2, filjfn
  2371.     setz t3,
  2372.     JFNS
  2373.      erjmp .+1
  2374.     tmsg <
  2375.  If stuck, type:
  2376.  Carriage Return to send next line,
  2377.  ^P to resend current line,
  2378.  ^C^C to cancel.  Here goes...]
  2379. >
  2380.     ;...
  2381.  
  2382. ; Get a line from the file.
  2383.  
  2384. $tran3:    skipe cmseen        ; ^M typed?
  2385.      jrst [    tmsg < Sending next...]
  2386. >                ; Yes, type msg
  2387.         setzm cmseen    ; and unset flag.
  2388.         jrst .+1 ]
  2389.  
  2390.     move t1, filjfn        ; Input file pointer
  2391.     move t2, [point 8, strbf2] ; Where to put the line
  2392.     movei t3, ^d512        ; Maximum characters to read
  2393.     movei t4, .chlfd    ; but preferably terminate on linefeed.
  2394.     SIN
  2395.      erjmp [movei t1, .fhslf ; Get last process error.
  2396.         GETER        ; Test for eof.
  2397.         hrrzs t2    ; Erase fork handle from left half.
  2398.         caie t2, iox4    ; Was error EOF?
  2399.          %ermsg (,$tranx) ; No, give message.
  2400.         tmsg <
  2401. [KERMIT-20: Transmit Complete.]
  2402. >                ; Yes, reassure.
  2403.         jrst $tranx ]
  2404.     ldb t4, t2        ; Was last char a LF?
  2405.     caie t4, .chlfd
  2406.      ibp t2            ; If not, don't overwrite it.
  2407.     setz t4,        ; Deposit a null, overwriting
  2408.     dpb t4, t2        ;  last char if it was a LF.
  2409.     ;...
  2410.  
  2411. ; TRANSMIT, cont'd...  Echo the string if necessary.
  2412.  
  2413. $tran4:    skipe cpseen        ; ^P typed?
  2414.      jrst [    tmsg < - Resending...
  2415. >                ; Yes, type msg
  2416.         setzm cpseen    ; and unset flag.
  2417.         jrst .+1 ]
  2418.  
  2419.     move t1, [point 8, strbf2] ; Point to the string.
  2420.     move t2, t1        ; Here too.
  2421.     skipn duplex        ; Half duplex?
  2422.      jrst $tran5        ;  No.
  2423.     PSOUT            ; Yes, display it at the tty.
  2424.     movei t1, .chlfd    ; Also need to add linefeed.
  2425.     PBOUT
  2426.  
  2427. ; Tack on desired parity, in place.
  2428.  
  2429.     move t2, [point 8, strbf2] ; Point to the string.
  2430.  
  2431. $tran5:    ildb t1, t2        ; Get a byte.
  2432.     jumpe t1, $tran6    ; If null, done.
  2433.     call @parity        ; Set parity bit.
  2434.     dpb t1, t2        ; Put it back.
  2435.     jrst $tran5        ; Back for more.
  2436.  
  2437. ; Send the string
  2438.  
  2439. $tran6:    move t1, netjfn        ; ... out the communication line.
  2440.     move t2, [point 8, strbf2]
  2441.     setzb t3, t4
  2442.     SOUT
  2443.      %jserr (,$tranx)
  2444.  
  2445. ; Now wait for prompt.
  2446.  
  2447. $tran7:    move t4, [point 7, strbuf] ; Point to string buffer.
  2448.  
  2449. $tran8:    ildb t3, t4        ; Get first character of search string.
  2450.     jumpe t3, $tran3    ; If no more then we have the prompt.
  2451.     move t1, netjfn        ; Get char from line.
  2452.     setz t2,
  2453.     BIN
  2454.      %jserr (,$tranx)
  2455.     andi t2, ^o177        ; Strip any parity.
  2456.     movei t1, .priou    ; Echo it.
  2457.     BOUT
  2458.     skipn incase        ; Case sensitive compare?
  2459.      jrst [    cail t2, "a"    ;  No, fold.
  2460.          caile t2, "z"
  2461.          skipa
  2462.          txz t2, 40
  2463.         jrst .+1 ]
  2464.     camn t2, t3        ; Match?
  2465.      jrst $tran8        ;  Yes, get next.
  2466.     jrst $tran7        ; No, rewind search string, then get next.
  2467.  
  2468. ; Done, call terminal restore routines in reverse order.
  2469.  
  2470. $tranx:    call cmpoff        ; ^M, ^P interrupts off.
  2471.     call ttyou        ; Restore controlling tty.
  2472.     call ccoff2        ; ^C trap off.
  2473.     call unbits        ; Put line back to previous state.
  2474.     movei t1, .priin    ; Flush any junk they may have typed
  2475.     CFIBF
  2476.      erjmp .+1
  2477.     move t1, filjfn        ; Close the file.
  2478.     CLOSF
  2479.      %jserr (,$tranz)
  2480.     skipa
  2481. $tranz:    RLJFN            ; Release the JFN.
  2482.      erjmp .+1
  2483.     setzm filjfn        ; Zero the JFN holder.
  2484.     ret
  2485.  
  2486. ;[143] LOCAL TYPE
  2487. htype:    asciz |
  2488. TYPE filespec
  2489.  
  2490.   TYPE is the same as LOCAL TYPE.  It types the specified file or files at your
  2491.   terminal.  Unlike the DEC-20 TYPE command, it will try to do input from each
  2492.   file based on its byte size.  Also, Control-O output suppression applies only
  2493.   on a per-file basis.
  2494. |
  2495. typbk:    gj%old!gj%ifg!gj%flg    ; Flag bits,,most recent generation.
  2496.     .priin,,.priou        ; COMND i/o.
  2497.     repeat 6,<0>        ; No defaults, except all generations.
  2498. typbkl==<.-typbk>        ; Length of this GTJFN argument block.
  2499.  
  2500. .ytype:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  2501.     CLZFF
  2502.     noise <files>        ; Issue guide words.
  2503.     move t1, [typbk,,cjfnbk] ; Insert our file parsing defaults.    
  2504.     blt t1, cjfnbk+typbkl    ; Same as for DELETE.
  2505.     movei t1, [flddb. .cmfil]
  2506.     call cfield
  2507.     movem t2, pars3        ; Here's the JFN just parsed.
  2508.     ret
  2509.  
  2510. ; LOCAL TYPE command execution.
  2511.  
  2512.  
  2513. $ytype:    move t1, pars3        ; Get the JFN.
  2514.     setzm filjfn        ; Set up for file stepping.
  2515.     movem t1, ndxjfn
  2516.     hrrzm t1, nxtjfn
  2517.     call ccon        ;[169] Allow ^C out of this.
  2518.      jrst [    move t1, filjfn ;[169] Upon ^C, close the file.
  2519.         CLOSF        ;[169]
  2520.          erjmp $ytypz    ;[169]
  2521.         jrst $ytypz ]    ;[169] And quit
  2522. $ytyp2:    call gtnfil        ; Any more?
  2523.      jrst $ytypz        ;  No, done.
  2524.     push p, t1        ; Yes, save the JFN for a sec.
  2525.     tmsg <
  2526. >
  2527.     movei t1, .priou    ; Turn off any Control-O
  2528.     RFMOD
  2529.     txz t2, tt%osp
  2530.     SFMOD
  2531.     move t2, (p)        ; Say the name.
  2532.  
  2533.     setz t3,    
  2534.     JFNS
  2535.      erjmp .+1
  2536.     tmsg <
  2537.  
  2538. >
  2539.     pop p, t1        ; Restore the JFN.
  2540.     move t2, [1,,.fbbyv]    ; Get bytesize.
  2541.     movei t3, t4
  2542.     setz t4,
  2543.     GTFDB
  2544.      erjmp .+1
  2545.     movx t2, of%rd+fld(7,of%bsz) ; Assume 7-bit mode.
  2546.     ldb t3, [pointr (t4,fb%bsz)] ; Extract the bytesize.
  2547.     cain t3, ^d8        ; 8 bit?
  2548.      movx t2, of%rd+fld(^d8,of%bsz) ; Yes, 8-bit.
  2549.     OPENF            ; Open the file in appropriate mode.
  2550.      %jserr (,$ytyp2)    ; Report any errors.
  2551.     call typfil        ; Type the file
  2552.     move t1, filjfn        ; Close the file.
  2553.     CLOSF
  2554.      nop
  2555.     jrst $ytyp2        ; Go back back for another.
  2556.  
  2557. $ytypz:    tmsg <
  2558. >
  2559.     call ccoff
  2560.     ret            ; No more, done.
  2561.  
  2562. ; Routine to type a file at the local terminal.
  2563. ;
  2564. ; Type the file whose JFN is in FILJFN.  Return +1 always.
  2565. ;
  2566. typfil:    saveac<t1,t2,t3>
  2567.  
  2568.     setz t4,        ; EOF flag.
  2569.  
  2570. typfi2:    jumpl t4, r        ; EOF yet?
  2571.     move t1, filjfn        ; No, get JFN of the file.
  2572.     hrroi t2, strbuf    ; Get a bufferfull.
  2573.     movni t3, <strbln-1>    ; This many characters, leave room for null.
  2574.     setz t4,
  2575.     SIN
  2576.      erjmp [ setom t4
  2577.          jrst .+1 ]
  2578.     movei t1, .priou    ; Type what we got.
  2579.     hrroi t2, strbuf
  2580.     addi t3, <strbln-1>
  2581.     movns t3        ; Exactly this many.
  2582.     SOUT
  2583.     jrst typfi2        ; Go back for more.
  2584.  
  2585. ; REMOTE command help text.
  2586.  
  2587.  
  2588. hremot:    asciz |
  2589. REMOTE option
  2590.  
  2591. Ask the KERMIT server on the other end of the connection to execute a command
  2592. on its own system.  This command won't work unless you are running in local
  2593. mode (you have SET LINE n) and the KERMIT on the other end is running as a
  2594. server.
  2595.  
  2596. Options include:
  2597.  
  2598.  CWD            Change Working Directory (connect).
  2599.  DELETE filespec    Delete a file or file group.
  2600.  DIRECTORY filespec    Send a directory listing.
  2601.  HOST command        To be executed by remote system's command processor.
  2602.  SPACE             Disk usage query.
  2603.  TYPE filesec        Type a file or file group at the terminal.
  2604. |
  2605.  
  2606. $remot:    ; REMOTE and LOCAL command dispatcher...
  2607.  
  2608.     skipe takdep        ;[177] OK from TAKE file
  2609.      jrst $local        ;[177]
  2610.     skipn local
  2611.      jrst [    tmsg <?Must SET LINE before issuing a REMOTE command>
  2612.         ret ]
  2613.  
  2614. $local:    move t2, pars2        ; Get back data value.
  2615.     hrrz t1, (t2)        ; Get evaluation routine.
  2616.     call (t1)        ; Call it.
  2617.     ret
  2618.  
  2619. ; REMOTE CWD Parsing
  2620.  
  2621.  
  2622. .xcwd:    setzm pasbuf        ; Zero this out.
  2623.     setzm pasbuf+1        ;  ...
  2624.     noise <to directory>    ; Issue guide words.
  2625.     movei t1, [
  2626.      flddb. .cmtxt,cm%sdh,,<directory or area on server file system,
  2627.  or carriage return for default area>]
  2628.     call cfield        ; Parse a string.
  2629.     setzm pars3        ; Assume they didn't give an area.
  2630.     move t2, [point 7, atmbuf] ; Did they give one?
  2631.     ildb t1, t2
  2632.     jumpe t1, r        ; No, done.
  2633.  
  2634.     call getpas        ; They did, ask for password.
  2635.     movem t1, pars3        ; Save pointer to it.
  2636.     ret            ; Done.
  2637.  
  2638. ;[106] REMOTE CWD Execution
  2639.  
  2640.  
  2641. $xcwd:
  2642. $xcwd2:    setzm strbuf        ; Zero out old stuff
  2643.     setzm strbuf+1
  2644.     move t1, [point 7, atmbuf] ;  Copy directory name from here
  2645.     move t2, [point 7, strbuf] ;  to here.
  2646.  
  2647.     movei t4, "C"        ; CWD generic command.
  2648.     idpb t4, t2
  2649.     ibp t2            ; Leave room for length.
  2650.  
  2651.     setz t3,        ; Counter.
  2652. $xcwd3:    ildb t4, t1        ; Copy the directory string.
  2653.     jumpe t4, $xcwd4
  2654.     idpb t4, t2
  2655.     aoja t3, $xcwd3
  2656.  
  2657. ; Note that lengths here apply to UNPREFIXED values.  If a length turns out to
  2658. ; be the same as a prefix character, it will be quoted itself.
  2659.  
  2660. $xcwd4:    move t4, [point 7, strbuf, 13] ; Deposit count at head of field.
  2661.     addi t3, 40        ; Make it printable.
  2662.     dpb t3, t4
  2663.     skipn pars3        ; Got a password too?
  2664.      jrst $xcwdz        ;  No.
  2665.  
  2666. $xcwd5:    movem t2, strptr    ; Yes.  Save current pointer.
  2667.     ibp t2            ; Save a place for length of this field.
  2668.     setz t3,        ; Reset counter for new field.
  2669.     move t1, pars3
  2670.  
  2671. $xcwd6:    ildb t4, t1        ; Get a character.
  2672.     jumpe t4, $xcwd7    ; If zero, done.
  2673.     idpb t4, t2        ; Deposit it.
  2674.     aoja t3, $xcwd6        ; Count it & loop.
  2675.  
  2676. $xcwd7:    idpb t4, t2        ; Make it asciz.
  2677.     addi t3, 40        ; Make count printable.
  2678.     idpb t3, strptr        ; Deposit it at head of field.
  2679.  
  2680. $xcwdz:    move t1, [point 7, strbuf] ; Point to it.
  2681.     movei t2, "G"        ; Packet type is H.
  2682.     jrst dosrv        ; Go send it and handle the reply.
  2683.  
  2684. ; REMOTE DELETE, DIRECTORY, TYPE parsing -- Parse a remote filespec.
  2685.  
  2686. .rmfil:    noise <remote files>    ; Parse the rest of the command.
  2687.     movei t1, [flddb. .cmtxt,cm%sdh,,<remote file specification>]
  2688.     call cfield
  2689.     ret
  2690.  
  2691. ; REMOTE DELETE (Erase) execution
  2692.  
  2693. $xdele: movei t4, "E"        ; Generic command is E.
  2694.     jrst srvfil
  2695.  
  2696.  
  2697. ; REMOTE DIRECTORY execution
  2698.  
  2699. $xdire:    movei t4, "D"        ; Generic command is D.
  2700.     jrst srvfil
  2701.  
  2702.  
  2703. ; REMOTE TYPE command execution.
  2704.  
  2705. $xtype:    movei t4, "T"        ; Generic command is T.
  2706.     jrst srvfil
  2707.  
  2708.  
  2709. ; SRVFIL
  2710. ;
  2711. ; Common code to construct a generic one-field command.
  2712. ; Generic command is single character in t4.  Argument is in ATMBUF.
  2713. ; Puts a 1-character length field at the beginning.
  2714. ;
  2715. srvfil:    call sinfo        ;[128] Exchange parameters with I packet.
  2716.      ret            ;[133]  Failed, give up.
  2717.     setzm strbuf        ; Zero out old stuff
  2718.     setzm strbuf+1
  2719.     move t1, [point 7, atmbuf] ;  Copy directory name from here
  2720.     move t2, [point 7, strbuf] ;  to here.
  2721.  
  2722.     idpb t4, t2        ; Deposit generic command.
  2723.     ibp t2            ; Leave a space
  2724.  
  2725.     setz t3,        ; Initialize counter
  2726.  
  2727. srvfi2:    ildb t4, t1        ; Get next one.
  2728.     idpb t4, t2        ; Deposit this one.
  2729.      skipe t4        ; If null, done.
  2730.     aoja t3, srvfi2        ; Count it & loop.
  2731.  
  2732. ;*    jumpe t3, [        ; Make sure there was at least one character.
  2733. ;*        tmsg <?No file specified>
  2734. ;*        ret ]
  2735.  
  2736. srvfi3:    move t1, t3        ; Length
  2737.     addi t1, 40        ; CHAR of that.
  2738.     move t2, [point 7, strbuf, 13] ; Deposit count at head of field.
  2739.     dpb t1, t2
  2740.     move t1, [point 7, strbuf] ; Point to generic command.
  2741.     movei t2, "G"        ; Packet type is G.
  2742.     jrst dosrv        ; Go do it.
  2743.  
  2744. ; REMOTE SPACE parsing
  2745.  
  2746. .xdisk:    noise <usage query>
  2747.     confrm
  2748.     ret
  2749.  
  2750.  
  2751. ; REMOTE SPACE execution
  2752.  
  2753. $xdisk:    move t1, [point 7, [asciz/U/]] ; U command for data field.
  2754.     movei t2, "G"        ; Packet type is G.
  2755.     jrst dosrv
  2756.  
  2757.  
  2758. ; REMOTE HELP parsing
  2759.  
  2760. .xhelp:    noise <from KERMIT server>
  2761.     confrm
  2762.     ret
  2763.  
  2764. ; REMOTE HELP execution
  2765.  
  2766. $xhelp:    call sinfo        ; Exchange parameters.
  2767.      ret            ;[133] Failed, give up.
  2768.     move t1, [point 7, [asciz/H/]] ; H command for data field.
  2769.     movei t2, "G"        ; Packet type is G.
  2770.     jrst dosrv
  2771.  
  2772.  
  2773. ;[105] REMOTE HOST command.
  2774.  
  2775. .xhost:    noise <command>    ; Parse the rest of the REMOTE HOST command.
  2776.     movei t1, [
  2777.      flddb. .cmtxt,cm%sdh,,<command for server's host command processor>]
  2778.     call cfield
  2779.     ret
  2780.  
  2781. $xhost: skipe takdep        ;[176] Allow commands to servers from TAKE file
  2782.      jrst $xhos2
  2783.     skipe local        ; This only works if local Kermit.
  2784.      jrst $xhos2
  2785.     ermsg <Can't use REMOTE commands without prior SET LINE>,r
  2786.  
  2787. $xhos2:    move t1, [point 7, atmbuf] ; And move them from here
  2788.     move t2, [point 7, strbuf] ;  to here.
  2789.  
  2790. $xhos3:    ildb t4, t1        ; Copy the string.
  2791.     jumpe t4, $xhos4
  2792.     idpb t4, t2
  2793.     jrst $xhos3
  2794.  
  2795. $xhos4:    move t3, seolch        ; Terminate it with the host's eol character.
  2796.     idpb t3, t2
  2797.     idpb t4, t2        ; And a null.
  2798.  
  2799.     call ccon        ;[169] Enable ^C during this bit.
  2800.      jrst ccoff        ;[169]  Where to go if ^C happens.
  2801.     call sinfo        ; Exchange params.
  2802.      jrst ccoff        ;[169] Failed, give up, turn off ^C trap.
  2803.     call ccoff        ;[169]
  2804.     move t1, [point 7, strbuf] ; Point to command.
  2805.     movei t2, "C"        ; Packet type is C.
  2806.     jrst dosrv           ; Go send it and handle the reply.
  2807.  
  2808.  ; REMOTE ERROR -- a secret command to send a null error packet.
  2809.  
  2810. .xerr:    confrm
  2811.     ret
  2812.  
  2813. $xerr:    movei t1, "E"        ; Send an error packet.
  2814.     move t2, pktnum
  2815.     setzb t3, t4
  2816.     call spack
  2817.      nop
  2818.     ret
  2819.  
  2820.  
  2821.  
  2822.  
  2823. ; DOSRV
  2824. ;
  2825. ; Call this exactly like SRVCMD.
  2826. ;
  2827. ; Send a command to a server and dispatch appropriately depending on the reply.
  2828. ;
  2829. dosrv:    setzm gotx        ; Clear flags: "got X packet",
  2830.     setzm gots        ;  "got S packet".
  2831.     call srvcmd        ; Send a generic command.
  2832.      ret            ;  Didn't get good response.
  2833.     cain t1, "Y"        ; Was it an ACK?
  2834.      ret            ;  Yes, so we're done.
  2835.         
  2836. ; Come here if we're about to receive a multipacket reply.
  2837.  
  2838.     caie t1, "X"        ; Text header?
  2839.      jrst dosrv3        ;  No
  2840.     setom gotx        ; Yup, flag that we already got it.
  2841.     movei state, "F"    ; State state to file receive.
  2842.     skipn t3        ;[173](begin) Any contents?
  2843.      jrst $recvb        ; No.
  2844.     push p, t1        ; Yes, print them.
  2845.     hrroi t1, crlf
  2846.     PSOUT
  2847.     move t1, pktacs+3
  2848.     PSOUT
  2849.      erjmp $recvb
  2850.     hrroi t1, crlf
  2851.     PSOUT
  2852. dosrv2:    pop p, t1        ;[173](end)
  2853.     jrst $recvb        ; Go receive whatever is coming.
  2854.  
  2855. dosrv3:    cain t1, "S"        ; Or Send-Init?
  2856.      jrst [    setom gots    ; Yes, flag that we already got it.
  2857.         movei state, "R" ; Set state to receive init.
  2858.         jrst $recvb ]    ; Go receive what's coming.
  2859.  
  2860.     ermsg <Unexpected packet type returned by SRVCMD>,r
  2861.  
  2862. ; SRVCMD
  2863. ;
  2864. ; Routine to send a command to a server.
  2865. ; Call with:
  2866. ;  t1/ Byte pointer to string.
  2867. ;        First character is Generic Command, subsequent chars are arguments.
  2868. ;  t2/ Packet type, e.g. "G" for Generic, "C" for Host Command.
  2869. ;
  2870. ; Returns:
  2871. ;  +1 if reply was not received successfully.
  2872. ;  +2 If we got a good response, with
  2873. ;     t1/ packet type of response, "Y", "X", or "S".
  2874. ;     PKTACS/ Block of 4 words containing the data returned by RPACK.
  2875. ;
  2876. ;     If packet was ACK containing data, this routine prints it.
  2877. ;
  2878. srvcmd: skipe takdep        ;[176] Allow commands to servers from TAKE file
  2879.      jrst srvxx
  2880. srvxx:    saveac <q1,q2>        ; Preserve these work registers.
  2881.     dmove q1, t1        ; Copy arguments into them.
  2882.     skipn local        ;[177] Local Kermit?
  2883.      call inilin        ;[177] No, set TTY: up for packets.
  2884.     setzm numtry        ; Reset retry counter.
  2885.     setzm nnak        ; Init some statistics counters
  2886.     setzm ntimou        ;  ...
  2887.     setom bctone        ; Force 1-char checksum.
  2888.     move t1, netjfn        ; Clear out any stacked-up NAKs
  2889.     CFIBF%            ;
  2890.      %jserr (,.+1)        ; Give warning in case there's a problem.
  2891.     call ccon        ; Let them ^C out gracefully
  2892.      jrst srvcmx        ;  and go here if they do.
  2893.  
  2894.     call setlog        ; Set up any debugging log.
  2895.      nop
  2896.  
  2897. ; Put the command into the data field of the packet, using the normal
  2898. ; packet-filling technique, prefixing, etc.
  2899.  
  2900.     setzm data        ; Zero the buffer.
  2901.  
  2902. srvcma:    movei t1, gtsch        ; Indicate routine to be used for getting
  2903.     movem t1, source    ;  characters.
  2904.     movem q1, strptr    ; And where it should get them from.
  2905.     setom next        ; Set initial condition.
  2906.     move t1, maxdat        ; Get a buffer full of data.
  2907.     call getbuf        ; ...
  2908.      jumpn t1, srvcmx    ;  Clean up if this fails.
  2909.     setzm source        ; Got it, so put GETCH back to normal.
  2910.  
  2911.     movem t1, gclen        ; Save length.
  2912.     jumpn t1, srvcm2    ; Proceed if we got any.
  2913.  
  2914.     ermsg <No data for generic command>, srvcmx ; Do this otherwise.
  2915.     ;...
  2916.  
  2917. ;...SRVCMD, cont'd
  2918.  
  2919.  
  2920. ; Top of try-again loop.
  2921.  
  2922. srvcm2:    move q1, numtry        ; Too many tries?
  2923.     caml q1, maxtry
  2924.      ermsg <Can't send generic command, max tries exceeded>,srvcmx
  2925.     aos numtry        ; Not too many, count this try.
  2926.     move t1, q2        ; Packet type.
  2927.     setz t2,        ; Make the packet number zero.
  2928.     move t3, gclen        ; Length of data.
  2929.     move t4, [point 8, data] ; Point to data block.
  2930.     call spack        ; Send it off.
  2931.      jrst @[exp srvcm2, srvcmx](t1)    ; Handle nonfatal & fatal failures.
  2932.     setzm gotx        ; Assume it'll be an ACK.
  2933.     call rpack        ; Look for response.
  2934.      ermsg <RPACK failed>,srvcm2
  2935.  
  2936.     caie t1, "X"        ; X or Y?
  2937.      cain t1, "Y"
  2938.      jrst srvcmz        ; Good.
  2939.  
  2940.     caie t1, "S"        ; S or I?
  2941.      cain t1, "I"
  2942.      jrst srvcmz        ; That's ok too.
  2943.  
  2944.     cain t1, "E"        ; Error packet?
  2945.      jrst [    hrroi t1, [asciz/?Remote error -- /] ; Yes, print it.
  2946.         PSOUT%
  2947.         move t1, t4    ; Get pointer to it,
  2948.         PSOUT%        ; and print it.
  2949.          jrst srvcmx ]    ;[70]
  2950.     caie t1, "N"        ; NAK?
  2951.      cain t1, "T"        ; Or Timeout?
  2952.      jrst srvcm2        ;  One of those, go try again.
  2953.  
  2954.     ermsg <Invalid response from server>
  2955.  
  2956. ; Exit point for any kind of error, failure, or interruption
  2957.  
  2958. srvcmx:    call ccoff        ; Turn off ^C trap.
  2959.     call caxzof        ; Turn these interrupts off too.
  2960.     skiple filjfn        ;[135] Any file left open?
  2961.      jrst [    hrrz t1, filjfn    ;  Apparently, try to close it.
  2962.         setzm filjfn
  2963.         CLOSF
  2964.          erjmp .+1
  2965.         jrst .+1 ]    ;[135](end)
  2966.     skipn local        ;[177] Put controlling TTY back to normal
  2967.      call rrsl2        ;[177] ... (entry point to reslin)
  2968.     setzm source        ; Put things back to normal.
  2969.     seto t1,        ; Indicate no good response was received.
  2970.     ret            ; Return +1.
  2971.  
  2972.     ;...
  2973.  
  2974. ;...SRVCMD, cont'd
  2975.  
  2976.  
  2977. ; Exit here when response received successfully.
  2978.  
  2979. srvcmz:    dmovem t1, pktacs    ;[112] Save the ACs returned in RPACK
  2980.     dmovem t3, pktacs+2    ;[112]  ...
  2981.     movem t2, pktnum    ; Synchronize packet numbers.
  2982.     cain t1, "Y"        ;[121] Was the reply an ACK?
  2983.      jrst [    skipg t2, t3    ;[144] Yes, any characters?
  2984.          jrst .+1    ;[144] No.
  2985.         movei t1, puttch ;[144] Routine to display decoded characters.
  2986.         movem t1, dest    ;[144] ...
  2987.         move t1, t4    ;[144] Pointer to data buffer.
  2988.         call putbuf    ;[144] Go decode it.
  2989.          nop        ;[144]
  2990.         setzm dest    ;[144]
  2991.         jrst .+1 ]
  2992.     move t1, pktacs        ;[112] Get packet type back.
  2993.     call ccoff        ; Turn off ^C trap.
  2994.     skipn local        ;[177] Put controlling TTY back to normal
  2995.      call rrsl2        ;[177] ... (entry point to reslin)
  2996.     retskp            ; Done.
  2997.  
  2998. ;[58] SINFO added as part of edit 58.
  2999. ;
  3000. ; Call this routine before sending any server command which has a nontrivial
  3001. ; response.  For instance, it should be called before requesting a remote
  3002. ; directory listing, but need not be called before sending a CWD command,
  3003. ; which normally responds with a simple ACK.
  3004. ;
  3005. ; Action: Sends an info packet with our own parameters, waits for ACK with
  3006. ; other side's.  Uses packet number 0, does not increment the packet number.
  3007. ; If other side doesn't know about I packets, this routine returns as if a
  3008. ; an ACK was received containing all default values.
  3009. ;
  3010. ; Returns:
  3011. ;  +1 on failure, maximum tries exceeded.
  3012. ;  +2 on "success" getting a reply, even if it was an error packet,
  3013. ;     with other sides parameters set.
  3014. ;
  3015. sinfo:    saveac<t3,t4>        ;[128] Save these.
  3016.     setzm numtry        ; Give it a try,
  3017.     setzm pktnum        ;  starting out with a clean slate.
  3018.     setom bctone        ;[98] Use 1-char checksum.
  3019.  
  3020.     move t1, netjfn        ; Clear out any piled up NAKs.
  3021.     CFIBF%
  3022.      %jserr (,.+1)
  3023.     
  3024.     call setlog        ; Set up any debugging log.
  3025.      nop
  3026.     movei state, "S"    ;[133] This will be a little state switcher.
  3027.  
  3028. sinfo2:    movei t1, "I"        ;[100][133] Packet type.
  3029.     setom iflg        ;[100] Say we're doing I, not S.
  3030.     call sinit        ;[100] Let SINIT send it & get reply.
  3031.     cain t1, "E"        ; Other side doesn't know I packet?
  3032.      jrst [    setzb t3, t4    ;[133] Then set defaults this way.
  3033.         call spar    ;[133]
  3034.         jrst sinfoz ]    ;[133] And return successfully.
  3035.  
  3036. ;[133] Keep going if it doesn't get thru the first time.
  3037.  
  3038.     cain state, "F"        ; Switched into F state?
  3039.      jrst sinfoz        ;  Yes, so I was ACK'd, done.
  3040.     cain state, "S"        ; Still in S state?
  3041.      jrst sinfo2        ;  So go round again.
  3042.     
  3043. sinfox:    setzm iflg        ; Must have exceeded retry limit.
  3044.     ret            ; Fail.
  3045.  
  3046. sinfoz:    setzm iflg        ;[100] Done with sending I packet.
  3047.     retskp
  3048.  
  3049.     subttl    SET command
  3050.  
  3051.  
  3052. ; SET command help text.
  3053.  
  3054. hset:    asciz |
  3055. SET parameter [option] [value]
  3056.  
  3057.   Establish or modify various parameters for file transfer or terminal
  3058.   connection.  You can examine their values with the SHOW command.  The
  3059.   following parameters may be SET:
  3060.  
  3061.   BLOCK-CHECK error detection method
  3062.   BREAK       number of nulls at 50 baud for BREAK simulation
  3063.   DEBUGGING   mode or log file
  3064.   DELAY       how long to wait before starting to send
  3065.   DUPLEX      for terminal connection, full (remote echo) or half (local echo)
  3066.   ESCAPE      character for terminal connection
  3067.   FILE        for setting file parameters like name conversion and byte size
  3068.   FLOW-CONTROL for enabling and disabling XON/XOFF flow control
  3069.   HANDSHAKE   for turning around half duplex communication line
  3070.   INCOMPLETE  what to do with an incomplete file
  3071.   INPUT       desired behavior for INPUT command
  3072.   ITS-BINARY  special format for 8-bit binary files
  3073.   LINE        TTY line to use for terminal connection or file transfer
  3074.   PARITY      character parity to use
  3075.   PROMPT      for changing the KERMIT-20 program prompt
  3076.   RECEIVE     various parameters for receiving files
  3077.   RETRY       how many times to retry a packet before giving up
  3078.   SEND        various parameters for sending files
  3079.   SPEED       set speed (baud rate) of currently selected line
  3080.   TVT-BINARY  binary mode negotiation for ARPANET virtual terminals
  3081.  
  3082. For further information, type "help set" followed by one of these keywords.
  3083. Also, type "help define" to see how to define "macros" for SET commands.
  3084. |
  3085.  
  3086. ;[77] Parse SET command.  (This routine rewritten for edit 77.)
  3087.  
  3088. sfdb1:    flddb. .cmkey,,mactab,<SET macro,>,,sfdb2
  3089. sfdb2:    flddb. .cmkey,,settab
  3090.  
  3091. .set:    movei t1, sfdb2        ; Normal SET command table.
  3092.     hlrz t2, mactab        ; Anything in macro table?
  3093.     skipe t2        ; If so, include them too.
  3094.      skipe definf        ; Unless we're defining a macro.
  3095.      skipa            ; Don't allow recursive definitions!
  3096.      movei t1, sfdb1    ; Macro table is searched first.
  3097.     call rfield        ; Parse a keyword.
  3098.     ;...
  3099.  
  3100. ;...SET, cont'd
  3101.  
  3102.  
  3103. .set2:    setzm macrof        ; Assume regular SET keyword was parsed.
  3104.     hrrzs t3        ; See which function descriptor block was used.
  3105.     cain t3, sfdb1        ; The macro table?
  3106.      jrst [    hrrz t1, (t2)    ; Yes, get the data.
  3107.         hrli t1, (point 7,) ; This will be a pointer to the macro text.
  3108.         movem t1, pars2    ; Save it.
  3109.         confrm        ; Get confirmation.
  3110.         setom macrof    ; Set the macro flag.
  3111.         ret ]        ; No more to do.
  3112.  
  3113.     hrrz t2, (t2)        ; Get the command routine addresses.
  3114.     movem t2, pars2        ; Save into pars2.
  3115.     hlrz t1, (t2)    ; Get the next level routine.
  3116.     call (t1)        ; Call it.
  3117.  
  3118. ; If doing a DEFINE, loop through SET commands until CR typed.
  3119.  
  3120.     skipn definf        ; Doing DEFINE?  If so, allow comma here.
  3121.      ret
  3122.     movei t1, [flddb. .cmcma,cm%sdh,,<Comma for another SET parameter>,,[
  3123.             flddb. .cmcfm]
  3124.            ]
  3125.     call rfield
  3126.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  3127.     cain t3, .cmcma        ; Comma?
  3128.       jrst .set         ;  Yes, go back & get another SET parameter.
  3129.     ret            ; Confirmation, done.
  3130.  
  3131. ; SET keyword table.
  3132.  
  3133. settab:    %table
  3134.     %key <block-check>, [xwd .setbc,$setbc] ;[98]
  3135.     %key <break>, [xwd .setbr,$setbr]
  3136.     %key <debugging>, [xwd .setdb,$setdb]
  3137.     %key <delay>, [xwd .setdl,$setdl]
  3138.     %key <duplex>, [xwd .setdu,$setdu]
  3139.     %key <escape>, [xwd .setes,$setes]
  3140.     %key <expunge>, [xwd .setex,$setex] ;[143]
  3141.     %key <file>, [xwd .setfi,$setfi]
  3142.     %key <flow-control>, [xwd .setfl,$setfl] ;[143]
  3143.     %key <handshake>, [xwd .setha,$setha] ;[76]
  3144.     %key <incomplete>, [xwd .setab,$setab]
  3145.     %key <input>, [xwd .setin,$setrs] ;[160]
  3146.     %key <ITS-binary>, [xwd .setit,$setit]
  3147.     %key <line>, [xwd .setln,$setln]
  3148.     %key <parity>, [xwd .setpa,$setpa]
  3149.     %key <prompt>, [xwd .setpr,$setpr]
  3150.     %key <receive>, [xwd .setrc,$setrs]
  3151.     %key <retry>, [xwd .setre,$setre]
  3152.     %key <send>, [xwd .setsn,$setrs]
  3153.     %key <speed>, [xwd .setxp,$setsp]
  3154.     %key <TVT-Binary>, [xwd .setta,$setta] ;[129]
  3155.     %tbend
  3156.  
  3157. ; SET command, cont'd
  3158.  
  3159. ;[98] SET BLOCK-CHECK (This command added as part of edit 98)
  3160.  
  3161. hsbc:    asciz |
  3162.  SET BLOCK-CHECK option
  3163.  
  3164.    A block check is a quantity formed by arithmetically combining all the
  3165.    characters in a packet.  The sender of the packet appends the block check
  3166.    to it, the receiver recomputes the block check and compares it with the
  3167.    one that was received.  If they don't agree, the packet is retransmitted.
  3168.    The SET BLOCK-CHECK command is used to request one of three block check
  3169.    techniques:
  3170.  
  3171.      1-CHARACTER-CHECKSUM
  3172.         The standard KERMIT 6-bit checksum, the most efficient of the three
  3173.     options, sufficient in almost every case.  This is the default.
  3174.      2-CHARACTER-CHECKSUM
  3175.         A 12-bit checksum.  Adds transmission overhead, but catches more
  3176.     errors.
  3177.      3-CHARACTER-CRC
  3178.         A 16-bit cyclic redundancy check.  Adds even more overhead, catches
  3179.     even more errors.  Only use this for very noisy connections.
  3180.  
  3181.    KERMIT-20 will request the type of block check set by this command be used
  3182.    for a transfer.  If the other KERMIT agrees (not all KERMITs know how to
  3183.    compute the 2- and 3-character block checks), then the desired block check
  3184.    type will be used.  If not, the single character checksum will be used.
  3185. |
  3186.  
  3187. .setbc:    noise <type to>        ; Issue guide words
  3188.     movei t1, [flddb. .cmkey,,bctab,,<1>] ; Parse keyword, default is "1".
  3189.     call rfield
  3190.     hrrz t2, (t2)        ; Save the value we parsed.
  3191.     movem t2, pars3
  3192.     skipn definf        ; In a DEFINE command?
  3193.      confrm            ;  No, make them type a carriage return.
  3194.     ret
  3195.  
  3196. bctab:    %table
  3197.     %key <1-character-checksum>, "1"
  3198.     %key <2-character-checksum>, "2"
  3199.     %key <3-character-crc>, "3"
  3200.     %tbend
  3201.  
  3202. ; SET BLOCK-CHECK command execution.
  3203.  
  3204. $setbc:    move t1, pars3        ; Get what was parsed.
  3205.     movem t1, bctr        ; Save it as "block check type requested".
  3206.     ret
  3207.  
  3208. ; SET command, cont'd
  3209.  
  3210. ; SET INCOMPLETE
  3211.  
  3212. hsabf:    asciz |
  3213.  SET INCOMPLETE options
  3214.    Specify what to do when a file transfer fails before it is completed.
  3215.    The options are DISCARD (the default) and KEEP.  If you choose KEEP, then if
  3216.    a transfer fails to complete successfully, you will be able to keep the
  3217.    incomplete part that was received.
  3218. |
  3219.  
  3220. .setab:    noise <file disposition> ;[42] SET INCOMPLETE (file disposition)
  3221.     movei t1, [flddb. .cmkey,,[<2,,2>
  3222.         <[asciz/discard/],,0>
  3223.         <[asciz/keep/],,1>
  3224.         ],,<discard>]
  3225.     call rfield        ; Parse & confirm.
  3226.     hrrz t2, (t2)
  3227.     movem t2, pars3
  3228.     skipn definf        ;[77] In DEFINE?
  3229.      confrm            ;[77]  No, get confirmation.
  3230.     ret
  3231.  
  3232. ; SET command, cont'd
  3233.  
  3234.  
  3235. ; SET BREAK
  3236.  
  3237. hsbrea:    asciz |
  3238.  SET BREAK n
  3239.   Specify the number of nulls to be sent at 50 baud to simulate a BREAK
  3240.   signal when connected to a remote host via SET LINE and CONNECT.
  3241. |
  3242. .setbr:    noise (nulls)
  3243.     movei t1, [
  3244.      flddb. .cmnum,,^d10,<Number of nulls at 50 baud to simulate BREAK,>]
  3245.     call rfield
  3246.     skipge t2
  3247.      jrst [ tmsg <?Number must be positive>
  3248.         jrst cmder1 ]
  3249.     caile t2, maxnul
  3250.      jrst [    tmsg <?Too many nulls, maximum is >
  3251.         numout [maxnul]
  3252.         jrst cmder1 ]
  3253.     movem t2, pars3
  3254.     skipn definf        ;[77] In DEFINE?
  3255.      confrm            ;[77]  No, get confirmation.
  3256.     ret
  3257.  
  3258. $setbr:    move t2, pars3        ; Execute SET BREAK.
  3259.     movem t2, brk
  3260.     ret
  3261.  
  3262. ; SET DEBUG
  3263.  
  3264. hsdeb:    asciz |
  3265.  SET DEBUG options
  3266.    Show packet traffic explicitly on your terminal (if local) or in a file.
  3267.    Options are:
  3268.      STATES   Show Kermit state transitions and packet numbers (brief).
  3269.  
  3270.      PACKETS  Display each incoming and outgoing packet (lengthy).
  3271.  
  3272.      OFF      Don't display debugging information (this is the default).  If
  3273.               debugging was in effect, turn it off and close any log file.
  3274.  
  3275.    To record debugging information in a file, use LOG DEBUGGING.
  3276. |
  3277.  
  3278. .setdb:    noise <option>        ; SET DEBUGGING
  3279.     movei t1, [flddb. .cmkey,,dbgtab,,states]
  3280.     call rfield        ; Parse a keyword.
  3281.     hrrz t2, (t2)        ; Get the value for the keyword.
  3282.     movem t2, pars3        ; Save into pars3.
  3283.  
  3284. .stdbx:    skipn definf        ;[77] In DEFINE?
  3285.      confrm            ;[77]  No, get confirmation.
  3286.     ret
  3287.  
  3288. dbgtab:    %table
  3289.     %key <off>, 0
  3290.     %key <packets>, 2    ;[22]
  3291.     %key <states>, 1    ;[22]
  3292.     %tbend
  3293.  
  3294. dbstab:    %table            ;[41] (this table)
  3295.     %key <7>,7
  3296.     %key <8>,8
  3297.     %tbend
  3298.  
  3299. ;...SET command, cont'd
  3300.  
  3301.  
  3302. ; SET FILE
  3303.  
  3304. ; Help text...
  3305.  
  3306. hsfil:    asciz |
  3307.  SET FILE paramater keyword
  3308.    Establish file-related parameters:
  3309.  
  3310.    BYTESIZE keyword or number
  3311.      Byte size for DEC-20 file input/output.  The choices are SEVEN, EIGHT, and
  3312.      AUTO.  If SEVEN, do normal ASCII character i/o.  EIGHT is necessary for
  3313.      transmission of non-DEC-20 binary files, like .COM files from
  3314.      microcomputers.  AUTO is equivalent to SEVEN for incoming files, and for
  3315.      outgoing files means to use EIGHT if the DEC-20 file bytesize (as shown by
  3316.      the Exec VDIR command) is 8, otherwise use SEVEN.  The default is AUTO.
  3317.  
  3318.      SEVEN or AUTO can be used to send and receive DEC-20 binary files, such as
  3319.      .EXE or .REL files.  EIGHT is only for "foreign" 8-bit binary files.
  3320.  
  3321.    NAMING UNTRANSLATED or NORMAL-FORM
  3322.      If NORMAL-FORM the names of incoming or outgoing files will be converted
  3323.      to contain only uppercase letters, digits, and periods.  If UNTRANSLATED,
  3324.      filenames will be left alone.  If conversion is being done, all control
  3325.      and punctuation characters (other than ".") in filenames will be
  3326.      translated to "X", and lower case letters will be capitalized.
  3327.      UNTRANSLATED is the default.
  3328. |
  3329.  
  3330. ; Parse rest of SET FILE
  3331.  
  3332. sfitab:    %table            ; Table of file parameters to SET.
  3333.     %key <bytesize>,0
  3334.     %key <naming>,1
  3335.     %tbend
  3336.  
  3337. ; The following ruse using chained FDB's allows the old-style command to
  3338. ; be parsed most of the time, like "SET FILE 8".
  3339.  
  3340. sfifd1: flddb. .cmkey,,sfitab,,<bytesize>,sfifd2
  3341. sfifd2:    flddb. .cmkey,,sfbtab,<DEC-20 file byte size,>,<auto>
  3342.  
  3343. .setfi:    noise <parameter>    ;[84] SET FILE
  3344.     movei t1, sfifd1
  3345.     call rfield
  3346.     hrrz t2, (t2)
  3347.     hrrzs t3        ;[84] Which function descriptor block was used?
  3348.     setzm pars3        ;[84] Assume they specified a bytesize.
  3349.     cain t3, sfifd2        ;[84] They specified a bytesize?
  3350.      jrst .setfz        ;[84]  Yes, so don't parse it again.
  3351.     movem t2, pars3
  3352.     noise <to>
  3353.     movei t1, [flddb. .cmkey,,sfbtab,<DEC-20 file byte size,>,<auto>]
  3354.     skipe pars3        ;[84]
  3355.      movei t1, [flddb. .cmkey,,fntab,,<untranslated>] ;[84]
  3356.     call rfield        ; Parse a keyword.
  3357.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3358. .setfz:    movem t2, pars4        ;[84] Save here.
  3359.     skipn definf        ;[77] In DEFINE?
  3360.      confrm            ;[77]  No, get confirmation.
  3361.     ret
  3362.  
  3363. ; file name translation keywords.
  3364.  
  3365. fntab:    2,,2
  3366.     [asciz/normal-form/],,1
  3367.     [asciz/untranslated/],,0
  3368.  
  3369. ; file bytesize keyword table.
  3370.  
  3371. sfbtab:    %table
  3372.     %key <7-bit>, 0
  3373.     %key <8-bit>, 1
  3374.     %key <auto>, 2
  3375.     %key <eight-bit>, 1
  3376.     %key <seven-bit>, 0
  3377.     %tbend
  3378.  
  3379. ;...SET command, cont'd
  3380.  
  3381.  
  3382. ; SET PARITY
  3383.  
  3384. hspar:    asciz |
  3385.  SET PARITY keyword
  3386.    If parity is being used on the communication line, you must
  3387.    inform KERMIT-20, so it can send the desired parity on outgoing characters,
  3388.    and strip it from incoming ones.  The DEC-20 does not use parity on
  3389.    communication lines.  The choices are NONE (the default), ODD, EVEN, MARK,
  3390.    and SPACE.  NONE means no parity processing is done, and the 8th bit of
  3391.    each character can be used for data when transmitting binary files.
  3392.  
  3393.    If ODD, EVEN, MARK, or SPACE are selected, binary files will be transferred
  3394.    using 8th-bit-prefixing if the other side agrees, otherwise they cannot be
  3395.    be successfully transferred.  If NONE is specified, 8th-bit-prefixing will
  3396.    not be requested.
  3397.  
  3398.    SET PARITY should be used for communicating with hosts that require
  3399.    character parity, or through devices or networks (like TELENET) that add
  3400.    parity to characters that pass through them.  Both KERMITs should be set to
  3401.    the same parity.
  3402.  
  3403.    The specified parity is used both for terminal connection (CONNECT) and
  3404.    file transfer (SEND, RECEIVE, GET).
  3405. |
  3406.  
  3407. .setpa:    noise <to>        ; SET PARITY
  3408.     movei t1, [flddb. .cmkey,,partab,,none,]
  3409.     call rfield        ; Parse a keyword.
  3410.     hrrz t2, (t2)        ; Get the value for the keyword.
  3411.     movem t2, pars3        ; Save into pars3.
  3412.     skipn definf        ;[77] In DEFINE?
  3413.      confrm            ;[77]  No, get confirmation.
  3414.     ret
  3415.  
  3416. partab:    %table
  3417.     %key <even>, even
  3418.     %key <mark>, mark
  3419.     %key <none>, none
  3420.     %key <odd>, odd
  3421.     %key <space>, space
  3422.     %tbend
  3423.  
  3424. ;...SET command, cont'd
  3425.  
  3426.  
  3427. ;[137] SET PROMPT
  3428.  
  3429. hsprom:    asciz |
  3430.  SET PROMPT string
  3431.    Set the KERMIT-20 prompt to whatever character string you like.
  3432.    This is especially useful when connected to another DEC-20 through a
  3433.    dialer, using another KERMIT-20 on the remote system.  A unique prompt
  3434.    for each KERMIT-20 will clear up any confusion about which one you're
  3435.    talking to.
  3436. |
  3437.  
  3438. .setpr:    noise <to>        ; Parse the rest of the SET PROMPT command.
  3439.     movei t1, [
  3440.      flddb. .cmtxt,,,<KERMIT-20 command prompt>,<x>] ; Phony default.
  3441.     hrroi t2, [asciz/Kermit-20>/] ; Set up real default
  3442.     movem t2, .cmdef(t1)
  3443.     call cfield
  3444.     ret
  3445.  
  3446.  
  3447. ; Execute the SET PROMPT command.
  3448.  
  3449. $setpr:    move t1, [point 7, atmbuf] ; And move the characters from here
  3450.     move t2, [point 7, prompx] ;  to here.
  3451.  
  3452. $stpra:    ildb t4, t1        ; Copy the string.
  3453.     jumpe t4, $stprb
  3454.     idpb t4, t2
  3455.     jrst $stpra
  3456.  
  3457. $stprb:    idpb t4, t2        ; And a null.
  3458.     ret
  3459.  
  3460. ; SET command, cont'd
  3461.  
  3462. ; SET RETRY
  3463.  
  3464. hsrty:    asciz |
  3465.  SET RETRY option decimal-number
  3466.    Set the maximum number of retries allowed for:
  3467.      INITIAL CONNECTION -- How many times to try connecting before giving up.
  3468.      PACKETS -- How many times to try sending a particular packet.
  3469. |
  3470.  
  3471.  
  3472. .setre:    noise <maximum for>    ;[37] SET RETRY
  3473.     movei t1, [flddb. .cmkey,,[<2,,2>
  3474.         <[asciz/initial-connection/],,0>
  3475.         <[asciz/packets/],,1>
  3476.         ],,<packets>]
  3477.     call rfield
  3478.     hrrz t2, (t2)        ; Get the keyword index
  3479.     movem t2, pars3
  3480.     noise <to>        ; Prompt for the value
  3481.     movei t1, [flddb. .cmnum,,^d10,<times to retry before giving up,>,5]
  3482.     skipn pars3
  3483.      movei t1, [flddb. .cmnum,,^d10,<times to retry before giving up,>,16]
  3484.     call rfield
  3485.     movem t2, pars4
  3486.     skipn definf        ;[77] In DEFINE?
  3487.      confrm            ;[77]  No, get confirmation.
  3488.     ret
  3489.  
  3490. offon:    %table            ; Table for parsing ON or OFF.
  3491.     %key <off>, 0
  3492.     %key <on>, 1
  3493.     %tbend
  3494.  
  3495. ; SET command,  cont'd
  3496.  
  3497.  
  3498. ;[143] SET FLOW-CONTROL added as edit 143
  3499.  
  3500. hsflo:    asciz |
  3501.  SET FLOW-CONTROL option
  3502.    For communicating with full duplex systems.  The DEC-20 system is capable
  3503.    of regulating the flow of characters on the line using XON/XOFF flow
  3504.    control.  If characters are coming into the DEC-20 too fast, the DEC-20 will
  3505.    send an XOFF signal, Control-S, to tell the system on the other side to stop
  3506.    sending characters.  After it has finished processing the characters in its
  3507.    input buffer, it will send a Control-Q to tell the other side to resume
  3508.    sending.  The other system does the same thing when the DEC-20 is sending
  3509.    data characters.  KERMIT-20 will use XON/XOFF flow control on a full-duplex
  3510.    connection by default, and it will not use it on a half duplex connection.
  3511.    The options of the SET FLOW-CONTROL command are XON-XOFF and NONE.  If you
  3512.    SET FLOW-CONTROL to anything other than NONE, HANDSHAKE is set to NONE.
  3513. |
  3514. .setfl:    movei t1, [flddb. .cmkey,,flotab,,XON-XOFF] ; SET FLOW-CONTROL
  3515.     call rfield        ; Parse a keyword.
  3516.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3517.     movem t2, pars3        ; Save into pars3.
  3518.     skipn definf        ; In DEFINE?
  3519.      confrm            ;  No, get confirmation.
  3520.     ret
  3521.  
  3522. flotab:    %table            ; Flow-Control keywords
  3523.     %key <none>,0
  3524.     %key <XON-XOFF>,1
  3525.     %tbend
  3526.  
  3527. ;[76] SET HANDSHAKE added as edit 76.
  3528.  
  3529. hshan:    asciz |
  3530.  SET HANDSHAKE option
  3531.    For communicating with half duplex systems.  This lets you specify the line
  3532.    turnaround character sent by the half duplex host to indicate it has ended
  3533.    its transmission and is granting you permission to transmit.  When a
  3534.    handshake is set, KERMIT-20 will not send a packet until the half duplex
  3535.    host has sent the specified character.  The options are:
  3536.  
  3537.      NONE
  3538.      XOFF  (^S)
  3539.      XON   (^Q)
  3540.      BELL  (^G)
  3541.      CR    (^M, carriage return)
  3542.      LF    (^J, linefeed)
  3543.      ESC   (Escape)
  3544.      or an octal number specifying any ASCII control character.
  3545.  
  3546. If you SET HANDSHAKE to anything other than NONE, FLOW-CONTROL is set to NONE.
  3547. |
  3548.  
  3549.  
  3550. .setha:    movei t1, [flddb. .cmkey,,hshtab,,XOFF,[
  3551.      flddb. .cmnum,cm%sdh,^d8,<octal value of ASCII control character>]]
  3552.     call rfield        ; Parse a keyword.
  3553.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  3554.     caie t3, .cmnum        ; Number?
  3555.      hrrz t2, (t2)        ;  No, get the keyword's associated value.
  3556.     caile t2, 37        ; Control character?
  3557.      cain t2, 177
  3558.      skipa
  3559.      jrst [    tmsg <?Must be in ASCII control range, 0-37 or 177>
  3560.         jrst cmder1 ]
  3561.     movem t2, pars3        ; Save into pars3.
  3562.     skipn definf        ;[77] In DEFINE?
  3563.      confrm            ;[77]  No, get confirmation.
  3564.     ret
  3565.  
  3566. hshtab:    %table            ; Handshake keywords
  3567.     %key <bell>,7
  3568.     %key <CR>,15
  3569.     %key <ESC>,33
  3570.     %key <LF>,12
  3571.     %key <none>,0
  3572.     %key <XOFF>,23
  3573.     %key <XON>,21
  3574.     %tbend
  3575.  
  3576. ; SET command, cont'd
  3577.  
  3578. ;[160] SET INPUT
  3579.  
  3580. hsetin:    asciz |
  3581.  SET INPUT parameter value
  3582.    Specify how the INPUT command is to behave (see INPUT).
  3583.  
  3584.    SET INPUT DEFAULT-TIMEOUT n
  3585.       n is the number of seconds for an INPUT command to time out after
  3586.       not receiving the requested input, if no interval is explicitly
  3587.       given in the INPUT command.
  3588.  
  3589.    SET INPUT TIMEOUT-ACTION PROCEED or QUIT
  3590.       If the INPUT command comes from a command file (see TAKE command),
  3591.       then use this command to specify whether processing of the command
  3592.       file should proceed or quit after a timeout occurs.
  3593.  
  3594.    SET INPUT CASE IGNORE or OBSERVE
  3595.       Specify whether alphabetic case should be ignored ("a" matches "A")
  3596.       or observed ("a" does not match "A").
  3597. |
  3598.     ;...
  3599.  
  3600. ; SET INPUT parsing, like SET SEND/RECEIVE -- an extra level of parsing.
  3601.  
  3602.  
  3603. .setin:    movei t1, [flddb. .cmkey,,sintab] ; SET INPUT ...
  3604.     call rfield        ; Parse a keyword.
  3605.     hrrz t2, (t2)        ; Get the command routine addresses.
  3606.     movem t2, pars3        ; Save into pars3.
  3607.     hlrz t1, (t2)        ; Get the next level routine.
  3608.     call (t1)        ; Call it.
  3609.     ret
  3610.  
  3611. sintab:    %table
  3612.     %key <case>, [xwd .sinca,incase]
  3613.     %key <default-timeout>, [xwd .sindt,indeft]
  3614.     %key <timeout-action>, [xwd .sinta,intima]
  3615.     %tbend
  3616.  
  3617. .sinca:    noise <for matching>    ; SET INPUT CASE
  3618.     movei t1, [flddb. .cmkey,,castab,,<ignore>]
  3619.     jrst .sinkp        ; Go below & parse rest.
  3620.  
  3621. castab:    %table            ; Case table.
  3622.     %key <ignore>, 0
  3623.     %key <observe>, 1
  3624.     %tbend
  3625.  
  3626. .sindt:    noise <for INPUT commands> ; SET INPUT DEFAULT-TIMEOUT
  3627.     movei t1, [
  3628.      flddb. .cmnum,,^d10,<seconds,
  3629. when interval not specified in INPUT command,>]
  3630.     call rfield
  3631.     movem t2, pars4
  3632.     skipn definf        ; In DEFINE?
  3633.      confrm            ; No, get confirmation.
  3634.     ret
  3635.  
  3636. .sinta:    noise <for command file> ; SET INPUT TIMEOUT-ACTION
  3637.     movei t1, [flddb. .cmkey,,itatab,,<proceed>]
  3638.  
  3639. .sinkp:    call rfield        ; Parse keyword.
  3640.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3641.     movem t2, pars4        ; Save into pars4.
  3642.     skipn definf        ; In DEFINE?
  3643.      confrm            ; No, get confirmation.
  3644.     ret
  3645.  
  3646. itatab:    %table            ; INPUT timeout action table
  3647.     %key <proceed>, 0
  3648.     %key <quit>, 1
  3649.     %tbend
  3650.  
  3651. ; SET command, cont'd
  3652.  
  3653.  
  3654. ;[75] SET ITS-BINARY (format) ON or OFF
  3655.  
  3656. hsits:    asciz |
  3657.  SET ITS-BINARY (format) ON or OFF
  3658.    Specify whether ITS-Binary file headers are to be recognized or ignored.
  3659.    ITS binary format is a way (devised at MIT) of storing foreign 8-bit binary
  3660.    data on a 36-bit machine to allow automatic recognition of these files when
  3661.    sending them out again, so that you don't have to depend on the file byte
  3662.    size, or to issue explict SET FILE BYTESIZE commands to KERMIT.
  3663.  
  3664.    An ITS format binary file contains the sixbit characters "DSK8" left-
  3665.    adjusted in the first 36-bit word.  If ITS-BINARY is ON, then KERMIT-20 will
  3666.    send any file starting with this "header word" using 8-bit i/o, and will not
  3667.    send the header word itself, and it will store any incoming file that begins
  3668.    with that header word with 8-bit bytesize, again discarding the header word
  3669.    itself.  If ITS-BINARY is OFF, then the header word, if any, will be sent,
  3670.    and i/o will be according to the setting of FILE BYTESIZE.
  3671. |
  3672.  
  3673. .setit:    noise <format>        ; Issue guide word.
  3674.     movei t1, [flddb. .cmkey,,offon,,on] ; SET ITS-BINARY
  3675.     call rfield        ; Parse a keyword.
  3676.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3677.     movem t2, pars3        ; Save into pars3.
  3678.     skipn definf        ;[77] In DEFINE?
  3679.      confrm            ;[77]  No, get confirmation.
  3680.     ret
  3681.  
  3682. ; SET command, cont'd
  3683.  
  3684.  
  3685. ; SET LINE
  3686.  
  3687. hslin:    asciz |
  3688.  SET LINE octal-number
  3689.    Specify the octal TTY number to use for file transfer or CONNECT.
  3690.    If you issue this command, you will be running as a local Kermit, and you
  3691.    must log in to the remote system and run Kermit on that side in order to
  3692.    transfer a file.  If you don't issue this command, KERMIT-20 assumes it is
  3693.    running remotely, and does file transfer over its job's controlling
  3694.    terminal line.
  3695.  
  3696.    You can also select the line directly in the CONNECT command.
  3697. |
  3698.  
  3699. ; Parse rest of SET LINE command.
  3700.  
  3701. .setln:    noise <to tty>        ; SET LINE
  3702.     movei t1, [
  3703.      flddb. .cmnum,,^d8,<TTY to transfer files over,>,,[
  3704.      flddb. .cmcfm,cm%sdh,,<confirm to reset>]]
  3705.     call rfield        ; Parse a tty number.
  3706.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  3707.     caie t3, .cmnum        ; Is it a TTY number?
  3708.      jrst .setl1        ;  If not it must be a confirm.
  3709.     movem t2, pars3        ; Save the tty number.
  3710.     skipn definf        ;[77] In DEFINE?
  3711.      confrm            ;[77]  No, get confirmation.
  3712.     ret
  3713.  
  3714. .setl1:    move t4, mytty        ; Get the our terminal number.
  3715.     movem t4, pars3        ; Make believe we parsed it.
  3716.     ret
  3717.  
  3718. hsdel:    asciz |
  3719.  SET DELAY decimal-number
  3720.    How many seconds to wait before sending the first packet.  Use when remote
  3721.    and SENDing files back to your local Kermit.  This gives you time to
  3722.    "escape" back and issue a RECEIVE command before packets start arriving.
  3723.    The normal delay is 5 seconds.
  3724. |
  3725.  
  3726. .setdl:    noise <to>        ; SET DELAY
  3727.     movei t1, [flddb. .cmnum,,^d10,<seconds before sending first packet,>]
  3728.     call rfield        ; Parse a number.
  3729.     movem t2, pars3        ; Save the number.
  3730.     skipn definf        ;[77] In DEFINE?
  3731.      confrm            ;[77]  No, get confirmation.
  3732.     ret
  3733.  
  3734. ; SET command, cont'd
  3735.  
  3736.  
  3737. ; SET DUPLEX
  3738.  
  3739. hsdup:    asciz |
  3740.  SET DUPLEX keyword
  3741.    For use when CONNECTed to a remote system.  The choices are FULL and HALF.
  3742.    FULL means the remote system echoes the characters you type, HALF means
  3743.    the local system echoes them.  FULL is the default, and is used by most
  3744.    hosts.  HALF is necessary when connecting to IBM mainframes.
  3745. |
  3746.  
  3747. ; Parse SET DUPLEX
  3748.  
  3749. .setdu:    noise <to>        ;[18] SET DUPLEX
  3750.     movei t1, [flddb. .cmkey,,duptab,,<full>]
  3751.     call rfield
  3752.     hrrz t2, (t2)
  3753.     movem t2, pars3
  3754.     skipn definf        ;[77] In DEFINE?
  3755.      confrm            ;[77]  No, get confirmation.
  3756.     ret
  3757.  
  3758. duptab:    %table            ;[18] Table of legal duplexes
  3759.     %key <full>,dxfull
  3760.     %key <half>,dxhalf
  3761.     %tbend
  3762.  
  3763. ;[143] SET EXPUNGE
  3764. ;
  3765. hsexp:    asciz |
  3766.   SET EXPUNGE ON or OFF
  3767.     Tell whether you want a DELETE command (either the LOCAL DELETE command
  3768.     or a REMOTE DELETE command sent to a KERMIT-20 server) to expunge files as
  3769.     it deletes them.  On the DEC-20, a deleted file continues to take up space,
  3770.     and may be "undeleted" at a later time in the same session.  To expunge a
  3771.     deleted file means to remove it completely and irrevocably.  EXPUNGE is OFF
  3772.     (i.e. no automatic expunging of deleted files) by default.
  3773. |
  3774. .setex:    noise <deleted files automatically> ; SET EXPUNGE
  3775.     movei t1, [flddb. .cmkey,,offon,,on]
  3776.     call rfield        ; Parse a keyword.
  3777.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3778.     movem t2, pars3        ; Save into pars3.
  3779.     skipn definf        ;[77] In DEFINE?
  3780.      confrm            ;[77]  No, get confirmation.
  3781.     ret    
  3782.  
  3783. ; SET ESCAPE
  3784.  
  3785. hsesc:    asciz |
  3786.  SET ESCAPE octal-number
  3787.    Tell what control character you want to use to "escape" from remote
  3788.    connections.  34 (Control-Backslash ^\) by default.  The number is the octal
  3789.    value of the ASCII control character, 1 to 37.  When you type the escape
  3790.    character, you must follow it by a single-character "argument":
  3791.  
  3792.    C  Close connection
  3793.    S  Status report
  3794.    P  Push to a new Exec on the local system
  3795.    Q  If you have given a LOG SESSION command, temporarily Quit logging
  3796.    R  Resume logging to session log
  3797.    B  Attempt to send a simulated BREAK signal.
  3798.    ?  List available options
  3799.    or second copy of the escape character to send the escape character itself.
  3800. |
  3801.  
  3802. ; Parse rest of SET ESCAPE command.
  3803.  
  3804. .setes:    noise <character for connect to> ;[16] SET ESCAPE
  3805.     movei t1, [
  3806.      flddb. .cmnum,,^d8,<Value of ASCII control character,>,<34>]
  3807.     call rfield
  3808.     caile t2, 37        ; Control character?
  3809.      cain t2, 177
  3810.      skipa
  3811.      jrst [    tmsg <?Must be in ASCII control range, 0-37 or 177>
  3812.         jrst cmder1 ]
  3813.     movem t2, pars3
  3814.     skipn definf        ;[77] In DEFINE?
  3815.      confrm            ;[77]  No, get confirmation.
  3816.     ret
  3817.  
  3818. ; SET command, cont'd
  3819.  
  3820. ; SET RECEIVE parameters
  3821.  
  3822. hsrcv:    asciz |
  3823.  SET RECEIVE parameter
  3824.    Parameters to request or expect for incoming packets, as follows:
  3825.  
  3826.    END-OF-LINE octal-number
  3827.      Carriage return (15) by default.  The DEC-20 does not actually need any
  3828.      line terminator for incoming packets.
  3829.  
  3830.    PACKET-LENGTH decimal-number
  3831.      Maximum length packet for the other side to send, decimal number,
  3832.      between 10 and 9000, 80 by default.
  3833.  
  3834.    PADDING octal-number, PADCHAR octal-number
  3835.      Should never be necessary; the DEC-20 needs no padding.
  3836.  
  3837.    PAUSE floating-point-number
  3838.      How many seconds to pause before acknowledging a packet.
  3839.      Setting this to a nonzero value will slow down the rate at which
  3840.      data packets come in to the DEC-20, which may be necessary for DEC-20's
  3841.      that have "sensitive" front ends and cannot accept input at a high rate.
  3842.  
  3843.    QUOTE octal-number
  3844.      What printable character to use for quoting of control characters.
  3845.      Specify the octal ASCII value.  "#" (43) by default.  There should be no
  3846.      reason to change this.
  3847.  
  3848.    SERVER-TIMEOUT decimal-numer
  3849.      When running as a server, how often to send periodic NAKs during server
  3850.      server command wait.  0 means don't send them at all.  94 seconds maximum.
  3851.  
  3852.    START-OF-PACKET octal-number
  3853.      The control character to mark the beginning of incoming packets.  Normally
  3854.      SOH (Control-A, ASCII 1).  There should be no reason to change this.
  3855.  
  3856.    TIMEOUT decimal-number
  3857.      How many seconds the other Kermit should wait for a packet before asking
  3858.      for retransmission.  If 0, then no timing out will be done.  94 seconds
  3859.      maximum.
  3860. |
  3861.  
  3862. ; Parse rest of SET RECEIVE...
  3863.  
  3864. .setrc:    movei t1, [flddb. (.cmkey,,srtabl,,)] ; SET RECEIVE ...
  3865.     call rfield        ; Parse a keyword.
  3866.     hrrz t2, (t2)        ; Get the command routine addresses.
  3867.     movem t2, pars3        ; Save into pars3.
  3868.     hlrz t1, (t2)        ; Get the next level routine.
  3869.     call (t1)        ; Call it.
  3870.     ret
  3871.  
  3872. srtabl:    %table
  3873.     %key <end-of-line>, [xwd .seteo,reolch]
  3874.     %key <packet-length>, [xwd .setpk,rpsiz]
  3875.     %key <padchar>, [xwd .setpc,rpadch]
  3876.     %key <padding>, [xwd .setpd,rpadn]
  3877.     %key <pause>, [xwd .srpau,rpause] ;[36]
  3878.     %key <quote>, [xwd .setqu,rquote]
  3879.     %key <server-timeout>, [xwd .setim,srvtim] ;[137]
  3880.     %key <start-of-packet>, [xwd .setsp,rsthdr] ;[18]
  3881.     %key <timeout>,[xwd .setim,rtimou]
  3882.     %tbend
  3883.  
  3884. ; SET SEND parameters
  3885.  
  3886. hssnd:    asciz |
  3887.  SET SEND parameter
  3888.    Parameters for outgoing packets, as follows:
  3889.  
  3890.    END-OF-LINE octal-number
  3891.      The octal value of the ASCII character to be used as a line terminator
  3892.      for packets, if one is required by the other system.  Carriage return
  3893.      (15) by default.  You will only have to use this command for systems
  3894.      that require a line terminator other than carriage return.
  3895.  
  3896.    PACKET-LENGTH decimal-number
  3897.      Maximum packet length to send, decimal number, between 10 and 9000, 80 by
  3898.      default.  Shortening the packets might allow more of them to get through
  3899.      through without error on noisy communication lines.
  3900.  
  3901.    PADDING octal-number, PADCHAR octal-number
  3902.      How much padding to send before a packet, if the other side needs padding,
  3903.      and what character to use for padding.  Defaults are no padding, and NUL
  3904.      (0) for the padding character.
  3905.  
  3906.    PAUSE floating-point-number
  3907.      How many seconds to pause before sending each data packet.  Setting this
  3908.      to a nonzero value may allow some slow systems enough time to process
  3909.      a data packet sent by the DEC-20 before the next one arrives.  Normally,
  3910.      no per-packet pausing is done.
  3911.  
  3912.    QUOTE octal-number
  3913.      What printable character to use for quoting of control characters.
  3914.      Specify an octal ASCII value.  "#" (43) by default.  There should be no
  3915.      reason to change this.
  3916.  
  3917.    START-OF-PACKET octal-number
  3918.      The control character that marks the beginning of a packet.  Normally
  3919.      SOH (Control-A, ASCII 1).  There should be no reason to change this.
  3920.  
  3921.    TIMEOUT decimal-number
  3922.      How many seconds to wait for a packet before trying again.
  3923. |
  3924.  
  3925. .setsn:    movei t1, [flddb. (.cmkey,,sstabl,,)] ; SET SEND ...
  3926.     call rfield        ; Parse a keyword.
  3927.     hrrz t2, (t2)        ; Get the command routine addresses.
  3928.     movem t2, pars3        ; Save into pars3.
  3929.     hlrz t1, (t2)        ; Get the next level routine.
  3930.     call (t1)        ; Call it.
  3931.     ret
  3932.  
  3933. sstabl:    %table
  3934.     %key <end-of-line>, [xwd .seteo,seolch]
  3935.     %key <packet-length>, [xwd .setpk,spsiz]
  3936.     %key <padchar>, [xwd .setpc,spadch]
  3937.     %key <padding>, [xwd .setpd,spadn]
  3938.     %key <pause>, [xwd .sspau,spause] ;[35]
  3939.     %key <quote>, [xwd .setqu,squote]
  3940.     %key <start-of-packet>, [xwd .setsp,ssthdr] ;[18]
  3941.     %key <timeout>,[xwd .setim,stimou]
  3942.     %tbend
  3943.  
  3944. ;...SET command, cont'd
  3945.  
  3946.  
  3947. ; SET PACKET-LENGTH
  3948.  
  3949. .setpk:    noise <to>        ; SET SEND/RECEIVE PACKET-LENGTH
  3950.     movei t1, [
  3951.      flddb. .cmnum,cm%sdh,^d10,<Decimal number between 10 and 94>]
  3952.     call rfield        ; Parse the packet size.
  3953.     movem t2, pars4        ; Save the packet size.
  3954.     cail t2, ^d10        ; Is the number in the right range?
  3955.      caile t2, ^d9000    ;[179] (was ^d94)
  3956.       jrst [tmsg <?Illegal packet size>
  3957.         jrst cmder1 ]
  3958.     skipn definf        ;[77] In DEFINE?
  3959.      confrm            ;[77]  No, get confirmation.
  3960.     ret
  3961.  
  3962.  
  3963. .srpau:    noise <between packets to> ;[36] SET RECEIVE PAUSE
  3964.     movei t1, [
  3965.      flddb. .cmflt,,,<seconds to pause after receiving a packet,>,<0>]
  3966.     jrst .sxpau        ; Join common code.
  3967.  
  3968.  
  3969. .sspau:    noise <between packets to> ;[35] SET SEND PAUSE
  3970.     movei t1, [
  3971.      flddb. .cmflt,,,<seconds to pause before sending a packet,>,<0>]
  3972.  
  3973.  
  3974. .sxpau:    call rfield        ;[36] Common code.
  3975.     movem t2, pars4
  3976.     noise <seconds>
  3977.     skipn definf        ;[77] In DEFINE?
  3978.      confrm            ;[77]  No, get confirmation.
  3979.     skipge pars4        ; Is the number in the right range?
  3980.      jrst [    tmsg <?Must be a positive number>
  3981.         jrst cmder1 ]
  3982.     ret
  3983.  
  3984. .setpd:    noise <to>        ; SET SEND/RECEIVE PADDING
  3985.     movei t1, [
  3986.      flddb. .cmnum,,^d10,<number of padding characters, positive>,<0>]
  3987.     call rfield        ; Parse the number of padding chars.
  3988.     movem t2, pars4        ; Save the number.
  3989.     skipn definf        ;[77] In DEFINE?
  3990.      confrm            ;[77]  No, get confirmation.
  3991.     move t2, pars4        ; Get the amount of padding we parsed.
  3992.     skipge t2        ; Is the number in the right range?
  3993.      jrst [    tmsg <?Must be a positive number>
  3994.         jrst cmder1 ]
  3995.     ret
  3996.  
  3997. ;...SET command, cont'd
  3998.  
  3999.  
  4000. .setpc:    noise <to>        ; SET SEND/RECEIVE PADCHAR
  4001.     movei t1, [
  4002.      flddb. .cmnum,,^d8,<Value of ASCII character, 0 to 37, or 177,>]
  4003.     call rfield        ; Parse the padding character.
  4004.     movem t2, pars4        ; Save the padding char.
  4005.     skipn definf        ;[77] In DEFINE?
  4006.      confrm            ;[77]  No, get confirmation.
  4007.     move t2, pars4        ; Get the padding char we parsed.
  4008.     cain t2, ^o177        ;[149] Is it a DEL?
  4009.      ret            ;[149] OK.
  4010.     skipl t2        ; Is it in the control range, 0 to...
  4011.      caile t2, ^o37        ; ...37 octal?
  4012.       jrst [tmsg <?Illegal padding character> ; No, give error message
  4013.         jrst cmder1 ]    ; and allow command retry.
  4014.     ret            ; Yes, OK.
  4015.  
  4016. .seteo:    noise <to>        ; END-OF-LINE
  4017.     movei t1, [
  4018.      flddb. .cmnum,,^d8,<Value of ASCII control character, 0-37,>,<15>]
  4019.     call rfield        ; Parse the EOL char.
  4020.     skipl t2        ; Is the number in the right range?
  4021.      caile t2, ^o37        ;  Fix to compare correctly.
  4022.       jrst [tmsg <?Illegal EOL character>
  4023.         jrst cmder1 ]
  4024.     movem t2, pars4        ; Get the EOL char we parsed.
  4025.     skipn definf        ;[77] In DEFINE?
  4026.      confrm            ;[77]  No, get confirmation.
  4027.     ret
  4028.  
  4029.  
  4030. .setsp:    noise <to>        ;[18] START-OF-PACKET
  4031.     movei t1, [
  4032.      flddb. .cmnum,cm%sdh,^d8,<Octal value of ASCII control character>,<1>]
  4033.     call rfield
  4034.     skipl t2        ; Is the number in the right range?
  4035.      caile t2, ^o37        ;  Fix to compare correctly.
  4036.       jrst [tmsg <?Illegal start-of-packet character>
  4037.         jrst cmder1 ]
  4038.     movem t2, pars4
  4039.     skipn definf        ;[77] In DEFINE?
  4040.      confrm            ;[77]  No, get confirmation.
  4041.     ret
  4042.  
  4043.     ;...
  4044.  
  4045. ; More SET commands...
  4046.  
  4047. .setqu:    noise <to>        ; SET SEND/RECEIVE QUOTE
  4048.     movei t1, [
  4049.      flddb. .cmnum,,^d8,<Value of printable ASCII character,>,<43>] ;[21]
  4050.     call rfield        ;[21]
  4051.     caile t2," "        ;[21] Printable?
  4052.      caile t2, "~"        ;[21]
  4053.      jrst [    tmsg <?Must be printable character, range 41-176>
  4054.         jrst cmder1 ]    ;[21]
  4055.     movem t2, pars4        ;[21] OK, stash it.
  4056.     skipn definf        ;[77] In DEFINE?
  4057.      confrm            ;[77]  No, get confirmation.
  4058.     ret
  4059.  
  4060. .setim:    noise <to>        ; SET SEND/RECEIVE TIMEOUT
  4061.     movei t1, [
  4062.      flddb. .cmnum,,^d10,<Number of seconds before timing out, 1 to 94,>]
  4063.     call rfield        ; Parse the number.
  4064.     movem t2, pars4        ; Save the number.
  4065.     skipn definf        ;[77] In DEFINE?
  4066.      confrm            ;[77]  No, get confirmation.
  4067.     move t2, pars4        ; Get the number we parsed.
  4068.     cail t2, 0        ;[94] Is the number in the right range?
  4069.      caile t2, ^d94        ;  Fix to compare correctly.
  4070.       jrst [tmsg <?Illegal number of seconds>
  4071.         jrst cmder1 ]
  4072.     ret
  4073.  
  4074.     subttl SET command action routines.
  4075.  
  4076. ; SET ... command dispatcher.
  4077.  
  4078. $set:    skipe macrof        ;[77] Was a macro used?
  4079.      jrst $set2        ;[77] If so, go handle that.
  4080.     move t2, pars2        ; Get back data value.
  4081.     hrrz t1, (t2)        ; Get evaluation routine.
  4082.     call (t1)        ; Call it.
  4083.     ret
  4084.  
  4085.     ;...
  4086.  
  4087. ;...$SET, cont'd
  4088.  
  4089.  
  4090. ;[77] SET macro was typed.
  4091.  
  4092. $set2:    move t1, pars2         ; Pointer to macro text (SET operands)
  4093.     movem t1, macxp
  4094. ;*    PSOUT            ; echo it for debugging...
  4095.     setzm mdone        ; Say macro not done yet.
  4096.  
  4097. ; Loop to copy one set command into the command buffer.
  4098.  
  4099. $set3:    move t1, [ascii/set  /]    ; Fake a SET command
  4100.     movem t1, cmdbuf
  4101.     move t2, [point 7, cmdbuf, 27] ; Copy them to after "set "
  4102.     movem t2, sbk+.cmptr
  4103.  
  4104. ; Loop for each character.
  4105.  
  4106. $set4:    ildb t1, macxp        ; Get a character from the macro text
  4107.     aos sbk+.cminc        ; Account for it in the CSB
  4108.     sos sbk+.cmcnt        ;  ...
  4109.     jumpe t1, $set5        ; If null, done.
  4110.     cain t1, ","        ; Comma?
  4111.      jrst [    movei t1, .chcrt ; Yes, substitute a carriage return.
  4112.         idpb t1, t2
  4113.         aos sbk+.cminc
  4114.         sos sbk+.cmcnt
  4115.         movei t1, .chlfd ; And a linefeed...
  4116.         idpb t1, t2
  4117.         aos sbk+.cminc
  4118.         sos sbk+.cmcnt
  4119.         setz t1,    ; And a null...
  4120.         idpb t1, t2
  4121.         jrst $set6 ]    ; Go execute this part.
  4122.  
  4123.     idpb t1, t2        ; Not a comma, copy the character.
  4124.     jrst $set4
  4125.  
  4126. ; Get here at end of null-terminated macro body.
  4127.  
  4128. $set5:    idpb t1, t2        ;[80] Deposit the null.
  4129.     setom mdone        ; Flag that we're done interpreting the macro.
  4130.  
  4131. $set6:    move t1, sbk        ; Zero the CSB flags.
  4132.     hrrzm t1, sbk        ;  ...
  4133. ;*    hrroi t1, cmdbuf    ; Echo the command.
  4134. ;*    PSOUT            ; ...
  4135.     call .set        ; Go parse the string.
  4136.     call $set        ; Go execute what was parsed.
  4137.     skipn mdone        ; Any more?
  4138.      jrst $set3        ; Yes, go do them.
  4139.     setzm mdone        ; No, all done.
  4140.     ret
  4141.  
  4142. ;[42] SET INCOMPLETE
  4143.  
  4144. $setab:    move t1, pars3        ; Just save what we parsed.
  4145.     movem t1, abtfil
  4146.     ret
  4147.  
  4148.  
  4149. ; SET DEBUGGING
  4150.  
  4151. $setdb:    skipn t1, pars3        ;[38] See what we got.
  4152.      jrst [    setz debug,    ;[38] Turning debugging off.
  4153.         skipn t1, logjfn ;[38] Did we have a log?
  4154.          ret        ;[38] No, done.
  4155.         setz t2,    ;[144] Yes, any bytes written?
  4156.         RFPTR        ;[144]
  4157.          nop        ;[144]
  4158.         skipg t2    ;[144]
  4159.          txo t1, cz%abt    ;[144] None, don't bother keeping the log.
  4160.         setzm logjfn    ;[38] Zero this so we know...
  4161.         CLOSF        ;[38] Close it.
  4162.          erjmp .+1    ;[144] Ignore errors, may already be closed
  4163.         ret ]        ;[38]  by previous EXIT command.
  4164.  
  4165.     skipl debug, pars3    ; DEBUG. Get the value we parsed.
  4166.      caile debug, 2        ;[22] Make sure it's 0, 1, or 2.
  4167.      movei debug, 1        ;[22] ...
  4168.     ret
  4169.  
  4170. ; SET SEND/RECEIVE command dispatcher.
  4171.  
  4172. $setrs:    move t1, @pars3        ; SEND/RECEIVE.  Address of variable to set.
  4173.     move t2, pars4        ; The value that was parsed.
  4174.     movem t2, (t1)        ; Save the value.
  4175.     ret
  4176.  
  4177. ; SET DELAY
  4178.  
  4179. $setdl:    move t1, pars3        ; DELAY. Get the number of seconds to delay.
  4180.     movem t1, delay        ; Save the delay time.
  4181.     movem t1, odelay    ;[27] Here too, for saving & restoring.
  4182.     ret
  4183.  
  4184. ; SET DUPLEX
  4185.  
  4186. $setdu:    move t1, pars3        ;[18] DUPLEX.  Get what was parsed.
  4187.     movem t1, duplex
  4188.     ret
  4189.  
  4190. ; SET ESCAPE
  4191.  
  4192. $setes:    move t1, pars3        ;[16] ESCAPE.  Get what we parsed.
  4193.     movem t1, escape
  4194.     ret
  4195.  
  4196. ; SET EXPUNGE
  4197.  
  4198. $setex:    move t1, pars3        ;[143] SET EXPUNGE
  4199.     movem t1, expung
  4200.     ret
  4201.  
  4202. ; SET FILE
  4203.  
  4204. $setfi:    skipn t1, pars3        ;[84] Which file parameter are we setting?
  4205.      jrst $setf8        ;[84] Bytesize, go do that.
  4206.  
  4207. ;  ... FILE NAMING
  4208.  
  4209. $setfn:    sojn t1, [        ;[84] We'll have to get a little fancier
  4210.         tmsg <?Impossible parse value> ;[84] if more file parameters
  4211.         ret ]        ;[84] are added...
  4212.     move t1, pars4        ;[84] OK, get the value.
  4213.     movem t1, xfnflg    ;[84] Save it.
  4214.     ret            ;[84] Done.
  4215.  
  4216. ;  ... FILE BYTESIZE
  4217.  
  4218. $setf8:    move t1, pars4        ; BYTESIZE... Get the value of the flag.
  4219.     cain t1, 2        ; Is it autobyte?
  4220.      jrst [ setom autbyt    ;  If so, say so,
  4221.         setzm ebtflg    ;  and say this not so.
  4222.         ret ]
  4223.     setzm autbyt        ; Say no auto-byte.
  4224.     movem t1, ebtflg    ; Set the flag.
  4225.     ret
  4226.  
  4227. ; SET PARITY
  4228.  
  4229. $setpa:    move t1, pars3        ;[109] What did they say?
  4230.     caie t1, none        ;[109] Was the parity NONE?
  4231.      jrst [    setom ebqr    ;[89] No, so request 8th-bit prefixing.
  4232.         movei t2, dqbin    ;[89] Use the default prefix.
  4233.         movem t2, ebq    ;[89]
  4234.         tmsg <%Will request 8th-bit prefixing.
  4235. %If the other KERMIT doesn't agree,
  4236. %binary files cannot be sent correctly.
  4237. >
  4238.         jrst .+2 ]    ;[89]
  4239.      jrst [    movei t1, "Y"    ;[95] If none, just say we will do 8th-bit
  4240.         movem t1, ebq    ;[95]  prefixing if requested.
  4241.         setzm ebqr    ;[95] But we won't request it ourselves.
  4242.         jrst .+1 ]    ;[95]
  4243.     move t1, pars3
  4244.     movem t1, parity
  4245.     ret
  4246.  
  4247. ; SET RETRY
  4248.  
  4249. $setre:    move t1, pars3        ;[37] SET RETRY
  4250.     move t2, pars4
  4251.     movem t2, @[exp imxtry, maxtry](t1)
  4252.     ret
  4253.  
  4254. ;[143] SET FLOW-CONTROL
  4255.  
  4256. $setfl:    skipe t1, pars3        ; Get flow control option.
  4257.      setzm handsh        ; If nonzero, turn off handshake.
  4258.     movem t1, flow
  4259.     ret
  4260.  
  4261. ;[76] SET HANDSHAKE
  4262.  
  4263. $setha:    skipe t1, pars3        ;[143] Get the handshake option.
  4264.      setzm flow        ;[143] If nonzero, turn off flow control.
  4265.     movem t1, handsh    ; Save it.
  4266.     ret            ; Done.
  4267.  
  4268. ;[75] SET ITS-BINARY
  4269.  
  4270. $setit:    move t1, pars3        ; Just save the value in the ITS flag.
  4271.     movem t1, itsflg
  4272.     ret
  4273.  
  4274. ; SET LINE
  4275. ;
  4276. ;[87] Call with PARS3/ number of line to assign.
  4277. ;
  4278. $setln:    move t1, ttynum        ; Previous line number, if any.
  4279.     movem t1, oldnum    ; Remember it.
  4280.     move t1, pars3
  4281.     movem t1, ttynum    ;
  4282.     move t1, asgflg        ; Remember in case we already had another...
  4283.     movem t1, oasflg    ;
  4284.     move t1, netjfn        ;[80]
  4285.     movem t1, oldjfn    ;[80]
  4286.     setzm local        ; Assume we're a remote Kermit.
  4287.     move t1, ttynum        ;[80]
  4288.     came t1, mytty        ; Lines the same?
  4289.      setom local        ; No, so we're local.
  4290.     movei t1, .ttdes(t1)    ; Form device designator.
  4291.     DVCHR            ;
  4292.      erjmp asser1        ;
  4293.     hlre t1, t3        ; Who has it?
  4294.     movem t1, job        ; Job number of who has it, or -1 (or -2).
  4295.     setzm asgflg        ; Assume I don't have to assign it.
  4296.     skipn local        ; Own controlling TTY?
  4297.      jrst [    skipe tvtflg    ;[130] Yes, but is it an ARPANET TVT?
  4298.          jrst $stln2    ;[130]  If so, still have to OPENF in 8b mode.
  4299.         movei t1, .cttrm ; No, so I don't have to assign it.
  4300.         movem t1, netjfn ; Just use controlling terminal designator.
  4301.         jrst $stln3 ]
  4302.     move t3, myjob        ; My job number.
  4303.     camn t3, job        ; If I had it assigned already,
  4304.      jrst $stln2
  4305.     move t1, ttynum        ; Form device designator again,
  4306.     movei t1, .ttdes(t1)    ;  and...
  4307.     ASND            ;  give it a try.
  4308.      erjmp asser1        ; Uh oh, can't assign it.
  4309.     setom asgflg        ; Assigned it.  Set this flag to remember.
  4310.  
  4311.     ;...
  4312.  
  4313. ; $SETLN (SET LINE), cont'd
  4314.  
  4315. $stln2:    move t1, [170700,,filbuf] ; Pointer to file name buffer.
  4316.     move t2, [ascii/TTY/]    ; Build TTYn: filename.
  4317.     movem t2, filbuf    ; Into filbuf.
  4318.     move t2, ttynum        ; TTY number.
  4319.     movei t3, ^d8        ; Octal.
  4320.     NOUT%
  4321.      %jserr <Can't NOUT TTY number>,asserz
  4322.     movei t2, ":"        ; Add a colon.
  4323.     idpb t2, t1
  4324.     setz t2,
  4325.     idpb t2, t1
  4326.     movx t1, gj%sht        ; Now try to get a JFN on the TTY.
  4327.     hrroi t2, filbuf
  4328.     GTJFN%
  4329.      %jserr <Can't get JFN on TTY>,asserz ; Error, probably no such device.
  4330.     hrrzm t1, netjfn    ; Got JFN OK, save it as the "network" JFN.
  4331.     movx t2, fld(8,of%bsz)!of%wr!of%rd ; 8-bit bytes, read & write access.
  4332.     OPENF%            ; Open the device.
  4333.      erjmp asserr        ;  Can't, print informative error message.
  4334.     setzm setspd        ;[161] Flag that speed has not been SET.
  4335.  
  4336. $stln3:    move t1, oldjfn        ;[127] Get JFN of line previously used.
  4337.     skiple t1        ;[127] No previous one?
  4338.      cain t1, .cttrm    ;[127] Previous one was controlling terminal?
  4339.      jrst $stlnx        ;   One of those, nothing to do.
  4340.     CLOSF%            ; Close it.
  4341.       %jserr (,.+1)        ;
  4342.     setzm oldjfn        ; Remember that we did.
  4343.     skipe oasflg        ; Had I also assigned the old one?
  4344.      jrst [    skipg t1, oldnum ; Yes, did I remember the number?
  4345.          jrst .+1    ; No...    
  4346.         movei t1, .ttdes(t1) ; Yes, then deassign the old one.
  4347.         RELD%
  4348.          %jserr (,.+1)
  4349.         setzm oldnum    ; Set these to zero...
  4350.         setzm oasflg
  4351.         jrst .+1 ]
  4352.     ;...
  4353.  
  4354. ;...SET LINE, cont'd
  4355.  
  4356.  
  4357. $stlnx:    jrst $stlnz        ;[129] Skip next bit...
  4358.  
  4359. ;The following code is not used because a BBN TCP jsys is called.
  4360. ;Some ARPA sites don't have the BBN jsys's any more.  Those that have them
  4361. ;keep them in different places (MONSYM, TCPSYM, etc).  Rather than make the
  4362. ;program site-dependent, this has been replaced with a SET TVT command until
  4363. ;the DEC TCP jsys's become standard and widespread, assuming there will be a
  4364. ;GETAB or other jsys to tell whether a given TTY is a TVT.
  4365.  
  4366.     setzm tvtflg        ;[129] Assume not on tvt
  4367.     skipe local        ;[129] Are we local?
  4368.      jrst $stlnz        ;[129] Yes, skip this
  4369.  
  4370. ;[129] The next 10 or so lines of code adapted from MODEM.MAC
  4371.  
  4372.     movx t1,tcp%nt        ;[129] Want aobjn ptr for tvts
  4373.     STAT%            ;[129] Get it
  4374.      %jserr <STAT failed>,$stlnz ;[129]
  4375.     hrrz t3,mytty        ;[129] Tty line we're running on
  4376.     hrrz t1,t2        ;[129] Get first tvt
  4377.     camge t3,t1        ;[129] Are we less than the first?
  4378.      jrst $stlnz        ;[129] Yes
  4379.     hlres t2        ;[129] Calculate last tvt
  4380.     sub t1,t2        ;[129] ...
  4381.     subi t1,1        ;[129] ...
  4382.     camg t3,t1        ;[129] Are we .le. last tvt?
  4383.      setom tvtflg        ;[129] Yes, flag for later
  4384.  
  4385. ;[130] See if line is remote, and if so, if carrier is up.
  4386.  
  4387. $stlnz:    move t1, netjfn        ; Get the line's JFN back.
  4388.     call chklin        ;[134] Check on remote & carrier status.
  4389.  
  4390. ;* Note, commented out because it seems to take some time for carrier to come
  4391. ;* up when dialing out.  Better not to scare users.
  4392. ;*
  4393. ;*    hrroi t1, [asciz/
  4394. ;*%Warning - No carrier on remote line/]
  4395. ;*    skipe mdmlin
  4396. ;*     skipe carier        ; Give warning if none.
  4397. ;*     skipa
  4398. ;*     PSOUT
  4399.  
  4400. $stlzz:    movei t2, .chcrt    ; Send a CR down the line to get things going.
  4401.     BOUT
  4402.      erjmp r
  4403.     ret            ; Done.
  4404.  
  4405.     ;...
  4406.  
  4407. ; $SETLN (SET LINE), cont'd
  4408.  
  4409.  
  4410. ;[7] (this whole section...) Get here if error assigning link tty.
  4411.  
  4412. asserr:    movei t1, .fhslf    ; Got error trying to open link tty.
  4413.     GETER%
  4414.     hrrzs t2
  4415.     caie t2, opnx7        ; Somebody else has it?
  4416.      %jserr <Can't assign or open TTY>,asserz ; No, something else.
  4417.  
  4418. ; In use by someone else.  Say who.
  4419.  
  4420. asser1:    tmsg <
  4421. ?Line >
  4422.     numout ttynum, 8    ; Line so-&-so...
  4423.     tmsg < in use by job >    ; ...in use by job
  4424.     numout job        ; ...job number
  4425.     tmsg <, user >        ; Tell who the user is.
  4426.     move t1, job
  4427.     hrroi t2, t3
  4428.     movei t3, .jiuno
  4429.     GETJI
  4430.       erjmp asserx
  4431.     movei t1, .priou
  4432.     move t2, t3        ; User name of who has the line.
  4433.     DIRST
  4434.       erjmp asserx
  4435.     tmsg <
  4436. >
  4437.     jrst asserz
  4438.  
  4439. asserx:    tmsg <???
  4440. >
  4441.  
  4442. asserz:    move t2, oldnum        ; Restore old line.
  4443.     movem t2, ttynum
  4444.     move t2, oldjfn        ; And line JFN.
  4445.     movem t2, netjfn
  4446.     move t2, oasflg        ; And the I-assigned-it flag.
  4447.     movem t2, asgflg
  4448.     ret
  4449.  
  4450. ; Check the line whose JFN is in t1.
  4451. ; Set flags MDMLIN if line is remote, CARIER if line has carrier up.
  4452. ; SPEED is set to a nonnegative number if known, -1 otherwise.
  4453. ;
  4454. ; Returns +1 always, with t1 unchanged, t2-t4 modified.
  4455. ;
  4456. chklin:    saveac<t1>        ; Save the argument
  4457.     movei t2, .morsp    ; "Read Speed"
  4458.     MTOPR            ; Flag bits are returned in LH(T2)
  4459.      %jserr (,.+1)        ;  ...
  4460.     hrres t3        ; No split speed.
  4461.     setzm carier        ; Assume no carrier.
  4462.     setzm mdmlin        ; Assume line not modem-controlled.
  4463.     txnn t2, mo%rmt        ; Is it?
  4464.      jrst [    movem t3, speed    ;  No, it's local, so speed is valid.
  4465.         ret ]        ;  Don't have to worry about carrier.
  4466.     setom mdmlin        ; Yes, flag for SHOW LINE, etc.
  4467.     skipe setspd        ;[161] Was speed explicitly SET for this line?
  4468.      jrst chkli2        ;[161]  Yes, so skip next part.
  4469.     skipe monv        ; TOPS-10 V6 or later?
  4470.      jrst [    movem t3, speed    ;  Yes, so we can believe the speed.
  4471.         jrst chkli2 ]    ;  Go check carrier.
  4472.     came t3, speed        ; Pre-V6.  Does this agree with what was set?
  4473.      seto t3,        ;  No, so we don't really know the speed.
  4474.     movem t3, speed        ; Save the speed or else -1 for don't know.
  4475.  
  4476. ; Entry point just to see if we have carrier (assume MDMLIN already -1).
  4477.  
  4478. chkli2:    setzb t2, carier    ; See if we have carrier.
  4479.     RFMOD            ; Get mode word.
  4480.      erjmp .+1    
  4481.     txne t2, tt%car        ; Carrier?
  4482.      setom carier        ;  Yes.
  4483.     ret
  4484.  
  4485. ;
  4486. hspeed:    asciz |
  4487.  
  4488.  SET SPEED n
  4489.    Set the speed of the currently selected line -- the controlling terminal
  4490.    by default, or else the line specified in the most recent SET LINE
  4491.    command -- to the baud rate indicated by n, for example 1200.  Under
  4492.    releases of TOPS-20 prior to 6.0, you must issue this command before you
  4493.    can send a simulated BREAK signal during CONNECT.
  4494. |
  4495. .setxp:    noise <to>
  4496.     movei t1, [flddb. .cmkey,,baudtb]
  4497.     call rfield
  4498.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  4499.     movem t2, pars3        ; Save into pars3.
  4500.     skipn definf        ;[77] In DEFINE?
  4501.      confrm            ;[77]  No, get confirmation.
  4502.     ret    
  4503.  
  4504. baudtb:    %table
  4505.     %key <110>,^d110
  4506.     %key <1200>,^d1200
  4507.     %key <150>,^d150
  4508.     %key <1800>,^d1800
  4509.     %key <2000>,^d2000
  4510.     %key <2400>,^d2400
  4511.     %key <300>,^d300
  4512.     %key <3600>,^d3600
  4513.     %key <4800>,^d4800
  4514.     %key <600>,^d600
  4515.     %key <7200>,^d7200
  4516.     %key <9600>,^d9600
  4517.     %tbend
  4518.  
  4519. $setsp:    move t3, pars3        ; Get the speed that was parsed.
  4520.     movem t3, speed        ; Record it.
  4521.     move t1, netjfn        ; Get the output terminal JFN.
  4522.     movx t2, .mospd        ; Speed to set.
  4523.     hrl t3, speed        ; Input and output speeds the same.
  4524.     MTOPR            ; Attempt to set it.
  4525.      %jserr (,r)
  4526.     setom setspd        ;[161] Flag that speed was explicitly set.
  4527.     ret
  4528.  
  4529. ; $SETTA (SET TVT-BINARY)
  4530. ;
  4531. ; Request binary-mode negotion with ARPAnet TAC.
  4532. ;
  4533. ;[129] This command added as part of edit 129.
  4534. ;
  4535. hstac:    asciz |
  4536.  SET TVT-BINARY ON or OFF
  4537.    Only for users running KERMIT-20 on an ARPANET DEC-20, signed on to a
  4538.    DEC-20 TVT (ARPANET virtual terminal), either from another ARPA host, or
  4539.    through a TAC.  SET TVT ON causes KERMIT-20 to negotiate TELNET binary mode
  4540.    during file transfer.  Without this command, file transfer through a TVT
  4541.    would not work in most cases.
  4542.  
  4543.    OFF by default.  If you normally use KERMIT-20 through a TVT, you can put
  4544.    the command SET TVT-BINARY ON into your KERMIT.INI file.
  4545.  
  4546.    CAUTION: This facility requires certain facilities in the Release 5 TOPS-20
  4547.    ARPANET monitor: TELNET binary negotiations are accepted (bug fix), and the
  4548.    monitor does NOT double the TELNET attention character (IAC, octal 377).
  4549.    This program sends IAC escape sequences to negotiate TELNET binary mode,
  4550.    and doubles any IACs that appear in data during file transfer.
  4551.  
  4552.    Further caution: setting or unsetting binary mode takes about 8 seconds.
  4553. |
  4554.  
  4555. .setta:    noise <negotiation>     ; SET TVT-BINARY
  4556.     movei t1, [flddb. .cmkey,,offon,,on]
  4557.     call rfield        ; Parse a keyword.
  4558.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  4559.     movem t2, pars3        ; Save into pars3.
  4560.     skipn definf        ;[77] In DEFINE?
  4561.      confrm            ;[77]  No, get confirmation.
  4562.     ret    
  4563.  
  4564. $setta:    move t1, pars3        ; Get the value that was parsed.
  4565.     movem t1, tvtflg    ; Save it here.
  4566.     ret            ; Done.
  4567.  
  4568.     subttl    STATISTICS command
  4569.  
  4570. ; Help text for STATISTICS
  4571.  
  4572. hstatu:    asciz |
  4573. STATISTICS
  4574.  
  4575. Give statistics about the most recent file transfer.
  4576. |
  4577.  
  4578. ; Parse rest of STATISTICS command.
  4579.  
  4580. .stat:    noise <about last file transfer> ; STATISTICS
  4581.     confrm
  4582.     ret
  4583.  
  4584. ; Execute STATISTICS command.
  4585.  
  4586. $stat:    setzm otot        ;[180]
  4587.     tmsg <
  4588.  Maximum number of characters in packet:  >
  4589.     numout rpsiz
  4590.     tmsg < received; >
  4591.     numout  spsiz
  4592.     tmsg < sent
  4593. >
  4594.     skipn t2, stdat        ;[36] If no time was spent transferring,
  4595.      jrst $statx        ;[36]  skip the rest.
  4596.     tmsg < Number of characters transmitted in >
  4597.     idivi t2, ^d3        ; Convert thirds of seconds to seconds.
  4598.     movem t2, sec        ; Save the number of seconds.
  4599.     idivi t2, ^d60        ; Divide to get minutes.
  4600.     move t4, t3        ; Save the remainder.
  4601.     jumpe t2, $stat2    ; If no minutes then don't print them.
  4602.     numout t2
  4603.     tmsg < minutes and >
  4604. $stat2:    move t2, t4        ; Get the remainder.
  4605.     jumpe t2, $stat3    ; If no seconds then don't print them.
  4606.     numout t2
  4607.     tmsg < seconds>
  4608. $stat3:    tmsg <
  4609.     Sent:      >
  4610.     numout stot
  4611.     tmsg <        Overhead:    >
  4612.     movei t1, .priou    ; Output the number of chars in decimal.
  4613.     move t2, stot
  4614.     sub t2, stchr
  4615.     addm t2, otot        ;[180]
  4616.     numout t2
  4617.     tmsg <
  4618.     Received:  >
  4619.     numout rtot
  4620.     tmsg <        Overhead:    >
  4621.     movei t1, .priou    ; Output the number of chars in decimal.
  4622.     move t2, rtot
  4623.     sub t2, rtchr
  4624.     addm t2, otot        ;[180]
  4625.     numout t2
  4626.     ;...
  4627.  
  4628. ; STATISTICS command, cont'd
  4629.  
  4630.  
  4631.     tmsg <
  4632.     Total:     >
  4633.     movei t1, .priou    ; Output the number of chars in decimal.
  4634.     move t2, rtot
  4635.     add t2, stot
  4636.     move t4, t2        ; Save the total number of chars.
  4637.     numout t2
  4638.     tmsg <        Overhead:    >
  4639.     movei t1, .priou    ; Output the number of chars in decimal.
  4640.     move t2, otot        ;[180] Get total chars.
  4641.     numout t2
  4642.     tmsg <
  4643.  Total characters transmitted per second:    >
  4644.     move t2, t4        ; Total chars transmitted.
  4645.     idiv t2, sec        ; Divided by the number of seconds.
  4646.     numout t2
  4647.     tmsg <
  4648.  Effective data rate:    >
  4649.     skipn t2, stchr        ; Is the number of chars sent zero?
  4650.      move t2, rtchr        ;  If so we were receiving.
  4651.     idiv t2, sec        ; Divided by the number of seconds.
  4652.     imuli t2, ^d10        ; Multiply chars/sec by 10 to get bits/sec.
  4653.     numout t2
  4654.     tmsg < bps>
  4655.  
  4656. ;[180]...
  4657.     tmsg <
  4658.  ILDB: >
  4659.     numout ttildb
  4660.     tmsg <  SIN:  >
  4661.     numout ttisin
  4662.     tmsg <  SIN Max:  >
  4663.     numout ttimax
  4664.     tmsg <  BIN:  >
  4665.     numout ttibin    
  4666. ;...[180]
  4667.  
  4668.     skipge speed        ;[146] Do we know the speed?
  4669.      jrst $stat4        ; No.
  4670.     fltr t2, t2        ; Yes, float the effective data rate.
  4671.     fltr t4, speed        ; And the line speed.
  4672.     fmp t2, [100.0]
  4673.     fdv t2, t4
  4674.     tmsg <
  4675.  Efficiency:            >
  4676.     movei t1, .priou    
  4677.     setz t3,
  4678.     FLOUT
  4679.      erjmp .+1    
  4680.     tmsg < per cent>
  4681. $stat4:    skipn errptr        ; Was there an error?
  4682.      jrst $statx        ;  If not, done.
  4683.     tmsg <
  4684.  Canceled by error:  >
  4685.     move t1, errptr
  4686.     PSOUT%            ; If so output it.
  4687.     hrroi t1, crlf        ;[50]
  4688.     PSOUT%
  4689.     ;...
  4690.  
  4691. ; STATISTICS command, cont'd
  4692.  
  4693.  
  4694. ;[36] Interpacket pause.
  4695.  
  4696. $statx:    tmsg <
  4697.  Interpacket pause in effect: >
  4698.     movei t1, .priou
  4699.     move t2, pause
  4700.     setz t3,
  4701.     FLOUT
  4702.      nop
  4703.     tmsg < sec
  4704.  
  4705.  Timeouts: >            ;[54] How many timeouts and NAKs.
  4706.     numout ntimou
  4707.     tmsg <
  4708.  NAKs:       >
  4709.     numout nnak
  4710.  
  4711. ;[47][132] If debugging, tell most recent JSYS error.
  4712.  
  4713.     jumpe debug, $statz    ;[132] Debugging?
  4714. $statj:    tmsg <
  4715.  Last JSYS error: >        ; Yes, tell about last error.
  4716.     movei t1, .priou
  4717.     hrloi t2, .fhslf
  4718.     setz t3,
  4719.     ERSTR
  4720.      nop
  4721.      nop
  4722.     tmsg <
  4723.  Timer errors:    >        ;[132] Also, give hints if anything is
  4724.     numout timerx        ;  going wrong with timers.
  4725.  
  4726. $statz:    tmsg <
  4727.  
  4728. >
  4729.     ret
  4730.  
  4731. ; SHOW command.
  4732.  
  4733. ; Help text...
  4734.  
  4735. hshow:    asciz |
  4736. SHOW
  4737.  
  4738. Display current SET parameters, version of KERMIT-20, or other info:
  4739.  
  4740.   DAYTIME           Current date, time, phase of moon.
  4741.   DEBUGGING         Debugging mode and log file in effect, if any.
  4742.   FILE-INFO         Byte size for DEC-20 file i/o, incomplete file disposition.
  4743.   INPUT             Parameters for INPUT command.
  4744.   LINE              TTY line, parity, duplex, handshake, escape character.
  4745.   MACROS            Definitions for SET macros.
  4746.   PACKET-INFO       For incoming and outbound packets.  Items under RECEIVE
  4747.                     column show parameters for packets KERMIT-20 expects
  4748.                     to receive, under SEND shows parameters for outgoing
  4749.                     packets.
  4750.   TIMING-INFO       Delays, retries, server NAK intervals.
  4751.   VERSION           Program version of KERMIT-20.
  4752.   ALL               (default) All of the above.
  4753. |
  4754.  
  4755. ; Parse rest of SHOW command...
  4756.  
  4757. .show:    noise <parameters>    ; SHOW command
  4758.     movei t1, [flddb. .cmkey,,shotab,,<all>] ;[39]
  4759.     call cfield        ;[39]
  4760.     hrrz t2, (t2)        ;[39]
  4761.     movem t2, pars2        ;[39]
  4762.     ret
  4763.  
  4764. shotab:    %table            ;[39] (this whole keyword table)
  4765.     %key <all>,0
  4766.     %key <daytime>,$shday
  4767.     %key <debugging>,$shdeb
  4768.     %key <file-info>,$shfil
  4769.     %key <input-info>,$shinp ;[160]
  4770.     %key <line>,$shlin
  4771.     %key <macros>,$shmac    ;[77]
  4772.     %key <packet-info>,$shpkt
  4773.     %key <timing-info>,$shtim
  4774.     %key <version>,$shver
  4775.     %tbend
  4776.     
  4777. $show:    move q1, [ret]        ;[39] Return after each piece
  4778.     skipn t2, pars2        ;[39] unless ALL was selected, in which case
  4779.      jrst [    move q1, [nop]    ;[39] fall thru from piece to piece,
  4780.         jrst $shtop ]    ;[39] starting from top.
  4781.     tmsg <
  4782. >                ;[39] Single SHOW item.  Emit blank line,
  4783.     jrst (t2)        ;[39] then go show the requested stuff.
  4784.  
  4785. $shtop: ;[39] Top of SHOW command.
  4786.  
  4787. ; SHOW VERSION
  4788.  
  4789. $shver:    tmsg <TOPS-20 Kermit version >
  4790. $shv2:    ldb t2, [301100,,versio] ; major version
  4791.     numout t2, 8
  4792.     ldb t2, [220600,,versio] ;[95]
  4793.     skipe t2        ;[95] minor version
  4794.      call [    movei t1, "."    ;[95] Use new decimal notation
  4795.         PBOUT        ;[95]
  4796.         numout t2, 8    ;[95]
  4797.         ret ]
  4798.     hrrz t3, versio        ; edit
  4799.     skipe t3
  4800.      call [    movei t1, "("
  4801.         PBOUT
  4802.         numout t3, 8
  4803.         movei t1, ")"
  4804.         PBOUT
  4805.         ret ]
  4806.     ldb t4, [410300,,versio] ; who
  4807.     skipe t4
  4808.      call [    movei t1, "-"
  4809.         PBOUT
  4810.         numout t4, 8
  4811.         ret ]
  4812.     tmsg <
  4813.  
  4814. >
  4815.     xct q1            ;[39] return or proceed...
  4816.  
  4817. ; SHOW DAYTIME
  4818.  
  4819. $shday:    movx t1, .priou        ; Current date and time.
  4820.     seto t2,        ;
  4821.     movx t3, ot%day!ot%fdy!ot%fmn!ot%4yr!ot%dam!ot%spa!ot%scl
  4822.     ODTIM%
  4823.      erjmp .+1
  4824.     call moon        ; Phase of the moon.
  4825.  
  4826.     tmsg <
  4827. >
  4828.     xct q1            ;[39] return or proceed...
  4829.  
  4830. ; SHOW LINE
  4831.  
  4832. $shlin:    tmsg <TTY for file transfer:  >
  4833.     numout ttynum, 8
  4834.     move t4, mytty        ; See whether we're local or remote...
  4835.     hrroi t1, [asciz/
  4836.  (job's controlling terminal, KERMIT-20 is REMOTE)/]
  4837.     came t4, ttynum
  4838.      hrroi t1, [asciz/
  4839.  (assigned TTY line, KERMIT-20 is LOCAL)/]
  4840.     PSOUT%
  4841.  
  4842.     move t1, netjfn        ;[130] Tell about modem control & carrier.
  4843.     call chklin
  4844.     skipn mdmlin
  4845.      jrst $show3
  4846.     tmsg <
  4847.   Line has modem control
  4848.   Carrier:          >
  4849.     hrroi t1, [asciz/On/]    ; Say it's on.
  4850.     skipn carier        ; Is it?
  4851.      hrroi t1, [asciz/Off/]    ; No.
  4852.     PSOUT            ; Tell
  4853.  
  4854. $show3:    tmsg <
  4855.   Handshake:        >        ;[76] Handshake
  4856.     skipn t1, handsh    ; Any?
  4857.      jrst [    tmsg <None>
  4858.         jrst $shw3a ]
  4859.     call putc
  4860. $shw3a:    tmsg <
  4861.   Flow-Control:     >        ;[143]
  4862.     hrroi t1, [asciz/XON-XOFF/]
  4863.     skipn flow
  4864.      hrroi t1, [asciz/None/]
  4865.     PSOUT
  4866.  
  4867. $show4:    tmsg <
  4868.   Parity:           >
  4869.     move t2, parity
  4870.     hrroi t1, [asciz/None/]
  4871.     cain t2, space
  4872.      hrroi t1, [asciz/Space/]
  4873.     cain t2, mark
  4874.      hrroi t1, [asciz/Mark/]
  4875.     cain t2, odd
  4876.      hrroi t1, [asciz/Odd/]
  4877.     cain t2, even
  4878.      hrroi t1, [asciz/Even/]
  4879.     PSOUT%
  4880.  
  4881. $sho4a:    tmsg <
  4882.   Duplex:           >        ;[18]
  4883.     move t2, duplex
  4884.     hrroi t1, [asciz/Full/]
  4885.     caie t2, dxfull
  4886.      hrroi t1, [asciz/Half/]
  4887.     PSOUT
  4888.     ;...
  4889.  
  4890. ;...SHOW LINE, cont'd
  4891.  
  4892.     tmsg <
  4893.   Speed:            >            ; Line speed.
  4894.     skipl speed        ; If negative, we don't really know it.
  4895.      numout speed
  4896.     hrroi t1, [asciz/(Unknown)/]
  4897.     skipge speed        ; If not negative, we know it.
  4898.      PSOUT
  4899.  
  4900. $sho4b:    skipn local        ;[96] Don't confuse them with this
  4901.      jrst $sho4c        ;[96]  unless they're local.
  4902.     tmsg <
  4903.   Escape:           >
  4904.     move t1, escape
  4905.     call putc
  4906.  
  4907. $sho4c:    tmsg <
  4908.   Break Simulation: >
  4909.     hrroi t1, [asciz/Enabled/]
  4910.     skipg speed
  4911.      hrroi t1, [asciz/Disabled/]
  4912.     PSOUT
  4913.     skipg speed
  4914.      jrst $sho4d
  4915.     tmsg <, >
  4916.     numout brk
  4917.     tmsg < NULs at 50 baud>
  4918.  
  4919. $sho4d: tmsg <
  4920.   TVT Binary:       >         ;[129] ARPAnet TVT binary mode.
  4921.     hrroi t1, [asciz/Off/]
  4922.     skipe tvtflg
  4923.      hrroi t1, [asciz/On/]
  4924.     PSOUT
  4925.  
  4926. $sho4e:    tmsg <
  4927.   Log:              >
  4928.     skipg t2, sesjfn    ; are we logging?
  4929.      skipl t2, savjfn    ; or toggled off?
  4930.      skipa
  4931.      jrst [    tmsg <(none)>
  4932.         jrst $sho4f ]
  4933.     movei t1, .priou    ; so print the Log file
  4934.     setzb t3, t4        ; default format, no prefix
  4935.     JFNS            ; output it
  4936.      erjmp [tmsg <(none)>
  4937.         jrst $sho4f ]
  4938.     hrroi t1, [asciz/ (on)/] ; assume toggled on
  4939.     skipg sesjfn        ; is that correct?
  4940.      hrroi t1, [asciz/ (off)/] ; no, use other message
  4941.     PSOUT            ; output it
  4942.  
  4943. $sho4f:    ;put next one here...
  4944.  
  4945. $sho4x:    tmsg <
  4946.  
  4947. >
  4948.     xct q1            ;[39] return or proceed...
  4949.  
  4950. ; SHOW FILE-INFO
  4951.  
  4952. $shfil:    tmsg <Byte size for file I/O:  >
  4953.     hrroi t1, [ASCIZ/"Auto"/]
  4954.     skipn autbyt
  4955.      jrst [    hrroi t1, [asciz/Seven-Bit/]
  4956.         skipe ebtflg
  4957.          hrroi t1, [asciz/Eight-Bit/]
  4958.         jrst .+1 ]
  4959.     PSOUT%
  4960.     tmsg <
  4961.   File name conversion: >    ;[84]
  4962.     hrroi t1, [asciz/Off/]    ;[84]
  4963.     skipe xfnflg        ;[84]
  4964.      hrroi t1, [asciz/On/]    ;[84]
  4965.     PSOUT            ;[84]
  4966.     tmsg <
  4967.   ITS-binary-format file recognition >    ;[75]
  4968.     hrroi t1, [asciz/enabled/]    ;[75]
  4969.     skipn itsflg            ;[75]
  4970.      hrroi t1, [asciz/disabled/]    ;[75]
  4971.     PSOUT                ;[75]
  4972.     tmsg <
  4973.   Disposition for incomplete incoming files: > ;[42]
  4974.     hrroi t1, [asciz/Discard/]
  4975.     skipe abtfil        ;[42]
  4976.      hrroi t1, [asciz/Keep (whatever was received)/]
  4977.     PSOUT%            ;[42]
  4978.     tmsg <
  4979.   Deleted files are >        ;[143]
  4980.     hrroi t1, [asciz/NOT /]
  4981.     skipn expung
  4982.      PSOUT
  4983.     tmsg <expunged automatically
  4984.   Transaction log file: >    ;[126]
  4985.     skipn t2, tlgjfn    ; Any?
  4986.      jrst [    hrroi t1, [asciz/ (none)/] ; No.
  4987.         PSOUT
  4988.         jrst $shflx ]
  4989.     movei t1, .priou    ; Yes, a real file,
  4990.     setz t3,        ; Say what it is.
  4991.     JFNS
  4992.      %jserr (,.+1)
  4993. $shflx:    tmsg <
  4994.  
  4995. >
  4996.     xct q1            ;[39] return or proceed...
  4997.  
  4998. ; SHOW DEBUG
  4999.  
  5000. $shdeb:    tmsg <Debugging: >
  5001.     hrro t1, [
  5002.         [asciz/Off/]
  5003.         [asciz/States/]
  5004.         [asciz/Packets/]
  5005.         ](debug)
  5006.     PSOUT%
  5007.     jumpe debug, $shdbx    ;[38]
  5008.     tmsg <
  5009.   Debugging log file: >        ;[38]
  5010.     move t2, logjfn        ;[38] Any log file?
  5011.     cail t2, 1        ;[71] 0 or -1 means none.
  5012.      caile t2, 100        ;[71] 100 or above is .priou or whatever...
  5013.      jrst [    hrroi t1, [asciz/ (none)/] ;[38] None.
  5014.         PSOUT        ;[38]
  5015.         jrst $shdbx ]    ;[38]
  5016.     movei t1, .priou    ;[38] Yes, a real file,
  5017.     setz t3,        ;[38] Say what it is.
  5018.     JFNS            ;[38]
  5019.      %jserr (,.+1)        ;[38]
  5020.     tmsg <, bytesize >    ;[41]
  5021.     numout logbsz        ;[41]
  5022. $shdbx:    tmsg <
  5023.  
  5024. >                ;[39]
  5025.     xct q1            ;[39] return or proceed...
  5026.  
  5027. ; SHOW PACKET-INFO
  5028.  
  5029. ;[100] New headings, less confusing.
  5030. ;
  5031. $shpkt:    tmsg <Packet parameters:
  5032.  
  5033.               Inbound         Outbound
  5034.   Size:            >
  5035.     numout rpsiz,^d10
  5036.     tmsg <        >
  5037.     numout spsiz,^d10
  5038.     tmsg < characters
  5039.   Padding:         >
  5040.     numout rpadn
  5041.     tmsg <        >
  5042.     numout spadn
  5043.     tmsg <
  5044.   Pad Character:   >
  5045.     move t1, rpadch
  5046.     call putc
  5047.     tmsg <        >
  5048.     move t1, spadch
  5049.     call putc
  5050. $show8:    tmsg <
  5051.   End-Of-Line:     >
  5052.     move t1, reolch
  5053.     call putc
  5054.     tmsg <        >
  5055.     move t1, seolch
  5056.     call putc
  5057.     tmsg <
  5058.   Control Prefix:  >
  5059.     move t1, rquote
  5060.     call putc
  5061.     tmsg <        >
  5062.     move t1, squote
  5063.     call putc
  5064.     ;...
  5065.  
  5066. $showa: tmsg <
  5067.   Start-Of-Packet: >
  5068.     move t1, ssthdr        ;[18]
  5069.     call putc
  5070.     tmsg <        >
  5071.     move t1, rsthdr        ;[18]
  5072.     call putc
  5073.  
  5074. ;[100] New headings for this stuff.
  5075. $shpk2:    tmsg <
  5076.  
  5077.               Requested       Used
  5078.   8th-bit Prefix:  >        ;[88] Begin addition
  5079.     skipe ebqr        ; Did our user request 8th bit prefix?
  5080.      jrst [    move t1, ebq    ; Yes.
  5081.         call putc    ; Say what it is.
  5082.         tmsg <            >
  5083.         jrst .+1 ]
  5084.     skipn ebqr
  5085.      jrst [    tmsg <(none)       > ; No, just say we'll do it if asked.
  5086.         jrst .+1 ]
  5087.     skipe ebqflg        ; Was it used during last transfer?
  5088.      jrst [    move t1, ebq    ; Looks like it, say what prefix.
  5089.         call putc
  5090.         jrst .+1 ]    ;[88] End addition
  5091.     skipn ebqflg
  5092.      jrst [    tmsg <(none)>    ; No, just say we'll do it if asked.
  5093.         jrst .+1 ]
  5094.     tmsg <
  5095.   Repeat Prefix:   >        ;[92] Begin addition
  5096.     move t1, rptq        ; What we use to flag repeat counts.
  5097.     call putc
  5098.     tmsg <        >
  5099.     skipe rptflg        ; Was it actually used?
  5100.      jrst [    move t1, rptq
  5101.         call putc
  5102.         jrst .+1 ]    ;[92] End addition
  5103.     skipn rptflg
  5104.      jrst [    tmsg <(none)    > ; No, just say we'll do it if asked.
  5105.         jrst .+1 ]
  5106.     tmsg <
  5107.   Block Check:     >        ;[98] Block check type.
  5108.     move t1, bctr
  5109.     call putc
  5110.     tmsg <        >
  5111.     numout bctu        ;[98]
  5112.  
  5113.     tmsg <
  5114.  
  5115. >
  5116.     xct q1            ;[39] return or proceed...
  5117.  
  5118. ; SHOW TIME-INFO
  5119.  
  5120. $shtim:    tmsg <Timing parameters:
  5121.  
  5122.               Receive         Send
  5123.   Timeout:         >        ;[45]
  5124.     numout rrtimo        ;[128]
  5125.     tmsg <        >
  5126.     skipg stimou        ;[45]
  5127.      jrst [    tmsg <(none)>    ;[45]
  5128.         jrst $shpau ]    ;[45]
  5129.     numout stimou
  5130.     movei t1, "-"        ;[6]
  5131.     PBOUT%            ;[6]
  5132.     numout [maxtim]        ;[6]
  5133.     tmsg < sec>
  5134. $shpau:    tmsg <
  5135.   Pause:           >        ;[36]
  5136.     movei t1, .priou    ;[36]
  5137.     move t2, rpause        ;[36]
  5138.     setz t3,        ;[36]
  5139.     FLOUT            ;[36]
  5140.      nop            ;[36]
  5141.     tmsg <        >    ;[36]
  5142.     movei t1, .priou    ;[36]
  5143.     move t2, spause        ;[36]
  5144.     FLOUT            ;[36]
  5145.      nop            ;[36]
  5146.     tmsg < sec
  5147.  
  5148. Delay before sending first packet:  >
  5149.     move t1, delay        ;[100]
  5150.     skipe local        ;[100]
  5151.      setz t1,        ;[100]
  5152.     numout t1        ;[100]
  5153.     tmsg < sec
  5154. Packet retries before timeout:      >
  5155.     numout maxtry
  5156. $showc:    tmsg <
  5157. Number of retries for init packet:  >
  5158.     numout imxtry
  5159.     skipn srvtim
  5160.      jrst $shwc2
  5161.     tmsg <
  5162. Server sends NAKs every >
  5163.     numout srvtim
  5164.     tmsg < sec while waiting for command.>
  5165. $shwc2:    skipn debug        ; No blips if debugging.
  5166.      skipn local        ; Or if not local.
  5167.      jrst $showx        ;  ...
  5168. $showd:    tmsg <
  5169.  
  5170. "." for every >            ;[4]
  5171.     numout [blip]        ;[9]
  5172.     tmsg < packets, "%" for each NAK.>
  5173. $showx:    tmsg <
  5174.  
  5175. >                ;[4]
  5176.     xct q1
  5177.  
  5178. ;[160] Show INPUT parameters
  5179. ;
  5180. $shinp:    tmsg <Parameters for INPUT commands:>
  5181.     tmsg <
  5182.   Alphabetic Case: >
  5183.     hrroi t1, [asciz/Ignored in matching/]
  5184.     skipe incase
  5185.      hrroi t1, [asciz/Observed in matching/]
  5186.     PSOUT
  5187.     tmsg <
  5188.   Default Timeout: >
  5189.     skiple indeft
  5190.      numout indeft
  5191.     hrroi t1, [asciz/ sec/]
  5192.     skiple indeft
  5193.      PSOUT    
  5194.     hrroi t1, [asciz/Infinite/]
  5195.     skipg indeft
  5196.      PSOUT
  5197.     tmsg <
  5198.   Timeout Action:  >
  5199.     hrroi t1, [asciz/Proceed with command file
  5200.  
  5201. /]
  5202.     skipe intima
  5203.      hrroi t1, [asciz/Quit from command file
  5204.  
  5205. /]
  5206.     PSOUT    
  5207.     xct q1        
  5208.  
  5209.  
  5210. ;[77] SHOW MACRO DEFINITIONS
  5211. ;
  5212. $shmac:    tmsg <Macro definitions:>
  5213.     hlrz t4, mactab        ; Anything in macro table?
  5214.     skipg t4        ; Yes, tell what.
  5215.      jrst [    tmsg < (none)
  5216. >
  5217.         jrst $shmax ]    ; No, say so.
  5218.     tmsg <
  5219. >                ; Yes, list it/them.
  5220.     movei t3, 1
  5221.  
  5222. $shma2:    movei t1, 40        ; Space
  5223.     PBOUT
  5224.     hlro t1, mactab(t3)    ; Point to macro name.
  5225.     PSOUT            ; Print it.
  5226.     tmsg < = >
  5227.     hrro t1, mactab(t3)    ; Same deal for macro body.
  5228.     PSOUT
  5229.     aos t3            ; Bump index.
  5230.     sojg t4, $shma2        ; Do for all macros in table.
  5231.     tmsg <
  5232. >
  5233. $shmax:    ret            ;[83] Last one, always want to return.
  5234.  
  5235. ; PUTC - Routine to print a single character, using ^X notation, DEL, etc.
  5236. ;
  5237. ; Call with t1/ character to print.
  5238. ;
  5239. putc:    caile t1, "~"        ; Rubout?
  5240.      jrst [ tmsg <DEL>    ;  Yes, type this?
  5241.         ret ]
  5242.     caige t1, " "        ; Is it a control char?
  5243.      jrst [ push p, t1    ;  Save the char.
  5244.         movei t1, "^"    ;  Get the control quote.
  5245.         PBOUT%
  5246.         pop p, t1
  5247.         ori t1, ^o100    ;  Turn on the non-control bit.
  5248.         jrst .+1 ]
  5249.     PBOUT%
  5250.     ret
  5251.  
  5252.     subttl    BYE command
  5253.  
  5254. hbye:    asciz |
  5255. BYE    
  5256.  
  5257. When running as a local Kermit, talking to a KERMIT server over a TTY line
  5258. specified in a SET LINE command, use the BYE command to shut down and log out
  5259. the server.  This will also close any local debugging log file and exit from
  5260. the local KERMIT.
  5261. |
  5262.  
  5263. ; Parse rest of BYE command.
  5264.  
  5265. .bye:    noise (to remote server) ; Parse rest of BYE command.
  5266.     confrm
  5267.     ret
  5268.  
  5269. ; Execute the BYE command.
  5270.  
  5271. $bye:    move t1, [point 7, [asciz/L/]]    ; An "L" for the data field.
  5272.     movei t2, "G"        ; Packet type is G.
  5273.     call srvcmd        ;[121] Send the command.
  5274.      jrst $byez        ;  Some error, don't exit.
  5275.  
  5276. ;[16] From here to end is part of edit 16.
  5277.  
  5278. $byex:    movei q1, 5        ; Try this 5 times
  5279.     movei t1, ^d750        ; Sleep a second.
  5280.     DISMS%
  5281. $byex2:    movei t1, ^d250        ; Sleep a little bit
  5282.     DISMS%
  5283.     move t1, netjfn        ; Any messages?
  5284.     SIBE%
  5285.      skipa t3, t2        ; Yes, this many characters.
  5286.      jrst $byexx        ;  No, try again.
  5287.     hrroi t2, buffer    ; Get whatever is there.
  5288.     movei t4, .chlfd
  5289.     SIN%
  5290.     setz t3,
  5291.     idpb t3, t2
  5292.     hrroi t1, buffer    ; And print it.
  5293.     PSOUT%
  5294. $byexx: sojg q1, $byex2        ; See if we want to type some more.
  5295.  
  5296.     setzm buffer        ; Zero this out, just in case.
  5297.     tmsg <...>        ; Maybe there's more, but...
  5298.     move t1, netjfn        ;  can't wait forever for it,
  5299.     CFIBF%            ;  throw the rest away.
  5300.      erjmp .+1
  5301.     setom f$exit        ;[38] Set exit flag.
  5302.  
  5303. ; Error exit
  5304.  
  5305. $byez:    setzm f$exit        ;[70] Don't exit.
  5306.     ret            ;[70]
  5307.  
  5308.     subttl    FINISH command
  5309.  
  5310.  ;[28] The FINISH command is edit 28.
  5311.  
  5312. ; Help text for FINISH command.
  5313.  
  5314. hfinis:    asciz |
  5315. FINISH
  5316.  
  5317. When running as a local Kermit, talking to a KERMIT server over a TTY line
  5318. specified in a SET LINE command, use the FINISH command to shut down the
  5319. server without logging out the remote job, so that you can CONNECT back to it.
  5320. Also, close any local debugging log file.
  5321. |
  5322.  
  5323. ; Parse rest of FINISH command.
  5324.  
  5325. .finis:    noise (remote server operation) ; Parse rest of FINISH command.
  5326.     confrm
  5327.     ret
  5328.  
  5329.  
  5330. ; Execute FINISH command.
  5331.  
  5332. $finis:    move t1, [point 7, [asciz/F/]] ; An "F" for the data field.
  5333.     movei t2, "G"        ; Packet type is G.
  5334.     call srvcmd        ; Go send the command.
  5335.      nop            ;  Ignore any failure.
  5336.     ret            ; Done.
  5337.  
  5338. hclear:    asciz |
  5339. CLEAR
  5340.  
  5341. Clear the input and output buffers of the currently selected line;
  5342. attempt to clear any XOFF condition.  Useful in local mode, when the
  5343. connection to the remote system appears to be stuck.
  5344. |
  5345. .clear:    noise <line>
  5346.     confrm
  5347.     ret
  5348.  
  5349. $clear:    call ttxon        ; Clear output buffer, send XON, etc.
  5350.     CFIBF            ; Also clear input buffer.
  5351.      erjmp r
  5352.     ret
  5353.  
  5354. hclose:    asciz |
  5355. CLOSE keyword
  5356.  
  5357. Close the specified log file, TRANSACTION, DEBUGGING, or SESSION,
  5358. and stop recording to that file.
  5359. |
  5360. ; Parse CLOSE command.
  5361.  
  5362. .close:    noise (logging of)
  5363.     movei t1, [flddb. .cmkey,,logtab] ; Parse what kind of log.
  5364.     call cfield
  5365.     hrrz t2, (t2)
  5366.     movem t2, pars2
  5367.     ret
  5368.  
  5369. ; Execute CLOSE command.
  5370.  
  5371. $close:    move t4, pars2        ; Get dispatch table offset.
  5372.     setz t1,        ; Make a zero.
  5373.     jrst @[exp $clost, $closs, $closd](t4) ; Dispatch.
  5374.  
  5375. $clost:    exch t1, tlgjfn        ; Load transaction log JFN and zero it.
  5376.     jrst $closx
  5377.  
  5378. $closs:    exch t1, sesjfn        ; Load session log JFN and zero it.
  5379.     skipg t1        ; Were we using the saved JFN?
  5380.      move t1, savjfn    ; Try that.
  5381.     setzm savjfn        ; Also zero any saved copy.
  5382.     jrst $closx
  5383.  
  5384. $closd:    exch t1, logjfn
  5385.  
  5386. $closx:    skipg t2, t1        ; Move JFN to t2 for JFNS, check for validity.
  5387.      jrst [    tmsg <
  5388. ?Logging was not being done>
  5389.         ret ]        ;  If no valid JFN, give this message.
  5390.     movei t1, "["        ; JFN looks OK - opening bracket for message.
  5391.     PBOUT
  5392.     movei t1, .priou    ; Type the filename.
  5393.     setz t3,
  5394.     JFNS
  5395.      %jserr (,r)
  5396.     move t1, t2        ; JFN back to t1 for other JSYS's.
  5397.     move t3, t2        ; Save the JFN here, too.
  5398.     RFPTR            ; Get file position.
  5399.      seto t2,        ;  On error, substitute -1.
  5400.     CLOSF            ; Close the file.
  5401.      erjmp [hrrzs t1    ; If error, check what it was.
  5402.         caie t1, clsx1    ; Already closed?
  5403.          %ermsg (,r)    ;  No, give message.
  5404.         move t1, t3    ; Yes, get the JFN back.
  5405.         RLJFN        ; Release it.
  5406.          nop        ; Ignore any errors.
  5407.         jrst .+1 ]
  5408.     tmsg < Closed, >    ; Finish the message,
  5409.     numout t2        ; including count of bytes written.
  5410.     tmsg < Byte(s) Written]>
  5411.     ret
  5412.  
  5413.     subttl    CONNECT command
  5414.  
  5415. ; Help text for CONNECT...
  5416.  
  5417.  
  5418. hconne:    asciz |
  5419. CONNECT [number]
  5420.  
  5421. Establish a terminal connection to the system connected to the octal TTY number
  5422. specified here or in the most recent SET LINE command, using full duplex
  5423. echoing and no parity unless otherwise specified in previous SET commands, and
  5424. logging the session to the file specified in the most recent LOG SESSION
  5425. command, if any.  Get back to KERMIT-20 by typing the escape character followed
  5426. by the letter C.  The escape character is Control-Backslash (^\) by default.
  5427. When you type the escape character, several single-character commands are
  5428. possible:
  5429.  
  5430. C -- Close the connection and return to KERMIT-20.
  5431. B -- Transmit a BREAK signal.
  5432. S -- Show status of the connection.
  5433. Q -- Temporarily quit logging.
  5434. R -- Resume logging.
  5435. P -- Push to a new Exec.  POP from the Exec to get back to the connection.
  5436. ^\ (or whatever you have set the escape character to be) -- Typing the escape
  5437.  character twice sends one copy of it to the connected host.
  5438.  
  5439. You can use the SET ESCAPE command to define a different escape character.
  5440. |
  5441.     ;...
  5442.  
  5443. ;...CONNECT command, cont'd
  5444.  
  5445.  
  5446. ; Parse rest of CONNECT command...
  5447.  
  5448. .conne:    noise <to tty>
  5449.     movei t1, [
  5450.      flddb. .cmnum,cm%sdh,^d8,<octal tty number to connect to>,,[
  5451.      flddb. .cmcfm,cm%sdh,,<confirm to connect to selected line>]]
  5452.     call rfield        ; Parse a tty number.
  5453.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  5454.     caie t3, .cmnum        ; Is it a number?
  5455.      ret            ;  If not it must be a confirm.
  5456.     movem t2, pars3        ; Save the tty number.
  5457.     confrm
  5458.     ret
  5459.  
  5460. ;[151] CONNECT code totally rewritten as Edit 151.  Formerly, CONNECT was
  5461. ; accomplished by running a program TTLINK in a lower fork.  Now, the code is
  5462. ; integrated into this program.  This was done for two reasons:
  5463. ;
  5464. ; 1. V6 of TOPS-20 doesn't allow multiple JFNs on the same TTY device.
  5465. ; 2. TTLINK was interrupt-driven and therefore did not work under batch.
  5466. ;
  5467. ; This method, similar to that used in Mark Crispin's TELNET program, uses
  5468. ; separate input and output forks.  It works under batch because the "pty"
  5469. ; is always "hungry".
  5470. ;
  5471. $conne:    skipe pars3        ; Did we parse a TTY number?
  5472.      call $setln        ;  If so, use that one.
  5473.     move t4, mytty        ; Find our terminal number.
  5474.     camn t4, ttynum        ; Is this number the same as requested one?
  5475.      jrst [    tmsg <
  5476. ?You can't CONNECT to your own line.
  5477.  Please use the SET LINE n command to select another line.>
  5478.         ret ]
  5479.  
  5480. ; Set up controlling TTY for talk mode, issue connect message.
  5481.  
  5482.     call ttyini        ; Init controlling TTY.
  5483.     tmsg <[KERMIT-20: Connecting to remote host over TTY> ; Type message.
  5484.     numout ttynum,^d8
  5485.     tmsg <:, type >
  5486.     movei t1, 74        ; Left pointy bracket...
  5487.     PBOUT
  5488.     tmsg <CTRL->
  5489.     move t1, escape        ; (tell escape character)
  5490.     addi t1, "A"-1
  5491.     PBOUT
  5492.     movei t1, 76        ; ...Right pointy bracket
  5493.     PBOUT
  5494.     tmsg <C to return.]
  5495. >
  5496. ; Tell about session log, if any.
  5497.  
  5498.     skipg t2, sesjfn    ; Logging?
  5499.      jrst ttsfrk        ; No.
  5500.     tmsg <[KERMIT-20: Logging to File > ; Yes, tell them now.
  5501.     movei t1, .priou    ; Type the filename.
  5502.     setz t3,
  5503.     JFNS    
  5504.      %jserr (,.+1)
  5505.     tmsg <]
  5506. >                ; End of message.
  5507.  
  5508. ; Create and start a fork to get and display input from the remote end.
  5509.  
  5510. ttsfrk:    movx t1, <cr%map!cr%cap!cr%st!netin> ; Share our map, start at NETIN.
  5511.     CFORK
  5512.      %jserr (,r)
  5513.     movem t1, ttfork    ; It's running, save fork handle.
  5514.  
  5515. ;[151] Keyboard input loop.
  5516.  
  5517. ttinch:    skipn ttfork        ; Have a fork?
  5518.      jrst $connx        ;  No, it's gone, so disconnect.
  5519.     move t1, ttyjfn        ; Get a byte from the controlling TTY.
  5520.     BIN
  5521.      %jserr (<Can't input from tty>,<.+1>) ; What could happen?
  5522.     ldb t3, [point 7, t2, 35] ; Make copy without parity.
  5523.     camn t3, escape        ; Is it the escape character?
  5524.      jrst doesc        ; Yes, go process single-char command.
  5525.     skipe duplex        ; Have to echo locally?
  5526.      call echo        ;  Yes, do.
  5527.     move t1, t2        ; Tack on desired parity.
  5528.     call @parity        ; The parity routine wants the character in t1.
  5529.     move t2, t1
  5530.     move t1, netjfn        ; Output the character to the connected TTY.
  5531.     BOUT
  5532.      %jserr (<Can't output to line>,tterr) ; If error, go check.
  5533.     jrst ttinch        ; Go back and do it again.
  5534.  
  5535. ; Error handler for connected TTY.
  5536.  
  5537. tterr:    skipn mdmlin        ; Modem controlled line?
  5538.      jrst ttinch        ;  No, go back.
  5539.     call chkli2        ; Go check for carrier.
  5540.     skipn carier        ; Still have it?
  5541.      skipa            ;  No, close the connection.
  5542.     jrst ttinch        ; Yes, keep plugging away till they disconnect.
  5543.  
  5544. ; Lost carrier, shut down the connection.
  5545.  
  5546.     tmsg <
  5547. [KERMIT-20: Lost Carrier On Remote Connection -- Returning to DEC-20]
  5548.  
  5549. >
  5550.     jrst $connx
  5551.  
  5552. ;[151] Code for receive fork.  Runs forever, asynchronously, till killed.
  5553.  
  5554. netin:     move t1, netjfn        ; Wait for input
  5555.     BIN
  5556.      %jserr (<Can't input from line>,neterr) ; Handle any errors.
  5557.     txz t2, 200        ; Strip parity.
  5558.     move t1, ttyjfn        ; Display incoming character on screen.
  5559.     BOUT            
  5560.      %jserr (<Can't output to tty>,<.+1>)
  5561.     skipg t1, sesjfn    ; Logging?
  5562.      jrst netin        ;  No, go back for more.
  5563.     BOUT            ; Yes, do that.
  5564.      %jserr (<Can't write log>,netlgx)
  5565.     jrst netin        ; Loop forever.
  5566.  
  5567. ; Error handler for session log output.
  5568.  
  5569. netlgx:    setz t1,        ; Go shut down the session log.
  5570.     call $closs    
  5571.     jrst netin    
  5572.  
  5573. ; Error handler for network TTY.
  5574.  
  5575. neterr:    skipn mdmlin        ; Modem controlled line?
  5576.      jrst netin        ;  No, go back.
  5577.     call chkli2        ; Go check for carrier.
  5578.     skipn carier        ; Still have it?
  5579.      skipa            ;  No, close the connection.
  5580.     jrst netin        ; Yes, keep plugging away till they disconnect.
  5581.  
  5582. ; Lost carrier, shut down the connection.
  5583.  
  5584. neterx:    tmsg <
  5585. [KERMIT-20: Lost Carrier On Remote Connection -- Returning to DEC-20]
  5586.  
  5587. >
  5588.     setzm ttfork        ; Zero the fork handle/flag.
  5589.     HALTF            ; Halt this fork.
  5590.     0            ; Should never get here...
  5591.  
  5592. ;[151] Escape character was typed -- Get argument.
  5593.  
  5594. doesc:    move t1, ttyjfn
  5595.     BIN            ; Escape char was typed, get argument.
  5596.     trz t2, 200        ; Strip any parity bit.
  5597.     cail t2, "a"        ; Uppercase any letter.
  5598.      caile t2, "z"
  5599.      skipa    
  5600.      subi t2, 40
  5601.     cain t2, " "        ; The null command.
  5602.      jrst ttinch        ;  ...
  5603.     cain t2, "S"        ; Status query
  5604.      jrst [    move q1, [ret]    ; Calling convention for show line.
  5605.         call $shlin    ; Go show line parameters.
  5606.         jrst ttinch ]    ; Go back for more input.
  5607.     cain t2, "C"        ; Close connection.
  5608.      jrst $connx
  5609.     cain t2,"B"        ; is it a break?
  5610.      jrst [ call brkin0    ; yes, handle it
  5611.         jrst ttinch ]    ; then continue
  5612.     cain t2, "Q"        ; Quit logging
  5613.      jrst [    call qlog
  5614.         jrst ttinch ]
  5615.     cain t2, "R"        ; Resume logging
  5616.      jrst [ call rlog
  5617.         jrst ttinch ]
  5618.     cain t2, "?"        ; Help
  5619.      jrst [    hrroi t1, [asciz\
  5620. KERMIT-20 Single-Character CONNECT-Mode Commands:
  5621.  B - Send BREAK signal
  5622.  C - Close connection
  5623.  S - Status
  5624.  P - Push to Exec
  5625.  Q - Quit logging
  5626.  R - Resume logging
  5627.  ? - This message
  5628. Type the escape character twice to send one copy of it to the remote host.
  5629.  
  5630. Escape character is "\]
  5631.         PSOUT
  5632.         move t2, escape    ; Type the escape character.
  5633.         call echo
  5634.         tmsg <".
  5635. >
  5636.         jrst ttinch ]
  5637.     ;...
  5638.  
  5639. ;[151]...DOESC, cont'd
  5640.  
  5641.  
  5642.     camn t2, escape        ; Send escape character
  5643.      jrst [    skipe duplex    ; If local echo
  5644.          call echo    ;  take care of that.
  5645.         move t1, t2
  5646.         call @parity     ; Add desired parity to it.
  5647.         move t2, t1
  5648.         move t1, netjfn    ; Send it out the link.
  5649.         BOUT        ;
  5650.          %jserr (,tterr)
  5651.         jrst ttinch ]
  5652.     cain t2, "P"        ; PUSH to Exec
  5653.      jrst [    call fixtty    ; Put TTY in normal mode.
  5654.         call push    ; Do the pushing.
  5655.         call ttyini    ; Put back in talk mode.
  5656.         tmsg <
  5657. [KERMIT-20: Back at remote host]
  5658. >
  5659.         jrst ttinch ]
  5660.     movei t1, 7        ; Anything else, just beep
  5661.     PBOUT
  5662.     jrst ttinch
  5663.  
  5664. ; Come here to restore things.
  5665. ;
  5666. ; Take care of any session log file.  We want to close it, but leave the JFN
  5667. ; around in case the logging is resumed, the program continued, etc.
  5668. ;
  5669. $connx:    skipg t2, sesjfn    ; Is a log file open?
  5670.      jrst $conx2        ;  No, go do the rest.
  5671.     tmsg <
  5672. [KERMIT-20: Closing Log File >
  5673.     movei t1, .priou    
  5674.     setz t3,    
  5675.     JFNS
  5676.      %jserr (,.+1)
  5677.     tmsg <]
  5678. >
  5679.     move t1, t2        ; Get the JFN back into t1.
  5680.     hrli t1, (co%nrj)    ; Close, but don't release JFN.
  5681.     CLOSF%            ;  ...
  5682.      erjmp [hrrzs t1    ; If error, check what it was.
  5683.         cain t1, clsx1    ; Already closed?
  5684.          jrst .+1    ;  Yes, ignore.
  5685.         setzm sesjfn    ; Some other error, so JFNs are probably
  5686.         setzm savjfn    ; unusable, zero them out,
  5687.         %ermsg (,$conx2) ] ; complain, and return.
  5688.     movei t1, (t1)        ; Closed OK, open it again to prevent CLZFF
  5689.     movx t2, <fld(7,of%bsz)+of%app>    ; from stomping on the JFN.
  5690.     OPENF
  5691.      erjmp .+1
  5692.  
  5693. $conx2:    call fixtty        ; Put controlling tty back in data mode.
  5694.     movx t1, .priin        ; Flush any pending tty input.
  5695.     CFIBF
  5696.      erjmp .+1
  5697.     skipe t1, ttfork    ; Kill receive fork.
  5698.      KFORK%
  5699.      erjmp .+1
  5700.     setzm ttfork        ; Remember it's gone.
  5701.     movei t1, .priou    ; Output a CRLF if not at left margin.
  5702.     RFPOS%    
  5703.     hrroi t1, crlf
  5704.     trne t2, -1
  5705.      PSOUT%    
  5706.     tmsg <[KERMIT-20: Connection Closed]> ; Closed message.
  5707.     ret
  5708.  
  5709. ;[151] Character echoing routine.
  5710. ;
  5711. ; Need to do this because having tty open in binary mode overrides ccoc
  5712. ; settings.  t2 contains character to echo.
  5713. ;
  5714. echo:    saveac<t1,t2,t3>    ; Must save all ACs.
  5715.  
  5716.     trz t2, 200        ; Strip any parity.
  5717.     move t3, t2        ; Make a copy of the character.
  5718.  
  5719.     cail t3, 40        ;[18] Check most common case first,
  5720.      caile t3, 126        ;[18] namely, whether it's a printable
  5721.      skipa            ;[18] character.
  5722.      jrst echo2        ;[18] If so, just go print it.
  5723.  
  5724.     caig t3, 6        ; Check for control char, null thru ^F.
  5725.      jrst echo1
  5726.     cain t3, 13        ; ^K
  5727.      jrst echo1
  5728.     cail t3, 16        ; ^N-^Z
  5729.      caile t3, 32
  5730.      skipa
  5731.      jrst echo1
  5732.     cail t3, 34        ; ^\-^_
  5733.      caile t3, 37
  5734.      skipa
  5735.      jrst echo1
  5736.     cain t3, 33        ; ESC
  5737.      jrst [    movei t2, "$"    ; Echo as dollar sign
  5738.         jrst echo2 ]
  5739.     cain t3, 177        ; DEL
  5740.      jrst [    seto t3,     ; So it echoes as ^? (100-1=77="?")
  5741.         jrst echo1 ]
  5742.     move t2, t3        ; Anything else, just type it.
  5743.     jrst echo2
  5744.  
  5745. echo1:    skipg t1, ttyjfn    ; Echo it on the tty.
  5746.      movei t1, .priou
  5747.     movei t2, "^"        ; Print an uparrow
  5748.     BOUT
  5749.       %jserr (,.+1)
  5750.     skiple t1, sesjfn    ; Logging?
  5751.      call [    BOUT        ; Yes, do that.
  5752.          %jserr (,qlog)    ;  Error, print msg, close log, rtn from there.
  5753.         ret ]        ; No error.
  5754.     movei t2, 100(t3)    ; Convert to char to uncontrollified version.
  5755. echo2:    skipg t1, ttyjfn    ; Back to TTY.
  5756.      movei t1, .priou
  5757.     BOUT            ; Print the character itself.
  5758.      %jserr (,.+1)
  5759.     skiple t1, sesjfn    ; Logging?
  5760.      call [    BOUT        ; Yes, do that.
  5761.          %jserr (,qlog)    ;  Error, print msg, close log, rtn from there.
  5762.         ret ]        ; No error.
  5763.     ret
  5764.  
  5765. ;[151] BREAK-sending routine.  Simulate by sending some nulls at
  5766. ; a low baud rate.  Originally by Bill Schilit, Columbia.
  5767. ;
  5768. brkin0:    saveac <t1,t2,t3,t4>    ; save all used registers
  5769.     skipg speed        ; do we know about a speed?
  5770.      jrst brkin2        ; no, give a message
  5771.     move t1, netjfn        ; get the output terminal jfn
  5772.     movx t2, .mospd        ; set the speed
  5773.     hrlz t3, speed        ; same input speed
  5774.     hrri t3, ^d50        ; but output is lower (input,,output speeds)
  5775.     MTOPR
  5776.      %jserr (,r)
  5777.     skipg t3, brk        ; get count of nulls to send
  5778.      movei t3, defbrk    ; use the default
  5779.     caile t3, maxnul    ; greater than we support?
  5780.      movei t3, maxnul    ; yes, use that
  5781.     movns t3        ; make negative
  5782.     move t2, [point 7,nulls] ; point to them
  5783.     setzm t4        ; no stop char
  5784.     SOUT
  5785.      %jserr (,.+1)
  5786.     movx t2, .mospd        ; now reset speed
  5787.     move t3, speed
  5788.     hrls t3            ; make input same as output
  5789.     MTOPR
  5790.      %jserr (,r)
  5791.     ret
  5792.  
  5793. brkin2:    tmsg <
  5794. [KERMIT-20: Can't send BREAK, line speed unknown -- use SET SPEED command.]
  5795. >
  5796.     ret
  5797.  
  5798. defbrk==3            ; Default number of breaks.
  5799. maxnul==100            ; Maximum number of nulls.
  5800. nulls:    repeat <maxnul/5>+1,<0>    ; A string of nulls.
  5801.  
  5802. ;[151] Quit logging session during CONNECT.
  5803.  
  5804.  
  5805. qlog:    skipg t1, sesjfn    ; Do we have a session log?
  5806.      jrst [    tmsg <
  5807. %KERMIT-20 wasn't logging this session...
  5808. >
  5809.          ret ]
  5810.     movem t1, savjfn    ; Yes, save the JFN elsewhere.
  5811.     hrli t1, (co%nrj)    ; Close the log, but don't release JFN.
  5812.     CLOSF
  5813.      erjmp .+1
  5814.     setom sesjfn        ; Signal that we're not logging.
  5815.  
  5816. ; Open the log file again, to keep the JFN from getting flushed by CLZFF.
  5817.  
  5818.     movei t1, (t1)        ; Clear out bits from left half.
  5819.     movx t2, <fld(7,of%bsz)+of%app> ; Open for appending.
  5820.     OPENF
  5821.      %jserr (, [
  5822.         setom sesjfn
  5823.         jrst .+1 ])
  5824.     tmsg <
  5825. [KERMIT-20: Quit logging]
  5826. >
  5827.     ret
  5828.  
  5829.  
  5830. ;[151] Resume logging session after a hiatus.
  5831.  
  5832. rlog:    skiple sesjfn        ; Check for this...
  5833.      jrst [ tmsg <
  5834. %KERMIT-20 already logging...
  5835. >
  5836.         ret ]
  5837.     skipg t1, savjfn    ; Get the saved log JFN back.
  5838.      jrst [    tmsg <
  5839. %KERMIT-20 wasn't logging...
  5840. >
  5841.         ret ]
  5842.  
  5843. ; A log was selected, but not active.  Just juggle the JFNs.
  5844.  
  5845.     movem t1, sesjfn    ; Put saved JFN back as the log JFN.
  5846.     setom savjfn        ; Flag that there's no saved JFN.
  5847.     tmsg <
  5848. [KERMIT-20: Resume logging]
  5849. >
  5850.     ret
  5851.  
  5852.     subttl PUSH Command
  5853.  
  5854. ;[151] Push to Exec
  5855.  
  5856. push:    seto t1,        ; Save subsystem & program names...
  5857.     move t2, [-2,,pname]
  5858.     movei t3, .jisnm
  5859.     GETJI
  5860.      erjmp .+1
  5861.     tmsg <
  5862. [KERMIT-20: PUSHing to new EXEC.]
  5863. [POP from Exec to return.]
  5864. >
  5865.     skipe t1, execf        ; Have one already?
  5866.      jrst [    txo t1, sf%con    ;  Yes, just continue it.
  5867.         SFORK
  5868.          erjmp .+1    ;  Unless it disappeared...
  5869.         jrst push3 ]
  5870.     movx t1, cr%cap        ; No, create a fork.
  5871.     CFORK
  5872.      %jserr (,r)
  5873.     movem t1, execf        ; Save its handle.
  5874.        move t2, capas        ; Mask capas with this fork's enabled ones.
  5875.     txz t2, sc%log        ; Turn off logout capability.
  5876.     txo t2, sc%gtb        ; Turn on GETAB capability (must have it...)
  5877.     skipe jobtab+.jibat    ; Under batch?
  5878.      txz t2, sc%ctc        ;  If so, don't try to enable ^C capability.
  5879.     move t3,  t2        ; Enable capabilities.
  5880.     EPCAP
  5881.      %jserr (,r)        ;  Fail if can't, since Exec must have them.
  5882.     movx t1, gj%old+gj%sht    ; Get JFN on the Exec.
  5883.     hrroi t2, [asciz/SYSTEM:EXEC.EXE.0/]
  5884.     GTJFN
  5885.      %jserr (,r)
  5886.     move t4, t1        ; Save the JFN for a sec.
  5887.  
  5888.     hrl t1, execf        ; Get the Exec into the fork.
  5889.     GET
  5890.      %jserr (,r)
  5891.     move t1, t4        ; Release the Exec's JFN, don't need it.
  5892.     RLJFN
  5893.      nop
  5894.     move t1, execf        ; Exec fork handle.
  5895. push2:    setz t2,        ; Start up the fork.
  5896.     SFRKV
  5897.      %jserr (,r)
  5898. push3:    WFORK            ; Wait for it to halt.
  5899.     dmove t1, pname        ; Restore program/subsys name.
  5900.     SETSN
  5901.      nop
  5902.     ret
  5903.  
  5904. ; Put TTY in binary mode for output only.  Still allows normal input,
  5905. ; ^C trapping, etc.
  5906. ;
  5907. ttyob:    movei t1, .priou    ; Get CCOC words
  5908.     RFCOC
  5909.     dmovem t2, myccoc    ; Save em.
  5910.     move t2, [525252525252]    ; Make all characters output
  5911.     move t3, [525252525000]    ;  with no translation.
  5912.     SFCOC
  5913.     movei t2, .morxo    ; Get tty pause-end-of-page status.
  5914.     MTOPR%
  5915.      %jserr (,.+1)
  5916.     movem t3, ttpau        ; Save it.
  5917.     movei t2, .moxof    ; Set the terminal pause end...
  5918.     movei t3, .mooff    ; to no pause on end.
  5919.     MTOPR%
  5920.      %jserr (,.+1)
  5921.     ret
  5922.  
  5923. ; Restore TTY output to condition before TTYOB was called.
  5924.  
  5925. ttyou:    movei t1, .priou    ; Restore normal tty output.
  5926.     dmove t2, myccoc
  5927.     SFCOC
  5928.      %jserr (,.+1)
  5929.     movei t2, .moxof    ; Set terminal pause end-of-page...
  5930.     move t3, ttpau        ;  to what it used to be.
  5931.     MTOPR%
  5932.      %jserr (,.+1)
  5933.     ret
  5934.  
  5935. ;[151] Set up TTY for linking, and open any logging file.
  5936.  
  5937. ttyini:    movei t1, .fhslf    ; Read current process capabilities.
  5938.     RPCAP%
  5939.     movem t3, capas
  5940.     movei t1, .priin    ; Turn off terminal page mode and data mode.
  5941.     movem t1, ttyjfn
  5942.     RFMOD            ; Get tty mode word.
  5943.     movem t2, ttymod    ; Save it, to be restored later.
  5944. ; No echo, no data mode, full duplex.
  5945.      txz t2, <tt%eco!tt%dam!tt%dum!tt%lic> ;[129] Add TT$DUM
  5946. ; No wakeup stuff, infinite width & length.
  5947.     txz t2, <tt%wkf!tt%wkn!tt%wkp!tt%wka!tt%wid!tt%len!tt%uoc>
  5948. ; No formfeed/tab/case interpretation, use XON/XOFF.
  5949.     txo t2, <tt%mff!tt%tab!tt%lca!tt%pgm>
  5950.     skipn handsh        ;[155] Doing handshake?
  5951.      skipn flow        ;[155] Doing flow control?
  5952.      txz t2, tt%pgm        ; Handshake, or no flow - don't do XON/XOFF.
  5953.     SFMOD            ; Set the bits
  5954.      %jserr (,r)
  5955.     STPAR            ; ...and the other bits...
  5956.      %jserr (,r)
  5957.     movx t1, .fhjob        ; Turn off ^C, ^O, ^T interrupts for whole job.
  5958.     RTIW
  5959.     movem t2, tiword
  5960.     tdz t2, [1b<.ticcc>+1b<.ticco>+1b<.ticct>]
  5961.     move t3, capas        ; Do we have  ^C capability?
  5962.     txne t3, sc%ctc        ; Can't do STIW if we don't...
  5963.      STIW
  5964.      %jserr (,.+1)
  5965.     call seslog        ; Open the session log file.
  5966.     ret
  5967.  
  5968. ; Open the session log file.
  5969.  
  5970. seslog:    skipg t1, sesjfn    ; Logging?
  5971.      ret            ;  No.
  5972.     movx t2, <fld(7,of%bsz)+of%app> ; Yes, open for appending.
  5973.     OPENF
  5974.      erjmp [hrrzs t1    ; Got an error, get code.
  5975.         cain t1, opnx1    ; Already open?
  5976.          ret        ;  Ignore the error.
  5977.         setzm sesjfn    ; Real error, disable logging.
  5978.         %ermsg (,r) ]
  5979.     ret
  5980.  
  5981.  
  5982. ;[151] Restore TTY parameters, turn off interrupts, and close any log file.
  5983.  
  5984. fixtty:    move t1, ttyjfn        ; Restore mode word.
  5985.     move t2, ttymod
  5986.     SFMOD            ; Do both of these...
  5987.     STPAR
  5988.     movx t1, .fhjob        ; Put tty back the way it was.
  5989.     move t2, tiword        ; put the terminal interrupt word
  5990.     move t3, capas        ; Mask capas with this fork's enabled ones.
  5991.     txne t3, sc%ctc        ; Can't do this if no ^C capability.
  5992.      STIW            ;
  5993.      %jserr (,r)
  5994.     ret
  5995.  
  5996. ;[77] DEFINE command, added as edit 77.
  5997. ;
  5998. hdefin:    asciz |
  5999. DEFINE macroname set-parameters
  6000.  
  6001. Define a "SET macro" to allow convenient association of one or more SET
  6002. parameters with a mnemonic keyword of your choice.  The set-parameters are
  6003. a list of one or more SET options, separated by commas.  If you use KERMIT-20
  6004. to communicate with several different kinds of systems, you may set up a macro
  6005. for each, for instance:
  6006.  
  6007.   DEFINE IBM PARITY MARK, DUPLEX HALF, HANDSHAKE XON, SEND PACKET-LENGTH 80
  6008.   DEFINE UNIX PARITY NONE, DUPLEX FULL, HANDSHAKE NONE
  6009.   DEFINE TELENET PARITY MARK
  6010.  
  6011. You may then type SET IBM, SET UNIX, and so forth to set all the desired
  6012. parameters with a single command.  It is convenient to include these
  6013. definitions in your KERMIT.INI file.
  6014.  
  6015. You may redefine an existing macro in the same manner as you defined it.
  6016. You can undefine an existing macro by typing an empty DEFINE command for it,
  6017. for instance:
  6018.  
  6019.   DEFINE IBM
  6020.  
  6021. Macro definitions may not include macro names.
  6022. |
  6023.  
  6024. ;...DEFIN, cont'd
  6025.  
  6026.  
  6027. .defin:    noise <SET macro named>    ; Macro definition
  6028.     movei t1, [
  6029.      flddb. .cmfld,cm%sdh,,<new macro name for combining SET options>,,[
  6030.      flddb. .cmkey,,mactab,<old macro name to delete or redefine,>]
  6031.      ]
  6032.     call rfield        ; Get the macro name
  6033.  
  6034. ; Check on space for name string.
  6035.  
  6036. .defi2:    move t2, namp        ; Get current name buffer pointer.
  6037.     movei t3, namx        ; Is it at the end of the buffer?
  6038.     caig t3, (t2)
  6039.      jrst [    tmsg <?Macro name buffer full>
  6040.         jrst cmder1 ]
  6041.  
  6042. ; Have room, align pointer to word boundary.
  6043.  
  6044. .defi3:    hlrz t4, t2        ; Is it on a word boundary?
  6045.     caie t4, 440700    
  6046.      jrst [    aos t2        ; No, put it on one.
  6047.         hrli t2, (point 7,)
  6048.         movem t2, namp
  6049.         jrst .+1 ]
  6050.     movem t2, onamp        ; Remember pointer to beginning of string.
  6051.  
  6052. ; Copy the macro name into the macro name buffer.
  6053.  
  6054.     move t1, [point 7, atmbuf] ; Copy the string out of the atom buffer.
  6055.  
  6056. .defi4:    ildb t4, t1        ; Get a character.
  6057.     idpb t4, namp        ; Copy it.
  6058.     jumpn t4, .defi4    ; Everything up to & including the first null.
  6059.  
  6060. ; Let them type CR here to undefine the macro, or else jump into the SET
  6061. ; command parser to let them define a new macro, or redefine an old one.
  6062. ;
  6063. .defi5:    noise <to SET>        ; Prompt with guide words.
  6064.     move t1, sbk+.cmptr    ; Get current pointer from comnd state block.
  6065.     movem t1, macptr    ; Save it as pointer to macro body.
  6066.  
  6067. .defi6:    setom definf        ; Flag that we're doing a DEFINE.
  6068.     movei t1, [flddb. .cmkey,,settab,,,[
  6069.      flddb. .cmcfm,cm%sdh,,<Carriage return to undefine this macro>]
  6070.      ]
  6071.     call rfield        ; Parse a keyword or a CR.
  6072.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  6073.     setom undeff        ; Assume we're undefining?
  6074.     cain t3, .cmcfm        ; Parsed a CR?
  6075.      ret            ;  Yes, so done.
  6076.     setzm undeff        ; No, we're defining after all.
  6077.     callret .set2        ; Go parse SET commands.
  6078.  
  6079. ; DEFINE command execution.
  6080.  
  6081. ; Echo back what was typed...
  6082.  
  6083. $defin:    skipe undeff        ; Define or Undefine?
  6084.      jrst $defi7        ;  Undefine, go do that.
  6085. ;[82]    move t1, onamp        ; Name
  6086. ;[82]    PSOUT
  6087. ;[82]    tmsg < = >
  6088.     move t1, macptr        ; Text
  6089. ;[82]    PSOUT
  6090.  
  6091. ; Check for room left in macro text buffer.
  6092.  
  6093.     move t3, macbp        ; Get current macro text buffer pointer.
  6094.     movei t2, macx        ; Is it at the end of the buffer?
  6095.     caig t2, (t3)
  6096.      jrst [    tmsg <?Macro text buffer full>
  6097.         ret ]
  6098.  
  6099. ; Adjust to word boundary.
  6100.  
  6101. $defi2:    hlrz t4, t3        ; Is it on a word boundary?
  6102.     caie t4, 440700    
  6103.      jrst [    aos t3        ; No, put it on one.
  6104.         hrli t3, (point 7,)
  6105.         jrst .+1 ]
  6106.     movem t3, macbp        ; This copy is to be used.
  6107.     movem t3, omacbp    ; This points to the beginning of the result.
  6108.  
  6109. ; Copy the text out of the command buffer.
  6110.  
  6111. $defi3:    ildb t4, macptr        ; Get a character.
  6112.     idpb t4, macbp        ; Copy it.
  6113.     jumpn t4, $defi3    ; Everything up to & including the first null.
  6114.     
  6115. ; Add <address of macro name,,address of body> to macro keyword table.
  6116.  
  6117. $defi4:    movei t1, mactab    ; Stick it in the macro table.
  6118.     hrlz t2, onamp        ; Address of keyword,,
  6119.     hrr t2, omacbp        ;  argument (address of body)
  6120.     TBADD            ; ...
  6121.      erjmp $defi5        ; Handle any errors below.
  6122.     ret            ; OK, done.
  6123.  
  6124.     ;...
  6125.  
  6126. ; DEFINE command, cont'd
  6127.  
  6128.  
  6129. ; TBADD got an error.
  6130.  
  6131. $defi5:    movei t1, .fhslf    ; What was it?
  6132.     GETER
  6133.     hrrzs t2
  6134.     cain t2, taddx1        ; Table full?
  6135.      jrst [    tmsg <?Macro table is full> ; Yes, give message.
  6136.         ret ]
  6137.  
  6138. ; Duplicate entry?
  6139.  
  6140. $defi6:    caie t2, taddx2        ; Duplicate?
  6141.      callret jserr0        ; No, something unforseen.  Give message.
  6142.  
  6143. ; Come here directly to undefine an existing macro.
  6144. ; First look it up.
  6145. ;
  6146. $defi7:    movei t1, mactab    ; Yes, look up its address in the kwd table.
  6147.     move t2, onamp        ; Pointer to macro name.
  6148.     TBLUK
  6149.      %jserr (,r)
  6150.     skipn undeff        ; Were we undefining?
  6151.      jrst $defi8        ;  No, don't be beastly then...
  6152.     txnn t2, tl%exm        ; Yes, found an exact match?
  6153.      jrst [    tmsg <%">    ; No, warn.
  6154.         move t1, onamp
  6155.         PSOUT
  6156.         tmsg <" not found in SET macro table>
  6157.         ret ]
  6158.  
  6159. ; Using the table index just obtained, delete the entry.
  6160.  
  6161. $defi8:    move t2, t1        ; The address we just got.
  6162.     movei t1, mactab
  6163.     TBDEL            ; Delete the old entry.
  6164.      %jserr (,r)
  6165.     skipe undeff        ; Were we undefining, or replacing?
  6166.      ret            ; Undefining, so done.
  6167.  
  6168. ; Try to add the new definition again.
  6169.  
  6170. $defi9:    hrlz t2, onamp        ; Address of keyword,,
  6171.     hrr t2, omacbp        ;  argument (address of body)
  6172.     movei t1, mactab    ; Stick it in the macro table.
  6173.     TBADD
  6174.      %jserr (,r)        ; This time really give up on error.
  6175.     ret
  6176.  
  6177. ;[125] LOG command
  6178. ;
  6179. ; LOG help text..
  6180.  
  6181. hlog:    asciz |
  6182. LOG TRANSACTIONS or SESSION or DEBUGGING (to) filespec
  6183.  
  6184. Log files are closed upon exit from KERMIT-20, or explicitly by the CLOSE
  6185. command.
  6186.  
  6187. TRANSACTIONS:
  6188.  
  6189. Direct KERMIT-20 to log transactions, such as files successfully sent or
  6190. received, files that could not be successfully sent or received, and so forth,
  6191. to the specified file.
  6192.  
  6193. SESSION:
  6194.  
  6195. Create a transcript of a CONNECT session, when running KERMIT-20 in local
  6196. mode and connected to a remote system, in the specified file.  Log is closed
  6197. when connection is closed.  Logging can be toggled by typing the connect
  6198. escape character followed by Q (Quit logging) or R (Resume logging).
  6199.  
  6200. DEBUGGING:
  6201.  
  6202. Log the selected information (STATES or PACKETS, type HELP SET DEBUG for
  6203. further information) to the specified file.  If log file not specified, then
  6204. use TTY if local, DEBUGGING.LOG if remote.  If specified, then log STATES by
  6205. default.  Also allow specification of bytesize for log file, 7 (normal,
  6206. default), or 8 (for debugging binary transfers, use FILDDT to inspect the log).
  6207. |
  6208. logtab:    %table
  6209.     %key <debugging>,2    ;[143]
  6210.     %key <session>,1
  6211.     %key <transactions>,0
  6212.     %tbend
  6213.  
  6214. .log:    noise <what>        ; Give guide word
  6215.     movei t1, [flddb. .cmkey,,logtab,,<session>] ; Parse what kind of log.
  6216.     call rfield
  6217.     hrrz t2, (t2)
  6218.     movem t2, pars2
  6219.  
  6220.     skipe t1, pars3        ; Release any piled up JFNs from reparsing
  6221.      RLJFN
  6222.      nop
  6223.  
  6224.     noise <to file>        ; Noise
  6225.     move t2, pars2
  6226.     move t1, [
  6227.         [flddb. .cmofi,,,,<TRANSACTION.LOG.-1>] ; transaction log.
  6228.         [flddb. .cmofi,,,,<SESSION.LOG.-1>] ; Default session log,
  6229.         [flddb. .cmofi,,,,<DEBUGGING.LOG.-1>] ; & debugging log.
  6230.         ](t2)        ; Note index!
  6231.  
  6232.     call rfield        ; Parse log filespec.
  6233.     movem t2, pars3        ; Stash JFN here.
  6234.     move t2, pars2        ;[143] Debugging log?
  6235.     caie t2, 2        ;[143]
  6236.      jrst [    confrm        ;[143] No, get confirmation    
  6237.         ret ]        ;[143] and return.
  6238.     noise <with file byte size> ;[41] Yes, parse the file byte size.
  6239.     movei t1, [flddb. .cmkey,,dbstab,<log-file bits per byte,>,7] ;[41]
  6240.     call rfield        ;[41] Parse it.  Defaults to 7.
  6241.     hrrz t2, (t2)        ;[41] Get result.
  6242.     movem t2, pars4     ;[41] Save it.
  6243.     noise <bits>        ;[41] Comforting noise...
  6244.     confrm
  6245.     ret
  6246.  
  6247. ; Open the desired log.
  6248.  
  6249. $log:    move t1, pars2        ; What kind of log?
  6250.     jrst @[exp $logt, $logs, $logd](t1) ; Dispatch
  6251.  
  6252.  
  6253. ;[126] Transaction log.
  6254.  
  6255. $logt:    skipe t1, tlgjfn    ; Already had one open?
  6256.      CLOSF            ;  Close it
  6257.      nop
  6258.     setzm tlgjfn        ; In case of failure.
  6259.     move t1, pars3        ; Open the log
  6260.     movx t2, of%wr!fld(7,of%bsz) ; Write access, 7-bit bytes.
  6261.     OPENF
  6262.      %jserr (,r)
  6263.     movem t1, tlgjfn    ; Save the jfn.
  6264.     hrroi t2, [asciz/KERMIT-20 Transaction Log File, /]
  6265.     setzb t3, t4
  6266.     SOUT
  6267.     seto t2,        ; Write header in log file.
  6268.     move t3, [ot%ntm!ot%day!ot%fdy!ot%fmn!ot%4yr]
  6269.     ODTIM
  6270.     hrroi t2, crlf
  6271.     setzb t3, t4
  6272.     SOUT
  6273.     hrroi t2, crlf
  6274.     setzb t3, t4
  6275.     SOUT    
  6276.     wtlog (<Opened Log: >, tlgjfn)
  6277.     ret
  6278.  
  6279. ;[126] end of addition.
  6280.  
  6281. ; Session log.
  6282.  
  6283. $logs:    move t1, pars3        ; Get JFN we parsed.
  6284.     setzm savjfn        ; Where to put this JFN when not logging.
  6285.     movx t2, <fld(7,of%bsz)!of%wr> ;[154] 7-bit bytesize, new file.
  6286.     OPENF            ; Open now, avoid being stomped by CLZFFs.
  6287.      erjmp [movei t1, (t1)    ; Got an error, get code.
  6288.         cain t1, opnx1    ; Already open?
  6289.          ret        ;  Ignore the error.
  6290.         setzm sesjfn    ; Real error, disable logging.
  6291.         %ermsg (,r) ]    ;[154](end)
  6292.     movem t1, sesjfn    ; Save the open JFN.
  6293.     ret
  6294.  
  6295. ; Debugging log.
  6296.  
  6297. $logd:    setzm logjfn        ;[38] Zero this out.
  6298.     move t1, pars3        ;[38] Get the JFN we parsed.
  6299.     move t4, pars4        ;[41] And bytesize we want.
  6300.     movem t4, logbsz     ;[41] Save bytesize for SHOW command.
  6301.     movx t2, <fld(7,of%bsz)!of%wr> ;[41] Write access, assume 7-bit.
  6302.     cain t4, 8        ;[41] 8-bit requested?
  6303.      movx t2, <fld(8,of%bsz)!of%wr> ;[41] Yes, use 8-bit bytes.
  6304.     OPENF%            ;[38]
  6305.      %jserr <Can't open log file>,r
  6306.     movem t1, logjfn     ;[38] Opened OK, save it.
  6307.     skipn debug        ;[41] Was debugging asked for?
  6308.      movei debug, 1        ;[41] Not yet, so set default debugging.
  6309.     ret
  6310.  
  6311. ; PROMPT command
  6312.  
  6313. ; PROMPT help text...
  6314.  
  6315. hpromp:    asciz |
  6316. PROMPT
  6317.  
  6318. If KERMIT-20 runs in server mode by default, typing the following command
  6319. to the TOPS-20 Exec
  6320.  
  6321.    kermit prompt
  6322.  
  6323. will start it up in interactive mode, and leave you at the "Kermit-20>" prompt.
  6324. |
  6325.  
  6326. ; Parse the rest of the PROMPT command.
  6327.  
  6328. .promp:    confrm            ; Confirm.
  6329.     ret
  6330.  
  6331. ; PROMPT command execution.
  6332.  
  6333. $promp:    setzm f$exit        ; Reset exit flag.
  6334.     ret
  6335.  
  6336.  
  6337. hpush:    asciz |
  6338. PUSH
  6339.  
  6340. Push to a DEC-20 command processor.  Get back to KERMIT with all current
  6341. settings intact by typing the Exec POP command.
  6342. |
  6343. ; Parse & execute PUSH command.
  6344.  
  6345. .push:    confrm
  6346.     ret
  6347.  
  6348. $push:    jrst push
  6349.  
  6350. ; SERVER command
  6351.  
  6352. ; Help text.
  6353.  
  6354. hserve:    asciz |
  6355. SERVER
  6356.  
  6357. Act as a server for another Kermit.  Take all further commands only from the
  6358. other Kermit.  Only works when running remotely.  After issuing this command,
  6359. escape back to your local system and issue SEND, RECEIVE or GET, REMOTE,
  6360. FINISH, BYE, or other server-oriented commands from there.  If your local
  6361. KERMIT does not have a BYE command, it does not have the full ability to
  6362. communicate with a KERMIT server in which case you shouldn't run KERMIT-20 as a
  6363. server.  If your local KERMIT does have a BYE command, use it to shut down and
  6364. log out the KERMIT server when you are done with it; otherwise, connect back to
  6365. the DEC-20, type several Control-C's to stop the server, and logout.
  6366.  
  6367. For doing nonstandard kinds of file transfer (for instance to send binary files
  6368. from a microcomputer), you must issue the appropriate SET commands before the
  6369. SERVER command.
  6370. |
  6371.  
  6372. ; Parse rest of SERVER command.
  6373.  
  6374. .serve:    confrm            ; Confirm.
  6375.     ret
  6376.  
  6377. ; Execute the SERVER command.
  6378.  
  6379. ;[144] Remove test for remote mode operation.  KERMIT-20 works fine as a
  6380. ; server over an assigned line, although the messages may look a bit strange.
  6381. ;
  6382. $serve:    call getcom        ; Go serve.
  6383. ;[137]    setzm f$exit        ;[110] Return to command mode if they ^C out.
  6384.     ret
  6385.  
  6386. ; GET remote files
  6387. ;
  6388. ;[11] This whole command is part of edit 11
  6389.  
  6390. ; GET command help text.
  6391.  
  6392. hget:    asciz |
  6393. GET [remote-filespec]
  6394.  
  6395. For use only when talking to a remote KERMIT server.
  6396.  
  6397. When running as a local KERMIT (i.e. when communicating with a remote KERMIT
  6398. over an assigned TTY line, which you have specified with the SET LINE
  6399. command), you may use the GET command to request the remote KERMIT server to
  6400. send you the specified files.  The filespec is any string that can be a legal
  6401. file specification for the remote system; it is not parsed or validated
  6402. locally.  As files arrive, their names will be displayed on your screen, along
  6403. with "." and "%" characters to indicate the packet traffic.  You may type
  6404. Control-A to get a brief status report, ^X to request that the current incoming
  6405. file be cancelled, ^Z to request that the entire incoming batch be cancelled.
  6406.  
  6407. If the remote KERMIT is not capable of server functions, then you will probably
  6408. get an error message back from it like "Illegal packet type".  In this case,
  6409. you must connect to the other Kermit, give a SEND command, escape back, and
  6410. give a RECEIVE command.
  6411.  
  6412. Syntax:  The GET command accepts an arbitrary string, terminated by a
  6413. carriage return.  The string specifies a file or files in the syntax of the
  6414. remote system.  The normal DEC-20 command characters for help (?), comment
  6415. delimitation (! and ;), and file indirection (@) are enabled at the beginning
  6416. of the field, you can only enter filenames starting with one of these
  6417. characters by "quoting" it with a Control-V, which is discarded before
  6418. sending the string to the remote system.
  6419.  
  6420. If you want to store the incoming file name with a different name than the
  6421. remote host sends it with, just type GET alone on a line; Kermit-20 will
  6422. prompt you separately for the source (remote) and destination (local)
  6423. file specification.  If more than one file arrives, only the first one will
  6424. be stored under the given name; the rest will be stored under the names
  6425. they are sent with.
  6426. |
  6427.  
  6428. ;...GET command, cont'd
  6429.  
  6430. ;[148] Rewritten to allow source & destination files specified separately.
  6431.  
  6432. .get:    noise <remote files>    ; Parse the rest of the GET command.
  6433.     setzm pars2        ; Make sure these are zero...
  6434.     setzm pars3
  6435.  
  6436.     movei t1, [flddb. .cmcfm,cm%sdh,,,,[
  6437.  flddb. .cmtxt,cm%sdh,,<Remote file specification in remote host's own syntax
  6438.  (Use CTRL-V to quote otherwise illegal characters like "!", "?", and "@"),
  6439.  or carriage return to enter source and destination names separately.>]]
  6440.  
  6441.     call rfield
  6442.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  6443.     cain t3, .cmcfm        ; Parsed a CR?
  6444.      jrst .get2        ;  Yes, go prompt.
  6445.  
  6446.     confrm            ; No, so go GET the specified file(s).
  6447.     move t1, [point 7, atmbuf] ; Let $GET know where to find the string.
  6448.     movem t1, pars2
  6449.     setzm filjfn
  6450.     ret
  6451.  
  6452. ; Prompt separately for source and destination filespecs.
  6453.  
  6454. .get2:    hrroi t1, [asciz/ Remote Source File: /] ; Prompt for remote filespec
  6455.     PSOUT
  6456.     move t1, [point 7, buffer]
  6457.     setzm buffer
  6458.     movem t1, pars2        ; Let $GET know where to find the string.
  6459.     move t2, [rd%crf+rd%bel+<MAXBUF>]
  6460.     hrroi t3, [asciz/ Remote Source File: /]
  6461.     RDTTY
  6462.      %jserr (,r)
  6463.     setz t2,        ; Write a zero over the terminating linefeed.
  6464.     dpb t2, t1
  6465.     skipn buffer        ; If they typed nothing, then skip next part.
  6466.      ret
  6467.  
  6468. ; Now get local filespec for storing the incoming file.
  6469.  
  6470. .get3:    hrroi t1, [asciz/ Local Destination File: /]
  6471.     call dpromp
  6472.     movei t1, [flddb. .cmofi]
  6473.     call cfield
  6474.     movem t2, pars3
  6475.     ret
  6476.  
  6477. ; GET command execution.
  6478.  
  6479. $get: skipe takdep        ;[176] Allow commands to servers from TAKE file
  6480.      jrst $get2
  6481.     skipe local        ; This only works if local Kermit.
  6482.      jrst $get2
  6483.     ermsg <Can't GET without prior SET LINE>, r
  6484.  
  6485. ;[148] Check for and validate local filespec.
  6486.  
  6487. $get2:    skipn local        ;[177] If we're in remote mode...
  6488.      call inilin    
  6489.     setzm filjfn        ; Assume no local file given.
  6490.     skipn t1, pars3        ; JFN of local file, if any...
  6491.      jrst $get3        ;  If none, skip this.
  6492.     DVCHR            ; Make sure it's on disk.
  6493.     txne t2, dv%typ        ; ...
  6494.      ermsg <Destination file must be on disk>, r
  6495.     move t1, pars3        ; Get this back.
  6496.     movem t1, filjfn    ; Save it here.
  6497.  
  6498. ; Handle the remote filespec.
  6499.  
  6500. $get3:    setz t3,        ; Count the characters...
  6501.     move t1, pars2        ; And move them from here
  6502.     move t2, [point 7, strbuf] ;  to here.
  6503.  
  6504. $get4:    ildb t4, t1        ; Now copy the rest.  Get a byte.
  6505.     cain t4, 26        ;[147] Control-V?
  6506.      ildb t4, t1        ;[147]  Yes, it's a quote, get next byte.
  6507.     idpb t4, t2        ; Deposit the byte.
  6508.     skipe t4        ; Null?
  6509.      aoja t3, $get4        ; No, then keep going.
  6510.     jumpe t3, [ermsg <No remote filespec given>,r] ; Yes, done, any chars?
  6511.  
  6512.     movem t3, temp2        ; Save this till after next part.
  6513.  
  6514. ; OK, they gave a remote filespec.  Send an info packet in case we want to
  6515. ; tell them to send with nonstandard parameters, like 8bq or fancy block check.
  6516.  
  6517.     setom bctone        ;[98] Force 1-char checksum.
  6518.     call sinfo        ;[100] Go send Info packet.
  6519.      ret            ;[133] Failed, give up.
  6520.     setom bctone        ;[100] In case sinfo or sinit clears this!
  6521.  
  6522. ; Parameters exchanged (perhaps), now send the R packet.
  6523.  
  6524. $get5:    move t3, temp2        ; Restore length.
  6525.     movei t1, "R"        ; Packet type is Receive-Init.
  6526.     setz t2,        ; Packet number is zero.
  6527.     move t4, [point 7, strbuf] ; Point to remote filespec.
  6528.     call spack        ; Send the packet.
  6529.      jrst $getx
  6530.     movei state, "R"    ; Sent it ok, go into receive state.
  6531.     callret $recvb
  6532.  
  6533. $getx:    ermsg <Can't send Receive-Init>,r
  6534.  
  6535.     subttl    RECEIVE command
  6536.  
  6537. ; Help text
  6538.  
  6539. hrecei:    asciz |
  6540. RECEIVE    [filespec]
  6541.  
  6542. Receive a file or file group from the other host.  If only one file is being
  6543. received, you may include the optional filespec as the name to store it under
  6544. when it arrives; otherwise, the name is taken from the incoming file header
  6545. packet.  Even if the name in the header packet is not a legal TOPS-20 file
  6546. name, KERMIT-20 will store it under that name, in which case you can refer to
  6547. it later only by quoting the illegal characters (spaces, lowercase letters,
  6548. control characters, etc) with ^V.  (You may also use SET FILE NAMING to have
  6549. KERMIT-20 pick out a more conventional name.)
  6550.  
  6551. If a file with the same name already exists, KERMIT-20 just creates a new
  6552. generation of the same name and type.
  6553.  
  6554. If running as a local Kermit, the names of the incoming files will be
  6555. displayed on your screen, along with "." and "%" characters to indicate the
  6556. packet traffic; you can type Control-A during the transfer for a brief status
  6557. report.
  6558.  
  6559. If you are asking KERMIT-20 to receive binary files from a microcomputer or
  6560. other 8-bit system, you must first type SET FILE BYTESIZE 8.  Otherwise, the
  6561. 8th bit of each byte will be lost.  For ordinary text files, no special action
  6562. is necessary.
  6563.  
  6564. If you have SET PARITY, then 8th-bit quoting will be requested.  If the other
  6565. side cannot do this, binary files cannot be transferred correctly.  In all
  6566. cases, KERMIT-20 will request the other KERMIT to compress repeated characters;
  6567. if the other side can do this (not all KERMITs know how) there may be a
  6568. significant improvement in transmission efficiency.
  6569.  
  6570. When running locally and receiving files, you can attempt to cancel the
  6571. current file by typing Control-X; this sends a cancellation request to the
  6572. remote KERMIT.  If the remote KERMIT understands this request, it will comply;
  6573. otherwise it will continue to send.  If a file group is being sent, you can
  6574. request the entire group be cancelled by typing Control-Z.
  6575.  
  6576. If running as a remote Kermit, you should escape back to your local Kermit and
  6577. give the SEND command.
  6578. |
  6579.  
  6580. ; RECEIVE command, cont'd
  6581.  
  6582.  
  6583. ; Parse a filespec or just confirmation.
  6584.  
  6585. .recv:    noise <into file>    ; First, issue noise word.
  6586.     movei t1, [
  6587.      flddb. .cmofi,cm%sdh,,<local output file specification>,,[
  6588.      flddb. .cmcfm,cm%sdh,,<confirm to use remote filespec>]]
  6589.     call rfield        ; Parse a file spec or a confirm.
  6590.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  6591.     caie t3, .cmofi        ; Is it an input file spec?
  6592.      ret            ;  If not it must be a confirm, so done.
  6593.  
  6594.     movem t2, filjfn    ; Filespec, so save the JFN,
  6595.     movei t1, [flddb. .cmcfm] ; and parse the confirmation.
  6596.     call rflde
  6597.      skipa            ; Error, handle it.
  6598.      ret
  6599.  
  6600. ; Parse error handler.
  6601.  
  6602.     skipg t1, filjfn    ; Release any JFN.
  6603.      RLJFN%
  6604.      erjmp .+1        ; Ignore any errors.
  6605.     setzm filjfn        ; Zero the JFN to indicate we don't have one.
  6606.     tmsg <?Not confirmed>    ; Issue our own parse message
  6607.     jrst cmder1        ;  and get back inside CMD to clean up.
  6608.  
  6609. ;[57] Resolve debugging status. (This made into a separate routine in edit 57).
  6610. ;
  6611. ; Call this routine at the beginning of any packet transaction (send, receive,
  6612. ; server command, etc).
  6613. ;
  6614. ; Returns +1 if there's no debugging going on
  6615. ;         +2 if there is, with the log jfn set up correctly.
  6616. ;
  6617. setlog:    jumpe debug, r        ; Return nonskip if not debugging.
  6618.     skipe t1, logjfn    ; Yes, has a log file been specified?
  6619.      jrst [    caie t1, .priou ; Yes, but is it the terminal?
  6620.          jrst rskp    ; No, it's a file, which is always OK.
  6621.         setzm logjfn    ; It's the TTY, so say no log file,
  6622.         jrst .+1 ]    ;  and do next bit.
  6623.     movei t1, .priou    ; No log file specified.
  6624.     skipe local        ; If running in local mode,
  6625.      movem t1, logjfn    ; use the terminal.
  6626.     retskp
  6627.  
  6628. ; RECEIVE, GET, REMOTE TYPE command execution.
  6629.  
  6630.  
  6631. ; Initialization -- First, stuff only for when not being a server.
  6632.  
  6633. $recv:    movei state, "R"    ; Start out in receive init state.
  6634.  
  6635. ; Entry point for server commands.
  6636.  
  6637. $recvb:    setom $recvf        ;[88] Executing RECEIVE command,
  6638.     setzm $sendf        ;[88] not SEND command.
  6639.     setzm ttildb        ;[180] (stats)
  6640.     setzm ttibin        ;[180] (stats)
  6641.     setzm ttisin        ;[180] (stats)
  6642.     setzm ttimax        ;[180] (stats)
  6643.     call caxzon        ;[62] Turn on keyboard interrupts.
  6644.     hrroi t1, [        ;[61] Tell about terminal interrupts,
  6645.      asciz/^A for status report, ^X to cancel file, ^Z to cancel batch.
  6646. /]
  6647.     skipe local        ;[62]  if local.
  6648.      PSOUT%            ;[62]
  6649.     call inilin        ; Initialize the line.
  6650.     call ccon        ; Turn on the ^C trap.
  6651.      jrst reslin         ;[27] On ^C go reset line & return from there.
  6652.     skipn gotx        ; If I don't already have an X packet,
  6653.      setzm pktnum        ;  inititialize the packet sequence number.
  6654.  
  6655. ; Entry point for server.
  6656.  
  6657. $recvs:    GTAD            ; Current date/time for start of transaction.
  6658.     movem t1, stdat
  6659.     setzm stot        ; Initialize statistics variables.
  6660.     setzm rtot
  6661.     setzb schr, stchr
  6662.     setzb rchr, rtchr
  6663.     setzm files        ;[61] File counter
  6664.     setom rptot        ;[4]  Init received-packet counter to -1.
  6665.     setom sptot
  6666.     setzm nnak        ;[54] Init the number of NAKs
  6667.     setzm ntimou        ;[54]  and the number of timeouts.
  6668.     setzm timerx        ;[132] Timer error counter.
  6669.     setzm errptr        ; Zero the error message pointer.
  6670.     setom bctone        ;[98] Force block check type to 1 initially.
  6671.  
  6672.     skipe autbyt        ;[72] Using autobyte?
  6673.      setzm ebtflg        ;[72]  If so reset eight-bit-mode flag.
  6674.     move t1, rpause        ;[36] Get the requested receive-pause interval
  6675.     movem t1, pause        ;[36]  and make it the current one.
  6676.     setzm numtry        ; Set the number of tries to zero.
  6677.  
  6678. $recva:    call setlog        ;[57] Set up any debugging log.
  6679.      nop
  6680.     ;...
  6681.  
  6682. ; RECEIVE command, cont'd
  6683.  
  6684. ; State Table Switcher
  6685.  
  6686. $recv2:    cain state, "D"        ; Are we in the data receive state?
  6687.      jrst [    call rdata    ; Yes, go read data packets.
  6688.         jrst $recv2 ]
  6689.     cain state, "F"        ; Are we in the file receive state?
  6690.      jrst [    move t1, filjfn    ;  Get the file's JFN.
  6691.         call rfile    ;  Call receive file.
  6692.         jrst $recv2 ]
  6693.     cain state, "R"        ; Are we in the receive initiate state?
  6694.      jrst [    call rinit    ;  Call receive initiate.
  6695.         jrst $recv2 ]
  6696.     cain state, "C"        ; Are we in the receive complete state?
  6697.      jrst [    movei t1, "C"
  6698.         move t2, pktnum
  6699.         call diamsg    ;[38]
  6700.         GTAD%        ;  Get the time we ended.
  6701.         subm t1, stdat    ;  Figure how long it all took.
  6702.         movei t1, .chbel ;[31] Give a beep
  6703.         skipe local    ;[31] if local
  6704.          PBOUT        ;[31]
  6705.         jrst $recvz ]    ;[88] Done.
  6706.  
  6707.     cain state, "A"        ; Are we in the receive cAncel state?
  6708.      jrst [    movei t1, "A"    ; Print diagnostic message if debugging.
  6709.         move t2, pktnum    ;  ...
  6710.         call diamsg    ;  ...
  6711.         GTAD%        ; Get the time we ended.
  6712.         subm t1, stdat    ; Figure how long it all took.
  6713.         call giveup    ; Clean up the file if necessary.
  6714.         jrst $recvz ]    ;[88] Done.
  6715.  
  6716.     movei t1, "U"        ; Undefined...
  6717.     move t2, pktnum
  6718.     call diamsg
  6719.  
  6720. $recvz:    call caxzof        ;[62] Turn off ^A,^X,^Z traps.
  6721.     call reslin        ;[88] Put the line back the way it was.
  6722.     setzm $recvf        ;[88] RECEIVE command finished.
  6723.     ret
  6724.  
  6725.     subttl receive routines
  6726.  
  6727. ; RINIT -- Receive Initiate; get other side's Send-Init packet.
  6728. ;
  6729. rinit:    saveac <q1>        ; Save this AC.
  6730.  
  6731.     skipe gots        ; Got the S packet already?
  6732.      jrst rinit3        ;  Yes, don't try to read it.
  6733.  
  6734. ; Give up if we've tried too many times, otherwise keep trying.
  6735.  
  6736.     aos q1, numtry        ; Increment the number of tries.
  6737.     caml q1, imxtry        ; Have we reached the maximum number of tries?
  6738.      jrst [    movei state, "A" ;  Change the state to cAncel.
  6739.         kermsg <Can't receive Send-Init>,r ] ;[46]
  6740.     call rpack        ; Try to get a packet.
  6741.      jrst [    move t2, pktnum    ;[53]  Failed, NAK the one we want.
  6742.         callret nak ]    ;[53]
  6743.         
  6744. ; Got a packet.  Check the type and take appropriate action.
  6745.  
  6746. rinit2:    cain t1, "E"        ;[32] Error packet?
  6747.      jrst pxerr        ;[82]  Yes, print it & cancel.
  6748.  
  6749. ; Should have the other side's Send-Init packet at this point, with T1-T4
  6750. ; containing the various pointers, counts, etc.
  6751.  
  6752. rinit3:    setzm gots        ; Clear this flag.
  6753.     move q1, t1        ; Save the packet type.
  6754.     GTAD%            ; Get the time we start.
  6755.     movem t1, stdat        ; Save it.
  6756.     caie q1, "S"        ; Got a send-init?
  6757.      jrst [    move t2, pktnum    ;  No, something else, or timed out.
  6758.         callret nak ]    ;  Just NAK the packet we wanted.
  6759.     movem t2, pktnum    ; Yes, synchronize packet numbers.
  6760.     call spar        ; Get what the other side wants us to do.
  6761.     move t4, [point 8, data] ; Tell the other side what we want
  6762. rinit4:    call rpar        ;  it to do, by returning our Send-Init
  6763.     movei t1, "Y"        ;  parameters in our ACK to its Send-Init.
  6764.     move t2, pktnum        ; Packet number.
  6765.     move t4, [point 8, data] ; The address of the data.
  6766.     call spack        ; Send our params in the acknowledgment.
  6767.      jrst rinitx
  6768.  
  6769. rinit5: call rrinit        ; Go set things up for receiving.
  6770.     
  6771. rinitz:    movei state, "F"    ; Set the state to file receive.
  6772.     ret
  6773.  
  6774. rinitx:    movei state, "A"     ; Failed, set state to cAncel.
  6775.     ret
  6776.  
  6777. ;[126] Set things up for receiving.
  6778. ;
  6779. ; This code is used by RINIT and by XSEND.
  6780. ;
  6781. rrinit:    move t2, numtry        ; Get the number of tries.
  6782.     movem t2, oldtry    ; Save it.
  6783.     setzm numtry        ; Reset the number of tries.
  6784.     aos t2, pktnum        ; Increment the packet number,
  6785.     andi t2, 77        ; modulo 100,
  6786.     movem t2, pktnum    ; and save it back.
  6787.     call ebqmsg        ; Maybe print message about 8 bit prefix.
  6788.     setzm bctone        ; Enable fancy block checks.
  6789.  
  6790. ;[126] Log the beginning of this transaction.
  6791.  
  6792.     skipe iflg        ;[134] Is this an I packet?
  6793.      ret            ;[134]  If so, skip logging.
  6794.  
  6795.     wtlog <-- Receive Begins -->
  6796.  
  6797. ; The following can be called to log ebq & bct for either send or receive.
  6798.  
  6799. rrlog: skipn t1, tlgjfn        ; Logging transactions?
  6800.      jrst rinitz        ;  No, skip ahead.
  6801.     hrroi t2, [asciz/   8th bit prefixing: /]
  6802.     setzb t3, t4
  6803.     SOUT
  6804.     hrroi t2, [asciz/Off/]
  6805.     skipe ebqflg
  6806.      hrroi t2, [asciz/On/]
  6807.     setzb t3, t4
  6808.     SOUT
  6809.     hrroi t2, [asciz/
  6810.    Block check type: /]
  6811.     SOUT
  6812.     move t2, bctu
  6813.     movei t3, ^d10
  6814.     NOUT
  6815.      nop
  6816.     hrroi t2, crlf
  6817.     setzb t3, t4
  6818.     SOUT
  6819.     ret
  6820.  
  6821. ;[89] EBQMSG
  6822. ;
  6823. ;Print warning message if 8th bit prefixing requested but won't be done.
  6824.  
  6825. ebqmsg:    skipe local        ; Local?
  6826.      jrst [    skipn ebqr    ; Yes, wanted 8th bit quoting?
  6827.          jrst .+1     ;  No, so no message will be needed.
  6828.         hrroi t1, [asciz/
  6829. %Warning: Other side won't do 8th-bit prefixing.
  6830. %Binary files will not be transmitted correctly.
  6831. /]                ; Yes,
  6832.         skipn ebqflg    ;  will other side do it?
  6833.          PSOUT        ; No, warn.
  6834.         jrst .+1 ]
  6835.     ret
  6836.  
  6837. ; RFILE - Receive File Header
  6838.  
  6839. rfile:    saveac<q1>
  6840.     setzm cxseen        ;[62] Zero ^X,^Z flags, since they apply
  6841.     setzm czseen        ;[62] on a per-file basis.
  6842.     setzm bctone        ;[99] Can't hurt... (but why do we need it????)
  6843.     move q1, numtry        ; Have we reached the maximum number of tries?
  6844.     caml q1, maxtry        ;  ...
  6845.      jrst [ movei state, "A" ; Yes, change the state to cAncel.
  6846.         kermsg <Can't receive File-Header>,r ]
  6847.     aos numtry        ; No, count this try.
  6848.     skipe gotx        ;[112] Already got an "X" packet?
  6849.      jrst rfil3t        ;[112]  Yes, so don't need to get one.
  6850.     call rpack        ; Try to get a packet.
  6851.      jrst [    move t2, pktnum    ;[53]  Failed, NAK the one we want.
  6852.         callret nak ]    ;[53]
  6853.  
  6854. rfile1:    caie t1, "S"        ; Got a packet.  What's the type?
  6855.      jrst rfile2        ;  Send-Init?  Missed our previous ACK?
  6856. rfil1a:    move q1, oldtry        ; Yes, Send-Init.  Get the number of tries.
  6857.     caml q1, imxtry        ; How many times have we tried to ACK this?
  6858.      jrst [    movei state, "A" ; Too many, change the state to cAncel.
  6859.         kermsg <Too many Send-Inits>,r ]
  6860.     aos oldtry        ; Save the updated number of tries.
  6861.     skipg q1, pktnum    ;[3] Get the present packet number.
  6862.      movei q1, 100        ;[3]  If it just wrapped around, do this.
  6863.     caie t2, -1(q1)        ; Is the packet's number one less than now?
  6864.      ret            ;  No, fail, stay in this state, keep trying.
  6865.     setzm numtry        ; OK, it's the Send-Init again.
  6866.     move t4, [point 8, data] ;[50] ...
  6867.     call rpar        ; Put our parameters in it.
  6868.     movei t1, "Y"        ; Send the ACK with our parameters again.
  6869.     move t2, pktnum        ;[47] Not for the current packet,
  6870.     sos t2            ;[47] but the previous one.
  6871.     call spack        ;  ...
  6872.      jrst @[exp rfil1a, rinitx](t1) ; Handle failures.
  6873.     ret
  6874.     ;...
  6875.  
  6876. ; RFILE, Cont'd
  6877.  
  6878.  
  6879. rfile2:    caie t1, "Z"        ; Is the packet an EOF packet?
  6880.      jrst rfile3        ;  No, try something else.
  6881. rfil2a:    move q1, oldtry        ; Yes, EOF.  How many ACKs have we sent?
  6882.     caml q1, maxtry        ; Too many?
  6883.      jrst [    movei state, "A" ; Yes, change the state to cAncel.
  6884.         kermsg <Can't ACK EOF in RFILE>,r ]
  6885.     aos oldtry        ; Save the updated number of tries.
  6886.     skipg q1, pktnum    ;[3] Get the present packet number.
  6887.      movei q1, 100        ;[3] If it just wrapped around, do this.
  6888.     caie t2, -1(q1)        ; Is the packet's number one less than now?
  6889.      ret            ;  No, then hold out for right one.
  6890.     setzm numtry        ; OK, it's the previous packet again.
  6891.     movei t1, "Y"        ; Restart count, and re-ACK it.
  6892.     setzb t3, t4        ; No data.
  6893.     call spack        ; Send the packet.
  6894.      jrst @[exp rfil2a, rfil2x](t1)
  6895.     ret
  6896.  
  6897. rfil2x: movei state, "A"    ; Set state to cAncel.
  6898.     ret
  6899.  
  6900. ; Process the remote file header
  6901.  
  6902. rfile3:    came t2, pktnum        ; Packet number OK?
  6903.      ret            ;  No, hold out for the right one.
  6904.  
  6905. ;[104] Begin change for receiving "X" packets.
  6906.  
  6907.     cain t1, "F"        ; Start of file?
  6908.      jrst rfil3k        ;  Yes.
  6909.     caie t1, "X"        ; Text header?
  6910.      jrst rfile4        ;  No.
  6911.  
  6912. rfil3t:    setzm gotx        ;[112] Reset this flag.
  6913.     setom filjfn        ; Yes, indicate this way.
  6914.     skipn local
  6915. ;[177]     jrst [    movei state, "A"
  6916. ;[177]        kermsg <Can't receive screen text in remote mode>, r ]
  6917.     jrst rfil3c        ;[177] Let it come, just don't print it.
  6918.  
  6919. ; Local, print the file name on the screen.
  6920.  
  6921.     hrroi t1, [asciz/
  6922.  /]
  6923.     PSOUT
  6924.     move t1, t4
  6925.     PSOUT
  6926.      erjmp .+1
  6927.     hrroi t1, crlf
  6928.     PSOUT
  6929.     jrst rfil3c        ; Skip past file opening stuff.
  6930.  
  6931. ;[104] End change.
  6932.  
  6933.     ;...
  6934.  
  6935. ; RFILE, Cont'd
  6936.  
  6937.  
  6938. ; Come here with normal file header.
  6939.  
  6940. rfil3k:    move t1, t4        ; Got the header we want, point to filename.
  6941.     move t2, t3        ; Get the length of the filename string.
  6942.     call makfil        ; Go get JFN on it.
  6943.      jrst [    movei state, "A" ;  Can't, set state to cAncel.
  6944.         ret ]        ; MAKFIL has already issued appropriate E pkt.
  6945.     movem t1, filjfn    ; All OK, save the JFN.
  6946.  
  6947. ; Open the file.
  6948.  
  6949.     setzm itsfil        ;[75] Assume not ITS binary file.
  6950.     setzm itscnt        ;[75] Init counter for header char matching.
  6951.     move t1, filjfn        ; Open the file.
  6952.     movx t2, fld(36,of%bsz)!of%wr ; 36-bit bytes, write access.
  6953.     OPENF%            ; Open the file (fix bytesize later).
  6954.      %jsker <Can't open file>, rfil3a ;[42] Send this + JSYS error msg.
  6955.     wtlog <Opened: >,filjfn ;[126]
  6956.     jrst rfil3b        ;[42] Opened OK, skip error handling.
  6957.  
  6958. ; Come here if the file can't be opened.
  6959.  
  6960. rfil3a:    skipe t1, tlgjfn    ;[126] Log this failure in transaction log.
  6961.      jrst [    wtlog <Can't Receive >,filjfn
  6962.         hrroi t2, [asciz/   Because: /]
  6963.         setzb t3, t4
  6964.         SOUT
  6965.         hrloi t2, .fhslf ; Tell why.
  6966.         setz t3,
  6967.         ERSTR
  6968.          nop
  6969.          nop
  6970.         hrroi t2, crlf
  6971.         setzb t3, t4
  6972.         SOUT
  6973.         jrst .+1 ]
  6974.  
  6975.     move t1, filjfn        ; Get the output JFN.
  6976.     RLJFN%            ; Release it.
  6977.      nop            ;[33] Ignore any error.
  6978.     setzm filjfn        ; Clear the JFN.
  6979.     movei state, "A"     ; Change state to cAncel.
  6980.     ret
  6981.     ;...
  6982.  
  6983. ; RFILE, Cont'd...
  6984.  
  6985. ;[66] If outputting to a file, set up the mapping page pointers.
  6986.  
  6987. rfil3b:    skiple filjfn        ;[66] JFN on a file?
  6988.      jrst [    move t1, [point 7, mappag*1000]    ;[66] Yes, point to page.
  6989.         skipe ebtflg        ;[66] Eight bit mode?
  6990.          hrli t1, (point 8,)    ;[66] Then use 8-bit bytes.
  6991.         movem t1, pagptr    ;[66] Save it here.
  6992.         setzm pagno        ;[66] Begin at file page zero.
  6993.         jrst .+1 ]
  6994.  
  6995. ; If running locally, echo filename to screen.
  6996.  
  6997.     movei t1, 7        ;[66] Remember file byte size for reporting.
  6998.     skipe ebtflg        ;[66] (this may be revised later because
  6999.      movei t1, 8        ;[66]  of ITS binary headers or similar...)
  7000.     movem t1, bytsiz    ;[66]
  7001.  
  7002.     setom rcving        ;[62] Indicate we're receiving a file.
  7003.     skipn local        ;[12] Local Kermit?
  7004.      jrst rfil3c        ;[12]  No, no terminal messages necessary.
  7005.     movei t1, .priou    ;[12] Yes, print the file name.
  7006.     RFPOS%            ;[12] First see if we need to start a new line.
  7007.     hrroi t1, crlf        ;[12]  ...
  7008.     trne t2, -1        ;[12]  ...
  7009.      PSOUT%            ;[12]
  7010.     movei t1, .priou     ;[12] Now print the file name.
  7011.     hrrz t2, filjfn        ;[12]
  7012.     setz t3,        ;[12]
  7013.     JFNS%            ;[12]
  7014.      nop            ;[12]
  7015.     movei t1, " "        ;[12]
  7016.     PBOUT%            ;[12]
  7017.  
  7018. ; ACK file header, initialize counters and go into Receive-Data state.
  7019.  
  7020. rfil3c:    movei t1, "Y"        ; Acknowledge the packet.
  7021.     move t2, pktnum        ; This packet number.
  7022.     setzb t3, t4        ; No data.
  7023.     call spack        ; Send the packet.
  7024.      jrst rfil3x
  7025.     setzm mapflg        ; Say no pages mapped in yet.
  7026.     move t2, numtry        ; Get the number of tries.
  7027.     movem t2, oldtry    ; Save it.
  7028.     setzm numtry        ; Reset the number of tries.
  7029.     aos t2, pktnum        ; Increment the packet number,
  7030.     andi t2, 77        ; modulo 100,
  7031.     movem t2, pktnum    ; and save it back.
  7032.     setz rchr,        ;[128] Initialize file character counter.
  7033.     movei state, "D"    ; Set the state to file send.
  7034.     ret
  7035.  
  7036. rfil3x:    movei state, "A"    ; On fatal errors, set the state to cAncel.
  7037.     ret
  7038.  
  7039. ;...RFILE, cont'd
  7040.  
  7041.  
  7042. ; It wasn't a File Header or EOF packet; check for other possibilities.
  7043.  
  7044. rfile4:    caie t1, "B"        ; End of transmission?
  7045.      jrst rfile5        ;  No.
  7046.     came t2, pktnum        ; Yes, but is it the right packet number?
  7047.      ret            ;  No, hold out for the right one.
  7048.     movei t1, "Y"        ; All OK, acknowledge the EOT packet.
  7049.     setzb t3, t4        ; No data.
  7050.     call spack        ; Send the packet.
  7051.      skipa state, "A"
  7052.      movei state, "C"    ; Sent ok, set state to Complete.
  7053.     move t1, netjfn        ;[158] Wait until the packet
  7054.     DOBE            ;[158]  gets all the way out.
  7055.      erjmp .+1        ;[158]
  7056.     skiple filjfn        ;[126] Were we writing to a file?
  7057.      wtlog <Receive Complete> ;[126] Yes, record in transaction log.
  7058.     ret
  7059.  
  7060. rfile5:    cain t1, "T"        ; Timer interrupt pseudo packet?
  7061.      jrst [    move t2, pktnum    ; Yes, NAK the expected packet.
  7062.         callret nak ]
  7063.     cain t1, "E"        ;[82] Error packet?
  7064.      jrst pxerr        ;[82]  Yes, print it & cancel.
  7065.  
  7066. rfilex:    ret            ;[46] Something else, just hold out...
  7067.  
  7068. ; RDATA -- Receive Data state.
  7069.  
  7070. rdata:    saveac <q1,q2>        ; Save these
  7071.     aos q1, numtry        ;[42] Too many tries for this packet?
  7072.     camle q1, maxtry    ;[42]
  7073.      kermsg <Retry count exhausted in RDATA>, rdterr
  7074.     call rpack        ; Get a packet.
  7075.      jrst [    move t2, pktnum    ;[53] Failed, NAK the one we want.
  7076.         callret nak ]    ;[53]
  7077.     caie t1, "D"        ; Got one.  Data packet?
  7078.      jrst rdata3        ;[42] No, go see what it is.
  7079.     came t2, pktnum        ; Yes, but is it the right data packet?
  7080.      jrst rdata2        ;  No.
  7081.  
  7082. ; Process a normal data packet.
  7083.  
  7084. rdok:    move t1, t4        ; Got the one we want, point to data.
  7085.     move t2, t3        ; Get the length of the data.
  7086.     call putbuf        ;[66] Write the buffer to the output file.
  7087.      kermsg <Can't write to file>,rdterr ; This error is always fatal.
  7088.     movei t1, "Y"        ; No error, acknowledge the packet we got.
  7089.     move t2, pktnum        ; This sequence number.
  7090.     setzb t3, t4        ; Assume no data.
  7091.     skipn cxseen        ;[62] Was ^X typed?
  7092.      skipe czseen        ;[62] Or ^Z?
  7093.      jrst [    move t3, [byte(8)"Z",0]    ;[62]  Yes, put a "Z"
  7094.         skipn czseen    ;[62] or
  7095.          move t3, [byte(8)"X",0] ;[62] an "X" in the
  7096.         movem t3, data    ;[62] data field of the ACK
  7097.         movei t3, 1    ;[62] (length of data is 1)
  7098.         move t4, [point 8, data] ;[62] and point to it.
  7099.         jrst .+1 ]    ;[62]
  7100.     call spack        ; Send the packet.
  7101.      jrst @[exp r, rdterr](t1) ;[60]  Handle fatal & nonfatal errors.
  7102.     move t2, numtry        ; Get the number of tries.
  7103.     movem t2, oldtry    ; Save it.
  7104.     setzm numtry        ; Reset the number of tries.
  7105.     aos t2, pktnum        ; Increment the packet number,
  7106.     andi t2, 77        ; modulo 100,
  7107.     movem t2, pktnum    ; and save it.
  7108.     ret
  7109.  
  7110.     ;...
  7111.  
  7112. ; RDATA, cont'd
  7113.  
  7114.  
  7115. ; Got a data packet, but it's the wrong one.
  7116.  
  7117. rdata2:    move q1, oldtry        ; Get the number of tries.
  7118.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  7119.      kermsg <Too many retries in RDATA2>,rdterr ; Yes.
  7120.     aos oldtry        ; Not too many, update number of tries.
  7121.     skipg q1, pktnum    ;[3]  Get the present packet number.
  7122.      movei q1, 100        ;[3]  If it just wrapped around, do this.
  7123.     caie t2, -1(q1)        ; Is it the previous packet?
  7124.      ret            ;[46] No, fail, don't change state, retry.
  7125.     setzm numtry        ; Yes, previous packet; start count over.
  7126.     movei t1, "Y"        ; Acknowledge it again.
  7127.     setzb t3, t4        ; No data.
  7128.     call spack        ; Send the ACK.
  7129.      jrst @[exp r, rdterr](t1) ;[60]  Handle fatal & nonfatal errors.
  7130.     ret            ; Otherwise return OK.
  7131.  
  7132. rdata3:    caie t1, "F"        ; File header?
  7133.      jrst rdata4        ;  Nope, try something else.
  7134.     caie t1, "X"        ; Text header?
  7135.      jrst rdata4        ;  Not that either.
  7136.     move q1, oldtry        ; Yes, "F" or "X". Get the number of tries.
  7137.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  7138.      kermsg <Can't ACK file header in RDATA3>,rdterr ; Yes, quit.
  7139.     aos oldtry        ; Not yet, update number of tries.
  7140.     skipg q1, pktnum    ;[3]  Get the present packet number.
  7141.      movei q1, 100        ;[3]  If it just wrapped around, do this.
  7142.     caie t2, -1(q1)        ;  Is the packet's number one less than now?
  7143.      ret            ;[46] No, fail, don't change state, retry.
  7144.     setzm numtry        ; Yes, so start count over.
  7145.     movei t1, "Y"        ; Acknowledge the file header again.
  7146.     setzb t3, t4        ; No data.
  7147.     call spack        ; Send the packet.
  7148.      jrst @[exp r, rdterr](t1) ;[60]  Handle fatal & nonfatal errors.
  7149.     ret            ; else try again to get data.
  7150.  
  7151. ; RDATA, cont'd
  7152.  
  7153.  
  7154. ; End Of File.
  7155.  
  7156. rdata4:    caie t1, "Z"        ; Is it an EOF?
  7157.      jrst rdata5        ;  No, try next thing...
  7158.     came t2, pktnum        ; Yes, is the packet number correct?
  7159.      ret            ;[46] No, ignore this packet, keep trying.
  7160.     jumpn t3, [        ; Was there any data in the EOF packet?
  7161.         ildb t3, t4    ; Yes, see what it is.
  7162.         caie t3, "D"    ; Code for Discard the file?
  7163.          jrst .+1     ;  No, proceed.
  7164.         call giveup    ; Yes, go "close/cancel" this one,
  7165.         jrst rdat5a ]    ;  and then proceed normally.
  7166.  
  7167.     call rdclos        ;[42] Not discarding, close the file normally.
  7168.      jrst rdterr        ;[174] If can't give up.
  7169.  
  7170. rdat4a:    aos files        ;[61] Count the file.
  7171.     hrroi t1, [asciz/[OK]/]    ;[19] Closed the file OK, make comforting msg.
  7172.     skipe local        ;[19] Print it if local.
  7173.      PSOUT%            ;[19]
  7174.  
  7175. rdat5a:    movei t1, "Y"        ; Acknowledge the eof packet.
  7176.     move t2, pktnum
  7177.     setzb t3, t4        ; normally (no data).
  7178.     call spack        ; Send the ACK.
  7179.      nop            ; On any error, just forge ahead.
  7180.  
  7181.     addm rchr, rtchr    ; Add character count for this file to total.
  7182.     setz rchr,        ; Reset for next file.
  7183.     move t2, numtry        ; Get the number of tries.
  7184.     movem t2, oldtry    ; Save it.
  7185.     setzm numtry        ; Reset the number of tries.
  7186.     aos t2, pktnum        ; Increment the packet number,
  7187.     andi t2, 77        ; modulo 100,
  7188.     movem t2, pktnum    ; and save it.
  7189.     movei state, "F"    ; Change state to "F"
  7190.     ret            ;  and go back to the state switcher.
  7191.  
  7192. ; Come here if there was a timeout or error.
  7193.  
  7194. rdata5:    cain t1, "T"        ; Timer interrupt pseudo packet?
  7195.      jrst [    movei t1, "N"    ; Yes, send a NAK.
  7196.         move t2, pktnum ;  for the expected packet.
  7197.         setzb t3, t4    ; No data.
  7198.         call spack    ; Try to send it.
  7199.          jrst rdterr    ;[46] Can't, set state to cAncel.
  7200.         ret ]        ; Return to state switcher.
  7201.     cain t1, "E"        ;[82] Error packet?
  7202.      call pxerr        ;[82]  Yes, print it, then fall thru...
  7203.     ;...
  7204.  
  7205. ;...RDATA (cont'd)
  7206.  
  7207.  
  7208. ; Handler for fatal errors reading/storing data, cancels the transfer.
  7209.  
  7210. rdterr:    call giveup        ; Go clean up the file.
  7211.     movei state, "A"    ; Change the state to cAncel.
  7212.     ret
  7213.  
  7214. ; Come here to close a partially received file.  It will be discarded or
  7215. ; kept, depending on setting of ABTFIL, i.e. SET INCOMPLETE (FILE DISPOSTION).
  7216. ;
  7217. giveup:    skipe abtfil        ;[134] Do we discard or keep?
  7218.      jrst [    wtlog <Incomplete File Kept: >, filjfn ;[134]  Keep.
  7219.         hrroi t1, [asciz/[keeping partial file]/]
  7220.         skipe local
  7221.          PSOUT
  7222.         call rdclos    ; Go close as much of it as we have.
  7223.          jrst .+1    ; Discard it if we have some problem.
  7224.         ret ]        ; Closed partial file OK.
  7225.  
  7226.     wtlog <Incomplete File Discarded: >,filjfn ;[126] Discard.
  7227.     hrroi t1, [asciz/[discarding]/]    ; Say what we're up to.
  7228.     skipe local        ; Print message if local.
  7229.      PSOUT            ;
  7230.     skipg filjfn        ; Real file?
  7231.      jrst givexx        ;  If not, done.
  7232.     call unmapo        ; Go unmap the file
  7233.      nop            ; Don't worry if we can't.
  7234.     hrrz t1, filjfn        ; Clear out any junk from left half.
  7235.     txo t1, cz%abt        ; Discarding, so cancel the file.
  7236.     CLOSF%            ; Close it.
  7237.      erjmp [move t1, filjfn ; On any error,
  7238.         RLJFN        ;  at least try to release the JFN.
  7239.          erjmp givexx    ;  ...
  7240.         jrst givexx ]
  7241.  
  7242. givexx:    setzm filjfn        ; Say we have no file.
  7243.     ret
  7244.  
  7245. ; UNMAPO - Clean up the file mapping page for an output file.
  7246. ;
  7247. ; Returns +1 on failure, +2 on success.
  7248. ;  On failure, an error packet is sent, which cancels the transfer.
  7249. ;
  7250. ; Uses t1,t2,t3.
  7251. ;
  7252. ; Note that unmapping the memory page also makes it disappear.  The next write
  7253. ; to the page will create a fresh page with all 0's.
  7254. ;
  7255. ; The trick at the beginning catches the case where the page has already been
  7256. ; unmapped because we just filled in the last byte.  Since this routine is
  7257. ; called both by the page filler (PUTCH) and by the file closer (RDCLOS, to
  7258. ; catch a final partial page), we must worry about files that end on a page
  7259. ; boundary.  Putting an ERJMP after any instruction that references memory will
  7260. ; catch "illegal memory read" errors, and will thus prevent us from attempting
  7261. ; to unmap a page that has already been unmapped and still has not been
  7262. ; written into.
  7263.  
  7264. unmapo:    move t1, mappag        ;[66] Has the page been used at all?
  7265.      erjmp rskp        ;[66]  No, done.
  7266.  
  7267.     movx t1, <.fhslf,,mappag> ; Yes, map them out, our fork,,mapping page
  7268.     hrl t2, filjfn        ;  file JFN,,...
  7269.     hrr t2, pagno        ;  ...page file page number.
  7270.     movx t3, pm%rd!pm%wr    ; Read and write access.
  7271.     PMAP%            ; Map it out.
  7272.      %jsker (,r)        ;  Can't - fail.
  7273.     retskp
  7274.  
  7275. ; RDCLOS -- Close the output file, update the FDB, etc...
  7276. ; Return +1 on error, +2 on success.
  7277.  
  7278. rdclos:    skipg filjfn        ;[103] Output was to a real file?
  7279.      jrst rdclsz        ;[103]  No, skip all this.
  7280.     call unmapo        ; First, clean out the PMAPping page.
  7281.      ret            ;  Oops, failed, pass it along...
  7282.  
  7283. ; Now close the file.
  7284.  
  7285. rdclsa:    movx t1, co%nrj        ; Flag for not releasing JFN.
  7286.     hrr t1, filjfn        ; Get the JFN.
  7287.     CLOSF%            ; Close it.
  7288.      %jsker <Can't close file>,r ; Return error.
  7289.  
  7290. ; Update FDB information about byte size, number of bytes.
  7291.  
  7292.     hrli t1, .fbsiz        ; OK, now fix FDB.  Set the number of bytes
  7293.     txo, t1, cf%nud        ; Don't update disk yet.
  7294.     hrr t1, filjfn        ; Move in the JFN.
  7295.     seto t2,        ; Change all bits in the word.
  7296.     move t3, rchr        ; The number of bytes in the file.
  7297.     CHFDB%
  7298.      erjmp .+1        ; Keep going if we get an error.
  7299.  
  7300. rdclsb:    hrli t1, .fbbyv        ; Set the byte size.
  7301.     hrr t1, filjfn
  7302.     movx t2, fb%bsz        ; Byte size field mask.
  7303.     movx t3, fld(7,fb%bsz)    ; Value
  7304.     skipn itsfil        ;[75] ITS binary file?
  7305.      skipe ebtflg        ; Or eight-bit mode?
  7306.      movx t3, fld(8,fb%bsz)    ; Set it that way, then.
  7307.     ldb t4, [pointr (t3,fb%bsz)] ; Get the bytesize in t4 as a number.
  7308.     CHFDB%
  7309.      erjmp .+1        ; Keep going if we get an error.
  7310.     ;...
  7311.  
  7312. ;...RDCLOS, cont'd
  7313.  
  7314.  
  7315. ;[126] Take care of any transaction logging.
  7316.  
  7317.     skiple filjfn        ; Real file?
  7318.      skipg t1, tlgjfn    ; Transaction log?
  7319.      jrst rdclsc        ;  No, skip this.
  7320.     hrroi t2, [asciz/   Written: /] ; Yes, log this info.
  7321.     push p, t4
  7322.     setzb t3, t4
  7323.     SOUT
  7324.      erjmp .+1
  7325.     move t2, rchr        ; Number of bytes.
  7326.     movei t3, ^d10
  7327.     NOUT
  7328.      erjmp .+1
  7329.     movei t2, 40        ; A space
  7330.     BOUT
  7331.      erjmp .+1
  7332.     pop p, t2        ; Byte size
  7333.     NOUT
  7334.      erjmp .+1
  7335.     hrroi t2, [asciz/-bit bytes
  7336. /]
  7337.     setz t3,
  7338.     SOUT
  7339.      erjmp .+1
  7340.  
  7341. ; Finish closing the output file by releasing its JFN.
  7342.  
  7343. rdclsc:    skiple filjfn        ;[126]
  7344.      wtlog <Closed: >,filjfn ;[126] Transaction log message.
  7345.     hrrz t1, filjfn        ; Release the JFN.
  7346.     RLJFN%
  7347.      nop
  7348. rdclsz:    setzm filjfn        ; Say we have no more file.
  7349.  
  7350.     retskp
  7351.  
  7352.     subttl    Utility protocol routines
  7353.  
  7354.  
  7355. ; SPAR - Get the arguments from a Send-Init packet.
  7356. ;
  7357. ;[47] Substitute them for our own unless we have given our own SET commands.
  7358. ;[47] The way this is done here is less than perfect, but will work most of
  7359. ;[47] the time (it won't work if the user SETs a value to be the same as the
  7360. ;[47] default, or if the remote sends different parameters each time, or...
  7361. ;[47] But it's better than it was before.  If it becomes an issue, we can
  7362. ;[47] add flags for each value saying who changed it, and figure out when
  7363. ;[47] to set it back to the default, etc...
  7364. ;
  7365. ;[50] Call with:
  7366. ;[50]  t3/ Length of Send-Init packet data field (number of parameters)
  7367. ;[50]  t4/ Pointer to Send-Init packet data field.
  7368. ;[50] The ACs t3-t4 are automatically set up this way upon return from RPACK,
  7369. ;[50] provided nothing has been done to them before calling SPAR.
  7370. ;
  7371. spar:    saveac<q1>        ;[48]
  7372.  
  7373. ; Packet Size
  7374.  
  7375. spar1:    move t2, spsiz        ;[168] Get current setting.
  7376.     sojl t3, spar1a        ;[100] Make sure the field is in packet.
  7377.     ildb t2, t4        ; It is, get it.
  7378.     subi t2, " "        ; Convert it to a number.
  7379. spar1a:    move q1, spsiz        ;[47] See what we have now.
  7380.     caie q1, dspsiz        ;[47] Has default been changed already?
  7381.      jrst spar2        ;[47] Yes, probably by SET command, keep that.
  7382.     caige t2, spmin        ;[47] No, check bounds for new value.
  7383.      movei t2, spmin    ;[47] If too small, use our minimum.
  7384.     caile t2, spmax        ;[47] Or if too great,
  7385.      movei t2, spmax    ;[47] use our maximum value.
  7386.     movem t2, spsiz        ; Set the maximum packet size to send.
  7387.  
  7388. ; Timeout.
  7389.  
  7390. spar2:    move t2, stimou        ;[168] Get current setting.
  7391.     sojl t3, spar2a        ;[100] Got a packet field for this?
  7392.     ildb t2, t4        ; Yes, get it.
  7393.     subi t2, " "        ; Convert the character to a number.
  7394. spar2a:    skipge t2        ;[49][168]  Make sure it's
  7395.      setz t2,        ;[43] not negative.
  7396.     move q1, stimou        ;[47] Has the default already been changed,
  7397.     caie q1, dstim        ;[47] for instance, by a SET command?
  7398.      jrst spar3        ;[47]  Yes it has, so let that take precedence.
  7399.     cain t2, rtimou        ;[131] Same as other side's timeout?
  7400.      aos t2            ;[131] If so, make it a little bit different.
  7401.     movem t2, stimou    ; Set the time out interval.
  7402.     movem t2, otimou    ;[26] Here too, in case we want to change it.
  7403.     ;...
  7404.  
  7405. ; SPAR, cont'd
  7406.  
  7407. ; Padding
  7408.  
  7409. spar3:    move t2, spadn        ;[100][168] Set up default.
  7410.     sojl t3, spar3a        ;[100] Make sure the field is there.
  7411.     ildb t2, t4        ; Get the 3rd field.
  7412.     subi t2, " "        ; Convert it to a number.
  7413. spar3a:    move q1, spadn        ;[47][168] Check if default already changed.
  7414.     caie q1, dspadn        ;[47]
  7415.      jrst spar4        ;[50] It has, don't do this.
  7416.     skipge t2        ;[50] Make sure the number makes sense.
  7417.      movem t2, spadn    ;[50] OK, set the padding.
  7418.  
  7419. ; Pad character
  7420.  
  7421. spar4:    move t2, spadch        ;[100][168] Set up default.
  7422.     sojl t3, spar4a        ;[100] Make sure the field is there.
  7423.     ildb t2, t4        ; Get the 4th field.
  7424.     addi t2, ^o100
  7425.     andi t2, ^o177
  7426. spar4a:    move q1, spadch        ;[47][168] Check for default already changed.
  7427.     caie q1, dspad        ;[50]
  7428.      jrst spar5        ;[50]
  7429.     cain t2, 177        ;[50] DEL?
  7430.      jrst spar4a        ;[50]  Yes, can use it.
  7431.     cail t2, 0        ;[50] No, some other control character?
  7432.      caile t2, 37        ;[50]  ...
  7433.      skipa            ;[50]  Nope, reject it.
  7434.      movem t2, spadch    ; OK, set the padding char.
  7435.  
  7436. ; End Of Line
  7437.  
  7438. spar5:    move t2, seolch        ;[168] Set up default.
  7439.     sojl t3, spar5a        ;[100] Make sure the field is there.
  7440.     ildb t2, t4        ; Get the 5th field.
  7441.     subi t2, " "        ; Convert it to a number.
  7442. spar5a:    move q1, seolch        ;[47][168] Default changed already?
  7443.     caie q1, dseol        ;[47]
  7444.      jrst spar6        ;[50]  Yes, so don't do this.
  7445.     cail t2, 0        ;[50] No, did they give a control character?
  7446.      caile t2, 37        ;[50]  ...
  7447.      skipa            ;[50]  Nope, reject it.
  7448.      movem t2, seolch    ; OK, in range, set the EOL character.
  7449.  
  7450. ; Control Prefix
  7451.  
  7452. spar6:    move t2, rquote        ;[168][132][100] Get current setting.
  7453.     sojl t3, spar6a        ;[100] Make sure the field is there.
  7454.     ildb t2, t4        ; Get the 6th field.
  7455. spar6a:    move q1, rquote        ;[168][132][47] Default already changed?
  7456.     caie q1, drquot        ;[132][50]
  7457.      jrst spar7        ;[50]  Yes, don't change it again.
  7458.     caile t2, " "        ;[50] No, check for printable character
  7459.      caile t2, "~"        ;[50]  other than space.
  7460.      skipa            ;[50]  Out of range, reject it.
  7461.      movem t2, rquote    ;[132] OK, set the quote character.
  7462.     ;...
  7463.  
  7464. ;...SPAR, cont'd
  7465.  
  7466. ; [88] 8th-bit prefix support added as edit 88.
  7467.  
  7468. spar7:    sojl t3, spar7x        ; Did they give one?  If not, do default.
  7469.     ildb t2, t4        ; They did, get it.
  7470.     caie t2, "Y"        ; Is it WILL?
  7471.      jrst spar7a        ;  No, go check for WON'T.
  7472.  
  7473. ; Other side sent "Y" (WILL).
  7474.  
  7475.     skipe ebqr        ; Did our user request prefixing?
  7476.      jrst [    move t2, ebq    ;[89]  Yes, use the specified prefix.
  7477.         movem t2, ebqfld ; Put it here to be sent to other side.
  7478.         setom ebqflg    ; Flag that we're doing this.
  7479.         cain t2, "N"    ; But did she request NOT to do it?
  7480.          setzm ebqflg    ;  In that case, don't.
  7481.         jrst spar8 ]
  7482.     jrst spar7x        ; Didn't request it, so DON'T.
  7483.  
  7484. ; Other side sent "N" (WON'T).
  7485.  
  7486. spar7a:    cain t2, "N"        ; Is it WON'T?
  7487.      jrst spar7x        ;[89] Yes, so DON'T.
  7488.  
  7489. ; Not "Y" or "N".  See if it's a valid prefix character.
  7490.  
  7491. spar7b:    call prechk        ; Call the prefix checking routine.
  7492.      jrst spar7x        ;  It's not valid.
  7493.  
  7494. ; Other side sent valid prefix character.
  7495.  
  7496. spar7c:    skipe $sendf        ;[89] Sending?
  7497.      jrst [    camn t2, ebq    ;[89] Yes, matches what we said?
  7498.          jrst spar7d    ;[89]  Yes, go ahead.
  7499.         move q1, ebqfld    ;[89] No, but...
  7500.         caie q1, "Y"    ;[89]  if this was "Y", then it's still OK.
  7501.          jrst spar7x    ;[89] Otherwise, forget it.    
  7502.         jrst .+1 ]    ;[89]
  7503.  
  7504. ; Got &/Y, Y/&, or &/& combination, so may be OK to do 8-bit prefixing.
  7505.  
  7506. spar7d:    caie t2, rquote        ; Same as one of the control quotes?
  7507.     cain t2, squote
  7508.      jrst [ movei t2, "N"    ;  One of those, must refuse.
  7509.         jrst spar7y ]
  7510.     movem t2, ebq        ; Unique, so save it as the 8b prefix.
  7511.     movei t2, "Y"        ; Acknowledge that we will use it.
  7512.     movem t2, ebqfld    ;   ...
  7513.     setom ebqflg        ; Set the flag saying we must do this.
  7514.     jrst spar8        ; On to next field.
  7515.  
  7516. ; Field was none of the above.  Take default action.
  7517.  
  7518. spar7x:    movei t2, "Y"        ; What we normally say.
  7519. spar7y:    movem t2, ebqfld    ; Put it where RPAR can find it.
  7520.     setzm ebqflg        ; No 8th-bit prefixing.
  7521.  
  7522. ; [88] (End of addition) ....
  7523.  
  7524. ;...SPAR, cont'd
  7525.  
  7526. ;[98] Block check type. (This section added as part of edit 98)
  7527.  
  7528. spar8:    movei t2, "1"        ;[100] Set default, in case this field omitted.
  7529.     sojl t3, spar8a        ;[100] See if there is one.
  7530.     ildb t2, t4        ; Here it is...
  7531.     cail t2, "1"        ; Between 1
  7532.      caile t2, "3"        ;  and 3?
  7533.      movei t2, "1"        ;  No, substitute default value.
  7534.     skipe $sendf        ; I'm sending?
  7535.      jrst [    came t2, bctr    ;  Yes, does this match what I requested?
  7536.          movei t2, "1"    ;  No, so fall back to default.
  7537.         jrst .+1]
  7538. spar8a:    movem t2, bctr        ; Save as block check type requested.
  7539.     subi t2, "0"        ; Convert to a number 1-3,
  7540.     movem t2, bctu        ; and save as block check type to be used.
  7541.  
  7542. ;...SPAR, cont'd
  7543.  
  7544.     
  7545. ; [92] Repeat count prefix support added as edit 92.
  7546.  
  7547. spar9:    sojl t3, spar9x        ; If they didn't give one, don't do this.
  7548.     ildb t2, t4        ; They did, see what it is.
  7549.         
  7550. ; Is it a valid prefix character?
  7551.  
  7552. spar9b:    call prechk        ; Call the prefix checking routine.
  7553.      jrst spar9x        ;  It's not valid.
  7554.  
  7555. ; Other side sent valid prefix character.
  7556.  
  7557. spar9c:    skipe $sendf        ; I'm sending?
  7558.      jrst [    caie t2, rptq    ; Yes, see if theirs matches what I said.
  7559.          jrst spar9d    ;  It does, proceed.
  7560.         jrst spar9x ]    ; It doesn't, don't do repeat counts.
  7561.  
  7562. ; Got a valid prefix, but make sure it's not already in use.
  7563.  
  7564. spar9d:    caie t2, rquote        ; Same as one of the control quotes?
  7565.      cain t2, squote
  7566.      jrst spar9y
  7567.     skipe ebqflg        ; Doing 8th-bit prefixing?
  7568.      caie t2, ebq        ; Yes, check that prefix too.
  7569.      skipa            ; It's OK.
  7570.      jrst spar9x        ; It's the same, don't do repeat counts.
  7571.  
  7572. ; OK, it's valid, it's unique.
  7573.  
  7574. spar9e:    movem t2, rptq        ; Save it as what we'll be using.
  7575.     movem t2, rptfld    ; What we'll reply, in case we're receiving.
  7576.     setom rptflg        ; Set the flag.
  7577.     jrst spar10        ; Go on to next field.
  7578.  
  7579. ; Come here if we're not going to do repeat counts.
  7580.  
  7581. spar9x:    movei t2, " "        ; Blank means default which is no repeat count.
  7582. spar9y:    movem t2, rptfld    ; Put it here to reply in case we're receiving,
  7583.     setzm rptflg        ; and flag that we're not going to do it.
  7584.  
  7585. ; [92] (End of addition)
  7586.  
  7587.     ;...
  7588.  
  7589. ;...SPAR, cont'd
  7590.  
  7591. ; [ 179] Capabilities mask, window size (not supported), and long packet size.
  7592.  
  7593. spar10:    sojl t3, sparx        ; [179] This field present?
  7594.     ildb t2, t4        ; [179] Yes, get it.
  7595.     subi t2, " "        ; [179] Convert it to a number.    
  7596.     trnn t2, 2        ; [179] Long Packets capability on?
  7597.      jrst sparx        ; [179] No, done.
  7598.     sojl t3, sparx        ; [179] Skip Window size
  7599.     ildb t2, t4        ; [179] ...
  7600.     sojl t3, sparx        ; [179] Big part
  7601.     ildb t1, t4        ; [179] ...
  7602.     subi t1, " "        ; [179] Convert it to a number.    
  7603.     imuli t1, ^d95        ; [179] ...
  7604.     sojl t3, sparx        ; [179] small part
  7605.     ildb t2, t4        ; [179] ...
  7606.     subi t2, " "        ; [179] Convert to number
  7607.     add t1, t2        ; [179] Add to big part
  7608.     movem t1, spsiz        ; [179] New packet length.
  7609.  
  7610. ; Exit.  Set up maximum data field size based on what transpired above.
  7611.  
  7612. sparx:    move t1, spsiz        ; Get the send packet size.
  7613.     subi t1, 4        ; Deduct the constant overhead,
  7614.         sub t1, bctu        ; and the length of the checksum.
  7615.     subi t1, 2        ; Room to leave at end: 2 for possible #X,
  7616.     skipe rptflg        ; and if doing repeat counts,
  7617.      subi t1, 2        ; another 2 for repeat prefix,
  7618.     skipe ebqflg        ; and if doing 8th-bit prefixing,
  7619.      subi t1, 1        ; another one for that.
  7620.     movem t1, maxdat    ; Save max length for data field here.
  7621.     ret
  7622.  
  7623.  
  7624. ; PRECHK - Check if character in T2 is valid prefix character.
  7625. ; Return +1 if not, +2 if it is.
  7626. ;
  7627. prechk:    cail t2, ^d33        ; Is it in the 33-62 range?
  7628.      caile t2, ^d62
  7629.      skipa            ; No, see if it's in the high range.
  7630.      retskp            ; Yes, it's in range.
  7631.     cail t2, ^d96        ; Or in the 96-126 range?
  7632.      caile t2, ^d126
  7633.      ret            ; No, something else, not a valid prefix.
  7634.     retskp            ; Yes, it's valid.
  7635.  
  7636. ; RPAR
  7637. ;
  7638. ; Sets up the data field of an init packet with the our own parameters,
  7639. ; which we want the other side to honor.
  7640. ;
  7641. ; Call with:
  7642. ;  t4/ Pointer to data field for S or I packet, or its ACK.
  7643. ;  EBQFLD contains the character to send in the 8-bit-quote field.
  7644. ; Returns with:
  7645. ;  t3/ Length of data field (number of elements).
  7646. ;  t4/ Original pointer to data field.
  7647. ; The ACs t3-t4 are returned suitably for a call to SPACK.
  7648. ;
  7649. rpar:    saveac <t1,t2,t4,q1>    ; Save temp ACs, and t4 for return.
  7650.     move q1, rpsiz        ; 1 Get the packet size.
  7651.     caile q1, ^d94        ;  Fix to compare correctly.
  7652.      movei q1, ^d94        ;[179] Yes, make it 94.
  7653.     addi q1, " "        ;   Make the char printable.
  7654.     idpb q1, t4        ;   Put it in the data block.
  7655.  
  7656. ;[128] Tell the other side how to time out, based on the current 15-min ldav.
  7657.  
  7658.     movei t1, 2        ; Request 15-minute load average.
  7659.     call ldav
  7660.     move t2, rtimou        ; Other side use this timeout when I'm recving.
  7661.     cain state, "S"        ;[131] But am I sending?
  7662.      subi t2, 2        ;[131]  Make it a little different.
  7663.     call adjtim        ; Adjust based on load average.
  7664.  
  7665.     movem t2, rrtimo    ;   Save time for reporting.
  7666.     addi t2, " "        ;   Make it printable.
  7667.     idpb t2, t4        ;   Put it in the data block.
  7668.     
  7669. ; Easy fields...
  7670.  
  7671.     move q1, rpadn        ; 3 Get the padding.
  7672.     addi q1, " "        ;   Make the char printable.
  7673.     idpb q1, t4        ;   Put it in the data block.
  7674.     move q1, rpadch        ; 4 Get the padding char.
  7675.     addi q1, ^o100        ;   De-controllify it.
  7676.     andi q1, ^o177        ;
  7677.     idpb q1, t4        ;   Put it in the data block.
  7678.     move q1, reolch        ; 5 Get the EOL char.
  7679.     addi q1, " "        ;   Make the char printable.
  7680.     idpb q1, t4        ;   Put it in the data block.
  7681.     move q1, squote        ; 6 [132] Get the quote char.
  7682.     idpb q1, t4        ;   Put it in the data block.
  7683.     move q1, ebqfld        ; 7 Say what we'll do about 8th-bit quoting.
  7684.     idpb q1, t4        ;   Put in the data block.
  7685.     move q1, bctr        ; 8 Block check type requested.
  7686.     idpb q1, t4        ;   Put in the data block.
  7687.     move q1, rptfld        ; 9 The repeat-count-prefix field.
  7688.     idpb q1, t4        ;   Put in the data block.
  7689.  
  7690. ; [179] Capabilities mask
  7691.  
  7692.     movei q1, 2        ; [179] 10 Set long-packet capability bit
  7693.     addi q1, " "        ; [179] Convert to ASCII
  7694.     idpb q1, t4        ; [179] Deposit in packet
  7695.     movei t3, ^d10        ; [179] Ten bytes of data so far
  7696.     move q1, rpsiz        ; [179] RECEIVE PACKET-LENGTH
  7697.     caig q1, ^d94        ; [179] Regular (short) packet?
  7698.      ret            ; [179] Done.
  7699.  
  7700. ; [179] Long packets requested
  7701.  
  7702.     movei q1, " "        ; [179] Window size is 0 (no sliding windows)
  7703.     idpb q1, t4        ; [179] Deposit
  7704.     aos t3            ; [179] Count
  7705.     move q1, rpsiz        ; [179] RECEIVE PACKET-LENGTH
  7706.     idivi q1, ^d95        ; [179] Big part (quotient)
  7707.     addi q1, " "        ; [179] Convert to ASCII
  7708.     idpb q1, t4        ; [179] Deposit
  7709.     aos t3            ; [179] Count
  7710.     addi q2, " "        ; [179] Small part (remainder)
  7711.     idpb q2, t4        ; [179] Deposit
  7712.     aos t3            ; [179] Count
  7713.  
  7714.     ret            ; Done
  7715.  
  7716. ; Miscellaneous small routines for NAKs & Error packets.
  7717.  
  7718.  
  7719. ; Send a NAK.  Expects to find the packet number to NAK in AC2.
  7720.  
  7721. nak:    stkvar <naktry>        ; Counter for NAKs.
  7722.     setom naktry
  7723.     
  7724. nak2:    aos t1, naktry        ; Count this try.
  7725.     camle t1, maxtry    ; Less than maximum?
  7726.      jrst nakx        ;  No, fail.
  7727.     movei t1, "N"        ; Send a NAK.
  7728.     setzb t3, t4        ; No data.
  7729.     call spack        ; Send the packet.
  7730.      jrst @[exp nak2, nakx](t1) ; Handle failures.
  7731.     aos nnak        ; Sent the NAK OK, count it.
  7732.     ret
  7733.  
  7734. nakx:    movei state, "A"    ;  If we can't, set state to cancel.
  7735.     ret
  7736.  
  7737. ; Print the contents of an error packet, if local.
  7738. ;
  7739. ; t1-t4 contain the packet parameters from RPACK.
  7740. ; Sets state to cAncel.
  7741. ; Returns +1 always.
  7742.  
  7743. pxerr:    movei state, "A"    ; Set state to cAncel.
  7744.     skipe iflg        ; Doing Info packet?
  7745.      ret            ;  Skip this.
  7746.     movem t4, errptr
  7747.     hrroi t1, [asciz/?Remote error -- /] ; Yes, print message.
  7748.     PSOUT%
  7749.     move t1, errptr        ; Get pointer to it,
  7750.     PSOUT%            ; and print it.
  7751.  
  7752. ;[126] Print the error in the transaction log too.
  7753.  
  7754.     skipn t1, tlgjfn    ; (if any)
  7755.      ret
  7756.     wtlog <Transaction Cancelled by Error from Other Kermit:>
  7757.     move t2, errptr
  7758.     setzb t3, t4
  7759.     SOUT
  7760.     hrroi t2, crlf
  7761.     SOUT
  7762.     ret
  7763.  
  7764.     subttl    SEND command
  7765.  
  7766. ; Help text.
  7767.  
  7768. hsend:    asciz |
  7769. SEND filespec (AS) [target-name]
  7770. SEND wild-filespec1 (INITIAL) [initial-file]
  7771.  
  7772. Send a file or file group from the DEC-20 to the other host.  If the filespec
  7773. contains wildcard characters (* or %) then all matching files will be sent, in
  7774. alphabetical order by name.  If a file can't be opened for read access, it will
  7775. be skipped.  The name of each file is passed to the other host in a file header
  7776. packet, so that the file can be stored there with the same or similar name.
  7777.  
  7778. If a single file is specified, you may optionally specify a diffent name for it
  7779. "target-name") to be sent in the file header packet.  This name is not parsed;
  7780. it is sent to the other system as is, except any lowercase letters are raised
  7781. to upper case.
  7782.  
  7783. If a wildcard file group is specified, you may optionally specify an initial
  7784. file to send.  This is handy to continue a previously interrupted wildcard
  7785. transfer from where it left off, or to skip some files that would be
  7786. transmitted first.
  7787.  
  7788. If running as a local Kermit, the name of each file will be displayed on your
  7789. screen as the transfer begins, a "." will be displayed for every 5 data packets
  7790. sucessfully sent, and a "%" for every retransmission or timeout that occurs
  7791. you may also elect other typeout options with the SET DEBUG command).  If you
  7792. see many "%" characters, you are probably suffering from a noisy connection.
  7793. You can type Control-A at any point during the transfer to get a brief status
  7794. report.
  7795.  
  7796. When running locally and sending files, you can cancel (stop sending) the
  7797. current file by typing Control-X.  If sending a file group, Control-X will
  7798. cause the current file to be skipped, and KERMIT-20 will go on to the next
  7799. file.  Control-Z will cancel sending the entire group and return you to
  7800. KERMIT-20 command level.
  7801.  
  7802. If running as a remote Kermit, you should escape back to your local Kermit and
  7803. give the RECEIVE command.  If you don't do this fast enough, several
  7804. "send-init" packets may arrive prematurely; don't worry, KERMIT-20 will keep
  7805. sending them until it gets a response.
  7806.  
  7807. If communication line parity is being used, KERMIT-20 will request that the
  7808. other KERMIT accept a special kind of prefix notation for binary files.  This
  7809. is an advanced feature, and not all KERMITs have it; if the other KERMIT does
  7810. not agree to use this feature, binary files cannot be sent correctly.  This
  7811. includes executable programs, relocatable object modules, files with EDIT line
  7812. sequence numbers (as produced by EDIT, SOS, or OTTO), etc.
  7813.  
  7814. KERMIT-20 will also ask the other KERMIT whether it can handle a special prefix
  7815. encoding for repeated characters.  If it can, then files with long strings of
  7816. repeated characters will be transmitted very efficiently.  Columnar data,
  7817. highly indented text, and binary files are the chief beneficiaries.
  7818. |
  7819.  
  7820. ;...SEND command, cont'd
  7821.  
  7822.  
  7823. ; SEND command parsing.
  7824.  
  7825. .send:    noise <from files>    ; Issue guide words.
  7826.     move t2, cjfnbk+.gjgen    ; Get the JFN flag bits.
  7827.     txo t2, gj%ifg!gj%old    ; Old file(s), allow wild cards.
  7828.     trz t2, -1        ;[172] Default to most recent generation only.
  7829.     movem t2, cjfnbk+.gjgen    ; Return the JFN flag bits.
  7830.     setzm cjfnbk+.gjext    ;[172] No default extension.
  7831.     movei t1, [flddb. (.cmfil,cm%sdh,,<input file spec (possibly wild)>,,)]
  7832.     call rfield        ; Parse a file spec or a confirm.
  7833.     movem t2, pars2        ;[111]
  7834.     tlnn t2, 770000        ; Any wildcards in it?
  7835.      jrst [    noise <as>    ;[96] No, then let them choose a new name.
  7836.         movei t1, [    ;[96]
  7837.          flddb. .cmtxt,cm%sdh,,<Carriage return to send with this name,
  7838.  or specify file name to use on target system>]    ;[96]
  7839.         jrst .send2 ]
  7840.     noise <initial>        ; Wildcard(s) given, prompt for initial.
  7841.     movei t1, [flddb. (.cmcfm,cm%sdh,,<Carriage return to send them all>,,[
  7842.            flddb. (.cmfil,cm%sdh,,<First file to send>)])]
  7843. .send2:    call rflde        ; Parse the field.
  7844.      jrst .sende        ;[63] Handle errors explicitly.
  7845.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  7846.     movem t3, pars3        ;[96] Save it for execution.
  7847.     cain t3, .cmcfm        ; Confirmation?
  7848.      ret            ;  Yes, just return.
  7849.     cain t3, .cmfil        ;[96] File?
  7850.      jrst [    hrrm t2, pars2    ;[117] No, initial filespec - substitute it.
  7851.         movei t1, [flddb. .cmcfm] ; Get command confirmation.
  7852.         call rflde
  7853.          jrst .sende
  7854.         ret ]
  7855.  
  7856. ;[96] If they gave an alternate name, copy it out of the atom buffer.
  7857.  
  7858.     caie t3, .cmtxt        ; Text?
  7859.      jrst .sende        ;  No, error.
  7860.     move t1, [point 7, atmbuf] ; Copy the string out of the atom buffer.
  7861.     move t2, [point 7, buffer]
  7862.     setzm buffer
  7863.     call movstu
  7864.     jumpe t3, [        ; If nothing, act like we parsed a confirm.
  7865.         movei t3, .cmcfm
  7866.         movem t3, pars3
  7867.         ret ]
  7868.     ret
  7869.  
  7870. .sende:    move t1, filjfn        ; Error - get the JFN.
  7871.     RLJFN%            ; Release it.
  7872.      erjmp .+1        ;  Ignore any errors.
  7873.     setzm filjfn        ; Nullify the JFN.
  7874.     tmsg <?Not confirmed>
  7875.     jrst cmder1
  7876.  
  7877. ; MOVSTU -- Move string routine, uppercasing any lowercase letters.
  7878. ;  Eat any leading whitespace.
  7879. ;  Call with t1/ source pointer
  7880. ;            t2/ destination pointer
  7881. ;  Returns with t1, t2 updated, t3/ character count, t4/ 0.
  7882. ;
  7883. movstu:    seto t3,        ; Counter, started at -1.
  7884.  
  7885. movstx:    ildb t4, t1        ; Get a character.
  7886.     jumpn t3, movsty    ; Have we got at least one nonwhitespace?
  7887.     caie t4, 40        ; No, is this a blank?
  7888.      cain t4, 11        ;  or a tab?
  7889.      jrst movstx        ;  One of those, skip it.
  7890. movsty:    cail t4, "a"        ; Convert to upper case if necessary.
  7891.      caile t4, "z"
  7892.      skipa
  7893.      trz t4, 40
  7894.     idpb t4, t2        ; Copy it.
  7895.     aos t3            ; Count it.
  7896.     jumpn t4, movstx    ; Everything up to & including the first null.
  7897.  
  7898.     ret    
  7899.  
  7900. ; SEND command execution.
  7901.  
  7902. $send:    setom $sendf        ;[88] Executing SEND command,
  7903.     setzm $recvf        ;[88] not RECEIVE command.
  7904.     setzm ttildb        ;[180] (stats)
  7905.     setzm ttibin        ;[180] (stats)
  7906.     setzm ttisin        ;[180] (stats)
  7907.     setzm ttimax        ;[180] (stats)
  7908.     move t1, pars2        ;[111] Get JFN we just parsed.
  7909.     movem t1, ndxjfn    ;[111] Save the wildcard bits here.
  7910.     hrrzm t1, nxtjfn    ;[111] Initialize file lookahead.
  7911.     call gtnfil        ;[111] Get JFN of first file.
  7912.      ermsg <No files to send>,r ;[111] (if any).
  7913.     call caxzon        ;[59] Turn on ^A,^X,^Z interrupts.
  7914.     hrroi t1, [        ;[61] Tell about terminal interrupts,
  7915.      asciz/^A for status report, ^X to cancel file, ^Z to cancel batch./]
  7916.     skipe local        ;[61]  (if local).
  7917.      PSOUT%            ;[61]
  7918.     call inilin        ; Initialize the line
  7919.     call ccon        ;  and turn on ^C trap.
  7920.      jrst reslin        ;[10] on ^C, go reset line, return from there.
  7921.  
  7922. ; Entry point for server.
  7923.  
  7924. $sends:    setzm stot        ; Initialize statistics variables.
  7925.     setzm rtot
  7926.     setzb schr, stchr
  7927.     setzb rchr, rtchr
  7928.     setzm files
  7929.     setom sptot        ;[4] Init the sent-packet counter to -1.
  7930.     setom rptot
  7931.     setzm nnak        ;[54] Init the number of NAKs
  7932.     setzm ntimou        ;[54]  and the number of timeouts.
  7933.     setzm errptr        ; Zero the error message pointer.
  7934.     setzm timerx        ; Timer error counter.
  7935.     GTAD%            ; Get the time we start.
  7936.     movem t1, stdat        ; Save it for statistics.
  7937.  
  7938. ; Delay to give them time to escape back to other side and say "receive".
  7939.  
  7940.     skipn srvflg        ; Don't delay if server
  7941.      skipe local        ;  or if local.
  7942.      jrst $send1
  7943.     ;...
  7944.  
  7945. ;...$SEND, cont'd
  7946.  
  7947.  
  7948. ;[128] Remote, do the requested delay.
  7949.  
  7950.     move t4, delay        ; The specified delay in seconds.
  7951.     lsh t4, 1        ; Make it half seconds.
  7952.  
  7953. $sndxx:    sojl t4, $send1        ; Countdown.
  7954.     movei t1, ^d500        ; Sleep half a second.
  7955.     DISMS
  7956.  
  7957.     skipn t1, netjfn    ; Got a file transfer jfn?
  7958.      jrst $sndxx        ;  No reason why we shouldn't, but...
  7959.     SIBE            ; Anything in input buffer?
  7960.      skipa
  7961.     jrst $sndxx
  7962.  
  7963. ;[128] If user escapes back to micro & types CR to send NAK for packet 0,
  7964. ; no need to delay any longer -- start sending immediately.
  7965.  
  7966. $sndzz:    BIN            ; Just get first character.
  7967.     came t2, rsthdr        ; Start of packet?
  7968.      jrst $sndxx        ;  No, they're probably fumbling w/the keyboard
  7969.     CFIBF            ; Yes, assume it's a NAK for packet 0,
  7970.      erjmp .+1        ;  discard the rest and start sending.
  7971.  
  7972. ; We can be sending with either a File Header (F) or a Text Header (X).
  7973. ; XFLG nonzero means X header, XFLG zero means F header.
  7974. ; If sending with F header, start with the Send-Init, as packet 0.
  7975. ; If sending with X, we can skip the Send-Init and send X as packet 1.
  7976. ;
  7977. ;[124] BUT...  If type 2 or 3 block check requested and agreed upon,
  7978. ;[124] cannot skip Send-Init (even if I packet exchange just occurred).
  7979.  
  7980. $send1:    movei state, "S"    ; Set the state to Send-Initiate.
  7981.     move t1, bctu        ;[124] What kind of block check are we using?
  7982.     caie t1, 1        ;[124] 2 or 3 character block check?
  7983.      jrst [    setzm pktnum    ;[124] Yes, then must send a Send-Init.
  7984.         jrst $sendb ]    ;[124]
  7985.  
  7986. ; Type 1 block check.  Can obey XFLG.
  7987.  
  7988.     skipn xflg        ; X or F header?
  7989.      setzm pktnum        ;  F, so reset packet number.
  7990.     skipe xflg        ; X or F?
  7991.      movei state, "F"    ;  If X, go straight into file-sending state.
  7992.  
  7993. $sendb:    move t1, spause        ;[36] Get the requested send-pause interval
  7994.     movem t1, pause        ;[36]  and make it the current one.
  7995.     setzm numtry        ; Set the number of tries to zero.
  7996.  
  7997. $senda:    call setlog        ;[57] Set up any debugging log.
  7998.      nop
  7999.  
  8000. ; SEND command, cont'd...  State Table Switcher:
  8001.  
  8002.  
  8003. $send2:    cain state, "D"        ; Are we in the data send state?
  8004.      jrst [    call sdata
  8005.         jrst $send2 ]
  8006.     cain state, "F"        ; Are we in the file send state?
  8007.      jrst [    call sfile    ;  Call send file.
  8008.         jrst $send2 ]
  8009.     cain state, "Z"        ; Are we in the end of file state?
  8010.      jrst [    call seof
  8011.         jrst $send2 ]
  8012.     cain state, "S"        ; Are we in the send initiate state?
  8013.      jrst [    movei t1, "S"    ;[100] Packet type for Send-Init.
  8014.         call sinit    ; Call send-initiate routine.
  8015.         jrst $send2 ]
  8016.     cain state, "B"        ; Are we in the end of send state?
  8017.      jrst [    call seot
  8018.         jrst $send2 ]
  8019.     cain state, "C"        ; Are we in the send complete state?
  8020.      jrst [    movei t1, "C"
  8021.         move t2, pktnum
  8022.         call diamsg
  8023.         call caxzoff    ;[59] Turn off keyboard interrupts
  8024.         call reslin    ;  Restore the line.
  8025.         GTAD%        ;  Get the time we ended.
  8026.         subm t1, stdat    ;  Figure how long it all took.
  8027.         movei t1, .chbel ;[31] Give a beep
  8028.         skipe local    ;[31] if local
  8029.          PBOUT        ;[31]
  8030.         ret ]
  8031.     cain state, "A"        ; Are we in the send cAncel state?
  8032.      jrst [    movei t1, "A"
  8033.         move t2, pktnum
  8034.         call diamsg    ;[38]
  8035.         call reslin    ;  Restore the line.
  8036.         GTAD%        ;  Get the time we ended.
  8037.         subm t1, stdat    ;  Figure how long it all took.
  8038.         move t1, filjfn ;[134] Last-ditch effort to close the file.
  8039.         setzm filjfn    ;[134]
  8040.         jumple t1, r    ;[134]
  8041.          CLOSF        ;[134]
  8042.          erjmp r    ;[134]
  8043.         ret ]
  8044.     movei t1, "U"        ; Some undefined state???
  8045.     move t2, pktnum
  8046.     call diamsg        ;[38]
  8047.         call caxzof        ;[59] Turn off ^A,^X,^Z traps.
  8048.     call reslin
  8049.     ret
  8050.  
  8051.     subttl Send routines
  8052.  
  8053. ; SINIT: Call with t1/packet type, "S" for Send-Init, "I" for Init-Info.
  8054. ;
  8055. sinit:    saveac <q1>
  8056.     move q1, numtry        ; Get the number of tries.
  8057.     caml q1, imxtry        ; Have we reached the maximum number of tries?
  8058.      jrst [    skipe local    ;[5] Yes.
  8059.          ermsg <Send-Init not ACK'd>,sinitx
  8060.         jrst sinitx ]    ; Go cancel the transfer
  8061.     aos numtry        ; Save updated number of tries.
  8062.     movei t4, "Y"        ;[88] Say we agree to do 8-bit prefixing.
  8063.     skipe ebqr        ;[88] Did our user explicitly ask for it?
  8064.      move t4, ebq        ;[89] In that case, specify requested prefix.
  8065.     movem t4, ebqfld    ;[88] Put it here.
  8066.     movei t4, drept        ;[92] Want to use this as repeat count prefix.
  8067.     movem t4, rptfld    ;[92] Put it here.
  8068.     move t4, [point 8, data] ;[50] The address of the data.
  8069.     call rpar        ; Set the information.
  8070.     move t2, pktnum        ; Packet number.  T1 already has packet type.
  8071.     setom bctone        ;[98] Force single char checksums.
  8072.     call spack        ; Send the packet.
  8073.      jrst @[exp r, sinitx](t1) ; Handle errors.
  8074.     call rpack        ; Get a packet.
  8075.      ret            ;  Trashed packet don't change state, retry.
  8076.  
  8077. sinity:    caie t1, "Y"        ; Check packet type.  ACK?
  8078.      jrst sinitn        ;  No, go see if it's a NAK.
  8079.     came t2, pktnum        ; ACK.  But is it the right ACK?
  8080.      ret            ;  No, don't settle, hold out for right one.
  8081.     call spar        ; Yes, get the information.
  8082.     setzm numtry        ; Reset the number of tries.
  8083.     aos t2, pktnum        ; Increment the packet number,
  8084.     andi t2, 77        ; modulo 100,
  8085.     movem t2, pktnum    ; and save it.
  8086.     call ebqmsg        ;[89] Go warn if problem w/8-bit prefixing.
  8087.     setzm bctone        ;[98] Finished with initialization.
  8088.     movei state, "F"    ; Set the state to file send.
  8089.  
  8090. ;[126] Start entry in transaction log.
  8091.  
  8092.     skipn t1, tlgjfn    ; (if any)
  8093.      ret
  8094.     skipe iflg        ; Not an I packet, is it?
  8095.      ret
  8096.     wtlog <-- Send Begins -->
  8097.     callret rrlog        ; Go log details.
  8098.  
  8099. sinitn:    cain t1, "N"        ;[30][54] NAK?
  8100.      aosa nnak        ;[54] Yes, count it & return.
  8101. sinitt:    cain t1, "T"        ; Timer interrupt pseudo packet?
  8102.      ret            ;[30] One of those, just keep trying.
  8103.     cain t1, "E"        ; But also print message if error packet.
  8104.      jrst pxerr        ;[82]
  8105. sinitx:    movei state, "A"    ; Anything else, just cancel.
  8106.     ret
  8107.  
  8108. ; SFILE - Send File Header
  8109.  
  8110. sfile:    setzm bctone        ; Don't require single-character checksum.
  8111.     setzm cxseen        ; Zero these here, since they apply on
  8112.     setzm czseen        ;  on a per-file basis.
  8113.     move t1, numtry        ; Get the number of tries.
  8114.     caml t1, maxtry        ; Have we reached the maximum number of tries?
  8115.      jrst [    movei state, "A" ;  Change the state to cAncel.
  8116.         kermsg <Can't send file header>, r ]
  8117.     aos numtry        ; No, count this try.
  8118.     jumpg t1, sfild3    ; After first try, skip opening file, etc.
  8119.  
  8120. sfilea:    skipn local        ;[12] Local Kermit?
  8121.      jrst sfileb        ;[12] No, skip this.
  8122.     movei t1, .priou    ;[12] Yes, print the file name.
  8123.     RFPOS%            ;[12] First see if we need to start a new line.
  8124.     hrroi t1, crlf        ;[12]  ...
  8125.     trne t2, -1        ;[12]  ...
  8126.      PSOUT%            ;[12]
  8127.     movei t1, .priou    ;[12] Now print the file name.
  8128.     hrrz t2, filjfn        ;[12]
  8129.     setz t3,        ;[12]
  8130.     JFNS%            ;[12]
  8131.      erjmp .+1        ;[12]
  8132.     movei t1, pars3        ;[96] Did we have another name to use?
  8133.     cain t1, .cmtxt        ;[96]
  8134.      jrst [    tmsg < as >    ;[96] Yes, say what it was.
  8135.         hrroi t1, buffer ;[96]
  8136.         PSOUT         ;[96]
  8137.         jrst .+1]    ;[96]
  8138.     movei t1, " "        ;[12] Leave a space.
  8139.     PBOUT%            ;[12]
  8140.     ;...
  8141.  
  8142. ; SFILE, cont'd
  8143.  
  8144. sfileb:    skipn source        ; Are we getting data from a file?
  8145.      jrst sfilb2        ; Yes, go open the file, etc.
  8146.     movei t1, "X"        ; No, so send X packet.
  8147.     move t2, pktnum        ; This packet number.
  8148.     setzb t3, t4        ; No data.
  8149.     jrst sfildy        ; Skip around all the file name baloney.
  8150.     
  8151. sfilb2:    move t1, filjfn        ;[15] JFN of file
  8152.     movx t2, fld(^d36,of%bsz)+of%rd ;[15]
  8153.     OPENF%            ;[15]
  8154.      erjmp sfilec        ;[44]
  8155.     skipn xflg        ;[126]
  8156.      wtlog <Opened File: >,filjfn ;[126]
  8157.     jrst sfiled        ;[44] Opened OK, proceed.
  8158.  
  8159. sfilec:    cain t1, opnx1        ;[44] Got an error.  "File already open"?
  8160.      jrst sfiled        ;[44] Yes, so it's not really an error.
  8161.     skipe t1, tlgjfn    ;[126] Log this failure in transaction log.
  8162.      jrst [    wtlog <Can't Send >,filjfn
  8163.         hrroi t2, [asciz/   Because: /]
  8164.         setzb t3, t4
  8165.         SOUT
  8166.         hrloi t2, .fhslf ; Tell why.
  8167.         setz t3,
  8168.         ERSTR
  8169.          nop
  8170.          nop
  8171.         hrroi t2, crlf
  8172.         setzb t3, t4
  8173.         SOUT
  8174.         jrst .+1 ]
  8175.  
  8176.     skipe local        ;[15] No, really an error.  Local?
  8177.      call [    hrroi t1, [asciz/ %Not sent because: /]
  8178.         PSOUT
  8179.         movei t1, .priou
  8180.         hrloi t2, .fhslf
  8181.         setz t3,
  8182.         ERSTR%
  8183.          nop
  8184.          nop
  8185.         ret ]
  8186.     call gtnfil        ; Try to get the next file.
  8187.      jrst [    setzm filjfn
  8188.         movei state, "B" ; No more, break transmission.
  8189.         ret ]
  8190.     jrst sfilea        ; Got one, go try to open it.
  8191.     ;...
  8192.  
  8193. ;...SFILE, Cont'd
  8194.  
  8195.  
  8196. ;[96] See if user wants to send the file with a different name.
  8197.  
  8198. sfiled:    move t1, pars3        ; Use another name?
  8199.     caie t1, .cmtxt        ;
  8200.      jrst sfild2        ; No, use the file's actual name.
  8201.     move t1, [point 7, buffer] ; Yes, copy the string the user gave us,
  8202.     move t2, [point 7, filbuf] ;[102] converting to upper case.
  8203.     call movstu        ; Returns length in t3.
  8204.     jrst sfild3        ; Proceed.
  8205.  
  8206. ; Come here to use the file's actual name.
  8207.  
  8208. sfild2:    move t1, [point 7, filbuf] ;[102] Put string in file name buffer.
  8209.     move t2, filjfn        ; The file's JFN.
  8210.     movx t3, js%nam+js%typ+js%paf ; Only name, type, and punctuation.
  8211.     setzb t4, filbuf
  8212.     JFNS%            ; Get the file name.
  8213.      erjmp [move t1, [point 7, [asciz/XXXXXX.XXX/]]    ; If any error
  8214.         movei t3, ^d10    ; substitute this string.
  8215.         jrst sfild4 ]
  8216.     ldb t3, t1        ;[175] See what the last character is.
  8217.     cain t3, "."        ;[175] Dot?
  8218.      jrst [    dpb t4, t1    ;[175] Yes, zero it out.
  8219.         seto t4,    ;[175] And remember.
  8220.         jrst .+1 ]    ;[175]
  8221.     move t2, t1        ; Set up to subtract the byte pointers.
  8222.     idpb t4, t1        ; Terminate the string
  8223.     move t1, [point 7, filbuf] ;[102] Get a pointer to our data block.
  8224.     call subbp        ; Subtract the byte pointers, get length in t3.
  8225.      ret            ;  Uh oh...  this should never happen.
  8226.     skipe t4        ;[175] Last char was dot?
  8227.      sos t3            ;[175] Yes, so count one less character.
  8228.     ;...
  8229.  
  8230. ;...SFILE, cont'd.
  8231.  
  8232. ;[84] Strip out ^V's, convert filename to "normal form" if requested.
  8233. ;[102] Do this using normal packet encoding & filling technique, but calling
  8234. ;[102] an alternate GETCH routine.
  8235.  
  8236. sfild3:    skipn filjfn        ;[128] Really a file?
  8237.      jrst [    movei t1, "X"    ; No, just send an empty X header.
  8238.         move t2, pktnum    ; Current packet number.
  8239.         setzb t3, t4    ; No data.
  8240.         jrst sfildy ]
  8241.  
  8242. ; Really a file.
  8243.  
  8244.     move t1, [point 7, filbuf] ;[102] Keep file buffer pointer in memory.
  8245.  
  8246. sfild4:    movem t1, filptr    ;[102] ...
  8247.     movei t1, gtfch        ;[102] Address alternate GETCH routine
  8248.     movem t1, source    ;[102] to call while getting characters.
  8249.     setom fildot        ;[102] Initialize filename dot counter.
  8250.     setom next        ;[102] Initialize character lookahead.
  8251.     move t1, maxdat        ;[102] Set up maximum length.
  8252.     call getbuf        ;[102] Fill up the packet with the filename.
  8253.      jumpn t1, [
  8254.         movei state, "A" ;[102] Shouldn't be any error here, but...
  8255.         ret ]        ;[102]  ...
  8256.     move t3, t1        ;[102] Set up length for call to SPACK.
  8257.  
  8258. ; Send the file header packet.
  8259.  
  8260. sfildx:    setzm source        ;[102] Done with alternate GETCH routine.
  8261.     movei t1, "F"        ; Packet type is File Header.
  8262.     skipe xflg        ; Unless it's teXt header...
  8263.      movei t1, "X"        ;  ...
  8264.     move t2, pktnum        ; Packet number.
  8265.     move t4, [point 8, data] ; Get a pointer to our data block.
  8266.  
  8267. sfildy:    call spack        ; Send the file header packet.
  8268.      skipa state, "A"    ; Failed, set state to cAncel & return.
  8269.     call rpack        ; Sent the file header OK, get reply.
  8270.      ret            ;  Trashed packet, don't change state, retry.
  8271.     ;...
  8272.  
  8273. ; SFILE, cont'd
  8274.  
  8275. ; Got a response, check for & handle ACKs.
  8276.  
  8277.     caie t1, "Y"        ; Check the packet, is it an ACK?
  8278.      jrst sfile3        ;  No.
  8279.  
  8280. sfile2:    came t2, pktnum        ; Yes, but is it the right ACK?
  8281.      ret            ;   No, don't settle, hold out for right one.
  8282.     setzm rcving        ; Indicate we're sending a file.
  8283.     aos rcving        ;  ...
  8284.     setzm numtry        ; Yes, reset the number of tries.
  8285.     aos t2, pktnum        ; Increment the packet number,
  8286.     andi t2, 77        ; modulo 100,
  8287.     movem t2, pktnum    ; and save it.
  8288.     skipn xflg        ;[126] Don't log if not sending a real file.
  8289.      jrst [    skipn t1, tlgjfn ;[126] Logging transactions?
  8290.          jrst .+1
  8291.         hrroi t2, [asciz/   Sending As "/] ; Yes, log this.
  8292.         setzb t3, t4
  8293.         SOUT
  8294.         hrroi t2, filbuf
  8295.         SOUT
  8296.         hrroi t2, [asciz/"
  8297. /]
  8298.         SOUT
  8299.         jrst sfil3a ]
  8300.     jrst sfil3a        ;[52] Join common code.
  8301.  
  8302. ; Check for & handle NAKs.
  8303.  
  8304. sfile3:    caie t1, "N"        ; NAK?
  8305.      jrst sfile4        ;  No.
  8306.  
  8307.     aos nnak        ;[54] Yes, count it.
  8308.     move t1, pktnum        ;[51] Get the expected packet number.
  8309.     aos t1            ;[51] Figure out what the next one would be,
  8310.     andi t1, 77        ;[51] mod 64.
  8311.     caie t1, (t2)        ;[51] Is the NAK for the next packet?
  8312.      ret            ;  No, so must send this packet again.
  8313.     setzm numtry        ; Yes, for next, same as ACK for this.
  8314.     movem t1, pktnum    ; Save incremented packet number.
  8315.     ;...
  8316.  
  8317. ; SFILE, cont'd
  8318.  
  8319.  
  8320. ;[75] Check for ITS binary format file.
  8321.  
  8322. sfil3a:    setzm itsfil        ; Assume this isn't an ITS file.
  8323.     skipn source        ; Skip this if it's not really a file.
  8324.      skipn itsflg        ; Looking for ITS files?
  8325.      jrst sfil3b        ;  No.
  8326.     setz t2,        ; Yes, do a 36-bit BIN.
  8327.     skiple t1, filjfn    ; ...
  8328.      BIN            ; ...
  8329.      erjmp sfil3b        ;  If there's some error, catch it later.
  8330.     came t2, [sixbit/DSK8/] ; Is it an ITS binary file?
  8331.      jrst sfil3b        ; No, then handle normally.
  8332.     setom itsfil        ; Yes, flag this file as ITS.
  8333.     hrroi t1, [asciz/(ITS binary format) /]
  8334.     skipe local        ; Say what happened if local.
  8335.      PSOUT
  8336.         
  8337. ; Get first chunk of data.
  8338.  
  8339. sfil3b:    setzm mapflg        ;[52] Say no pages mapped in yet.
  8340.     setzm eoflag        ;[72] Not EOF yet.
  8341.     setom next        ;[63] Initialize input character lookahead.
  8342.     move t1, maxdat        ;[63] Maximum length for data field.
  8343.     setz schr,        ;[128] Init number of file characters sent.
  8344.     call getbuf        ;[63] Fill the first data packet.
  8345.      jrst [    movem t1, cxseen ;[70] If error, send "discard" in EOF message.
  8346.         movei state, "Z" ; Get into EOF state.
  8347.         ret ]
  8348.     movei state, "D"    ; Got data, set the state to file send.
  8349.     movem t1, size        ; Save the length of the data.
  8350.     ret            ; Back to state switcher.
  8351.  
  8352. ; Catch-all for other states.
  8353.  
  8354. sfile4:    cain t1, "T"        ; Timer interrupt pseudo packet?
  8355.      ret            ; Yes, return without changing state.
  8356.     cain t1, "E"        ;[80] Error packet?
  8357.      call pxerr        ;[82] If so, print remote error message.
  8358.     movei state, "A"    ; Cancel the transaction.
  8359.     skiple t1, filjfn    ;[80] Close the file.
  8360.      CLOSF            ;[80]
  8361.      erjmp .+1        ;[80]
  8362.     setzm filjfn        ;[80]
  8363.     ret
  8364.  
  8365. ; GETCH replacement routine for getting characters from a filename string.
  8366. ; Uses global FILPTR for input string, FILDOT for counting dots in filename.
  8367. ; Strips any ^V used as a quote, and if requested converts name to normal form.
  8368. ;
  8369. ; Returns:
  8370. ;   +1 never (no reason to fail).
  8371. ;   +2 always, with NEXT containing next character, -1 if no more.
  8372. ;
  8373. gtfch:    ildb t1, filptr        ;[102] Get next character.
  8374.     jumpe t1, gtfchz    ;[102] If zero, must be done.
  8375.     cain t1, 26        ;[84]  Control-V?
  8376.      ildb t1, filptr    ;[102]  Yes, it's just a prefix, get next char.
  8377.     skipn xfnflg        ;[101] Converting to normal form?
  8378.      jrst gtfchx        ;[101] No, skip other conversions.
  8379.     cain t1, "."        ;[84]  Yes, is this a period?
  8380.      jrst [ aose fildot    ;[84]  Yes, don't put more than one.
  8381.          movei t1, "X"    ;[84]  Substitute "X" for any extra dots.
  8382.         jrst gtfchx ]    ;[84]  ...
  8383.  
  8384. gtfchy:    move t1, xfntab(t1)    ;[84] Translate it.
  8385.  
  8386. ; Return with character like GETCH.
  8387.  
  8388. gtfchx:    movem t1, next        ;[102] Put result in NEXT, as GETCH does.
  8389.     retskp            ;[102] Done.
  8390.  
  8391. ; "EOF" return, like GETCH
  8392.  
  8393. gtfchz:    setz t1,
  8394.     setom next
  8395.     ret
  8396.  
  8397. ; SDATA - Send a data packet.
  8398.  
  8399. sdata:    skipn cxseen        ;[59] Control-X typed?
  8400.      skipe czseen        ;[59] Or Control-Z?
  8401.      jrst [    call unmapi    ;[59] Yes, must unmap current input file page.
  8402.          nop        ;[59] Ignore any errors.
  8403.         movei state, "Z" ;[59] Get into EOF state.
  8404.         ret ]        ;[59] Back to state switcher.
  8405.  
  8406.     saveac <q1>        ; ^X/^Z not typed, normal case.
  8407. sdatab:    move q1, numtry        ; Get the number of tries.
  8408.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  8409.      jrst [ movei state, "A" ;  Change the state to cAncel.
  8410.         ermsg <Too many retries>, r ]
  8411.     aos numtry        ; Increment number of tries.
  8412.     movei t1, "D"        ; File send packet.
  8413.     move t2, pktnum        ; Packet number.
  8414.     move t3, size        ; Get the data length.
  8415.     move t4, [point 8, data] ; Get a pointer to our data block.
  8416.     call spack        ; Send the data packet.
  8417.      jrst @[exp sdatab,sdatax](t1) ; Handle errors.
  8418.     call rpack        ; Get a packet.
  8419.      ret            ;  Trashed packet, don't change state, retry.
  8420.  
  8421. sdatay:    caie t1, "Y"        ; Got one, check the type.  Is it ACK?
  8422.      jrst sdatan        ;  No, go check for NAK.
  8423.     came t2, pktnum        ; Yes, but is it the right ACK?
  8424.      ret            ;  No, don't settle, hold out for right one.
  8425.     soje t3, [        ;[62] Any data (interested in one & only char)?
  8426.         ildb t3, t4    ;[62] Yes, what?
  8427.         cain t3, "X"    ;[62] Is it an "X"?
  8428.          jrst [    setom cxseen ;[140] Yes, set the C-X flag.
  8429.             move t3, source    ;[140] What's the source of our data?
  8430.             cain t3, dirch ;[140] A directory listing?
  8431.              setom czseen ;[140] If so, set C-Z flag, too.
  8432.             jrst sdaty2 ] ;[140]
  8433.         cain t3, "Z"    ;[62] Is it an "Z"?
  8434.          setom czseen    ;[62]  Yes, pretend ^Z was typed...
  8435.         jrst .+1 ]    ;[62] Go thru one more time, then out.
  8436.  
  8437. sdaty2:    setzm numtry        ; Correct normal packet, reset retry counter.
  8438.     aos t2          ;[51] Increment the packet number,
  8439.     andi t2, 77        ; modulo 100,
  8440.     movem t2, pktnum    ; and remember it.
  8441.     jrst sdata2        ;[52] Go get some more data to send.
  8442.  
  8443. sdatan:    cain t1, "N"        ; NAK?
  8444.      jrst [    move t1, pktnum    ;[51] Yes, get the expected packet number.
  8445.         aos nnak    ;[54] Count the NAK.
  8446.         aos t1        ;[51] Figure out what the next one would be,
  8447.         andi t1, 77    ;[51] mod 64.
  8448.         caie t1, (t2)    ;[51] Is the NAK for the next packet?
  8449.          ret        ;  No, then must send current one again.
  8450.         setzm numtry    ; Yes, a NAK for n+1(mod 64) = ACK for n,
  8451.         movem t1, pktnum ; so play like we got an ACK,
  8452.         jrst sdata2 ]    ;[52] and go get next packetful of data.
  8453.  
  8454.     ;...
  8455.  
  8456. ;...SDATA, cont'd
  8457.  
  8458.  
  8459. ; Handle timeout or unexpected packet types.
  8460.  
  8461. sdatat:    cain t1, "T"        ; Timer interrupt pseudo packet?
  8462.      ret
  8463.     cain t1, "E"        ;[82] Error packet?
  8464.      jrst pxerr        ;[82]  Yes, print it & cancel.
  8465. sdatax:    movei state, "A"    ; Anything else, just cancel..
  8466.     ret
  8467.  
  8468.  
  8469. ; Fill up the next buffer of data.
  8470.  
  8471. sdata2:    move t1, maxdat        ;[63] Length to work with.
  8472.     call getbuf        ;[63] Try to get next bufferful.
  8473.      jrst [    movem t1, cxseen ;[70] If error, tell other side to discard.
  8474.         movei state, "Z" ; Set state to EOF.
  8475.         ret ]        ;  Go back to state switcher.
  8476.     movem t1, size        ; Got more data, save length, and
  8477.     ret            ; return, remaining in state "D".
  8478.  
  8479. ; SEOF - Send End Of File packet.
  8480.  
  8481.  
  8482. seof:    move t1, numtry        ; No ^X/^Z, get the number of tries.
  8483.     caml t1, maxtry        ; Have we reached the maximum number of tries?
  8484.      jrst [    movei state, "A" ;  Change the state to cAncel.
  8485.         ermsg <Can't send EOF>, r ]
  8486.     aos numtry        ; Still within our limit, bump retry count.
  8487.     movei t1, "Z"        ; Send a Z (EOF) packet.
  8488.     move t2, pktnum        ; Packet number.
  8489.     skipn cxseen        ;[59] Are we discarding this file?
  8490.      skipe czseen        ;[59]
  8491.      jrst [    move t3, [point 8, data] ;[59] Yes,
  8492.         movei t4, "D"    ;[59] put a "D" for Discard in data field
  8493.         idpb t4, t3    ;[59] ...
  8494.         movei t3, 1    ;[59] Say the data length is 1
  8495.         move t4, [point 8, data] ;[59] point to it again...
  8496.         jrst .+2 ]    ;[59] Skip next instruction!
  8497.      setzb t3, t4        ; Normal case -- no data field.
  8498.     call spack        ; Send the packet.
  8499.      jrst @[exp seof, seofx](t1) ; Handle any errors.
  8500.     call rpack        ; Get a packet.
  8501.      ret            ;  Trashed packet, don't change state, retry.
  8502.  
  8503. ; Got a response.  Check for ACK and handle it.
  8504.  
  8505.     caie t1, "Y"        ;[52] Check the packet type.  Is it an ACK?
  8506.      jrst seof2        ;[52]  No...
  8507.     came t2, pktnum        ; Yes but, is it the right ACK?
  8508.      ret            ;  No, don't settle, hold out for right one.
  8509.     aos t2, pktnum        ; Increment the packet number,
  8510.     andi t2, 77        ; mod 100,
  8511.     movem t2, pktnum    ; and save it.
  8512.     jrst seof4        ;[52] Join common code.
  8513.  
  8514. ; Check for NAK and handle it.
  8515.  
  8516. seof2:    caie t1, "N"        ; NAK?
  8517.      jrst seof3        ;  No.
  8518.     aos nnak        ;[54] Yes, count it.
  8519.     move t1, pktnum        ;[51] What packet were we looking for?
  8520.     aos t1            ;[51] Is the NAK for the next packet?
  8521.     andi t1, 77        ;[51] (mod 64)
  8522.     caie t1, (t2)        ;[51]
  8523.      ret            ;  No, then must send this one again.
  8524.     movem t1, pktnum    ; Yes, behave like it was an ACK for this one.
  8525.     jrst seof4        ;[52] Join common code.
  8526.  
  8527. ; SEOF, cont'd
  8528.  
  8529.  
  8530. ; Check for other types & handle.
  8531.  
  8532. seof3:    cain t1, "T"        ; Timer interrupt pseudo-packet?
  8533.      ret            ; If so, just keep going.
  8534.     cain t1, "E"        ;[80] Error packet?
  8535.      call pxerr        ;[82] If so, print it.
  8536.     skiple t1, filjfn    ;[80] Close the file.    
  8537.      CLOSF            ;[80]
  8538.      erjmp .+1        ;[80]
  8539.     setzm filjfn        ;[80]
  8540. seofx:    movei state, "A"    ; Otherwise cancel.
  8541.     ret
  8542.  
  8543. ; EOF packet was ACK'd OK, close the file, get the next one (if any).
  8544.  
  8545. seof4:    skipn xflg        ;[126] Sending a real file?
  8546.      jrst [    skipn t1, tlgjfn ;[126] Transaction log?
  8547.          jrst .+1
  8548.         hrroi t2, [asciz/   Sent: /] ; Yes, log this info.
  8549.         setzb t3, t4
  8550.         SOUT
  8551.         move t2, schr    ; Number of bytes.
  8552.         movei t3, ^d10
  8553.         NOUT
  8554.          nop
  8555.         movei t2, 40    ; A space
  8556.         BOUT
  8557.         movei t2, 7    ; Bytesize
  8558.         skipe ebtflg
  8559.          aos t2
  8560.         NOUT
  8561.          nop
  8562.         hrroi t2, [asciz/-bit bytes
  8563. /]
  8564.         setzb t3, t4
  8565.         SOUT
  8566.         jrst .+1 ]
  8567.  
  8568.     setzm numtry        ;[52] Reset the retry counter.
  8569.     addm schr, stchr    ; Add the last file's size to the total.
  8570.     setz schr,        ; Zero the present count.
  8571.     aos files        ;[61] Count the file.
  8572.     skipn source        ;[128] Sending a file?
  8573.      jrst [    skipg t1, filjfn ;[128] Yes, get the JFN of the file just sent.
  8574.          jrst .+1    ;[128]  If no valid JFN, don't bother closing.
  8575.         txo t1, co%nrj    ; Don't release it, GNJFN still needs it.
  8576.         CLOSF%        ; Close the file.
  8577.          %jserr (,.+1)    ;[59] Print msg but continue if error.
  8578.         jrst .+1 ]    ;[121]
  8579.     ;...
  8580.  
  8581. ;...SEOF, cont'd
  8582.  
  8583.  
  8584. ; Messages to screen and transaction log.
  8585.  
  8586.     skiple filjfn        ;[127] Transaction log stuff.
  8587.      skipe xflg        ;[126]  Don't bother if not a real file.
  8588.      skipa            ;[126]
  8589.      wtlog <Closed >,filjfn    ;[126]
  8590.     hrroi t1, [asciz/[OK]/]    ; Normal comforting message.
  8591.     skipe cxseen        ; But was sending interrupted this way?
  8592.      hrroi t1, [asciz/[interrupted]/] ; Yes, say so.
  8593.     skipe czseen        ; Or this way?
  8594.      hrroi t1, [asciz/[group interrupted]/] ; Yes, say so.
  8595.     move t4, t1        ; Keep for log.
  8596.     skipe local        ; Local use?
  8597.      PSOUT            ; Yes, print selected message.
  8598.     skipe t1, tlgjfn    ;[126] If we have a transaction log, there too.
  8599.      jrst [    move t2, t4
  8600.         setz t3,
  8601.         skipn cxseen
  8602.          skipe czseen
  8603.         SOUT        
  8604.         jrst .+1 ]
  8605.  
  8606. seof5:    skipn source        ;[121] Really doing files?
  8607.      call gtnfil        ; If so, get the next file to send.
  8608.      jrst [    setzm filjfn    ;  If not, or if no more, zero the JFN,
  8609.         movei state, "B" ; set state to complete,
  8610.         ret ]        ;[59]  and return to state switcher.
  8611.     movei state, "F"    ; OK, switch to File-send state.
  8612.     ret
  8613.  
  8614. ; SEOT -- Send End Of Transmission packet.
  8615.  
  8616.  
  8617. seot:    saveac <q1>
  8618. seotb:    move q1, numtry        ; Get the number of tries.
  8619.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  8620.      jrst [    movei state, "A" ;  Change the state to cAncel.
  8621.         ermsg <Can't send EOT>, r ]
  8622.     aos numtry        ; Increment number of tries.
  8623.     movei t1, "B"        ; Packet type is Break (EOT).
  8624.     move t2, pktnum        ; Packet number.
  8625.     setzb t3, t4        ; No data.
  8626.     call spack        ; Send the packet.
  8627.      jrst @[exp seotb, seotx](t1) ; Handle any errors.
  8628.     call rpack        ; Get a packet.
  8629.      ret            ;  Trashed packet don't change state, retry.
  8630.     cain t1, "Y"        ; Check the packet.
  8631.      jrst [    came t2, pktnum    ;  Is it the right ACK?
  8632.          ret        ;   No, don't settle, hold out for right one.
  8633.         setzm numtry    ;  Reset the number of tries.
  8634.         aos t2, pktnum    ; Increment packet number
  8635.         andi t2, 77    ; mod 100
  8636.         movem t2, pktnum ; save it back.
  8637.         movei state, "C" ;  Complete state.
  8638.         skipn xflg    ;[126] Put message in transaction log,
  8639.          wtlog <Send Complete> ;[126] if it was a real file transfer.
  8640.         ret ]
  8641.     cain t1, "N"        ; NAK?
  8642.      jrst [    aos nnak    ;[54] Yes, count the NAK.
  8643.         move t1, pktnum    ;[51] Is the NAK for the next packet?
  8644.         aos t1        ;[51]
  8645.         andi t1, 77    ;[51]
  8646.         caie t1, (t2)    ;[51]
  8647.          ret        ;  No, must send current one again.
  8648.         movem t1, pktnum ; Yes, behave like it was an ACK for this one.
  8649.         setzm numtry    ; Reset the number of tries.
  8650.         movei state, "C" ; Complete state.
  8651.         ret ]
  8652.     cain t1, "T"        ; Timer interrupt pseudo packet?
  8653.      ret
  8654.     cain t1, "E"        ;[82] Error packet?
  8655.      jrst pxerr        ;[82]  Yes, print it & cancel.
  8656. seotx:    movei state, "A"    ; Otherwise cancel.
  8657.     ret
  8658.  
  8659. ;[63] Rewrite file routines.
  8660. ;
  8661. ; GETBUF - Get buffer (i.e. packet) full of characters from input file.
  8662. ;
  8663. ; Call with
  8664. ;  AC1/ desired number of characters to get (i.e. data buffer size)
  8665. ; Returns:
  8666. ;  +1, failure, with AC1/ 0 if end of input file, or nonzero if other error.
  8667. ;  +2, success, with AC1/ number of characters actually gotten, and
  8668. ;      the result accessible by [point 8, data].
  8669. ;
  8670. getbuf:    saveac<q1,q2,q3,q4>
  8671.  
  8672.     skipg t1         ; Make sure the number is not 0 or negative.
  8673.      ret            ;  This gives the right return code.
  8674.     caile t1, ^d9000    ; Make sure the number is not too big.
  8675.      movei t1, ^d9000
  8676.     move q4, t1        ; Maximum number of characters to return.
  8677.     setz q2,        ; Counter for actual characters returned.
  8678.     move q3, [point 8, data] ; Where to put the result.
  8679.     setzm rpt        ;[126] Clear leftover repeat counts from last.
  8680.  
  8681. getbfa:    skipge next        ; First time through, get first character.
  8682.      jrst [    call getch
  8683.          jumpn t1, r    ;[64] Pass along any failure
  8684.         setz t1,    ; Since GETCH puts the character it got in NEXT
  8685.         exch t1, next    ; it has to be moved to CH, just this once.
  8686.         movem t1, ch
  8687.         jrst .+1 ]
  8688.     
  8689. getbfb:    skipl ch        ; Do we have one?  If not, must be EOF.
  8690.      caml q2, q4        ; Or buffer full?
  8691.      jrst getbfx        ; If so, return it.
  8692.  
  8693. ; Get next character for lookahead.
  8694.  
  8695. getbfc:    call getch        ; Get next one.
  8696.      jumpn t1, r        ;[64] Pass along any failure
  8697.     call encode        ; Go do any prefixing.
  8698.     skipge t1, next        ; Set up for next time through.
  8699.      jrst getbfx        ;  If no next, we're done.
  8700.     movem t1, ch        ; Otherwise next is now current.
  8701.     jrst getbfa        ; Loop till done.
  8702.  
  8703. ; Return the buffer.
  8704.  
  8705. getbfx:    skipg t1, q2        ; Return length of data
  8706.     ret            ; +1 if 0 (= EOF)
  8707.     retskp            ; +2 if greater than zero.
  8708.  
  8709. ;[63] This routine added as part of edit 63.
  8710. ;
  8711. ; ENCODE - Process a character -- do any prefixing, etc, necessary to
  8712. ; insert the character into a data packet.
  8713. ;
  8714. ; Call with character in global CH, global RPTFLG and EBQFLG indicating
  8715. ; whether repeat and 8th-bit prefixing are to be done.
  8716. ;
  8717. ; Returns:
  8718. ;  +1 always, with CH unmodified, q2/ updated packet length.
  8719. ;  Uses t2-t4.
  8720. ;
  8721. encode:    move t4, ch        ; Get current character.
  8722.     skipn rptflg        ; Doing repeat count prefixing?
  8723.      jrst enco8        ;  No, skip to next part.
  8724.  
  8725. ; Repeat count processing.  Check if this character same as next.
  8726.  
  8727. encor:    camn t4, next        ; Same as next one?
  8728.      jrst [    aos t2, rpt    ; Yes, just count it.
  8729.         caige t2, ^d94    ; Count within bounds?
  8730.          ret        ;  Yes, done.
  8731.         sos t2        ;[93] No, adjust as though next char different.
  8732.         jrst encor4 ]    ; Go emit a repeat sequence for this much.
  8733.  
  8734. ; Different, see if there were any repeats.
  8735.  
  8736. encor2:    skipg t2, rpt        ; CH not same as next.  Any repeats?
  8737.      jrst enco8        ; No, on to next part.
  8738.     caige q2, (q4)        ;[93] Yes, near end of buffer?
  8739.      cain t2, 1        ; Or only repeated once?
  8740.      jrst [    setzm rpt    ;[144] Set all the repeat count back to zero.
  8741.         call enco8    ;[144] Call self, skipping around this part,
  8742.         move t4, ch    ;[144] and again.
  8743.         call enco8    ;[144]
  8744.         ret ]        ;[93] and return.
  8745.  
  8746. ; Repeated more than once -- general case.
  8747.  
  8748. encor4:    move t3, rptq        ; Emit a repeat sequence --
  8749.     idpb t3, q3        ; the repeat prefix character,
  8750.     addi t2, <40+1>        ;[93] followed by 'tochar(count+1)'
  8751.     idpb t2, q3        ;  because if it's repeated 1x there are 2...
  8752.     addi q2, 2        ; Account for these prefix characters.
  8753.     setzb t2, rpt        ; Clear repeat count.
  8754.  
  8755.     ;...
  8756.  
  8757. ;...ENCODE, cont'd
  8758.  
  8759.  
  8760. ; 8th-bit prefixing.
  8761.  
  8762. enco8:    setz t2,        ; Bit-8 flag.
  8763.     trzn t4, 200        ; Test & clear parity bit.
  8764.      jrst encoc        ;  Not set, on to next part.
  8765.     seto t2,        ; Remember it was on.
  8766.     skipn ebqflg        ; Doing 8th-bit quoting?
  8767.      jrst encoc        ;  No, so skip this.
  8768.     move t3, ebq        ; Yes, stick in an 8th-bit prefix.
  8769.     idpb t3, q3    
  8770.     aos q2            ; Count it.
  8771.  
  8772. ; Control prefixing.
  8773.  
  8774. encoc:    cail t4, 40        ; Control character
  8775.      cain t4, .chdel    ; or DEL?
  8776.      jrst [ xori t4, 100    ; Yes, convert to printable
  8777.         jrst encoc4 ]    ; and go insert a control prefix.
  8778.  
  8779. ; Prefix prefixing.
  8780.  
  8781. encoc1:    camn t4, squote        ; Control Prefix?
  8782.      jrst encoc4        ;  Yes.
  8783.  
  8784. encoc2:    skipn rptflg        ; Repeat processing?
  8785.      jrst encoc3        ;  No.
  8786.     camn t4, rptq        ; Yes, is the character the repeat prefix?
  8787.      jrst encoc4        ;  Yes, insert a control prefix before it.
  8788.  
  8789. encoc3:    skipe ebqflg        ; Eighth-bit prefixing?
  8790.     came t4, ebq        ; Is the character the 8th-bit prefix?
  8791.      jrst encocx
  8792.  
  8793. encoc4:    move t3, squote        ; Insert a control prefix.
  8794.     idpb t3, q3
  8795.     aos q2            ; Count it.
  8796.  
  8797. ; Now, finally, insert the character itself.
  8798.  
  8799. encocx:    skipe t2        ; Was 8th bit on originally?
  8800.      skipe ebqflg        ;[109] Yes, but did we quote it already?
  8801.      skipa            ;[109] In that case, don't put it back.
  8802.      tro t4, 200        ;  It was on & wasn't quoted so put it back.
  8803.     idpb t4, q3        ; Deposit it.
  8804.     aos q2            ; Count it.
  8805.  
  8806.     ret
  8807.  
  8808.     subttl File routines
  8809.  
  8810. ;[63] This routine added as part of edit 63.
  8811. ;
  8812. ; GETCH - Get a character from the disk file.
  8813. ; If global SOURCE is nonzero, it is assumed to contain an address of a
  8814. ; routine to be used instead of this one.
  8815. ;
  8816. ; Returns:
  8817. ;  +1 on failure, with t1/0 if EOF, t1/-1 if real error getting character.
  8818. ;  +2 on success, with global NEXT containing the character, -1 if EOF.
  8819. ;
  8820. getch:    skipe t1, source    ;[102] Alternate routine to call?
  8821.      jrst (t1)        ;[102]  Yes, go there instead.
  8822.     saveac <q1,q2,q3>    ; Save permanent ACs.
  8823.     skipe eoflag        ; Is the end of file flag set?
  8824.      jrst [    setzm eoflag    ; Yes, reset EOF flag for next time,
  8825.         jrst getchz ]    ;  and return EOF.
  8826.     skipe mapflg        ; Do we have anything mapped in?
  8827.      jrst getch3        ;  Yes, don't have to do mapping.
  8828.  
  8829. getch1:    move t1, filjfn        ; No, must do mapping, here's the JFN.
  8830.     movx t2, <2,,.fbbyv>    ; Get number of pages and bytes
  8831.     movei t3, pagcnt    ;  into pagcnt and bytcnt,
  8832.     GTFDB%            ;  from the file descriptor block.
  8833.      %jsker <Can't get file length>,getchx ; Return error.
  8834.     skipn bytcnt        ; Any bytes in the file?
  8835.      jrst [    setom eoflag    ;  No, set end-of-file flag.
  8836.         jrst getchz ]    ;  And return EOF.
  8837.     ldb t2, [point 6, pagcnt, 11] ; Get the file byte size.
  8838.     movem t2, bytsiz    ; Save it.
  8839.  
  8840. ; 7- or 8-bit input from the file?  First, check for ITS binary format.
  8841.  
  8842.     skipe itsfil        ;[75] ITS binary format file?
  8843.      jrst getcha        ;[75] Yes, then skip "autobyte" stuff.
  8844.  
  8845. ; Next, if doing "autobyte", use the file byte size.
  8846.  
  8847.     skipe autbyt        ;[81] Are we using autobyte?
  8848.      jrst [    setzm ebtflg    ; Yes, assume seven-bit bytes.
  8849.         cain t2, ^d8    ; Really 8-bit?
  8850.          setom ebtflg    ;  Yes, act like user requested 8-bit.
  8851.         jrst .+1 ]
  8852.  
  8853. ; Now, if we're to do 8-bit input, convert the byte count if necessary.
  8854.  
  8855. getcha:    skipn itsfil        ; ITS binary file?
  8856.      skipe ebtflg        ; Or eight bit mode?
  8857.      jrst [    cain t2, ^d8    ; Yes, is the byte size 8?
  8858.           jrst getchb    ;[170] If so go adjust byte count if necessary.
  8859.         movei t3, ^d36    ; Get the size of a word.
  8860.         idiv t3, t2    ; Divide by the byte size.
  8861.         move q1, bytcnt    ; Get the number of bytes in file.
  8862.         idiv q1, t3    ; Divide by the bytes/word to get words.
  8863.         imuli q1, 4    ; Multiply by 4 (as if 8-bit bytes).
  8864.         movem q1, bytcnt ; Save the new byte count.
  8865.         jrst getchb ]    ;[170] Go adjust byte count.
  8866.     ;...
  8867.  
  8868. ;...GETCH, cont'd
  8869.  
  8870. ; Or, if we're to do 7-bit input, fix the byte count for that.
  8871.  
  8872.     caie t2, 7        ; If the bytesize is not 7 or 8, treat as 7.
  8873.      cain t2, ^d8        ;[170] (don't do this to 8-bit files!
  8874.      skipa            ;[170]  ...)
  8875.      jrst [    movei t3, ^d36    ; Must convert, get the size of a word.
  8876.         idiv t3, t2    ; Divide by the byte size.
  8877.         move q1, bytcnt    ; Get the number of bytes in file.
  8878.         idiv q1, t3    ; Divide by the bytes/word to get words.
  8879.         imuli q1, 5    ; Multiply by 5 (as if 7bit bytes).
  8880.         movem q1, bytcnt ; Save the new byte count.
  8881.         jrst getch2 ]    ; Go map in page.
  8882.  
  8883. getchb:    skipn itsfil        ;[86][170] ITS binary file?
  8884.      jrst getch2        ;[86]  No, proceed.
  8885.     move q1, bytcnt        ;[86] Yes, get byte count.
  8886.     subi q1, 4        ;[86] Subtract 4 to account for header.
  8887.     movem q1, bytcnt    ;[86] Save it back.
  8888.  
  8889. ; Byte size figured out, now map in the first page.
  8890.  
  8891. getch2:    hrlzs t1        ; Form file JFN,, page 0
  8892.     hrlm t1, pagcnt        ; Zero the left half of pagcnt.
  8893.     call mapi        ; Map it in.
  8894.      jrst getchx        ;  Pass along any failure.
  8895.     skipe itsfil        ;[75] ITS binary file?
  8896.      aos pagptr        ;[75] Yes, skip first word of it.
  8897.     setzm pagno        ; Present page is zero.
  8898.     setom mapflg        ; Say we've got a page mapped in.
  8899.  
  8900. ; Come here if/when/after page is mapped in...
  8901.  
  8902. getch3:    caml schr, bytcnt    ; Any more bytes in file?
  8903.      jrst [    setom eoflag    ; No, Set the end of file flag.
  8904.         call unmapi    ; Unmap the input file page.
  8905.          ret        ;  Fail if we can't
  8906.         setzm mapflg    ; Say nothing mapped in.
  8907.         jrst getchz ]    ; Return EOF.
  8908.  
  8909.     ildb t2, pagptr        ; There are more; get the next one.
  8910.      erjmp getch%        ;[70] (illegal memory read, hole in file...)
  8911.     aos schr        ;[64] Got it OK, count it.
  8912.     ;...
  8913.  
  8914. ;...GETCH, cont'd
  8915.  
  8916. getch4:    hrrz t1, pagptr        ; Are we at the end of the page yet?
  8917.     caige t1, <mappag+1>*1000 ;[64]...
  8918.      jrst getch5        ; No, go return the character.
  8919.     call unmapi        ; Yes, unmap the input page.
  8920.      jrst getchx        ;  Pass along any failure.
  8921.     move t1, pagno        ; Get the present page number.
  8922.     aos t1            ; Increment it.
  8923.     caml t1, pagcnt        ; Any more pages?
  8924.      jrst [    setom eoflag    ; No, set the end of file flag for next time.
  8925.         setzm mapflg    ; Say nothing mapped in,
  8926.         jrst getch6 ]    ; and return normally with the char we got.
  8927.     movem t1, pagno        ; Save the new number.
  8928.     hrl t1, filjfn        ;  <file JFN,, page 0>
  8929.     call mapi        ; Map in the page.
  8930.      jrst getchx        ;  Pass along any failure.
  8931.     ildb t2, pagptr        ; Get the next character.
  8932.      erjmp getch%        ;[70] (Illegal memory read, hole in file...)
  8933.  
  8934. ; Got the character in t2.  Worry about bit 35 if doing 7-bit i/o.  The trick
  8935. ; is to set the parity bit ("b8") of every 5th character to the value of b35
  8936. ; of the PDP-10 word it came from.  The same trick is used by TOPS-20 when
  8937. ; writing ANSI-ASCII tapes.  This allows DEC-10/20 .EXE and other 36-bit binary
  8938. ; files, and SOS-line numbered files, to be sent to 8-bit systems and retrieved
  8939. ; intact.  No adverse effects are suffered by ordinary text files.
  8940.  
  8941. getch5:    move q1, schr        ;[64] Count the character.
  8942.     skipn itsfil        ;[75] ITS binary file?
  8943.      skipe ebtflg        ; Eight bit mode?
  8944.      jrst getch6        ;  One of those, no need to do this.
  8945.                 ;
  8946.     idivi q1, 5        ; No, 7-bit, divide character number by 5.
  8947.     skipn q2        ; Last character of word if remainder is 0.
  8948.      jrst [    move q1, pagptr ;  In that case, get the entire contents.
  8949.         move q1, (q1)    ;
  8950.         trne q1, 1    ; Bit 35 on?
  8951.          tro t2, 200    ; Yes, turn on bit 8 of this character.
  8952.         jrst .+1 ]
  8953.  
  8954. getch6:    movem t2, next        ; Return the character.
  8955.     retskp
  8956.  
  8957. ; EOF return.
  8958.  
  8959. getchz:    setz t1,        ; Return zero error code,
  8960.     setom next        ; and character -1.
  8961.     ret
  8962.     ;...
  8963.  
  8964. ;...GETCH, cont'd
  8965.  
  8966.  
  8967. ; Error return.
  8968.  
  8969. getch%:    skipe local        ;[70]
  8970.      ermsg <Illegal memory read> ;[70]
  8971.  
  8972. getchx:    setob t1, next        ; Return -1 error code, and character -1.
  8973.     movx t2, <.fhslf,,mappag> ;[70] Unmap any page that's still mapped in.    
  8974.     setz t3,        ;[70]
  8975.     PMAP%            ;[70]
  8976.      erjmp .+1        ;[70] Ignore errors.
  8977.     setzm mapflg        ;[70]
  8978.     ret
  8979.  
  8980.  
  8981. ; MAPI - Map in file page.
  8982. ;
  8983. ; Call with
  8984. ;  t1/ jfn,,page number.
  8985. ;
  8986. ; Returns
  8987. ;  +1 on failure.
  8988. ;  +2 on success, with PAGPTR adjusted to point back to beginning of page.
  8989. ;
  8990. mapi:    movx t2, <.fhslf,,mappag> ; Form our fork,,mapping page
  8991.     movx t3, pm%rd        ; Just want to read it.
  8992.     PMAP%            ; Map it in.
  8993.      %jsker <Can't map in file page>,r ;  Error, fail.
  8994.     move t3, [point 7, mappag*1000]    ; Success, get a pointer to the page.
  8995.     skipn itsfil        ;[75] An ITS binary file?
  8996.      skipe ebtflg        ; Or eight bit access?
  8997.      hrli t3, (point 8,)    ; Yes, then use 8-bit pointer.
  8998.     movem t3, pagptr
  8999.     retskp            ; Return successfully.
  9000.  
  9001.  
  9002. ; UNMAPI -- Unmap an input file page.
  9003. ;
  9004. ; Returns +1 on error, +2 on success.
  9005.  
  9006.  
  9007. ; First check to see where we're getting our input from.
  9008. ;
  9009. unmapi:    skipn t1, source    ;[139] But are we really reading from a file?
  9010.      jrst unmap3        ;[139]  Yes, really unmap.
  9011.     caie t1, dirch        ;[139] No, is it a directory listing?
  9012.      jrst unmap2        ;[139] No, something else.
  9013.  
  9014. ; From a directory listing buffer.  Clear it & reset pointers for next time.
  9015.  
  9016.     call dmpbuf        ;[139] Yes, directory listing; clear buffer.
  9017.     setzm source        ;[139] Indicate no more alternate source.
  9018.     ret            ;[139] Done.
  9019.  
  9020. ; From some other source (add others here).
  9021.  
  9022. unmap2:    ret
  9023.  
  9024. ; Source is really a file, unmap the current file page.
  9025.  
  9026. unmap3:    seto t1,        ; Indicate unmap.
  9027.     movx t2, <.fhslf,,mappag> ; This process.
  9028.     setz t3,
  9029.     PMAP%            ; Unmap the page.
  9030.      %jsker <Error unmapping page>,r
  9031.     retskp
  9032.  
  9033. ;[66] PUTBUF -- Write the contents of the data field of a packet out to a file.
  9034. ;
  9035. ; Call with:
  9036. ;  t1/ pointer to data buffer.
  9037. ;  t2/ number of characters.
  9038. ;  pagptr/ output file page byte pointer.
  9039. ; Returns:
  9040. ;  +1: Failure, Couldn't write the whole buffer, Error packet already sent.
  9041. ;  +2: Success
  9042. ;
  9043. putbuf:    saveac <q1,q2>        ; Preserve these ACs.
  9044.     dmove q1, t1        ; Save the arguments.
  9045.  
  9046. putbf2:    jumple q2, rskp        ; Are we done?
  9047.     ildb t2, q1        ; Not yet, get the next character from the pkt.
  9048.     call decode        ; Go decode and store it.
  9049.      ret            ;  Pass along any error.
  9050.     cain rchr, 4        ;[75] Just finished 4th character?
  9051.      call itschk        ;[75]  Yes, see if it was the ITS binary hdr.
  9052.     soja q2, putbf2        ; Loop.
  9053.  
  9054.  
  9055. ;[75] ITSCHK -- See if first 4 bytes of file are ITS binary file header.
  9056. ;
  9057. ; Uses t1-t3.
  9058. ; Returns +1 always, with ITSFIL set if the first 4 bytes are the ITS binary
  9059. ;  file header, sixbit/DSK8/, and with the various pointers and counters
  9060. ;  adjusted appropriately.  By the way, since this routine sets RCHR back to
  9061. ;  zero, it gets called again 4 characters later -- this should do no harm.
  9062. ;
  9063. itschk: skiple itscnt        ; No header characters counted?
  9064.      skipn itsflg        ; Is ITS checking enabled?
  9065.      ret            ;  No, forget it.
  9066.     move t1, itscnt        ; We were counting the matching characters...
  9067.     setzm itscnt        ; Reset the counter.
  9068.     caie t1, 4        ; The four characters matched?
  9069.      ret            ;  No, done.
  9070.     setom itsfil        ; Yes, flag it.
  9071.     move t1, [point 8, <mappag*1000>] ; Set up page pointer for 8 bit.
  9072.     movem t1, pagptr
  9073.     setz rchr,        ; Rewind the character counter.
  9074.     movei t1, 8        ; Record file bytesize correctly
  9075.     movem t1, bytsiz    ;  ...
  9076.     hrroi t1, [asciz/(ITS binary format) /]
  9077.     skipe local        ; Say what happened if local.
  9078.      PSOUT
  9079.     ret
  9080.  
  9081. ;[66] DECODE -- Convert data in Kermit packet to its original form.
  9082. ;
  9083. ; Call with:
  9084. ;  t2/ Character to decode
  9085. ;  q1/ Buffer pointer
  9086. ;  q2/ Position in buffer
  9087. ; Returns:
  9088. ;  +1: Failure, if output could not be done.
  9089. ;  +2: Success, with q1,q2 updated.
  9090. ;
  9091. ; Note: If the input character is a prefix of any kind, this routine
  9092. ; will input all further characters necessary to complete the prefixed
  9093. ; sequence, and update the counts and pointers appropriately.
  9094. ;
  9095. decode:    saveac<q4>        ; Preserve this one.
  9096.  
  9097. decod0:    move t3, t2        ; Make a copy with the parity bit intact.
  9098.     andi t2, 177        ; And without, so comparisons will work.
  9099.  
  9100. decod1:    setzm rpt        ; Reset repeat count.
  9101.     skipn rptflg        ; Repeat count processing?
  9102.      jrst decod2        ;  No.
  9103.     camn t2, rptq        ; Yes.  Is this the repeat prefix?
  9104.      jrst [    ildb t2, q1    ; Yes.  Get the count.
  9105.         andi t2, 177    ; Let's be cautious...
  9106.         subi t2, 40    ; Convert from character to number.
  9107.         movem t2, rpt    ; Save the repeat count.
  9108.         ildb t2, q1    ; Get the next character.
  9109.         move t3, t2    ; Copy with parity (in case it's not a prefix)
  9110.         trz t2, 200    ;  and without...
  9111.         subi q2, 2    ; Account for the repeat prefix sequence.
  9112.         jrst .+1 ]
  9113.     ;...
  9114.  
  9115. ;...DECODE, cont'd
  9116.  
  9117.  
  9118. decod2:    setzm ebqchr        ;[90] Say no 8th-bit prefix on this character.
  9119.     skipn ebqflg        ; Doing 8th-bit quoting?
  9120.      jrst decod3        ;  No.
  9121.     camn t2, ebq        ; Yes, is this the 8th-bit prefix?
  9122.      jrst [    ildb t2, q1    ; Yes, get the character it is prefix of.
  9123.         move t3, t2    ; Copy with parity in case not ctl prefix
  9124.         tro t3, 200    ;  ...
  9125.         trz t2, 200    ;  and without (this shouldn't anyway, but...)
  9126.         setom ebqchr    ;[90] Flag that we did this.
  9127.         sos q2        ; Account for it.
  9128.         jrst .+1 ]
  9129.  
  9130. decod3:    came t2, rquote        ; Control Prefix?
  9131.      jrst decod4        ;  No...
  9132.     ildb t2, q1        ; Yes, get its argument.
  9133.     move t3, t2        ; Copy with parity
  9134.     trz t2, 200        ;  and without...
  9135.     skipe ebqchr        ;[90] Was there an 8th-bit prefix?
  9136.      tro t3, 200        ;[90]  If so, set the 8th bit.
  9137.     sos q2            ; Account for the ctl prefix.
  9138.     cail t2, "@"        ; Check if the character is in the sequence
  9139.      caile t2, "_"        ;  "@ABC...XYZ[\]^_"
  9140.      skipa            ;  No, take it literally.
  9141.      xori t2, 100        ; Yes, controllify.
  9142.     cain t2, "?"        ; Or is it a question mark?
  9143.      movei t2, 177        ; Yes, then it's really a DEL.
  9144.  
  9145. decod4:    trne t3, 200        ; 8th bit was on?
  9146.      tro t2, 200        ;  Yes, then put it on in the result.
  9147.  
  9148. decod5:    skipn q4, rpt        ; Repeat Count.
  9149.      movei q4, 1        ; If zero, make it 1.
  9150.  
  9151. decod6:    jumple q4, decodz    ; Loop for repeat count.
  9152.     aos rchr        ; Count the data character.
  9153.     
  9154. ; The following check must be done here.  We can't look directly at RECPKT,
  9155. ; because it will contain quoting characters which must be evaluated by this
  9156. ; routine.  We can't do it by looking at the result in MAPPAG after calling
  9157. ; PUTCH, because we might be writing to MAPPAG with a 7-bit pointer.
  9158.  
  9159.     caile rchr, 4        ;[75] Check for the ITS header in 1st 4 chars.
  9160.      jrst decod7        ;[75] If past first 4, don't check.
  9161.     camn t2, [exp 0, 223, 72, 330, 0](rchr) ;[75] Check this character.
  9162.      aos itscnt        ;[75] If it matches, count it.
  9163.  
  9164. decod7:    call putch        ; Output the character.
  9165.      ret            ; Pass along any failure.
  9166.     soja q4, decod6        ; Until done.
  9167.     
  9168. decodz:    retskp            ; Success.
  9169.  
  9170. ;[66] PUTCH -- Output a character to a file.
  9171. ;
  9172. ; Call with:
  9173. ;  t2/ Character to output.
  9174. ;  pagptr/ Pointer to where to put it (if disk file).
  9175. ; Returns:
  9176. ;  +1: Failure (disk full, etc).
  9177. ;  +2: Success, pagptr updated. (Uses t1-t4)
  9178. ;
  9179. putch:    skipe t1, dest        ; Alternate PUTCH routine?
  9180.      jrst (t1)        ;  Yes, go to it.
  9181.     skiple filjfn        ;[177] To file?
  9182.      jrst putch2        ;[177] Yes, go do that.
  9183.     skipn local        ;[177] No, to screen.
  9184.      retskp            ;[177] But if remote, skip it.
  9185.     move t1, t2        ; No, then just put it on the screen.
  9186.     PBOUT            ;* Pretty dumb, make this more efficient
  9187.     retskp             ;* later...
  9188.  
  9189. ; File output.  Test to see if page is full.
  9190.  
  9191. putch2:    move t1, pagptr        ; Copy the byte pointer.
  9192.     ibp t1            ; Increment the copy.
  9193.     hrrzs t1        ; Clear out the LH.
  9194.     caig t1, <<<mappag+1>*1000>-1> ; At the end yet?
  9195.      jrst putch5        ;  No, proceed.
  9196.  
  9197. ; A page is filled up -- map it out.
  9198.  
  9199. putch3:    move t4, t2        ; Yes, save the character around this.
  9200.     call unmapo        ; Go unmap the current page.
  9201.      ret            ;  Pass along any failure.
  9202.     move t2, t4        ; Get back the character.
  9203.     aos pagno        ; Advance the file page number.
  9204.  
  9205. ; Rewind the memory page back to word 0.
  9206.  
  9207. putch4:    move t1, [point 7, mappag*1000]    ; Success, make a pointer
  9208.     skipn itsfil        ;[75]
  9209.      skipe ebtflg        ; of the appropriate
  9210.      hrli t1, (point 8,)    ; byte size.
  9211.     movem t1, pagptr    ; Store it.
  9212.  
  9213. ; Deposit the character into the memory page.
  9214.  
  9215. putch5:    idpb t2, pagptr        ; Put it in the page.
  9216.     ;...
  9217.  
  9218. ;...PUTCH, cont'd
  9219.  
  9220.  
  9221. ; Worry about bit 35.
  9222.  
  9223. putch6: skipe itsfil        ;[75][81] ITS binary file?
  9224.      retskp            ;[75]  Yes, don't worry about this.
  9225.     skipn ebtflg        ; Output to 7-bit file?
  9226.      trnn t2, 200        ; AND parity bit is on?
  9227.      retskp            ; No, done.
  9228.  
  9229. putch7:    move t3, rchr        ; Yes, both, get the char count,
  9230.     idivi t3, 5        ; modulo 5.
  9231.     jumpg t4, rskp        ; Is this the last char in the word?
  9232.  
  9233. putch8:    move t3, pagptr        ; Yes, get its contents.
  9234.     move t4, (t3)        ; ...
  9235.     tro t4, 1        ; Turn on bit 35.
  9236.     movem t4, (t3)        ; Put it back.
  9237.     retskp            ; Done.
  9238.  
  9239.     subttl File Routines
  9240.  
  9241. ; GTNFIL - Get next file from wild file specification.
  9242. ; Return +1 with AC1/0 if no more, or +2 with JFN of next file in AC1.
  9243. ;
  9244. ;[111] Rewritten to do 1-file lookahead as part of edit 111.
  9245. ;
  9246. gtnfil:    move t1, filjfn        ; Release the JFN of the previous file.
  9247.     RLJFN
  9248.      erjmp .+1
  9249.     setzm filjfn
  9250.  
  9251. ; Check to see if we really want to or can get the next file.
  9252.  
  9253.     setz t1,        ; Assume no more files.
  9254.     skipn czseen        ;[59] If CTRL-Z seen, then get no more files.
  9255.      skipn t1, nxtjfn    ; No CTRL-Z.  Get next JFN.
  9256.      ret            ; None, so we're done.
  9257.  
  9258. ; Make a separate JFN for the file so that wildcard stepping won't be wiped
  9259. ; out by anything we do to it, like deleting it, renaming it, etc.
  9260.  
  9261.     hrrz t2, t1        ; Get the filename string.
  9262.     hrroi t1, strbuf
  9263.     setz t3,
  9264.     JFNS
  9265.      erjmp r
  9266.     movx t1, gj%old!gj%sht    ; Get a new JFN on it.
  9267.     hrroi t2, strbuf
  9268.     GTJFN
  9269.      erjmp r
  9270.     hrrzm t1, filjfn    ; Save it here.
  9271.     setzm strbuf
  9272.  
  9273. ; Get new next JFN.
  9274.  
  9275.     move t1, nxtjfn        ; Get the JFN again.
  9276.     hll t1, ndxjfn        ; Get wildcard flags into left half.
  9277.     GNJFN            ; Get the next JFN.
  9278.      setz t1,        ; If no more, set this to zero.
  9279.     movem t1, nxtjfn    ; Save result for next time.
  9280.  
  9281. ; Return with current JFN.
  9282.  
  9283.     move t1, filjfn        ; Return JFN of current file in t1.
  9284.     retskp            ; Return +2 indicating another file was found.
  9285.  
  9286. ;[119] MAKFIL - Rewritten as part of edit 119.
  9287. ;
  9288. ; Construct an output filespec from name given in file header packet.
  9289. ;
  9290. ; Call with:
  9291. ;  T1/ Pointer to a file name from packet.
  9292. ;  T2/ Number of characters.
  9293. ;
  9294. ; Return:
  9295. ;  +1: Failure
  9296. ;  +2, Success, with JFN in T1.
  9297. ;
  9298. makfil:    skipe filjfn        ; Do we have a file yet?
  9299.      jrst [ move t1, filjfn    ;  If so just return its JFN.
  9300.         retskp ]
  9301.     skipg t2        ; Are there at least a few chars?
  9302.      jrst [    setz t1,
  9303.         kermsg <File name not specified>, r ]
  9304.  
  9305.     call decodf        ;[141] Decode the file name.
  9306.      kermsg <Can't decode filename>, r
  9307.  
  9308. ; Now fix up the name, if desired, and get a JFN on it.
  9309.  
  9310.     call filfix        ; Go check & fix the filename syntax.
  9311.     movx t1, gj%sht!gj%fou    ; Short form.
  9312.     GTJFN%
  9313.      erjmp makfix        ;[132] On error, go do something else.
  9314.     retskp
  9315.  
  9316. ;[132] Despite all efforts, couldn't construct legal name for file.
  9317.  
  9318. makfix:    movx t1, gj%sht!gj%fou    ; Get a JFN for...
  9319.     hrroi t2, [asciz/-UNTRANSLATABLE-FILENAME-.KERMIT.-1/]    ; ...this.
  9320.     GTJFN    
  9321.      %jsker <Can't get JFN in MAKFIL>,r ; This should never fail, but...
  9322.     move q1, t1        ; Log what happened.
  9323.     wtlog <Illegal incoming name changed to >,q1
  9324.     move t1, q1        ; Get this back.
  9325.     retskp
  9326.  
  9327. ;[141] Moved to separate routine as part of edit 141.
  9328. ;
  9329. ; Decode a file found in the data field of a KERMIT packet.
  9330. ; Call with:
  9331. ;  t1/ pointer to data field.
  9332. ;  t2/ number of characters in data field.
  9333. ;
  9334. ; Returns:
  9335. ;  +1 on failure,
  9336. ;  +2 on success, with pointer to decoded filename in t1.
  9337. ;
  9338. decodf:    saveac <q1>        ; Preserve this.
  9339.     move q1, t1        ; Save argument for a sec.
  9340.     move t1, [point 7, strbuf] ; Build decoded name here.
  9341.     movem t1, strptr
  9342.     setzm strbuf        ; Clear out the string buffer
  9343.         move t1, [strbuf,,strbuf+1] ; so result will be asciz.
  9344.     blt t1, strbz        ; ...
  9345.  
  9346.     movei t1, putsch    ; Routine to deposit decoded characters.
  9347.     movem t1, dest        ; ...
  9348.     move t1, q1        ; Get argument back.
  9349.     call putbuf        ; Decode the file name string.
  9350.      ret            ;  Failed for some reason, pass it along.
  9351.     setzm dest        ; Decoded OK, restore normal destination.
  9352.     move t1, [point 7, strbuf] ; Return pointer to decoded file name.
  9353.     retskp            ; +2.
  9354.  
  9355. ; FILFIX - Fix incoming file names by quoting illegal characters with ^V.
  9356. ;*(Should also make sure length is no greater than 39.39)
  9357. ;
  9358. ; Call with t1/ Pointer to filename
  9359. ; Returns +1 always, with t2 pointing to legal TOPS-20 filename.
  9360. ;
  9361. filfix:    skipe xfnflg        ;[84] Doing filename conversion?
  9362.      jrst filcnv        ;[84]  Yes, then go do that.
  9363.     move t3, [point 7, filbuf] ; No, but still have to quote funnies.
  9364.     setzm filbuf        ;[174]
  9365.     setom fildot        ; Count dots.
  9366.  
  9367. filfx2:    ildb t2, t1        ; Get the next character.
  9368.     jumpe t2, [        ; No more, done.
  9369.         idpb t2, t3    ; Put the null in.
  9370.         move t2, [point 7, filbuf] ; Return a pointer to the filename.
  9371.         ret ]
  9372.  
  9373. ; Got a character, validate it.
  9374.  
  9375.     cail t2, "A"        ; Upper case letters are legal.
  9376.      caile t2, "Z"    
  9377.      skipa
  9378.      jrst filfx4
  9379.     cail t2, "0"        ; Digits are legal.
  9380.      caile t2, "9"
  9381.      skipa
  9382.      jrst filfx4
  9383.     caie t2, "$"        ; Dollar sign is legal
  9384.      cain t2, "-"        ; So is dash.
  9385.      jrst filfx4
  9386.     caie t2, "_"        ; Underscore is legal.
  9387.      cain t2, 73        ; Allow semicolon for attributes.
  9388.      jrst filfx4
  9389.     cain t2, "."        ; Dot?
  9390.      jrst [    aosg fildot    ; Yes, count it.
  9391.          jrst filfx4    ; First dot, ok to use it.
  9392.         jrst filfx3 ]    ; Not first, go prefix it.
  9393.     cail t2, "a"        ;[153] A lower case letter?
  9394.      caile t2, "z"        ;[153] ...
  9395.      skipa            ;[153]  No, something very illegal then.
  9396.      jrst [    trz t2, 40    ;[153] Yes, convert to upper and
  9397.         jrst filfx4 ]    ;[153] use it.
  9398.  
  9399. ; Get here with illegal character that must be prefixed with control-V.
  9400.  
  9401. filfx3:    movei t4, ^o26        ; Control-V.
  9402.     idpb t4, t3        ; Insert it before the character.
  9403.  
  9404. ;[174] Deposit the character, but if first and a dot, insert an X before it.
  9405.  
  9406. filfx4:    skipn filbuf        ; Something in buffer already?
  9407.      caie t2, "."        ; No, first character is a dot?
  9408.      jrst filfxx        ; OK to go ahead.
  9409.     movei t4, "X"        ; 1st char would be a dot, so...    
  9410.     idpb t4, t3        ;[174]
  9411.  
  9412. filfxx:    idpb t2, t3        ; Now deposit the actual character.
  9413.     jrst filfx2        ; Loop till done.
  9414.  
  9415. ;[84] Convert incoming filename to "normal form".
  9416. ; This routine added as part of edit 84.
  9417.  
  9418. filcnv:    move t3, [point 7, filbuf] ; Where to put new file name.
  9419.     setzm filbuf        ;[174]
  9420.     movei q1, 1        ; Dot counter.
  9421.  
  9422. filcn2:    ildb t4, t1        ; Get next character.
  9423.     jumpe t4, filcnx    ;[142] If null, done.
  9424.     caie t4, "."        ; Dot?
  9425.      jrst filcn4        ;  No.
  9426.  
  9427. ;[174] check for names starting with dot.
  9428.  
  9429.     skipn filbuf        ; Anything in name yet?
  9430.      jrst [    movei t4, "X"    ;  No, insert an X.
  9431.         idpb t4, t3
  9432.         movei t4, "."
  9433.         jrst .+1 ]    ;[174]
  9434.      soje q1, filcn4        ; Yes, make sure there's only one dot.
  9435.     movei t4, "X"        ; If more, translate extra dots to X's.
  9436.     jrst filcn5
  9437.  
  9438. filcn4:    move t4, xfntab(t4)    ; Translate it.
  9439. filcn5:    idpb t4, t3        ; Put it back.
  9440.     jrst filcn2        ; Loop till done.
  9441.  
  9442. filcnx:    setz t2,        ; Put a null at the end.
  9443.     idpb t2, t3
  9444.     move t2, [point 7, filbuf] ; Return a pointer to the file.
  9445.     ret
  9446.  
  9447. ; Translate table to turn funny characters into X's, raise lower case
  9448. ; letters, leave upper case letters and digits, and periods alone.
  9449. ; For translating file names to "normal form".
  9450.  
  9451. xfntab:    repeat <^d46>,<exp "X">
  9452.     exp ".","X"
  9453.     exp "0","1","2","3","4","5","6","7","8","9"
  9454.     repeat <7>,<exp "X">
  9455.     exp "A","B","C","D","E","F","G","H","I","J","K","L","M","N"
  9456.     exp "O","P","Q","R","S","T","U","V","W","X","Y","Z"
  9457.     repeat <6>,<exp "X">
  9458.     exp "A","B","C","D","E","F","G","H","I","J","K","L","M","N"
  9459.     exp "O","P","Q","R","S","T","U","V","W","X","Y","Z"
  9460.     repeat <5>,<exp "X">
  9461.     0
  9462.  
  9463.     subttl    Line routines
  9464.  
  9465.  
  9466. ; INILIN -- Initialize the communication line for file transfer.
  9467. ;
  9468. inilin:    skipe inited        ;[177] Already init'd?  Don't do it again.
  9469.      ret            ;[177]
  9470.     call gtclas        ;[130] Check status of class scheduler.
  9471.  
  9472. ; Set all the terminal mode bits for transparent i/o.
  9473.  
  9474. inil2:    call dobits        ; Go do the bits.
  9475.      ret            ;  Pass along any failures.
  9476.     call doarpa        ; Set up any Arpanet stuff.
  9477.  
  9478. ; Clear the comm line's input buffer.
  9479.  
  9480.     move t1, netjfn        ;[82] Clear the line in case a bunch of NAKs
  9481.     CFIBF            ;[1]  have piled up.
  9482.      erjmp .+1        ;[147] Ignore any errors.
  9483.     setom inited        ;[177] Flag we've done this.
  9484.     ret
  9485.  
  9486. ; Get Scheduler Class information.
  9487. ;
  9488. gtclas:    setzm class        ; Start out assuming scheduler class 0.
  9489.     movei t1, .skrcv    ; Class scheduler on?
  9490.     movei t2, t3
  9491.     movei t3, 2        ; Just want 2 words.
  9492.     SKED%
  9493.      erjmp gtclsa        ; Not R4 or above?  Say it's not on.
  9494.     txnn t4, sk%stp        ; Class scheduler on?
  9495.      skipa            ; Yes, it's on - t4 nonzero.
  9496. gtclsa:     setz t4,        ; No, it's off - t4 zero.
  9497.     movem t4, skdflg    ; Set scheduler flag accordingly.
  9498.     jumpe t4, r        ; If no scheduler, go on to next part.
  9499.  
  9500. ;[130] Scheduler is on, get my scheduler class.
  9501.  
  9502.     movei t2, skdblk    ; Get job's scheduler class.  Here's arg block.
  9503.     movei t1, 5        ; Store length of arg block
  9504.     movem t1, .sacnt(t2)    ;  in arg block.
  9505.     move t1, myjob        ; My job number.
  9506.     movem t1, .sajob(t2)    ; Also into arg block.
  9507.     movx t1, .skrjp        ; Function code for getting job class info.
  9508.     SKED%
  9509.      erjmp .+2        ; Leap frog
  9510.      skipa            ;  to set class to -1 if there was an error.
  9511.      setom .sajcl(t2)    ;
  9512.     move t1, skdblk+.sajcl    ; Now get class.
  9513.     movem t1, class        ; Save it here.
  9514.     ret
  9515.  
  9516. ; Set communication line bits for transparent i/o.
  9517. ; Returns +1 on failure, +2 on success.
  9518. ;
  9519. dobits:    move t1, netjfn        ; JFN for connection to other system.
  9520.     movx t2, .mornt        ; Read system message status.
  9521.     MTOPR
  9522.      %jserr (,dobit2)
  9523.     movem t3, sysmsg    ; Save here for later restoral.
  9524.     movx t2, .mosnt        ; Now refuse system messages.
  9525.     movx t3, .mosmn
  9526.     MTOPR
  9527.      %jserr (,dobit2)
  9528.  
  9529. dobit2:    movx t1, <tl%cro!tl%cor!tl%sab!tl%sta> ;[147] Clear/Refuse links,
  9530.     hrr t1, ttynum        ;[147]  on the line used for file transfer.
  9531.     txo t1, .ttdes        ;[147] (TLINK wants a device designator.)
  9532.     seto t2,
  9533.     TLINK
  9534.      erjmp dobit3        ;[147] Ignore any failure.
  9535.  
  9536. dobit3:    move t1, netjfn        ; JFN for the file transfer line.
  9537.     movei t2, .morxo    ; Get terminal pause end-of-page status.
  9538.     MTOPR%
  9539.      %jserr (,r)
  9540.     movem t3, oldpau    ; Save the old pause mode.
  9541.     movei t2, .moxof    ; Now set to...
  9542.     movei t3, .mooff    ;  no pause on end.
  9543.     MTOPR%
  9544.      %jserr (,r)
  9545.     RFMOD%            ; Get current mode for this line.
  9546.      %jserr (,r)
  9547.     setom carier
  9548.     setzm mdmlin        ;[130] Assume line not modem-controlled.
  9549.     txne t2, tt%car        ;[130] Is it?
  9550.      setom mdmlin        ;[130]  Yes, flag.
  9551.     movem t2, oldmod    ; Save the present mode.
  9552.  
  9553. ;[97] Turn off undesired bits (program echoing, links, translation).
  9554. ;[97] Turn on desired bits (full duplex; TTY has form feed, tab, lowercase).
  9555. ;[97] Note that any other settings are left intact, in particular TT%ECM, which
  9556. ;[97] can cause a TAC to do its own echoing if turned off.
  9557.  
  9558. dobit4:    ; No echo, no links, no advice, no data mode, full duplex.
  9559.     txz t2, <tt%eco!tt%alk!tt%aad!tt%dam!tt%dum!tt%lic> ;[129] Add TT$DUM
  9560. ; No wakeup stuff, infinite width & length.
  9561.     txz t2, <tt%wkf!tt%wkn!tt%wkp!tt%wka!tt%wid!tt%len!tt%uoc> ;[127]
  9562. ; No formfeed/tab/case interpretation, use XON/XOFF.
  9563.     txo t2, <tt%mff!tt%tab!tt%lca!tt%pgm> ;[129] REMOVE TT%DUM!!!
  9564.  
  9565.     skipn handsh        ;[155] Doing handshake?
  9566.      skipn flow        ;[155] Doing flow control?
  9567.      txz t2, tt%pgm        ; Handshake, or no flow - don't do XON/XOFF.
  9568.     SFMOD%            ; Set the bits.
  9569.      %jserr (,.+1)
  9570.     STPAR%
  9571.      %jserr (,.+1)
  9572.     retskp
  9573.  
  9574. ;[129] Do any required ARPAnet stuff.
  9575. ;
  9576. ; Important Note: The ability to send binary mode telnet negotiations
  9577. ; depends on the monitor NOT doubling IACs on TVT lines.  Some versions of
  9578. ; TOPS-20 (particularly BBN's TCP monitor) will do this.
  9579. ;
  9580. ; Returns +1 always, but prints warning on failure.
  9581. ;
  9582. doarpa:    skipn tvtflg        ; Are we on tvt?
  9583.      ret
  9584.  
  9585.     move t1,netjfn        ; Yes, talk binary.
  9586.     dmove t2,[exp <point 8,[byte(8) iac,will,trnbin]>,-3]
  9587.     SOUT%            ; This code adapted from MODEM.MAC
  9588.      %jserr(,doarpx)
  9589.     movei t1,^d4000        ; Sleep four seconds.
  9590.     DISMS%
  9591.     move t1,netjfn        ; Tell TVT "do binary".
  9592.     dmove t2,[exp <point 8,[byte(8) iac,do,trnbin]>,-3]
  9593.     SOUT%
  9594.      %jserr(,doarpx)
  9595.     movei t1,^d4000
  9596.     DISMS
  9597.     ret
  9598.  
  9599. doarpx:    tmsg <
  9600. %KERMIT-20: Warning -- Can't negotiate binary mode with TAC
  9601. >
  9602.     ret
  9603.  
  9604. ; RESLIN -- Reset/Restore the communications line.
  9605. ;
  9606. ; Restore old terminal modes, links, length & width, etc.
  9607. ; Turn off control-C trap.
  9608. ;
  9609. ; CALL RESLIN does nothing if server.
  9610. ; CALL RRSLIN restores the line even if server.
  9611. ;
  9612. reslin: skipe srvflg        ; Server?
  9613.      ret            ;  Yes, forget it.
  9614.  
  9615. rrslin:    call ccoff2        ; REALLY reset the line.
  9616. rrsl2:    skiple filjfn        ; Were we doing something with a file?
  9617.      jrst [    hrrz t1, filjfn    ; If so, try to close it.
  9618.         setzm filjfn
  9619.         CLOSF
  9620.          erjmp .+1
  9621.         jrst .+1 ]
  9622.     call unarpa        ; Undo Arpanet TAC binary mode.
  9623.     call unbits        ; Restore terminal bits.
  9624.     call ttxon        ; Clear up any XOFF condition.
  9625.     CFIBF            ; Also clear out any piled up junk.
  9626.      erjmp .+1
  9627.     setzm inited        ;[177] Flag we're back to normal.
  9628.     ret
  9629.  
  9630. ; Undo the effect of DOBITS -- restore all the communication line's
  9631. ; old bits & modes.
  9632. ;
  9633. unbits:    move t1, netjfn        ; Get the line.
  9634.     movei t2, .moxof    ; Set the terminal pause on end mode...
  9635.     move t3, oldpau        ;  to what it was before.
  9636.     MTOPR%
  9637.      %jserr (,.+1)
  9638.     move t1, netjfn        ; Communication line JFN.
  9639.     move t2, oldmod        ; Get the previous mode.
  9640.     SFMOD%
  9641.      %jserr (,.+1)
  9642.     STPAR%
  9643.      %jserr (,.+1)
  9644.     movx t2, .mosnt        ; Restore system msg refuse/accept.
  9645.     move t3, sysmsg
  9646.     MTOPR
  9647.      %jserr (,.+1)
  9648.  
  9649. ; Restore links and advice if necessary.
  9650.  
  9651.     setz t1,         ; Restore links & advice.
  9652.     move t2, oldmod        ; From old tty mode word.
  9653.     txne t2, tt%alk        ; Was receiving links before?
  9654.      txo t1, <tl%sab!tl%abs> ; Yes, so receive links.
  9655.     txne t2, tt%aad        ; Was receiving advice before?
  9656.      txo t1, <tl%sta!tl%aad> ; Yes, so receive links.
  9657.     jumpe t1, r        ; Skip to next part if no bits to set.
  9658.     hrr t1, ttynum        ; Must set bits, form tty designator
  9659.     txo t1, .ttdes        ;  ...
  9660.     setz t2,        ; Don't leave garbage in here...
  9661.     TLINK            ; Restore the settings.
  9662.      erjmp .+1        ; Ignore any errors.
  9663.     ret
  9664.  
  9665. ; Turn off Arpanet TAC binary mode.
  9666.  
  9667. unarpa:    skipn tvtflg        ; Are we on a tvt?
  9668.      ret            ; No, skip this.
  9669.     
  9670.     dmove t2, [exp <point 8,[byte(8) iac,wont,trnbin]>,-3]
  9671.     SOUT%            ; Yes, turn off binary mode.
  9672.      %jserr(,unarpx)
  9673.     movei t1, ^d4000    ; Wait 4 secs.
  9674.     DISMS%
  9675.     move t1, netjfn        ; Send the command.
  9676.     dmove t2, [exp <point 8,[byte(8) iac,dont,trnbin]>,-3]
  9677.     SOUT%
  9678.      %jserr(,unarpx)
  9679.     movei t1, ^d4000    ; Wait another 4 secs.
  9680.     DISMS%
  9681.     ret            ; Done.
  9682.  
  9683. unarpx:    tmsg <
  9684. %KERMIT-20: Warning -- Can't clear binary mode with TAC
  9685. >                ;[129] Error message for any of the above.
  9686.     ret
  9687.  
  9688. ;[91] Routine to unstop an XOFF'd line, added as edit 91.
  9689.  
  9690. ttxon:    saveac <t1,t2,t3>    ; Save these.
  9691.     move t1, netjfn        ; In case line was XOFF'd, this will
  9692.     CFOBF%            ;  turn it back on (see monitor source).
  9693.      erjmp r
  9694.  
  9695. ;[157] If we're doing flow control, send a ^Q (XON) to unstick the other side.
  9696.  
  9697.     skipn flow        ; Doing flow control?
  9698.      ret            ;  No, done.
  9699.     RFMOD            ; Yes, get terminal mode.
  9700.      erjmp r        
  9701.     move t3, t2        ; Save it.
  9702.     txzn t2, tt%dam        ; Data mode?
  9703.      jrst ttxon3        ;  No, binary, just send it.
  9704.  
  9705. ttxon2:    SFMOD            ; Put in binary mode.
  9706.      erjmp r
  9707.     call ttxon3        ; Send the XON.
  9708.     move t2, t3
  9709.     SFMOD            ; Put back in data mode.
  9710.      erjmp r
  9711.     ret
  9712.  
  9713. ttxon3:    movei t2, xon        ; Send an XON.
  9714.     BOUT
  9715.      erjmp r
  9716.     ret
  9717.  
  9718.     subttl Packet routines
  9719.  
  9720.  
  9721. ;[114] DIAMSG
  9722. ;
  9723. ; Print packet type and number if debugging "states".
  9724. ; Enter with:
  9725. ;   t1/ packet type
  9726. ;   t2/ packet number
  9727. ;   t4/ pointer to data
  9728. ;   logjfn/ debugging log file jfn
  9729. ; Returns +1 always, with all ACs unchanged.
  9730. ;
  9731. diamsg:    cain debug, 1        ; Only for protocol debugging.
  9732.      skipn logjfn        ; Got a log JFN?
  9733.      ret            ;  Nope, forget it.
  9734.     saveac <t1,t2,t3>    ; Save these.
  9735.     push p, t1        ; Save this for sec.
  9736.     move t1, logjfn        ; Get debugging log file JFN.
  9737.     movei t3, ^d10        ; in decimal.
  9738.     NOUT%
  9739.      erjmp deberr        ;[174]
  9740.     pop p, t2        ; Pop packet type
  9741.     BOUT
  9742.      erjmp deberr        ;[174]
  9743.     cain t2, "G"        ; Generic command?
  9744.      jrst [    move t3, t4    ; Log the first character of the data packet.
  9745.         ildb t2, t3
  9746.         BOUT
  9747.          erjmp deberr    ;[174]
  9748.         jrst .+1 ]
  9749. diamsz:    movei t2, " "        ; A space for delimitation.
  9750.     BOUT
  9751.      erjmp deberr        ;[174]
  9752.     ret
  9753.  
  9754. ;[174] Handle i/o errors writing to debugging log file.
  9755.  
  9756. deberr:    tmsg <
  9757. %KERMIT-20: Error writing debug log file - >
  9758.     movei t1, .priou
  9759.     hrloi t2, .fhslf
  9760.     setz t3,
  9761.     ERSTR
  9762.      nop
  9763.      nop
  9764.     tmsg <
  9765. >
  9766.     setz t1,        ; Close the log file if possible
  9767.     call $closd        ; and turn off debug log.
  9768.     ret
  9769.  
  9770. ; SPACK (Send-Packet)
  9771. ;
  9772. ; Assembles & sends a packet from the given arguments.   Assumes all quoting,
  9773. ; prefixing, condensing, etc, already done.  Sends the fields in the proper
  9774. ; order, validating the control fields to some extent, adding desired parity
  9775. ; (if any) to each character, calculates and appends the checksum, appends any
  9776. ; desired padding or eol characters, and does any required pause or handshake.
  9777. ;
  9778. ; Call with:
  9779. ;    AC1 - Type of packet (D,Y,N,S,R,E,F,Z,T,I, or any uppercase letter)
  9780. ;    AC2 - Packet sequence number (binary)
  9781. ;    AC3 - Number (binary) of characters in data field
  9782. ;    AC4 - 8-bit byte pointer to data characters
  9783. ; Returns: +1 on failure, with:
  9784. ;          AC1 - 0: SOUT failed or timeout on handshake (can retry).
  9785. ;              1: invalid argument (no point retrying).
  9786. ;          (These values are suitable indexes for a jump table)
  9787. ;       +2 on success, with ACs 1-4 unchanged.
  9788. ;
  9789. spack:    saveac <q1,q2,q3>    ; Preserve us!
  9790.  
  9791. ; Set things up.
  9792.  
  9793.     dmovem t1, actmp    ; Save what we were called with in a way that
  9794.     dmovem t3, actmp+2    ;  that they only are restored if we want to.
  9795.     movem t1, type        ; Save the type.
  9796.     call diamsg        ; Print diagnostic if desired.
  9797.     setz q2,        ; Zero the checksum AC.
  9798.     move q1, [point 8, sndpkt] ; Get a byte pointer to the send packet.
  9799.  
  9800. ; Start of packet.
  9801.  
  9802.     move t1, ssthdr        ;[18] Get the start of header char.
  9803.     call @parity        ; Call the appropriate parity routine.
  9804.     idpb t1, q1        ; Put in the packet.
  9805.  
  9806. ; Packet length.
  9807. ;
  9808. ;[98] This section changed to allow for different block check types.
  9809.  
  9810.     movem t3, datlen    ; Remember data length for later.
  9811.     skipe bctone        ; Forcing single-character checksum?
  9812.      aosa t3        ;  Yes, then always use type 1.
  9813.      add t3, bctu        ;  Otherwise add the block check length.
  9814.     addi t3, 2        ;[179] Account for SEQ and TYPE.
  9815.     movem t3, pktlen    ;[179] Remember value of packet length field.
  9816. ;[179]    cail t3, 5        ; Does the packet have the minimum length?
  9817.      camle t3, spsiz    ;  And is it below the maximum?
  9818.       kermsg <SPACK: Illegal message length>,spxx2 ; No, fatal.
  9819.     addm t3, stot        ;[22] It's OK, account for the whole packet.
  9820.  
  9821.     setzm islong        ;[179] Assume regular (short) packet
  9822.     caile t3, ^d94        ;[179] Long packet?
  9823.      setom islong        ;[179] Set flag.
  9824.  
  9825.     addi t3, " "        ;[179] Convert to ASCII.
  9826.     skipe islong        ;[179] Long?
  9827.      movei t3, " "        ;[179] Put a blank here
  9828.  
  9829.     add q2, t3        ; Add the LEN field to the checksum.
  9830.     move t1, t3
  9831.     call @parity        ; Call the appropriate parity routine.
  9832.     idpb t1, q1        ; Put the LEN field into the packet.
  9833.     ;...
  9834.  
  9835. ; SPACK, cont'd
  9836.  
  9837.  
  9838. ; Packet sequence number.
  9839.  
  9840.     skipl t1, t2        ; Is the sequence number valid? (0-64)?
  9841.      cail t2, ^o100
  9842.      ermsg <SPACK: Illegal packet sequence number>,spxx2 ; No, fatal.
  9843.     addi t1, " "        ; Add a space so the number is printable.
  9844.     add q2, t1        ; Add the number to the checksum.
  9845.     call @parity        ; Call the appropriate parity routine.
  9846.     idpb t1, q1        ; Put the sequence number into the packet.
  9847.  
  9848. ; Packet type.
  9849.  
  9850.     move t1, type        ; Get the type.
  9851.     cail t1, "A"        ; Check if the type is a capital letter.
  9852.      caile t1, "Z"
  9853.      ermsg <SPACK: Illegal message type>, spxx2 ;[60] Not, fatal.
  9854.     add q2, t1        ; Add in the message type to the checksum.
  9855.     call @parity        ; Call the appropriate parity routine.
  9856.     idpb t1, q1        ; Put the type into the packet.
  9857.     skipg t3, datlen    ; Is there any data?
  9858.      jrst spack3        ;  No, finish up.
  9859.  
  9860. ;[179] Extended header for long packet.
  9861.  
  9862.     skipn islong        ;[179] Long packet?
  9863.      jrst spack2        ;[179] No
  9864.     move t1, pktlen        ;[179] Yes, length
  9865.     subi t1, 2        ;[179] This time we only count data + checksum
  9866.     idivi t1, ^d95        ;[179] Big part of length (quotient)
  9867.     addi t1, " "        ;[179] Convert to ASCII
  9868.     add q2, t1        ;[179] Add to checksum
  9869.     call @parity        ;[179] Tack on parity
  9870.     idpb t1, q1        ;[179] Deposit in packet
  9871.     addi t2, " "        ;[179] Same deal for small part (remainder)
  9872.     add q2, t2        ;[179] Add to checksum
  9873.     move t1, t2        ;[179] Move remainder to t1 for parity routine
  9874.     call @parity        ;[179]
  9875.     idpb t1, q1        ;[179]
  9876.     push p, q2         ;[179] Save current packet checksum
  9877.     move t2, q2        ;[179] Form header checksum
  9878.     andi q2, ^o300        ;[179] ...
  9879.     lsh q2, -6        ;[179]
  9880.     add q2, t2        ;[179]
  9881.     ldb t1, [point 6, q2, 35] ;[179]
  9882.     addi t1, " "        ;[179]
  9883.     pop p, q2        ;[179] Restore packet checksum
  9884.     add q2, t1        ;[179] Include header checksum in it
  9885.     call @parity        ;[179] Add parity to header checksum
  9886.     idpb t1, q1        ;[179] Put it in the packet
  9887.     move t3, datlen        ;[179] Set t3 as spack2 expects to find it.
  9888.  
  9889. ; Loop to put each data character in the packet.
  9890.  
  9891. spack2:    ildb t1, t4        ; Get the next character.
  9892.     add q2, t1        ; Add it to the checksum.
  9893.     call @parity        ; Call the appropriate parity routine.
  9894.     idpb t1, q1        ; Put the character into the packet.
  9895.     sojg t3, spack2        ; Loop for all characters.
  9896.     ;...
  9897.  
  9898. ; SPACK, cont'd.
  9899.  
  9900. ;[98] SPACK3-SPAK3X rewritten as part of edit 98.
  9901.  
  9902.  
  9903. ; Done with the data, now append the appropriate kind of block check.
  9904.  
  9905. spack3:    skipe bctone        ; Doing send-init exchange?
  9906.      jrst spak3a        ;  Then always use type 1.
  9907.     move t1, bctu        ; Get block check type,
  9908.     jrst @[exp spxx2, spak3a, spak3b, spak3c](t1) ; and do it.
  9909.  
  9910. ; Single-character 6-bit checksum.
  9911.  
  9912. spak3a:    move t3, q2        ; Make an extra copy of the checksum.
  9913.     andi q2, ^o300        ; AND out all but 2 bits.
  9914.     lsh q2, -6        ; Shift them to the far right.
  9915.     add q2, t3        ; Add in the original value.
  9916.     ldb t1, [point 6, q2, 35] ; Take modulo 64.
  9917.     addi t1, " "        ; Add a space so the result is printable.
  9918.     call @parity        ; Call the appropriate parity routine.
  9919.     idpb t1, q1        ; Put the checksum into the packet.
  9920.     jrst spak3x        ; Done with checksum.
  9921.  
  9922. ; 2-Character 12-bit checksum.
  9923.  
  9924. spak3b:    ldb t1, [point 6, q2, 29] ; Get bits 24-29 (high order 6 bits).
  9925.     addi t1, " "        ; CHAR of that.
  9926.     call @parity        ; Do any parity.
  9927.     idpb t1, q1        ; Deposit this as first character of checksum.
  9928.     ldb t1, [point 6, q2, 35] ; Get bits 30-35 (low order 6 bits).
  9929.     addi t1, " "        ; CHAR of that.
  9930.     call @parity        ; Do any parity.
  9931.     idpb t1, q1        ; Deposit this as second checksum character.
  9932.     jrst spak3x        ; Done with checksum.
  9933.  
  9934. ; 3-character 16-bit CRC CCITT.
  9935.  
  9936. spak3c:    move t1, datlen        ; Length of the data field.
  9937.     addi t1, 3        ; Plus LEN, SEQ, and TYPE fields.
  9938.     skipe islong        ;[179] Long packet?
  9939.      addi t1, 3        ;[179] Add length of header.
  9940.     move t2, [point 8, sndpkt, 7] ; Point to packet starting at LEN field.
  9941.     call crcclc        ; Go compute the CRC.
  9942.     move q2, t1        ; Here it is.
  9943.     ldb t1, [point 4, q2, 23] ; Get bits 20-23 (high order 4 bits).
  9944.     addi t1, " "        ; CHAR of that.
  9945.     call @parity        ; Do any parity.
  9946.     idpb t1, q1        ; Deposit this as first CRC character.
  9947.     jrst spak3b        ; Go back and do other two CRC characters.
  9948.     ;...
  9949.  
  9950. ; SPACK, cont'd
  9951.  
  9952.  
  9953. ; Supply requested End-of-Line.
  9954.  
  9955. spak3x:    move t1, seolch        ; Get the requested EOL char.
  9956.     call @parity        ; Call the appropriate parity routine.
  9957.     idpb t1, q1        ; Add it to the packet.
  9958.     setz t1,        ; Get a null.
  9959.     idpb t1, q1        ; Put it at the end.
  9960.  
  9961. ;[36] Do any requested interpacket pausing.
  9962.  
  9963. spack5:    skipe t1, pause        ; Pausing?
  9964.      jrst [    fmp t1, [1000.0] ; Yes, convert to milliseconds.
  9965.         fixr t1, t1    ; And then to an integer.
  9966.         DISMS        ; Sleep for that long.
  9967.         jrst .+1 ]
  9968.  
  9969. ; Do any requested padding.
  9970.  
  9971. spak5a:    skipg t4, spadn        ;[34] Sending pad characters?
  9972.      jrst spack6        ;[34]  No, just send the packet.
  9973.     move t1, spadch        ;[34] Yes, this is the character.
  9974.     call @parity        ;[34] Tack on desired parity.
  9975.     move t2, t1        ;[34] Shuffle ACs...
  9976.     move t1, netjfn        ;[34] Where to send the padding.
  9977. spak5b:    BOUT            ;[34] Output the padding character.
  9978.      %jserr <SPACK: Can't send padding>,spack6 ;[34] Warn about errors.
  9979.     sojg t4, spak5b        ;[34] This many pad characters.
  9980.  
  9981.     ;...
  9982.  
  9983. ; SPACK, cont'd
  9984.  
  9985. ;[131] If ARPANET TVT then must double any hex FF's (TELNET IAC).
  9986. ; Note, since IAC is DEL with parity bit on, we should never see one, right?
  9987. ;
  9988. spack6:    move t2, [point 8, sndpkt] ; The address of the packet.
  9989.     skipn tvtflg        ; TVT-Binary mode?
  9990.      jrst spak6x        ; No, just go send it.
  9991.  
  9992.     move t2, [point 8, sndpkt] ; Yes, must double any IACs.
  9993.     move t3, [point 8, tvtbuf] ; Copy data field to this place.
  9994. spak6a:    ildb t1, t2        ; Byte loop.  Get one.
  9995.     jumpe t1, spak6b    ; Done?
  9996.     idpb t1, t3        ; No, copy it.
  9997.     cain t1, iac        ; IAC?
  9998.      idpb t1, t3        ;  Yes, copy it again.
  9999.     jrst spak6a        ; Till done.
  10000. spak6b:    setz t1,        ; Done, make result asciz.
  10001.     idpb t1, t3        ;  ...
  10002.     move t2, [point 8, tvtbuf] ; Point to result.
  10003.  
  10004. ;[131] End.  Now, finally send the packet.
  10005.  
  10006. spak6x:    move t1, netjfn        ; JFN for sending the packet.
  10007.     setzb t3, t4        ; Terminate on a null.
  10008.     SOUT%            ; Send the string.
  10009.      erjmp spxx1        ;  JSYS error, go handle.
  10010.  
  10011. spak6y:    aos sptot        ;[4] Count the packet we sent.
  10012.     skipn debug        ;[128] Debugging?
  10013.      jrst spackb        ;  No, how about blips?
  10014.     caie debug, 2        ;[128] Yes, packets?
  10015.      jrst spackz        ; No, states, that's taken care of elsewhere.
  10016.  
  10017. ; Debugging -- Log the packet.
  10018.  
  10019.     skipn t1, logjfn    ; Yes, but make sure we have a destination.
  10020.      jrst spackz        ;  We don't, skip this.
  10021.     hrroi t2, [asciz/
  10022. S,/]                ; We do, give a crlf and "S," first.
  10023.     setzb t3, t4
  10024.     SOUT
  10025.      erjmp spkder
  10026.     seto t2,        ; Include time stamp, current date/time.
  10027.     movx t3, ot%nda        ; But no date.
  10028.     ODTIM
  10029.      erjmp spkder
  10030. spackd:    movei t2, ","        ; Comma,
  10031.     BOUT
  10032.      erjmp spkder
  10033.     setzb t3, t4
  10034.     move t2, [point 8, sndpkt] ; Now the packet itself.
  10035.     SOUT
  10036.      erjmp spkder
  10037.     hrroi t2, crlf        ; Another crlf
  10038.     SOUT
  10039.      erjmp spkder
  10040.     jrst spackz
  10041.     ;...
  10042.  
  10043. ;...SPACK, cont'd
  10044.  
  10045. ;[174] Recover from errors writing to debugging log.
  10046.  
  10047. spkder:    call deberr
  10048.     jrst spackz
  10049.  
  10050. ;[4] Put blips on user's screen if local.
  10051.  
  10052. spackb:    skipl filjfn        ;[106] No blips if output is to TTY.
  10053.      skipn local        ; Not debugging, but still local?
  10054.      jrst spackz        ;  Remote, don't make blips.
  10055.     move t3, type        ; Local, am I sending a NAK packet?
  10056.     movei t1, "%"        ; Print a "%" for each one I send.
  10057.     move t2, numtry        ; Or each resend I have to do.
  10058.     caig t2, 1        ;
  10059.      cain t3, "N"        ;
  10060.      jrst spackx        ;
  10061.     setz t3,        ; Not a NAK, is it time to blip?
  10062.     move t4, sptot        ; Check the absolute packet number.
  10063.     divi t3, blip        ; We do it every "blip" packets.
  10064.     jumpn t4, spackz    ; Not time for a blip.
  10065.     movei t1, "."        ; It's time, here's the blip.
  10066. spackx:    PBOUT%            ; "."
  10067.  
  10068. ; Common exit point for successful exit.
  10069.  
  10070. spackz:    dmove t1, actmp        ;[60] Restore what we were called with
  10071.     dmove t3, actmp+2    ;[60]
  10072.     retskp
  10073.  
  10074. ; Exit point for nonfatal errors.
  10075.  
  10076. spxx1:    skipe mdmlin        ; Modem line?
  10077.      jrst [    move t1, netjfn    ;  Yes, see if we just dropped carrier.
  10078.         call chkli2
  10079.         skipn carier    ; Still have it?
  10080.          jrst spxx2    ;  No, then fatal.
  10081.         jrst .+1 ]    ; Yes, can continue trying.
  10082.     setz t1,        ;[60] Indicate nonfatal.
  10083.     ret
  10084.  
  10085. ; Exit for fatal errors.
  10086.  
  10087. spxx2:    movei t1, 1        ;[60] Indicate fatal.
  10088.     ret
  10089.  
  10090. ; RPACK -- Receive-Packet
  10091. ;
  10092. ; This routine waits for a packet to arrive.  It reads characters until it
  10093. ; finds the start-of-packet character, normally SOH.  It then reads the packet
  10094. ; into RECPKT based on the length supplied in the length field (no termination
  10095. ; character necessary).
  10096. ;
  10097. ; Returns:
  10098. ;   +1 failure (if the checksum is wrong or the packet trashed)
  10099. ;   +2 success with:
  10100. ;       t1/ Packet type
  10101. ;       t2/ Packet number
  10102. ;       t3/ Length of data field
  10103. ;       t4/ 8-bit byte pointer to data field
  10104. ;
  10105. rpack:    saveac <q1,q2,q3>    ; Save these ACs.
  10106.     stkvar <pktbct>        ; Block check type for this packet.
  10107.  
  10108.     setzm islong        ;[179] Assume packet is not long.
  10109.  
  10110.     cain debug, 2        ; Logging packets?
  10111.      skipn t1, logjfn    ; Yes, make sure there's a log.
  10112.      jrst rpackb
  10113.  
  10114.     hrroi t2, [asciz/
  10115. R,/]                ; "R" for Receive
  10116.     setzb t3, t4
  10117.     SOUT
  10118.      erjmp [call deberr    ;[174] Recover from debug log errors.
  10119.         jrst rpacka ]
  10120.     seto t2,        ; Time stamp, current date/time.
  10121.     movx t3, ot%nda        ; But no date.
  10122.     ODTIM
  10123.      erjmp [call deberr    ;[174]
  10124.         jrst rpacka ]
  10125.     movei t2, "/"        ; Current timeout interval.
  10126.     BOUT
  10127.      erjmp [call deberr    ;[174]
  10128.         jrst rpacka ]
  10129.     movei t1, tmout        ; Place to go on timeout.
  10130.     call timeit        ; Set the timer
  10131.     move t1, logjfn
  10132.     move t2, curtim        ; Log current time interval
  10133.     movei t3, ^d10
  10134.     NOUT
  10135.      erjmp [call deberr    ;[174]
  10136.         jrst rpacka ]
  10137.  
  10138. rpacka:    movei t2, ","
  10139.     BOUT
  10140.      erjmp [call deberr    ;[174]
  10141.         jrst rpackb ]
  10142.     move t1, netjfn        ; JFN of the communication line.
  10143.     jrst rpack0        ; Already set timer...
  10144.  
  10145. ; Here if not logging packets.
  10146.  
  10147. rpackb:    movei t1, tmout        ; Place to go on timeout.
  10148.     call timeit        ; Time out if it takes too long.
  10149.     move t1, netjfn        ; JFN of the communication line.
  10150.     ;...
  10151.  
  10152. ;...RPACK, cont'd
  10153.  
  10154. ; Eat interpacket garbage, read up to start-of-packet character.
  10155.  
  10156. rpack0:    call inchar        ; Get a character from the line.
  10157.      jrst rperr        ;  If we can't, go fail.
  10158.     came t2, rsthdr        ;[18] Is the char the start of header char?
  10159.      jrst rpack0        ;  No, go until it is (or we are timed out).
  10160.  
  10161. ; Now read the packet.
  10162.  
  10163. rpack1:    move q1, [point 8, recpkt] ; OK, now point to the packet buffer.
  10164.     idpb t2, q1        ; Put the start character into the packet.
  10165.  
  10166.  
  10167. ; Packet length field = number of characters to follow the length field,
  10168. ; up to and including the last block check character.
  10169.  
  10170.     call inchar        ; Get next character from the line.
  10171.      jrst rperr
  10172.     camn t2, rsthdr        ;[18] Is the char the start of header char?
  10173.      jrst rpack1        ;  Yes, then go start over.
  10174.     idpb t2, q1        ; Copy character to packet buffer.
  10175.     move q2, t2        ; Start the checksum.
  10176.     move q3, t2        ; Save the length here for later.
  10177.  
  10178. ; Packet sequence number.
  10179.  
  10180.     call inchar        ; Get the next character
  10181.      jrst rperr
  10182.     camn t2, rsthdr        ;[18] Start of header?
  10183.      jrst rpack1        ;  Yes, go start over.
  10184.     idpb t2, q1        ; No, put it in the packet.
  10185.     add q2, t2        ; Add it to the checksum.
  10186.     subi t2, " "        ; Get the real packet number.
  10187.     movem t2, num        ; Save it for later.
  10188.  
  10189. ; Packet type.
  10190.  
  10191.     call inchar        ; Next character.
  10192.      jrst rperr
  10193.     camn t2, rsthdr        ;[18] SOH?
  10194.      jrst rpack1        ;  Yes, go back.
  10195.     idpb t2, q1        ; Not SOH, keep it.
  10196.     add q2, t2        ; Add it to the checksum.
  10197.     movem t2, type        ; It's the message type, remember it.
  10198.     ;...
  10199.  
  10200. ;...RPACK, cont'd
  10201.  
  10202.  
  10203. ;[123] Beginning of change
  10204. ;
  10205. ; Now determine block check type for this packet.  Here we violate the layered
  10206. ; nature of the protocol by inspecting the packet type in order to detect when
  10207. ; the two sides get out of sync.  Two heuristics allow us to resync here:
  10208. ;
  10209. ;   a. An S packet always has a type 1 checksum.
  10210. ;   b. A NAK never contains data, so its block check type is LEN-2.
  10211.  
  10212.     subi q3, " "        ;[179] Convert ASCII length to number.
  10213.     skipn q3        ;[179] Is it zero?
  10214.      setom islong        ;[179] Yes - long packet.
  10215.     skipn islong        ;[179] Long?
  10216.      subi q3, 2        ;[179] No, subtract 2 for SEQ & TYPE fields.
  10217.     move t1, bctu        ; Expected block check type.
  10218.     skipn bctone        ; But if type 1 is required,
  10219.      cain t2, "S"        ; or if this is an S packet,
  10220.      movei t1, 1        ; then force the type to 1.
  10221.     cain t2, "N"        ; But, is this a NAK?
  10222.      move t1, q3        ; Yes, so this must be the block check type.
  10223.     movem t1, pktbct    ; Save the block check type we have determined.
  10224.  
  10225.     skipn islong        ;[179] Long packet?
  10226.      jrst rpackc        ;[179] No, go get data.
  10227.     move t1, netjfn        ;[179] Set up for inchar.
  10228.     call inchar        ;[179] Get next character.
  10229.      jrst rperr        ;[179]
  10230.     idpb t2, q1        ;[179] Save it.
  10231.     add q2, t2        ;[179] Add to checksum.
  10232.     subi t2, " "        ;[179] Convert to number.
  10233.     move q3, t2        ;[179] Set to make...
  10234.     imuli q3, ^d95        ;[179] big part of length.
  10235.     call inchar        ;[179] Get next character.
  10236.      jrst rperr        ;[179]
  10237.     idpb t2, q1        ;[179] Save it.
  10238.     add q2, t2        ;[179] Add to checksum.
  10239.     subi t2, " "        ;[179] Convert to number.
  10240.     add q3, t2        ;[179] Add to big part of length.
  10241.     call inchar        ;[179] Get next character (header checksum)
  10242.      jrst rperr        ;[179]
  10243.     idpb t2, q1        ;[179] Save it.
  10244.     add q2, t2        ;[179] Add to checksum.
  10245.  
  10246. ; [179] HERE WE SHOULD CHECK THE HEADER CHECKSUM...
  10247. ; [179] But no big deal since overall checksum will catch any errors later.
  10248.  
  10249. ; Now subtract the block check length from the packet length, which gives the
  10250. ; length of the data field.
  10251.  
  10252. rpackc:    sub q3, pktbct        ; Calculate the data length.
  10253.     movem q3, datlen    ; Save it.
  10254.  
  10255. ; Take in the data field.
  10256.  
  10257.     move t1, netjfn        ; Get the packet input jfn back again.
  10258.  
  10259. ;[123] End of change.
  10260.  
  10261.     movem q1, datptr    ; Return pointer to the data buffer.
  10262.     skipg q3, datlen    ; Use character count for loop control.
  10263.      jrst rpbc        ;[99] If none, go get the block check.
  10264.  
  10265. ; Loop to get the specified number of data characters.
  10266.  
  10267. rpack2:    hrrz t2, q1        ;[117] Check for buffer overflow.
  10268.     cail t2, recpkz        ;[117] If we're past the end, go back and
  10269.      jrst rpack0        ;[117]  eat characters until a ^A.
  10270.     call inchar        ; Get a character from the line.
  10271.      jrst rperr        ;  Oops, can't.
  10272.     camn t2, rsthdr        ; Is the char the start of header char?
  10273.      jrst rpack1        ;  Yes, then go start over.
  10274.     idpb t2, q1        ; Put the char into the packet.
  10275.     add q2, t2        ; Add it to the checksum.
  10276.     sojg q3, rpack2        ; Get next character, if any.
  10277.     ;...
  10278.  
  10279. ;...RPACK, cont'd
  10280.  
  10281.  
  10282. ; Count exhausted, next characters will be the block check.
  10283. ;
  10284. ;[98] This section, thru RPACK4, mostly rewritten as part of edit 98.
  10285.  
  10286. rpbc:    movem q1, bctemp    ; Save pointer to block check.
  10287.     move q3, pktbct        ;[123] Length of block check for this packet.
  10288.  
  10289. ;[123]    skipl datlen        ;[99] If data len negative, must be type 1 NAK!
  10290. ;[123]     skipe bctone        ;  or if this flag is set,
  10291. ;[123]     movei q3, 1        ;  must look for single-character checksum.
  10292.  
  10293. ; Get the checksum bytes and add them up.
  10294.  
  10295.     setz t3,        ; Accumulator for checksum.
  10296. rpack3:    call inchar        ; Get a character.
  10297.      jrst rperr
  10298.     camn t2, rsthdr        ;[18] Is the char the start of header char?
  10299.      jrst rpack1        ;  Yes, then go start over.
  10300.     idpb t2, q1        ; Got one, deposit it.
  10301.     lsh t3, 6        ; Accumulate numeric value
  10302.     addi t3, -40(t2)    ;  ...
  10303.     sojg q3, rpack3        ; Go back and get the rest.
  10304.     
  10305.     setz t1,        ; Make the string ASCIZ.
  10306.     idpb t1, q1
  10307.  
  10308. ;[135] If doing handshake, look for that now.
  10309. ;[135] (This code moved from beginning of SPACK)
  10310.  
  10311. rpakh1:    skipn handsh        ; Doing handshake?
  10312.      jrst rpakcc        ;  Nope.
  10313. rpakh2:    move t1, netjfn        ; Try to get a character
  10314.     call inchar        ;  from the line.
  10315.      jrst rpakhx        ; If there was an error, try to proceed
  10316.     andi t2, 177        ; Strip the high bit.
  10317.     came t2, handsh        ; Is it the handshake character?
  10318.      jrst rpakh2        ;  No, keep going till it is.
  10319. rpakhx:    ;...
  10320.  
  10321. ;[135](end of change)
  10322.  
  10323. ;...RPACK, cont'd
  10324.  
  10325.  
  10326. ; Check the checksum.
  10327.  
  10328. rpakcc:    skipl datlen        ;[99] If negative data length, or
  10329.      skipe bctone        ;  explicitly requested to,
  10330.      jrst rpak3a        ;  then compute 1 character checksum.
  10331.     move t1, bctu        ; Otherwise get the type which we're using.
  10332.     jrst @[exp rperr, rpak3a, rpak3b, rpak3c](t1)
  10333.  
  10334. ; Here for single-character 6-bit checksum.
  10335.  
  10336. rpak3a:    move q3, q2        ; Make a copy of the arithmetic checksum.
  10337.     andi q2, ^o300        ; And out all but 2 bits.
  10338.     lsh q2, -6        ; Shift them to the far right.
  10339.     add q2, q3        ; Add in the original value.
  10340.     andi q2, 77        ; Get the modulo 64 of the char total.
  10341.     jrst rpak3x        ; Go check it.
  10342.  
  10343. ; Two-character 12-bit checksum.
  10344.  
  10345. rpak3b:    andi q2, 7777        ;[100] Mask out all but 12 bits.
  10346.     jrst rpak3x        ; Go compare.
  10347.  
  10348. ; 3-character 16-bit CRC CCITT.
  10349.  
  10350. rpak3c:    move t1, datlen        ; Get the data length.
  10351.     addi t1, 3        ; Account for LEN, SEQ, and TYPE fields.
  10352.     skipe islong        ;[179] Long packet?
  10353.      addi t1, 3        ;[179] Also account for extended header.
  10354.     move t2, [point 8, recpkt, 7] ; Point to packet starting at LEN field.
  10355.     call crcclc        ; Compute CRC.
  10356.     ldb q2, [point 16, t1, 35] ;[100] Get exactly 16 bits worth.
  10357.     ;...
  10358.  
  10359. ;...RPACK, cont'd
  10360.  
  10361.  
  10362. ; Compare the two block checks.
  10363.  
  10364. rpak3x:    caie t3, (q2)        ; Are they equal?
  10365.      jrst badbc        ;  No, bad block check.
  10366.  
  10367. ; All OK, turn off timer, flush buffer.
  10368.  
  10369. rpack4:    call timoff        ; Got packet OK, turn off the timer.
  10370.     move t1, netjfn        ;[17] Clear out any further junk from input
  10371.     CFIBF%            ;[17] buffer, there should be nothing there
  10372.      erjmp .+1        ;[17] till after we reply.
  10373.  
  10374. ; Set up ACs 1-4 with results and return successfully.
  10375.  
  10376. rpackx:    aos rptot        ; Count the packet we received.
  10377.     move q1, bctemp        ; Pointer to first character of block check.
  10378.     setz t1,        ; Terminate the data string, nullifying
  10379.     idpb t1, q1        ;  the block check.
  10380.  
  10381.     move t1, type        ; Return the packet type in T1,
  10382.     move t2, num        ;  the sequence number in T2,
  10383.     call diamsg        ; Log the packet type & number if desired.
  10384.     skipge t3, datlen    ;  the number of data characters in T3,
  10385.      setz t3,        ;***
  10386.     move t4, datptr        ; and a pointer to the data in t4.
  10387.     retskp            ; Return +2.
  10388.  
  10389. ; Come here if block checks don't compare.
  10390.  
  10391. badbc:    skipn t1, logjfn    ;[38] No, do we have a debugging log?
  10392.      jrst rperr        ;[38]  No, skip messages.
  10393.     setzb t3, t4        ;[38] Yes, say checksum was bad.
  10394.     hrroi t2, [asciz/
  10395. %chksum /]            ;[29]
  10396.     SOUT
  10397.      erjmp [call deberr    ;[174]
  10398.         jrst .+1 ]
  10399.  
  10400. ; Exit thru here upon any kind of error except a timeout.
  10401.  
  10402. rperr:    call timoff        ; Cancel the time out.
  10403.     move t1, netjfn        ;[17] Flush any stacked up packets from the
  10404.     CFIBF%            ;[17] input buffer.  If anything's there, we
  10405.      erjmp .+1        ;[17] don't want it!
  10406.     ret            ; Return unsuccessfully.
  10407.  
  10408.     subttl Support Routines for RPACK.
  10409.  
  10410.  
  10411. ; INCHAR -  Get a character from the communication line.
  10412. ;
  10413. ; Call with:
  10414. ;  t1/ JFN of comm line.
  10415. ;
  10416. ; Returns:
  10417. ;  +1 on failure, with state set to "A" if carrier dropped.
  10418. ;  +2 on success with:
  10419. ;     t1/ unchanged
  10420. ;     t2/ character, with parity bit stripped if parity is being used.
  10421. ;
  10422. inchar:    saveac <t1>        ; Save the JFN.
  10423.  
  10424. ;[180] Begin buffering communications input change.
  10425.  
  10426.     skiple tticnt        ; Something in buffer?
  10427.      jrst [    sos tticnt    ; Yes, decrement count
  10428.         ildb t2, ttiptr    ; Load next byte.
  10429.         aos ttildb    ; (stats)
  10430.         jrst inch3 ]    ; Go handle byte.
  10431.     SIBE%            ; Buffer empty - see if anything is waiting.
  10432.      jrst [ caile t2, IOBUF     ; Adjust if more than buffer size.
  10433.          movei t2, IOBUF
  10434.         movem t2, tticnt ; Remember how many we asked for
  10435.         movn t3, t2     ; Negative version for SIN
  10436.         move t2, [point 8, ttibuf] ; Where to put them
  10437.         movem t2, ttiptr ; Reset buffer pointer
  10438.         SIN%         ; Try to read
  10439.          erjmp inchxx     ; Error...
  10440.         aos ttisin     ; Number of SINs for stats
  10441.         add t3, tticnt     ; How many we got (t3 is negative)
  10442.         camle t3, ttimax ; Maximum size of a SIN for stats
  10443.          movem t3, ttimax
  10444.         movem t3, tticnt ; Save the input byte count
  10445.         skipg tticnt     ; More than zero
  10446.          jrst inch2     ; Less than one - go do blocking BIN
  10447.         sos tticnt     ; Decrement count
  10448.         ildb t2, ttiptr     ; Load next byte.
  10449.         aos ttildb     ; (stats)
  10450.         jrst inch3 ]     ; Go handle byte.
  10451.  
  10452. ; Do BIN if SIBE sees nothing waiting or if SIN gets nothing.
  10453. ;[180] End buffering change.
  10454.  
  10455. inch2:    setzm tticnt        ;[180]
  10456.     setz t2,        ; (in case of error)
  10457.     BIN%            ; Get a character from the line.
  10458.      erjmp inchxx        ;[130] Error, go see what.
  10459.     aos ttibin        ;[180] (stats)
  10460. inch3:                ;[180] (label added).
  10461.     cain debug, 2        ; Logging packets?
  10462.      call [    skipn t1, logjfn ; Yes, make sure there's a log.
  10463.          ret
  10464.         BOUT        ; Record the character.
  10465.          erjmp deberr    ;[174]
  10466.         ret ]
  10467.     aos rtot        ; Increment total character count.
  10468.     move t1, parity        ; What type of parity?
  10469.     caie t1, none        ; If none, don't touch the parity.
  10470.      andi t2, ^o177        ;  Else, take out parity.
  10471.     retskp            ; Done, return successfully.
  10472.  
  10473. ;[130] Error handler to check for carrier dropped.
  10474.  
  10475. inchxx:    skipn mdmlin        ; Modem controlled line?
  10476.      ret            ;  No, just return +1 to indicate error.
  10477.     move t1, netjfn        ; Yes, see if we still have carrier
  10478.     call chkli2        ; ...
  10479.     skipe carier        ; Do we?
  10480.      ret            ;  Yes, so some other error, handle normally.
  10481.     wtlog <Carrier Dropped, Connection Terminated> ; No, lost it.  Log.
  10482.     movei state, "A"    ; Cancel this transaction.
  10483.     setzm carier        ; Say no more carrier.
  10484.      ret
  10485.  
  10486.  
  10487. ; Come here on timeout, via interrupt handler.
  10488.  
  10489. tmout:    call rperr        ;[46] Clean up timers & buffer...
  10490.     call ttxon        ;[91] Unstop the line in case it was XOFF'd.
  10491.     movei t1, "T"        ; Make believe we got a "Timeout" packet
  10492.     move t2, pktnum
  10493.     setzb t3, t4        ; No data.
  10494.     call diamsg
  10495.     retskp            ; Return successfully as if with real packet.
  10496.  
  10497.     subttl CRC and Parity Routines
  10498.  
  10499.  
  10500. ;[66] CRC calculation
  10501. ;
  10502. ; This routine will calculate the CRC for a string, using the
  10503. ; CRC-CCITT polynomial.
  10504. ;
  10505. ; The string should be the fields of the packet between but not including
  10506. ; the <mark> and the block check, which is treated as a string of bits with
  10507. ; the low order bit of the first character first and the high order bit of the
  10508. ; last character last -- this is how the bits arrive on the transmission line.
  10509. ; The bit string is divided by the polynomial
  10510. ;
  10511. ;  x^16+x^12+x^5+1
  10512. ;
  10513. ; The initial value of the CRC is 0.  The result is the remainder of this
  10514. ; division, used as-is (i.e. not complemented).
  10515. ;
  10516. ; Contributed by Nick Bush, Stevens Institute of Technology.
  10517. ;
  10518. ; Call with
  10519. ;  t1/ length of string
  10520. ;  t2/ 8-bit byte pointer to string
  10521. ; Returns +1 always, with t1/ 16-bit CRC, t2 unchanged.
  10522. ;
  10523. ; AC usage:
  10524. ;    t1/ Accumulated CRC
  10525. ;    q4/ Remaining length
  10526. ;    q3/ Byte pointer to string
  10527. ;    q2/ temp
  10528. ;    q1/ temp
  10529. ;
  10530. crcclc:    saveac <q1,q2,q3,q4,t2>    ; Save q1-q4, and t2.
  10531.     dmove q3,t1        ; Get arguments.
  10532.     setz t1,        ; Initial CRC is 0.
  10533.     move t2, parity        ;[136] Get parity.
  10534.  
  10535. crcc.1:    ildb q1, q4        ; Get a character.
  10536.     caie t2, none        ;[136] Parity = NONE?
  10537.      andi q1, ^o177        ;[136] No, doing parity, strip parity bit.
  10538.     xori q1, (t1)        ; Add in with current CRC.
  10539.     ldb q2, [point 4,q1,31]    ; Get high 4 bits.
  10540.     andi q1, ^o17        ; And low 4 bits.
  10541.     move q1, crctb2(q1)    ; Get low portion of CRC factor.
  10542.     xor q1, crctab(q2)    ; Plus high portion.
  10543.     lsh t1, -^d8        ; Shift off a byte from previous CRC.
  10544.     xor t1, q1        ; Add in new value.
  10545.     sojg q3, crcc.1        ; Loop for all characters.
  10546.     
  10547.     ret            ; Done, return +1 with CRC in t1.
  10548.  
  10549. ; Data tables for CRC-CCITT generation
  10550.  
  10551. crctab:    oct    0
  10552.     oct    10201
  10553.     oct    20402
  10554.     oct    30603
  10555.     oct    41004
  10556.     oct    51205
  10557.     oct    61406
  10558.     oct    71607
  10559.     oct    102010
  10560.     oct    112211
  10561.     oct    122412
  10562.     oct    132613
  10563.     oct    143014
  10564.     oct    153215
  10565.     oct    163416
  10566.     oct    173617
  10567.  
  10568. crctb2:    oct    0
  10569.     oct    10611
  10570.     oct    21422
  10571.     oct    31233
  10572.     oct    43044
  10573.     oct    53655
  10574.     oct    62466
  10575.     oct    72277
  10576.     oct    106110
  10577.     oct    116701
  10578.     oct    127532
  10579.     oct    137323
  10580.     oct    145154
  10581.     oct    155745
  10582.     oct    164576
  10583.     oct    174367
  10584.  
  10585.     subttl    Parity routines
  10586.  
  10587. ; Default, don't touch the eighth bit.
  10588.  
  10589. none:    ret
  10590.  
  10591. ; Mark, bit 8 is always 1.
  10592.  
  10593. mark:    ori t1, ^o200        ; Turn on the parity bit.
  10594.     ret
  10595.  
  10596. ; Space, opposite of mark, bit 8 is always zero.
  10597.  
  10598. space:    andi t1, ^o177        ; Turn off the parity bit.
  10599.     ret
  10600.  
  10601. ; Even, the total number of on bits should be even.
  10602.  
  10603. even:    saveac <t2>
  10604.     andi t1, ^o177        ; Start off with bit 8 = 0.
  10605.     move t2, t1
  10606.     jrst evnodd
  10607.  
  10608. ; Odd, the total number of on bits should be odd.
  10609.  
  10610. odd:    saveac <t2>
  10611.     andi t1, ^o177        ; Turn off the parity bit.
  10612.     movei t2, ^o200(t1)    ; Start off with bit 8 = 1.
  10613.  
  10614. evnodd:    lsh t2, -4        ; Get high order 4 bits of character
  10615.     xori t2, (t1)        ; Fold into 4 bits.
  10616.     trce t2, 14        ; Left two bits both 0 or 1?
  10617.      trnn t2, 14        ;  or both 1?
  10618.      xori t1, 200        ; Yes, set parity
  10619.     trce t2, 3        ; Right two bits both 0?
  10620.      trnn t2, 3        ;  or both 1?
  10621.      xori t1, 200        ; Yes, set parity.
  10622.     ret
  10623.  
  10624.     subttl Server Operation
  10625.  
  10626. ; GETCOM
  10627. ;
  10628. ; We come here if we are in server mode.  We just wait for a packet of one of
  10629. ; the following types:
  10630. ;
  10631. ;    S    Send init - just follow the normal path from here
  10632. ;    R    Receive init - like a local "send filespec"
  10633. ;    I    Init (all-purpose exchange of parameters)
  10634. ;    G    Generic command:
  10635. ;        L    Logout - the other side is done, log out this job
  10636. ;        F    Finish - exit from Kermit
  10637. ;        U    Disk Usage query
  10638. ;        T    Type a file
  10639. ;        etc
  10640. ;
  10641. ; First, issue a message telling the user what to do.
  10642. ;
  10643. getcom:    movei t1, [        ;[157] In case line gets XOFF'd while
  10644.         call ttxon    ;[157] typing the message, unstick it,
  10645.         jrst getcm2 ]    ;[157] and proceed.
  10646.     call timeit        ;[157] Set the timer.
  10647.     skipe local        ;[174] Local mode?
  10648.      jrst [    tmsg <
  10649.  Entering server mode on TTY>    ;[174] Yes, give appropriate message.
  10650.         numout ttynum, 8
  10651.         skipl speed
  10652.          jrst [    tmsg <, >
  10653.             numout speed
  10654.             tmsg < baud>
  10655.             jrst getcmm ]
  10656.         jrst getcmm ]    ;[174]
  10657.     tmsg <
  10658.  Kermit Server running on DEC-20 host.  Please type your escape
  10659.  sequence to return to your local machine.  Shut down the server by
  10660.  typing the BYE command to KERMIT on your local machine.>
  10661.  
  10662. getcmm:    tmsg <
  10663. >
  10664. getcm2:    call timoff        ;[157] Turn off timer.
  10665.     setom srvflg        ; Flag that we are serving.
  10666.     call inilin        ; Initialize the line.
  10667.     call ccon        ; Don't let someone ^C without reseting line.
  10668.      jrst xgfin2        ;  On control-C, go "finish".
  10669.     setzm delay        ; No delay in server mode.
  10670.     setzb t3, t4        ; Set default parameters in case we get some
  10671.     call spar        ;  command before first Send-Init or Info.
  10672.     jrst xxwait        ; Go wait for a command packet.
  10673.  
  10674. ; Server command loop.  Server commands should always jrst back to here,
  10675. ; even upon error, except for those that specify exit from server mode.
  10676. ;
  10677. xxwait:    skipe mdmlin        ;[130] Modem line?
  10678.      skipe carier        ;[130] Did carrier drop?
  10679.      skipa            ;[130] No.
  10680.      jrst xgfin2        ;[130] Yes, go clean up.
  10681.  
  10682.     setom sptot        ;[134] Clear packet statistics counters
  10683.     setom rptot        ;[134] ...
  10684.     setzm xflg        ; Clear the server "type" flag.
  10685.     setzm source        ; Ditto for GETCH source.
  10686.     setzm dest        ; Ditto for PUTCH destination.
  10687.     setzm ffunc        ; And for file function.
  10688.     move t1, srvtim        ; Get the default server packet time out.
  10689.     movem t1, stimou    ; Set it so we don't time out as often.
  10690. xxwt2:    setom bctone        ;[98] Set this so we use type 1 checksum.
  10691.     setzm pktnum        ; Initial packet sequence number.
  10692.     call rpack        ; Get a packet.
  10693.      skipa            ;  On error, NAK what we're looking for.
  10694.     cain t1, "T"        ; Timer interrupt pseudo packet?
  10695.      jrst [    move t2, pktnum    ; Yes, NAK that "packet".
  10696.         call nak    ;
  10697.          jrst xxwt2    ; Go round again.
  10698.         jrst xxwt2 ]    ; (no matter what)
  10699.     cail t1, "A"        ;[150] Packet type in range?
  10700.      caile t1, "Z"        ;[150]
  10701.      kermsg <Packet type out of range>,xxwait ;[150] No.
  10702.  
  10703. ; Got a real command.  Restore the normal timeout interval and do the command.
  10704.  
  10705.     movem t2, pktnum    ; Save packet number.
  10706.     push p, t1        ; We can't use any normal AC's here...
  10707.     move t1, otimou        ; Put normal timeout back.
  10708.     movem t1, stimou
  10709.     pop p, t1
  10710.     jrst @<xxcmd-<"A">>(t1)    ;[150] Go do the indicated command.
  10711.  
  10712. ;[150] Server command dispatch table and error message routines.
  10713.  
  10714.  
  10715. xxcmd:    xxinv            ; A - Attributes, shouldn't come now
  10716.     xxinv            ; B - EOT, shouldn't come now
  10717.     xhost            ; C - Host Command
  10718.     xxinv            ; D - Data, shouldn't come now
  10719.     xxwait            ; E - Error, just ignore
  10720.     xxinv            ; F - File header, shouldn't come now
  10721.     xgen            ; G - Generic Command
  10722.     xxunk            ; H - Undefined
  10723.     xinfo            ; I - Info Packet
  10724.     xxunk            ; J - Undefined
  10725.     xxunk            ; K - Undefined
  10726.     xxunk            ; L - Undefined
  10727.     xxunk            ; M - Undefined
  10728.     xxwait            ; N - NAK, ignore
  10729.     xxunk            ; O - Undefined
  10730.     xxunk            ; P - Undefined
  10731.     xxunk            ; Q - Undefined
  10732.     xrecv            ; R - Receive (GET), server sends
  10733.     xsend            ; S - Send, server receives
  10734.     xxwait            ; T - (Already handled specially above)
  10735.     xxunk            ; U - Undefined
  10736.     xxunk            ; V - Undefined
  10737.     xxunk            ; W - Undefined
  10738.     xxinv            ; X - Text Header, shouldn't come now
  10739.     xxwait            ; Y - ACK, ignore
  10740.     xxinv            ; Z - EOF, shouldn't come now
  10741.     0            ; (superstition)
  10742.  
  10743. ; Routine to issue informative error messages.
  10744.  
  10745. xxunk:    move t4, [point 7, xxumsg] ; Get "unknown command" message.
  10746.     movei t3, xxulen    ; And its length
  10747.     jrst xxmsg
  10748.     
  10749. xxinv:    move t4, [point 7, xxbmsg] ; Get "invalid use of..." message.
  10750.     movei t3, xxblen    ; And its lentgh.
  10751.  
  10752. xxmsg:    push p, t4        ; Save msg pointer.
  10753.     ibp t4            ; Point past opening quote.
  10754.     idpb t1, t4        ; Deposit the packet type.
  10755.     movei t1, "E"        ; Send an Error packet.
  10756.     move t2, pktnum        ; This is the packet number.
  10757.     pop p, t4        ; Get original pointer back.
  10758.     call spack        ; Send the error packet.
  10759.      nop
  10760.     jrst xxwait        ; Go back to command wait.
  10761.  
  10762.     subttl Server commands.
  10763.  
  10764. ; Server SEND command (i.e. send to me, I'm the server, I receive the files.)
  10765. ;
  10766. ; We've just received a Send-Init.
  10767. ;
  10768. xsend:    setzm numtry        ; Packet retry counter.
  10769.     movem t2, pktnum    ; Synchronize packet numbers.
  10770.     call spar        ; Get the Send-Init parameters.
  10771.     move t4, [point 8, data] ;[50] Now send back our own,
  10772.     call rpar        ; which we put in the data field of our ACK.
  10773.     movei t1, "Y"        ; Set up the ACK.
  10774.     move t2, pktnum        ; Packet number.
  10775.     call spack        ; Send the packet.
  10776.      jrst xxwait        ;* Give up if we can't.(?)
  10777.     call rrinit        ;[126] Set things up for receiving.
  10778.     movei state, "F"    ; Set the state to file send.
  10779.     call $recvs        ;[42] Go look like we're receiving.
  10780.      nop            ;
  10781.     jrst xxwait        ; Get another command when done.
  10782.  
  10783.  
  10784.  
  10785. ; Server RECEIVE (or GET) command -- Server sends files.
  10786. ;
  10787. ; We've just received a Receive-Init packet, containing a filename.
  10788. ; (Or a remote TYPE command).  T1-T4 contain packet parameters returned
  10789. ; by RPACK.
  10790. ;
  10791. xrecv:    move t1, t4        ;[141] Pointer to encoded filespec.
  10792.     move t2, t3        ;[141] Number of characters.
  10793.     call decodf        ;[141] Decode it.
  10794.      kermsg <Can't decode filename>, xxwait ;[141] Can't? Give message.
  10795.     move t2, t1        ;[141] Decoded OK, point to decoded filespec.
  10796.  
  10797. ; Entry point when filespec already decoded.
  10798.  
  10799. xrecv2:    movx t1, gj%sht!gj%old!gj%ifg ; Old file and allow wildcarding.
  10800.     GTJFN%            ; Get a JFN.
  10801.      %jsker (,xxwait)    ; Can't, send error packet and loop.
  10802.     movem t1, ndxjfn    ;[111] Got JFN, save wildcard bits here.
  10803.     hrrzm t1, nxtjfn    ;[111] Initialize file lookahead.
  10804.     call gtnfil        ;[111] Get next (in this case, first) file.
  10805.      nop            ;[111] Could never fail, right?
  10806.     call $sends        ; Go send the file(s).
  10807.      nop            ;  (in case it skips for some reason...)
  10808.     jrst xxwait        ; Go back & get another command.
  10809.  
  10810.  
  10811. ; HOST command.
  10812.  
  10813. xhost:    kermsg <Host commands not implemented>, xxwait
  10814.  
  10815. ;[150] Server GENERIC command.  Get the subcommand and execute it.
  10816.  
  10817.  
  10818. xgen:    ildb t1, t4        ; Get the first character of the data field.
  10819.     cail t1, "A"        ; Validate.
  10820.      caile t1, "Z"
  10821.      kermsg <Generic command out of range>, xxwait ; Bad.
  10822.     sos t3            ; Command in range, account for it.
  10823.     jrst @<xxgcmd-<"A">>(t1) ; Dispatch to it.
  10824.  
  10825.  
  10826. ;[150] Server generic command dispatch table.
  10827.  
  10828. xxgcmd:    xgundf            ; A - Undefined
  10829.     xgundf            ; B - Undefined
  10830.     xgcwd            ; C - CWD
  10831.     xgdir            ; D - Directory
  10832.     xgdel            ; E - Erase (delete)
  10833.     xgfin            ; F - Finish
  10834.     xgundf            ; G - Undefined
  10835.     xghelp            ; H - Help
  10836.     xgnyi            ; I - Login (not yet implemented)
  10837.     xgnyi            ; J - Journal control (nyi)
  10838.     xgnyi            ; K - Copy (nyi)
  10839.     xglogo            ; L - Logout, Bye
  10840.     xgnyi            ; M - Short message
  10841.     xgundf            ; N - Undef
  10842.     xgundf            ; O - Undef
  10843.     xgnyi            ; P - Program invocation (nyi)
  10844.     xgnyi            ; Q - Server status query (nyi)
  10845.     xgnyi            ; R - Rename (nyi)
  10846.     xgundf            ; S - Undef
  10847.     xgtype            ; T - Type
  10848.     xgdisk            ; U - Disk Usage
  10849.     xgnyi            ; V - Variable Set/Query
  10850.     xgnyi            ; W - Who (Finger)
  10851.     xgundf            ; X - Undef
  10852.     xgundf            ; Y - Undef
  10853.     xgundf            ; Z - Undef
  10854.     0
  10855.  
  10856. xgundf:    move t4, [point 7, xxgums] ; Issue message for undefined command.
  10857.     movei t3, xxguln
  10858.     jrst xxmsg
  10859.  
  10860. xgnyi:    move t4, [point 7, xxgnms] ; Issue msg for unimplemented command.
  10861.     movei t3, xxgnln
  10862.     jrst xxmsg
  10863.  
  10864. ; Generic commands...
  10865.  
  10866.  
  10867. ; FINISH.  Shut down the server, but don't log out.
  10868.  
  10869. xgfin:    movei t1, "Y"        ;  Acknowledge packet.
  10870.     setzb t3, t4        ;  No data.
  10871.     call spack        ;  Send the packet.
  10872.      nop            ;[56]
  10873.     move t1, netjfn        ;[158] Wait for the ACK to get there.
  10874.     DOBE            ;[158] ...
  10875.      erjmp .+1        ;[158] ...
  10876.     setom f$exit        ;[137] Say we want to go back to command level.
  10877.  
  10878. xgfin2:    call rrslin        ;[121] Put line back in interactive state.
  10879.     move t1, odelay        ;[27] Restore normal delay
  10880.     movem t1, delay        ;[27]
  10881.     move t1, otimou        ;[27] and timout interval
  10882.     movem t1, stimou    ;[27]
  10883.     setzm srvflg        ;[27] and reset the server flag
  10884.     skipe t1, logjfn    ;[38] If we were logging,
  10885.      CLOSF            ;[38]  close the log.
  10886.      erjmp .+1        ;[38]  (Ignore any errors here.)
  10887.     setzm logjfn        ;[38]
  10888.     ret            ; Done
  10889.  
  10890. ; LOGOUT (or BYE) -- Shut down the server and log out.
  10891.  
  10892. xglogo:    movei t1, "Y"        ; Acknowledge the command.
  10893.     setzb t3, t4        ; No data.
  10894.     call spack        ; Send the packet.
  10895.      nop            ;
  10896.     move t1, netjfn        ;[158] Wait for the packet to arrive.
  10897.     DOBE            ;[158]...
  10898.      erjmp .+1        ;[158]...
  10899.     call rrslin        ; Restore the line for interactive use.
  10900.     move t1, odelay        ; Restore normal delay
  10901.     movem t1, delay        ;
  10902.     move t1, otimou        ; and timout interval
  10903.     movem t1, stimou    ;
  10904.     setzm srvflg        ; and reset the server flag.
  10905.     wtlog <BYE Received>    ;[126] Log the BYE.
  10906.     call clenup        ;[126] Close all logs.
  10907.     setom f$exit        ; Just in case we can't logout, set exit flag.
  10908.     seto t1,        ; -1 = Myself.
  10909.     LGOUT%            ; Log me out.
  10910.     %jsker (,r)        ; If this fails, print msg & go back.
  10911.  
  10912. ; Command to TYPE a file.  Just like sending a file, except must send "X"
  10913. ; packet instead of file header.
  10914.  
  10915. xgtype:    call getarg        ; Get the argument.
  10916.     setom xflg        ; Send file with X header.
  10917.     move t2, t4        ;[141] Point to filespec.
  10918.     jrst xrecv2        ;[141] Do like when we get an R packet.
  10919.  
  10920. ;[58] Init-Info mechanism added as edit 58.
  10921. ;
  10922. ; Get an "I" parameters packet from the user, record the parameters, and send
  10923. ; our own back in return.  This exchange is optional, but should take place
  10924. ; before any server/user transaction except file transfer, where it is required
  10925. ; and always takes place via the Send-Init mechanism.
  10926. ;
  10927. xinfo:    movem t2, pktnum    ; Set the parameters we just got.
  10928.     call spar
  10929.     setzm numtry
  10930.     move t4, [point 8, data] ; Respond with ours.
  10931.     call rpar
  10932.     movei t1, "Y"
  10933.     move t2, pktnum
  10934.     call spack
  10935.      nop            ; If they don't get it, they'll ask again...
  10936.     jrst xxwait
  10937.  
  10938. ; GTSCH -- Get String Character
  10939. ;
  10940. ; Alternate GETCH routine for getting a character from an ASCIZ string in
  10941. ; memory.  Uses global STRPTR for input string.
  10942. ;
  10943. ; Returns:
  10944. ;   +1 if no more characters left in string.
  10945. ;   +2 always, with NEXT containing next character, -1 if no more.
  10946. ;
  10947. gtsch:    ildb t1, strptr        ; Get next character.
  10948.     jumpe t1, gtschz    ; If zero, must be done.
  10949.  
  10950. ; Return with character like GETCH.
  10951.  
  10952. gtschx:    movem t1, next        ; Put result in NEXT, as GETCH does.
  10953.     retskp            ; Done.
  10954.  
  10955. ; "EOF" return, like GETCH
  10956.  
  10957. gtschz:    setz t1,
  10958.     setom next
  10959.     ret
  10960.  
  10961. ; PUTSCH
  10962. ;
  10963. ; Alternate PUTCH routine.  Just writes the character to a string in memory.
  10964. ; Call with t2/ character to write.
  10965. ;
  10966. putsch:    idpb t2, strptr        ; Here's the alternate PUTCH routine.
  10967.     retskp            ; It always succeeds.
  10968.  
  10969.  
  10970. ; PUTTCH
  10971. ;
  10972. ; Another alternate PUTCH routine.  Writes the character to the terminal.
  10973. ; Call like PUTCH and PUTSCH.
  10974. ;
  10975. puttch:    skipe local        ;[177] But only if in remote mode.
  10976.      retskp            ;[177]  ...
  10977.     push p, t1
  10978.     movei t1, .priou
  10979.     BOUT    
  10980.      erjmp .+1
  10981.     pop p, t1
  10982.     retskp
  10983.  
  10984.  
  10985. ; GETARG
  10986. ;
  10987. ; Decode server command packet, set up pointers, get first argument.
  10988. ;
  10989. ; Return +1 with:
  10990. ;  t3/ Length of first argument
  10991. ;  t4/ pointer to first argument
  10992. ;
  10993. getarg:    movei t1, putsch    ; Address of alternate PUTCH routine.
  10994.     movem t1, dest
  10995.     setzm strbuf        ; Clear decoding area.
  10996.     move t1, [strbuf,,strbuf+1]
  10997.     blt t1, strbz
  10998.     move t1, [point 7, strbuf] ; Where to put the decoded string.
  10999.     movem t1, strptr
  11000.     move t1, t4        ; Pointer to data to decode.
  11001.     move t2, t3        ; Length.
  11002.     call putbuf        ; Go decode the packet.
  11003.      jrst [    setzm dest
  11004.         kermsg <Can't decode server command>, xxwait ]
  11005.     setzm dest        ; Put PUTCH back to normal.
  11006.     move t4, [point 7, strbuf] ; Point to decoded string.
  11007.     ildb t3, t4        ; Get CHAR(length) of directory string.
  11008.     caige t3, 40        ;[128] If null, no need to convert.
  11009.      movei t3, 40        ;[128] This also catches funny cases.
  11010.     subi t3, 40        ; UNCHAR of that to make a number.
  11011.     ret
  11012.  
  11013. ;[107] CWD server command (Connect to directory in DEC-20 parlance).
  11014. ;
  11015. ; Changes Working Directory, sends new directory name back in ACK, or else
  11016. ; error packet if there's a problem.
  11017. ;
  11018. ; Arrive here with t4 containing pointer to argument string of form
  11019. ;  <length><directory><length><password>
  11020. ; where <length> is a single character (offset by CHAR),
  11021. ; and t3 containing the length of the string.
  11022. ;
  11023. xgcwd:    call getarg        ; Get the first argument.
  11024.     jumpg t3, xgcwd3    ; If positive, go handle string.
  11025.     jumpe t3, xgcwd5    ; If null, go connect back to own directory.
  11026.  
  11027.     kermsg <Bad length field in CWD packet>,xxwait ; Negative length???
  11028.  
  11029. ; Set up argument block for ACCES
  11030.  
  11031. xgcwd3:    move q1, t4        ; Byte pointer to directory string.
  11032.     adjbp t3, t4        ; Now point to password.
  11033.     ildb t4, t3        ; Get its length.
  11034.     move q2, t3        ; Put pointer in ACCES arg block.
  11035.     subi t4, 40        ; UNCHAR to make it a number.
  11036.     skipge t4        ; Normal kind of number?
  11037.      setz t4,        ;  No, must have fallen off end, so no pswd.
  11038.     setz t2,        ; Zero the length to make directory asciz.
  11039.     dpb t2, t3        ;  ...
  11040.     adjbp t4, t3        ; Make sure password is asciz.
  11041.     idpb t2, t4
  11042.  
  11043. ; Access the directory. ** Maybe should also mount structure if necessary?
  11044.  
  11045. xgcwd4:    move t1, [ac%con!<3>]    ; Function is Connect, arg block has 2 words.
  11046.     movei t2, q1        ; Address of argument block.
  11047.     seto q3,        ; Own job.
  11048.     ACCES
  11049.      %jsker (,xxwait)    ; Send any error message in error packet.
  11050.     jrst xgcwdz        ; Done connecting, go send ACK.
  11051.  
  11052. ;...XGCWD, cont'd
  11053.  
  11054.  
  11055. ; Come here to connect to own directory.
  11056.  
  11057. xgcwd5:    seto t1,        ; This job.
  11058.     hrroi t2, q1        ; Want one word, put it in q1.
  11059.     movei t3, .jilno    ; Logged-in directory number.
  11060.     GETJI
  11061.      %jsker (,xxwait)
  11062.     move t1, [ac%con!<3>]    ; Function is connect.
  11063.     setz q2,        ; No password needed
  11064.     seto q3,        ; Own job.
  11065.     movei t2, q1        ; Address of arg block.
  11066.     ACCES            ; Connect to own directory.
  11067.      %jsker (,xxwait)
  11068.     ;...
  11069.  
  11070. ;...XGCWD, cont'd
  11071.  
  11072.  
  11073. ; Done, send back ACK with directory string in it.
  11074.  
  11075. xgcwdz:    GJINF
  11076.     move t1, [point 7, strbuf]
  11077.     movem t1, strptr
  11078.     DIRST
  11079.      %jsker (,xxwait)
  11080.  
  11081.     movei t1, gtsch        ; Indicate routine to be used for getting
  11082.     movem t1, source    ;  characters.
  11083.     setom next        ; Set initial condition.
  11084.     move t1, maxdat        ; Get a buffer full of data.
  11085.     call getbuf        ; ...
  11086.      jumpn t1, xxwait    ;
  11087.     setzm source        ; Put GETCH back to normal.
  11088.     move t3, t1        ; Length
  11089.     movei t1, "Y"        ; Y for Yes (ACK)
  11090.     setz t2,        ; Packet number 0.
  11091.     move t4, [point 8, data] ; Point to string built by getbuf.
  11092.     call spack        ; Send the ACK.
  11093.      nop            ;  Nothing much we can do here...
  11094.     jrst xxwait        ; Done.
  11095.  
  11096. ;[56] Disk USAGE server query added in edit 56.
  11097. ;
  11098. ; Assumes reply will fit in data field of ACK packet; does not use
  11099. ; text header ("X") protocol.  Sends as much of reply as will fit.
  11100. ;
  11101. xgdisk:    seto t1,        ; Get disk usage of connected directory.
  11102.     GTDAL%
  11103.      %jsker <Can't get disk usage>,r
  11104.     dmove q1, t1        ; Save the numbers in q1,q2.
  11105.  
  11106.     move t1, [point 7, strbuf] ;[103] String pointer to data field.
  11107.     movem t1, strptr    ;[103]
  11108.     hrroi t2, [asciz/Quota: /]
  11109.     setzb t3, t4        ; Source string is null-terminated.
  11110.     SOUT%
  11111.      erjmp xgdis2
  11112.  
  11113.     move t2, q1        ; Quota, or "+Inf"
  11114.     cail t2, [^d100000000]
  11115.      jrst [    hrroi t2, [asciz/+Inf/]
  11116.         SOUT
  11117.         jrst xgdsk2 ]
  11118.  
  11119.     movei t3, ^d10        ;  in decimal
  11120.     NOUT%
  11121.      erjmp xgdis2
  11122.  
  11123. xgdsk2:    hrroi t2, [asciz/, used: /]
  11124.     setzb t3, t4
  11125.     SOUT%
  11126.      erjmp xgdis2
  11127.     move t2, q2        ; Pages used,
  11128.     movei t3, ^d10        ;  in decimal
  11129.     NOUT%
  11130.      erjmp xgdis2
  11131.     hrroi t2, [asciz/ (pages)/] ; Specify units
  11132.     setzb t3, t4
  11133.     SOUT%
  11134.      erjmp xgdis2
  11135.  
  11136. xgdis2:    move t2, strptr        ;[103] Check length
  11137.     exch t1, t2
  11138.     call subbp
  11139.      %jsker <subbp foulup>,r
  11140.     idpb t4, t2        ; Done constructing string, make it asciz
  11141.     move q1, spsiz        ; Is the string bigger than max size to send?
  11142.     subi q1, 5
  11143.     caig q1, (t3)        ; (it should always fit).
  11144.      move t3, q1        ;  Yes, so cut it off at the limit.
  11145.     ;..
  11146.  
  11147. ;...XGDISK, cont'd
  11148.  
  11149.  
  11150. ;[103] Begin Change: Use standard packet filling technique to send this.
  11151.  
  11152.     movei t1, gtsch        ; Indicate routine to be used for getting
  11153.     movem t1, source    ;  characters.
  11154.     setom next        ; Set initial condition.
  11155.     move t1, maxdat        ; Get a buffer full of data.
  11156.     call getbuf        ; ...
  11157.      jumpn t1, xxwait    ;
  11158.     move t3, t1        ; Set up length.
  11159.     setzm source        ; Put GETCH back to normal.
  11160.  
  11161. ;[103] End Change.   Now send the packet.
  11162.  
  11163. xgdisz:    movei t1, "Y"        ; Formulate the ACK
  11164.     setz t2,        ; (Packet number should be 0, right?)
  11165.     move t4, [point 8, data] ; The data itself
  11166.     call spack        ; Send it off.
  11167.      nop            ;* What if it fails?
  11168.     jrst xxwait
  11169.  
  11170. ;[120] HELP server command.
  11171.  
  11172. srvhlp:    asciz /
  11173. The DECSYSTEM-20 KERMIT server is capable of the following:
  11174.  
  11175.                                     Command you would normally type to your
  11176.   Server Function:                  local KERMIT to invoke the server function:
  11177.  
  11178.   Receive a file or file group      SEND filespec
  11179.   Send a file or file group         GET filespec
  11180.   Logout                            BYE
  11181.   Exit to TOPS-20                   FINISH
  11182.   Delete a file or file group       REMOTE DELETE filespec
  11183.   List file(s) at the terminal      REMOTE TYPE filespec
  11184.   Provide a directory listing       REMOTE DIRECTORY filespec
  11185.   Change working directory          REMOTE CWD directory [password]
  11186.   Report disk usage                 REMOTE SPACE
  11187.   Send this message                 REMOTE HELP
  11188. /
  11189. srvhz:    0
  11190.     0            ; This padding seems to be necessary...
  11191.  
  11192. xghelp:    move t1, [point 7, srvhlp] ; Point to help text.
  11193.     movem t1, strptr    ; Put pointer here, where
  11194.     movei t1, gtsch        ;  routine for getting chars from a string
  11195.     movem t1, source    ;  can find it.
  11196.     setom next        ; Init char lookahead
  11197.     setom xflg        ; Send with X rather than F header.
  11198.     call $sends        ; Go send the text like a file
  11199.      nop
  11200.     setzm source        ;[121] Put send source back to normal.
  11201.     jrst xxwait
  11202.  
  11203. ;[116] DIRECTORY server command.
  11204.  
  11205. ; DIRCH
  11206. ;
  11207. ; Alternate GETCH routine for getting characters from a directory listing
  11208. ; in a memory buffer, and for refilling the buffer when it gets empty.
  11209. ;
  11210. dirch:    ildb t1, getptr        ; Get character.
  11211.     skipe t1        ; Null?
  11212.      jrst dirchx        ;  No, return the character.
  11213.  
  11214. ; No characters in buffer, try to refill.
  11215.  
  11216. dirch2:    call dmpbuf        ; If so, reset the buffer pointers, etc.
  11217.     call dirlst        ; And try to fill the listing buffer again.
  11218.     jumpe t1, dirchz    ; No more, done.
  11219.     move t1, [point 7, srvbuf] ; Get new listing buffer pointer.
  11220.     movem t1, getptr    ; Save it for getting characters.
  11221.     ildb t1, getptr        ; Get first character of new buffer.
  11222.     jumpe t1, dirchz    ; This shouldn't happen...
  11223.  
  11224. ; Return with character like GETCH.
  11225.  
  11226. dirchx:    movem t1, next
  11227.     retskp
  11228.  
  11229. ; "EOF" return, like GETCH.
  11230.  
  11231. dirchz:    setz t1,
  11232.     setom next
  11233.     ret
  11234.  
  11235. ; XGDIR - Server provides directory listing.
  11236.  
  11237. xgdir:    call getarg        ; Get the first (& only) argument
  11238.     jumpg t3, xgdir2    ; Got something, go do it.
  11239.     jumpe t3, [        ; Got nothing, do default directory.
  11240.         move t4, [point 7, [asciz/*.*.*/]] ;[174] (not hrroi!)
  11241.         jrst xgdir2 ]
  11242.  
  11243.     kermsg <Bad length field in DIRECTORY command>,xxwait ; Got junk.
  11244.  
  11245. ; Get JFN on the string we got, supply normal defaults like Exec does.
  11246.  
  11247. xgdir2:    move t2, t4        ; Point to filespec
  11248.     adjbp t3, t4        ; Make it asciz
  11249.     setz t4,
  11250.     idpb t4, t3
  11251.     movei t1, sdirbk    ; JFN block containing flags & defaults.
  11252.     GTJFN            ; Do long form GTJFN.
  11253.      %jsker (,xxwait)    ; Send error packet if we can't.
  11254.     move t2, t1        ; Construct heading in string buffer.
  11255.     setzm ffunc        ; Function is "directory".
  11256.     call dirhdr
  11257.     move t1, [point 7, srvbuf] ; Point to beginning of text buffer.
  11258.     movem t1, getptr    ; This is where we'll get characters from.
  11259.     movei t1, dirch        ; And this routine will do the getting.
  11260.     movem t1, source    ;  ...
  11261.     setom next        ; Initialize character lookahead.
  11262.     setom xflg        ; This produces some desired effects...
  11263.     call $sends        ; Go send the listing like it's a file.
  11264.      nop            ;  Ignore any skipping...
  11265.     jrst xxwait
  11266.  
  11267. sdirbk:    gj%old!gj%ifg!.gjall    ; Flags,,All generations.
  11268.     .nulio,,.nulio        ; No i/o.
  11269.     repeat <2>,<0>        ; Default device and directory.
  11270.     repeat <2>,<-1,,[asciz/*/]> ; Default name is "*.*"
  11271.     repeat <4>,<0>        ; Nothing special for the rest.
  11272.  
  11273.  
  11274. ;[118] XGDEL - Server provides file deletion.
  11275.  
  11276. xgdel:    call getarg        ; Get the first (& only) argument
  11277.     jumpg t3, xgdel2    ; Got something, go do it.
  11278.  
  11279.     kermsg <No file specified for deletion>,xxwait
  11280.  
  11281. ; Get JFN on the string we got, supply normal defaults like Exec does.
  11282.  
  11283. xgdel2:    move t2, t4        ; Point to filespec
  11284.     adjbp t3, t4        ; Make it asciz
  11285.     setz t4,
  11286.     idpb t4, t3
  11287.     movei t1, sdelbk    ; JFN block containing flags & defaults.
  11288.     GTJFN            ; Do long form GTJFN.
  11289.      %jsker (,xxwait)    ; Send error packet if we can't.
  11290.     move t2, t1        ; Construct heading in string buffer.
  11291.     movei t1, delfil    ; Routine for deleting a file.
  11292.     movem t1, ffunc        ; Make it the file function.
  11293.     call dirhdr        ; Start things off.
  11294.     move t1, [point 7, srvbuf] ; Point to beginning of text buffer.
  11295.     movem t1, getptr    ; This is where we'll get characters from.
  11296.     movei t1, dirch        ; And this routine will do the getting.
  11297.     movem t1, source    ;  ...
  11298.     setom next        ; Initialize character lookahead.
  11299.     setom xflg        ; This produces some desired effects...
  11300.     call $sends        ; Go send the listing like it's a file.
  11301.      nop            ;  Ignore any skipping...
  11302.     jrst xxwait
  11303.  
  11304. sdelbk:    gj%old!gj%ifg!.gjall    ; Flags,,All generations.
  11305.     .nulio,,.nulio        ; No i/o.
  11306.     repeat <^d8>,<0>    ; No other defaults.
  11307.  
  11308.     subttl    Timer Routines
  11309.  
  11310. ; Set a timer.  Call with t1/ Address of where to go upon timout.
  11311.  
  11312. timeit:    skipg stimou        ;[43] Doing timeouts?
  11313.      ret            ;[43]  No, skip this.
  11314.     pop p, t2        ; Get the return address off the stack.
  11315.     movem p, intstk        ; Save the stack.
  11316.     push p, t2        ; Restore stack.
  11317.     hrr t2, t1        ; Make interrupt PC point to time out addr.
  11318.     movem t2, intpc        ; Save the PC.
  11319.     movei t1, .fhslf
  11320.     movx t2, 1b0        ; Turn on channel 0.
  11321.     AIC
  11322.      %jserr <TIMEIT - Can't turn on timer channel>, <.+1>
  11323.  
  11324. ;[132] Remove any pending timer requests.
  11325.  
  11326. timei2:    move t1, [.fhslf,,.timal] ; Remove all pending timer requests.
  11327.     setzb t2, t3
  11328.     TIMER
  11329.      aos timerx        ; If we get a timer error, just count it.
  11330.  
  11331. timei3:    setz t1,        ;[130] Get 1-minute load average.
  11332.     call ldav        ;[130]
  11333.     move t2, stimou        ;[130] Minimum acceptable.
  11334.     call adjtim        ;[128] Adjust based on load average.
  11335.     move t1, [.fhslf,,.timel] ; Our process and time from now.
  11336.     movem t2, curtim    ;[131] Remember this for reporting.
  11337.     imuli t2, ^d1000    ; Make time into milliseconds.
  11338.     setz t3,        ; Channel zero.
  11339.     TIMER
  11340.      aos timerx        ; If we get an error, count it.
  11341.     ret
  11342.  
  11343. ; TIMOFF -- Turn off timer.
  11344.  
  11345. timoff:    skipg stimou        ;[43] Doing timeouts?
  11346.      ret            ;[43]  No, skip this.
  11347.     saveac <t1,t2>        ; Yes, save these ACs.
  11348.     move t1, [.fhslf,,.timbf] ; Turn off timer interrupts for this fork.
  11349.     hrloi t2, 377777    ; For all times before this (far in future).
  11350.     TIMER            ;
  11351.      aos timerx        ;  Count any error.
  11352.     movx t1, .fhslf        ; Deactivate the channel.
  11353.     movx t2, 1b0
  11354.     DIC
  11355.     ret
  11356.  
  11357. ; TMTRAP -- Timer interrupt handler.
  11358.  
  11359. tmtrap:    push p, t1        ; Get a work AC.
  11360.     move t1, intpc        ; Get the PC we want.
  11361.     hrli t1, (1b5)        ;[132] Set user mode to escape from any jsys.
  11362.     movem t1, pc1        ; Restore as if we came from there.
  11363.     pop p, t1
  11364.     move p, intstk        ; Pop any junk off the stack.
  11365.     aos ntimou        ; Count the timeout.
  11366.     DEBRK
  11367.  
  11368. ;[128] Make this a separate routine.
  11369. ;
  11370. ; ADJTIM -- Adjust timeout interval based on load average (ldav).
  11371. ;
  11372. ; Calculate Timeout = mintim + (ldav-MINLOD)*((MAXTIM-mintim)/MAXLOD)
  11373. ; If the load is low, this gives the minimum acceptable timeout, mintim.
  11374. ; If the load is very high, this gives the maximum timeout, MAXTIM.
  11375. ; In between, the timeout goes up linearly with given load average.
  11376. ; MINLOD, MAXLOD, and MAXTIM are defined as global symbols.
  11377. ;
  11378. ; Call with:
  11379. ;  t1/ 1, 5, or 15 minute ldav, floating point number as returned by GETAB.
  11380. ;  t2/ minimum acceptable timeout (mintim), seconds (integer).
  11381. ; Returns +1 always, with
  11382. ;  t2/ adjusted timeout interval, in seconds (integer).
  11383. ;
  11384. adjtim:    stkvar <mintim>        ; Local storage for second argument.
  11385.     movem t2, mintim    ; Save the minimum for later.
  11386.     fsb t1, [minlod]    ; Adjust load by subtracting the minimum.
  11387.     skipg t1        ; If negative, make it zero.
  11388.      setz t1,
  11389.     caml t1, [maxlod]    ; If too big, cut it off.
  11390.      move t1, [maxlod]
  11391.     movei t2, maxtim    ; Maximum timeout, seconds.
  11392.     sub t2, mintim        ; Less specified timeout interval.
  11393.     fltr t2, t2        ; Floated.
  11394.     fdv t2, [maxlod]    ; Divided by maximum load.
  11395.     fmp t1, t2        ; Multiplied by actual (adjusted) load.
  11396.     fixr t2, t1        ; Fixed & rounded.
  11397.     add t2, mintim        ; Add in requested minimum timeout.
  11398.     ret            ; Return with result in t2.
  11399.  
  11400. ;[130] This routine added as part of edit 130.
  11401. ;
  11402. ; LDAV -- Get the current load average.  Takes class scheduling into account.
  11403. ;
  11404. ; Call with
  11405. ;  t1/ 0 for 1-min, 1 for 5-min, 2 for 15-min ldav.
  11406. ;  SKDFLG/ -1 for class scheduler running, 0 for no class scheduler.
  11407. ;  CLASS/  This job's scheduler class.
  11408. ;
  11409. ; Returns +1 always, with requested load average in t1.
  11410. ;
  11411. ldav:    saveac <q1>        ; Save this.
  11412.     cail t1, 0        ; Argument in range?
  11413.      caile t1, 2
  11414.      setz t1,        ; Force to 0.
  11415.     move q1, t1        ; Save argument here.
  11416.     skipe skdflg        ; Class scheduler on?
  11417.      jrst ldav3        ;  Yes, go do it the special way.
  11418.  
  11419. ; Class scheduler off, use GETAB for system-wide load average.
  11420.  
  11421. ldav2:    hrlz t1, q1        ; Desired load average.
  11422.     add t1, [14,,.systa]    ; Scheduler off,
  11423.     GETAB            ;  use load avg from SYSTAT monitor table.
  11424.      erjmp ldavx
  11425.     ret
  11426.  
  11427. ; Class scheduler on, get load avg for this class from SKED%.
  11428.  
  11429. ldav3:    skipge t1, class    ; This job's scheduler class.
  11430.      jrst ldav2        ; Unless there was some error getting it...
  11431.  
  11432.     movem t1, skdblk+.sacls    ; Put it in the SKED% arg block.
  11433.     movei t1, 10        ; Arg block length
  11434.     movem t1, skdblk+.sacnt
  11435.     movei t1, .skrcs    ; Function is read class parameters.
  11436.     movei t2, skdblk    ;  into this arg block.
  11437.     SKED%
  11438.      %jserr (,ldavx)
  11439.     move t1, skdblk+.sa1ml(q1) ; Return the desired value.
  11440.     ret
  11441.  
  11442. ldavx:    move t1, [minlod]    ; Return this in case of any error.
  11443.     ret
  11444.  
  11445.     subttl    Interrupt Routines
  11446.  
  11447.  
  11448. ; Initialize the Priority Interrupt system.
  11449.  
  11450. pinit:    movei t1, .fhslf    ; This fork.
  11451.     move t2, [levtab,,chntab] ; Say where our tables are.
  11452.     SIR
  11453.     EIR            ; Enable the interrupt system.
  11454.     ret
  11455.  
  11456.  
  11457. ; Turn Control-C trap on.  Sets things up so that ^C will return control
  11458. ; to the instruction FOLLOWING the the call to this routine, with the
  11459. ; stack fixed up appropriately, e.g.
  11460. ;
  11461. ;    call ccon        ; Turn on ^C trap
  11462. ;     jrst foo        ; What to do if ^C is typed.
  11463. ;    move x, y        ; Execute this after the call to CCON.
  11464. ;
  11465. ; Returns +2 always.
  11466. ;    
  11467. $ccn==2                ; Number of ^C's to get out of ^C trap.
  11468.  
  11469. ccon:    movei t1, .fhslf    ; Read current process capabilities.
  11470.     RPCAP%
  11471.  
  11472. ;[10] Try to enable ^C capabilities unless under batch.
  11473.  
  11474.     tloe t3, (sc%ctc)    ; Do we have Control-C capas?
  11475.      jrst ccon2        ;  Yes, go on.
  11476.     EPCAP%            ; Nope, try to get them.
  11477.     RPCAP%            ; Did we?
  11478.     skipn jobtab+.jibat    ; Under batch?
  11479.      tloe t3, (sc%ctc)    ; Check the ^C bit.
  11480.      jrst ccon2        ;  If under batch
  11481.     ermsg <Can't enable ^C capability>,r ; Not under batch, give up.
  11482.  
  11483. ccon2:    movem t3, capas        ; Save them.
  11484.     movei t1, $ccn         ; Initialize ^C count to this.
  11485.     movem t1, ccn
  11486.     movem p, psave        ;[27] Save stack pointer.
  11487.     move t1, (p)        ;[27] And what it points to...
  11488.     movem t1, psave2    ;[27]
  11489.     movx t1, .fhslf        ; Now, for this fork,
  11490.     movx t2, 1b1        ;  activate channel 1
  11491.     AIC            ;  ...
  11492.      erjmp .+1        ;[10]
  11493.     move t1, [.ticcc,,1]    ;  for ^C.
  11494.     ATI            ;
  11495.      erjmp .+1        ;[10]
  11496.     retskp
  11497.  
  11498. ; Turn Control-C trap off.
  11499.  
  11500. ccoff:    skipe srvflg        ;[81] Being a server?
  11501.      ret            ;[81] Yes, so don't turn off the ^C trap.
  11502.  
  11503. ; Entry point for REALLY turning it off, even if server.
  11504.  
  11505. ccoff2:    saveac <t1,t2,t3>    ; Save these.
  11506.     setzm ccn        ; Put ^C count back to 0.
  11507.     movx t1, .fhslf        ; This fork.
  11508.     movx t2, 1b1        ; Deactivate channel 1.
  11509.     DIC
  11510.     RTIW            ; Fix up the interrupt mask
  11511.     tlz t2, (1b3)        ;  for ^C... (^C = ASCII 3 = bit 3)
  11512.     STIW            ;  ...
  11513.     move t3, capas        ; Restore capabilities.
  11514.     EPCAP
  11515.      erjmp .+1
  11516.     ret
  11517.  
  11518. ;[59] ^A, ^X, and ^Z interrupt control added as part of edit 59.
  11519.  
  11520. caxzon:    Remark - Turn on ^A, ^X, and ^Z interrupts.
  11521.  
  11522.     setzm cxseen        ; Say we haven't seen a ^X yet,
  11523.     setzm czseen        ; nor a ^Z.
  11524.     setzm caseen        ;  ...
  11525.     skipn local        ; Only do this if local!
  11526.      ret
  11527.     movei t1, .fhslf    ; This fork.
  11528.     movx t2, 1b<cachan>!1b<cxchan>!1b<czchan> ; Turn on the channels.
  11529.     AIC%
  11530.     move t1, [.ticca,,cachan] ; Put ^A on its channel.
  11531.     ATI%
  11532.     move t1, [.ticcx,,cxchan] ; Put ^X on its channel.
  11533.     ATI%
  11534.     move t1, [.ticcz,,czchan] ; And ^Z on its.
  11535.     ATI%
  11536.     ret
  11537.  
  11538. cmpon:    Remark - ^M, ^P interrupts on.
  11539.     movei t1, .fhslf    ; This fork.
  11540.     movx t2, 1b<cmchan>!1b<cpchan> ; These channels.
  11541.     AIC            ; Activate interrupt system.
  11542.     move t1, [.ticcm,,cmchan] ; Assign ^M to this channel.
  11543.     ATI
  11544.     setzm cmseen
  11545.     move t1, [.ticcp,,cpchan] ; Assign ^P to this one.
  11546.     ATI
  11547.     setzm cpseen
  11548.     ret
  11549.  
  11550. caxzof: Remark - Turn off ^A,^X,^Z interrupts.
  11551.  
  11552.     setzm cxseen        ; Turn off the flags
  11553.     setzm czseen        ;  ...
  11554.     setzm caseen        ;  ...
  11555.     skipn local        ; Nothing to do if remote, the interrupts
  11556.      ret            ;  weren't on anyway.
  11557.     movx t1, .fhslf        ; Turn off ^A,^X,^Z traps.
  11558.     movx t2, 1b<cachan>!1b<cxchan>!1b<czchan> ; Turn off these channels.
  11559.     DIC%            ; ...
  11560.     RTIW%            ; Fix up the interrupt mask
  11561.     tdz t2, [<1b1+1b24+1b26>] ; for ^A,^X,^Z
  11562.     STIW%            ;  ...
  11563.      %jserr (,.+1)
  11564.     ret
  11565.  
  11566. ; ^M, ^P interrupts off.
  11567.  
  11568. cmpoff:    setzm cmseen
  11569.     setzm cpseen
  11570.     movx t1, .fhslf        ; Turn off ^M trap.
  11571.     movx t2, 1b<cmchan>!1b<cpchan> ; Turn off channels.
  11572.     DIC            ; ...
  11573.     RTIW            ; Fix up the terminal interrupt mask
  11574.     tdz t2, [<1b13>!<1b16>]    ; for ^M, ^P
  11575.     STIW
  11576.      %jserr (,.+1)
  11577.     ret
  11578.  
  11579. cctrap:    sosle ccn        ; Count the ^C's.
  11580.      DEBRK%            ; If they haven't typed enough, just resume.
  11581.     call timoff        ; Turn off any timer.
  11582.     hrroi t1, [asciz/^C
  11583. /]
  11584.     PSOUT%            ; Echo the ^C.
  11585.  
  11586.     move p, psave        ;[27] Make sure stack pointer is right.
  11587.     move t1, psave2        ;[27] And stack top.
  11588.     movem t1, (p)        ;[27]
  11589.     hrli t1, (1b5)        ;[27] Get into user mode.
  11590.     movem t1, pc1        ; Put this place into our PC.
  11591.     pop p, t1        ;[80] Don't need it on the stack any more.
  11592.     DEBRK%            ; Resume where stack pointer points.
  11593.  
  11594. ;[61] Control-A trap handler.  Give brief progress report at terminal.
  11595. ;
  11596. catrap:    push p, t1        ; Save all ACs we might use.
  11597.     push p, t2
  11598.     push p, t3
  11599.     skipn rcving        ; Sending or receiving a file?
  11600.      jrst catrp1        ;  No.
  11601.     hrroi t1, [asciz/^A
  11602.  Sending /]            ; Yes, one...
  11603.     skipg rcving
  11604.      hrroi t1, [asciz/^A
  11605.  Receiving /]            ; ...or the other.
  11606.     PSOUT%
  11607.     movei t1, .priou    ; Say the filename
  11608.     setz t3,
  11609.     skipe t2, filjfn
  11610.      JFNS%
  11611.      erjmp .+1
  11612.     tmsg <, file bytesize >    ; File bytesize
  11613.     numout bytsiz
  11614.     skipl rcving        ; I/O bytesize, only if sending
  11615.      jrst [    tmsg <, i/o bytesize >
  11616.         movei t2, 7
  11617.         skipn itsfil    ;[75]
  11618.          skipe ebtflg
  11619.          movei t2, 8
  11620.         numout t2
  11621.         jrst .+1 ]
  11622.     tmsg <
  11623. >                ;[92]
  11624.     hrroi t1, [asciz/ (ITS binary)/] ;[75]
  11625.     skipe itsfil        ;[75]
  11626.      PSOUT            ;[75]
  11627.     hrroi t1, [asciz/ (8th-bit prefixing)/] ;[88]
  11628.     skipe ebqflg        ;[88]
  11629.      PSOUT            ;[88]
  11630.     hrroi t1, [asciz/ (compression)/] ;[92]
  11631.     skipe rptflg        ;[92]
  11632.      PSOUT            ;[92]
  11633.     hrroi t1, [asciz/ (block check type /] ;[98]
  11634.     PSOUT
  11635.     numout bctu        ;[98]
  11636.     movei t1, ")"        ;[98]
  11637.     PBOUT            ;[98]
  11638.     tmsg <
  11639.  At page >            ; What page we're at.
  11640.     move t2, pagno
  11641.     aos t2
  11642.     numout t2
  11643.     skipl rcving        ; Out of how many
  11644.      jrst [    tmsg < of >    ; (which we know only if we're sending)
  11645.         numout pagcnt
  11646.         jrst .+1 ]
  11647.  
  11648.     ;...
  11649.  
  11650. ;...CATRAP, cont'd
  11651.  
  11652.  
  11653. catrp1:    tmsg <
  11654.  Files: >            ; Say how many files,
  11655.     numout files
  11656.     tmsg <, packets: >    ; packets,
  11657.     skipl rcving
  11658.      numout sptot
  11659.     skipg rcving
  11660.      numout rptot
  11661.     tmsg <, chars: >    ; characters,
  11662.     move t2, stchr
  11663.     add t2, schr
  11664.     skipl rcving
  11665.      numout t2
  11666.     move t2, rtchr
  11667.     add t2, rchr
  11668.     skipg rcving
  11669.      numout rtot
  11670.     tmsg <
  11671.  NAKs: >            ; NAKS & timeouts.
  11672.     numout nnak
  11673.     tmsg <, timeouts: >
  11674.     numout ntimou
  11675.     tmsg <
  11676. >                ; End up with a CRLF
  11677.  
  11678.     pop p, t3        ; Restore ACs.
  11679.     pop p, t2
  11680.     pop p, t1
  11681.  
  11682.     DEBRK%            ; Resume.
  11683.  
  11684. ;[59] Control-X trap handler.
  11685.  
  11686. cxtrap:    setom cxseen        ; Just set the flag & echo the character.
  11687.     push p, t1
  11688.     move t1, source        ;[140] What's the source of our data?
  11689.     cain t1, dirch        ;[140] Is it a directory listing?
  11690.      setom czseen        ;[140] If so, set C-Z flag, too.
  11691. cxtrp2:    hrroi t1, [asciz\^X// \]
  11692.     PSOUT%
  11693.     pop p, t1
  11694.     DEBRK%
  11695.  
  11696.  
  11697. ;[59] Control-Z trap handler.
  11698.  
  11699. cztrap:    setom czseen        ; Just set the flag & echo the character.
  11700.     push p, t1
  11701.     hrroi t1, [asciz\^Z// \]
  11702.     PSOUT%
  11703.     pop p, t1
  11704.     DEBRK
  11705.  
  11706.  
  11707. ;[165] Control-M and -P trap handlers
  11708.  
  11709. cmtrap:    setom cmseen        ; Set ^M flag
  11710.     push p, t1        ; Echo CRLF
  11711.     tmsg <
  11712. >
  11713.     move t1, cmloc        ; Get place to resume.
  11714.     jrst cmptr2
  11715.  
  11716. cptrap:    setom cpseen        ; Set ^P flag
  11717.     push p, t1        ; Echo ^P
  11718.     tmsg <
  11719. ^P>
  11720.     move t1, cploc        ; Get place to resume.
  11721.  
  11722. cmptr2:    hrli t1, (1b5)        ; Get into user mode.
  11723.     movem t1, pc2        ; Resume at desired PC.
  11724.     pop p, t1
  11725.     DEBRK
  11726.  
  11727.  
  11728.     subttl subbp - Subtract two arbitrary byte pointers
  11729.  
  11730. ; Subroutine to subtract two byte pointers in current section.
  11731. ; The two byte pointers must point to bytes of the same size.
  11732. ;
  11733. ; Call with:
  11734. ;   t1/ First byte pointer.
  11735. ;   t2/ Second byte pointer.
  11736. ;    CALL SUBBP
  11737. ;
  11738. ; Returns:
  11739. ;   +1 if the byte sizes are different, with t1-t3 unchanged, or else
  11740. ;   +2 with:
  11741. ;      t1,t2/ Unchanged.
  11742. ;      t3/ The number of bytes of the specified bytesize in the string pointed
  11743. ;          to by the first byte pointer (in t1) up to, but not including, the
  11744. ;          byte pointed to by the second byte pointer (in t2).
  11745.  
  11746. subbp:    saveac    <q1,q2,q3,q4>    ; Save permanent regs for work below.
  11747.     ldb q1, [point 6, t1, 11] ; q1 := bytesize 1.
  11748.     ldb q2, [point 6, t2, 11] ; q2 := bytesize 2.
  11749.     came q1, q2        ; Are they equal?
  11750.      ret            ; No, failure
  11751.  
  11752. ; Byte sizes are equal, can do arithmetic.
  11753.  
  11754.     movei q2, @t1        ; Do address calculation for t1
  11755.     movei q4, @t2        ;  and t2.
  11756.     sub q4, q2        ; q4 := (A1 - A2) = N words.
  11757.     movei q2, ^d36        ; q2 := bits/word.
  11758.     idiv q2, q1        ; q2 := bytes/word.
  11759.     imul q4, q2        ; q4 := bytes in N words.
  11760.     move q2, q4        ; (to leave q3-q4 free for IDIV)
  11761.     ldb q3, [point 6, t2, 5] ; q3 := Q2
  11762.     ldb t3, [point 6, t1, 5] ; t3 := Q1
  11763.     sub t3, q3        ; t3 := (Q1 - Q2)
  11764.     idiv t3, q1        ; t3 := (Q1 - Q2) / S
  11765.     add t3, q2        ; Adjust previous count.
  11766.     retskp            ; And return, with success.
  11767.  
  11768. ;[6] (this whole routine, just for fun...)
  11769.  
  11770. moon:    saveac <5,6>
  11771.  
  11772. ; This code stolen from MOON.MAC (anybody know who wrote it?).
  11773. ; Just changed OUTCHR's to PBOUT%'s via a macro.  - Frank.
  11774. ;
  11775.     setzb 3,4
  11776.     seto 2,
  11777.     ODCNV%
  11778.      erjmp r
  11779.     tlz 4,77
  11780.     IDCNV%
  11781.      erjmp r        ; Return upon any error.
  11782.     tmsg <, Moon: >        ; OK so far, say what we're doing.
  11783.  
  11784. ; AC2= Universal time adjusted for time zone.
  11785.  
  11786.     move 1,2        ; Right place.
  11787.     sub 1,newmn        ; Sub off base new moon
  11788.     idiv 1,period        ; Divide by the period
  11789.     idiv 2,perio4        ; Get fractions of a period
  11790.     camg 3,perio8        ; Check for pahse + or -
  11791.      jrst moon1        ; Not more than 3+ days
  11792.  
  11793.     sub 3,perio4        ; Make it next phase -n days
  11794.     cain 2,3        ; Is it LQ+3D+?
  11795.      tdza 2,2        ; It is
  11796.      aoj 2,            ; Increment phase
  11797.  
  11798. moon1:    hllz 1,table(2)        ; Get SIXBIT phase
  11799.     skipge 3        ; 3 < 0 then minus phase output
  11800.      tloa 1,'-'        ; -
  11801.      tloa 1,'+'        ; +
  11802.      movms 3        ; Fix mag of 3
  11803.     move 2,[point 6,1]    ; Byte pointer
  11804.     movei 5,2        ; Loop 3 times
  11805.  
  11806. moon2:    ildb 4,2        ; Get a character
  11807.     addi 4," "        ; Make ASCII
  11808.     OUTCHR 4        ; Type it
  11809.     sojge 5,moon2        ; Loop
  11810.  
  11811.     movsi 4,-4        ; Make aobjn pointer
  11812.     ;...
  11813.  
  11814. moon3:    hrrz 2,table(4)        ; Get a multiplier
  11815.     trz 2,774000        ; Strip off ascii character
  11816.     imuli 3,(2)        ; Get the value decoded
  11817.     hlrz 1,3        ; Get value
  11818.     tlz 3,-1        ; Zap old LH
  11819.     move 5,1        ; Use 5 & 6 here
  11820.     idivi 5,12        ; Radix 10
  11821.     addi 5,60        ; Make ASCII
  11822.     caile 5,60        ; Check for leading zero
  11823.      OUTCHR 5        ;  Type it.
  11824.     addi 6,60        ; Make ASCII
  11825.     OUTCHR 6
  11826.     ldb 5,[point 7,table(4),24] ; Get d/h/m/s
  11827.     OUTCHR 5        ; Type it.
  11828.     OUTCHR ["."]        ; Follow with a dot.
  11829.     aobjn 4,moon3        ; Loop.
  11830.  
  11831.     tmsg <
  11832. >                ; A CRLF at the end.
  11833.     ret            ; Done, return.
  11834.  
  11835.     subttl Pure Data
  11836.  
  11837.  
  11838. ; Pure data for moon.
  11839.  
  11840. newmn:    125575,,34343        ; 28-jan-79 0120 est
  11841. per==35,,422752            ; 29d.12h.53m.19s
  11842. period:    per
  11843. perio4:    per/4
  11844. perio8:    per/10
  11845.  
  11846. table:    byte(18)'NM '(7)"d"(11)^D1 ; New moon - days - 1
  11847.     byte(18)'FQ '(7)"h"(11)^D24 ; First quarter - hours - 24
  11848.     byte(18)'FM '(7)"m"(11)^D60 ; Full moon - minutes - 60
  11849.     byte(18)'LQ '(7)"s"(11)^D60 ; Last quarter - seconds - 60
  11850.  
  11851.  
  11852.  
  11853. ; Some other miscellaneous pure data
  11854.  
  11855. crlf:    asciz/
  11856. /                ; A carriage-return-linefeed.
  11857.  
  11858.     Remark    Interrupt storage (pure)
  11859.  
  11860. levtab:    pc1
  11861.     pc2
  11862.     pc3
  11863.  
  11864. chntab:    phase 0
  11865. tmchan:    1,,tmtrap        ; Timer trap on channel 0, priority 1.
  11866. ccchan:    1,,cctrap        ; ^C trap on channel 1, same priority.
  11867. cachan:    2,,catrap        ; ^A trap on channel 2, lower priority.
  11868. cxchan:    2,,cxtrap        ; ^X trap on channel 3...
  11869. czchan:    2,,cztrap        ; ^Y trap ....       4
  11870. cmchan:    2,,cmtrap        ; ^M trap ....       5
  11871.     repeat <^d23-.>,<0>    ; (Skip reserved area, can't use these)
  11872. cpchan:    2,,cptrap        ; ^P trap on channel 6
  11873.     block ^d36-.
  11874.     dephase
  11875.     0            ; (superstition)
  11876. lits:    lit            ; Assemble literals here.
  11877.  
  11878.     subttl    Impure data storage
  11879.  
  11880. CMDSTG                ; Allocate COMND JSYS storage
  11881. pdl:    block pdlsiz        ;  and stack.
  11882. pc1:    0            ; Interrupt PC storage, levels 1,
  11883. pc2:    0            ;  2,
  11884. pc3:    0            ;  and 3.
  11885. intpc:    0            ; PC to restore on timer interrupt.
  11886. intstk:    0            ; Stack pointer to restore on timer interrupt.
  11887. ccn:    0            ; Number of ^C's typed.
  11888. caseen:    0            ; Flag for ^A trap.
  11889. psave:    0            ; Stack pointer for ^C interrupt.
  11890. psave2:    0            ; Stack top for ^C interrupt.
  11891. tsave:    0            ;[132] Same as above, but for timer interrupts.
  11892. tsave2:    0            ;[132]  ...
  11893. cmseen:    0            ;[165] Flag for ^M interrupt seen.
  11894. cmloc:    0            ;[165] Where to go on ^M interrupt.
  11895. cpseen:    0            ;[165] Flag for ^P interrupt seen.
  11896. cploc:    0            ;[165] Where to go on ^P interrupt.
  11897. cxseen:    0            ;[59] Flag for ^X interrupt seen.
  11898. czseen:    0            ;[59] Flag for ^Z interrupt seen.
  11899. capas:    0            ; Process capabilities.
  11900. inited:    0            ;[177] inilin/reslin flag.
  11901.  
  11902. pars1:    0            ; Data from first parse.
  11903. pars2:    0            ; Data from second parse.
  11904. pars3:    0            ; Data from third parse.
  11905. pars4:    0            ; Data from fourth parse.
  11906. pars5:    0            ;[41] ...
  11907. srvflg:    0            ; Are we serving?  Erase if we go for command.
  11908. iflg:    0            ;[100] -1 if sending INFO packet, else 0.
  11909. lcflg:    0            ;[56] LOCAL command (-1 = LOCAL, 0 = REMOTE).
  11910. definf:    0            ;[77] DEFINE flag nonzero if parsing DEFINE.
  11911. undeff:    0            ;[77] UNDEFF flag nonzero if DEFINE x <cr>.
  11912. source:    0            ;[102] Source routine for GETCH.
  11913. dest:    0            ;[107] Destination routine for PUTCH.
  11914. ffunc:    0            ;[118] File function (dir, del, ren, etc).
  11915. parsx==.-1            ; For zeroing the above.
  11916.     
  11917. dfstrt:    PROMP            ; Are we to be a SERVER or go to the PROMPT?
  11918.                 ;  (PROMP not PROMPT, which CMD package uses)
  11919. f$exit:    0            ; Exit flag for EXIT command or rescan entry.
  11920. ttyjfn:    .priin            ; JFN for controlling terminal.
  11921. logjfn:    0            ;[38] Debugging log file JFN.
  11922. tlgjfn:    0            ;[126] Transaction log file JFN.
  11923. sesjfn:    0            ;[128] Session log file JFN.
  11924. savjfn:    0            ; Place to save session log JFN.
  11925. logbsz:    0            ;[41] Log file byte size.
  11926. filjfn:    0            ; JFN of file being sent.
  11927. ndxjfn:    0            ; Indexable JFN, for wildcard stepping.
  11928. nxtjfn:    0            ;[111] JFN of next file to be sent.
  11929. netjfn:    0            ; Line for packet transmission.
  11930. ttymod:    0            ; Current mode word for controlling tty.
  11931. oldjfn:    0            ; JFN on previous line.
  11932. oldmod:    0            ; Previous mode of the line.
  11933. oldpau:    0            ; Previous terminal pause on end mode.
  11934. tiword:    0            ; Terminal interrupt word
  11935. sysmsg:    0            ;[82] Accept/refuse system message status.
  11936. ttynum:    0            ; Number of the TTY being used.
  11937. oldnum:    0            ;[7] Number of previous TTY in case of change.
  11938. mytty:    0            ;[4] TTY number of job's controlling terminal.
  11939. myccoc:    0            ;[161] CCOC words for my tty.
  11940.     0            ;[161] (two of them)
  11941. ttpau:    0            ;[161] Controlling TTY's pause chars.
  11942. myjob:    0            ;[7] My job number.
  11943. skdflg:    0            ;[130] Nonzero if class scheduler on.
  11944. class:    0            ;[130] My scheduler class.
  11945. job:    0            ;[7] Number of job that has TTY I want.
  11946.     ;...
  11947.  
  11948. ; Impure Data, cont'd
  11949.  
  11950. pname:    0            ; Name of this process
  11951.     0            ;  (need 2 words)
  11952. ttfork:    0            ; Fork number of the connect receive fork.
  11953. rufork:    0            ; Fork number for LOCAL RUN program fork.
  11954. rujfn:    0            ; JFN for LOCAL RUN program.
  11955. execf:    0            ; Fork number of PUSH (to Exec) fork.
  11956. errptr:    0            ; Pointer to most recent error string.
  11957. atmptr:    0            ; Atom buffer pointer.
  11958. xfnflg:    0            ;[84] Flag for file name conversion.
  11959. xflg:    0            ;[104] Flag for sending with X header.
  11960. ebtflg:    0            ; One if file is to be used in 8-bit mode.
  11961. autbyt:    1            ; One if auto-byte is to be used.
  11962. handsh:    0            ;[76] Handshake.
  11963. flow:    1            ;[143] Flow-Control (nonzero = XON/XOFF)
  11964. itsflg:    defits            ;[75] Flag for handling ITS-binary format files
  11965. itsfil:    0            ;[75] Flag for this file is ITS format.
  11966. itscnt:    0            ;[75] Counter for ITS header chars matched.
  11967. tvtflg:    0            ;[129] Negotiate binary mode on ARPANET TVT.
  11968. incase:    defics            ;[160] Case conversion flag for INPUT search.
  11969. indeft:    defito            ;[160] Default timeout for INPUT search.
  11970. intima:    defita            ;[160] Timeout action for INPUT search.
  11971. asgflg:    0            ;[7] -1 if I asg'd the TTY, 0 if already asg'd.
  11972. oasflg:    0            ;[7] Same, but for previous TTY.
  11973. actmp:    block 20        ;[59] A place for short-term saving of ACs.
  11974. pktacs:    block 6            ;[112] Place to save RPACK/SPACK ACs.
  11975. parity: defpar            ; Type of parity to use.
  11976. gotx:    0            ; Flag for "already got an X-packet".
  11977. gots:    0            ; Flag for "already got an S-packet".
  11978. mapflg:    0            ; One if a page is mapped in.  (Init to 0.)
  11979. mdmlin:    0            ;[130] -1 = modem-controlled line, 0 = not.
  11980. carier:    0            ;[130] Flag for carrier dropped.
  11981. monv:    0            ;[146] Monitor version (0 if less than 6.0).
  11982. speed:    0            ;[130] Ostensible line speed -- input,,output.
  11983. setspd:    0            ;[161] Flag speed was explicitly SET.
  11984. defbrk==3            ;[16] default nulls to send on break
  11985. brk:    defbrk            ;[16] nulls to send on BREAK key
  11986. local:    0            ; -1 = local Kermit, 0 = remote.
  11987. rcving:    0            ; -1=actually recving, +1=sending, 0=neither.
  11988. $sendf:    0            ; SEND command in progress.
  11989. $recvf:    0            ; RECEIVE command in progress.
  11990. pagptr:    0            ; Pointer into the page.
  11991. ;**************
  11992. pagcnt:    0            ; Number of pages in the file,
  11993. bytcnt:    0            ; and byte count
  11994. crdate:    0            ; and creation date (these 3 must be adjacent!)
  11995. ;**************
  11996. bytsiz:    0            ; Byte size of file.
  11997. abtfil:    0            ;[42] 0 = discard incomplete file, -1 = keep.
  11998. expung:    0            ;[143] Automatically expunge when deleting.
  11999. pagno:    0            ; Present page number.
  12000. stdat:    0            ; Time taken in transmitting.
  12001. size:    0            ; Size of the present data.
  12002. spsiz:    dspsiz            ; Maximum size packet to send.
  12003. rpsiz:    drpsiz            ; Maximum size packet to receive.
  12004. maxdat:    dspsiz-5        ;[63] Max length for data field.
  12005. srvtim:    dsrvtm            ;[137] Server command wait timeout interval.
  12006. stimou:    dstim            ; Interval for my own timer.
  12007. otimou:    dstim            ;[26] Place to save old timout interval.
  12008. rtimou:    drtim            ; Minimum timeout interval I need.
  12009. rrtimo:    drtim            ;[128] Above, adjusted for 15-min load avg.
  12010. ntimou:    0            ;[54] Timeout counter.
  12011. curtim:    0            ;[131] Current load-adjusted timeout interval.
  12012. timerx:    0            ;[132] Counter for timer errors.
  12013. nnak:    0            ;[54] NAK counter.
  12014.     ;...
  12015.  
  12016. ; Impure Data, cont'd
  12017.  
  12018. rpause:    drpaus            ;[35] Pause before ACKing data packet.
  12019. spause: dspaus            ;[36] Pause before sending data packet.
  12020. pause:    0            ;[36] Pause currently in effect.
  12021. spadch:    dspad            ; Pad char micro wants.
  12022. rpadch:    drpad            ; Pad char I want.
  12023. spadn:    dspadn            ; Number of pad chars for micro.
  12024. rpadn:    drpadn            ; Number for me.
  12025. seolch:    dseol            ; EOL char micro needs.
  12026. reolch:    dreol            ; EOL I need.
  12027. squote:    dsquot            ; Quote character micro wants.
  12028. rquote:    drquot            ; Quote character I want.
  12029. delay:    ddelay            ; How long before I send the first packet.
  12030. odelay:    ddelay            ;[27] For saving & restoring delay.
  12031. escape:    defesc            ; Escape character for connecting (default ^Y).
  12032. duplex:    dxfull            ; Duplex for connecting.
  12033. ssthdr:    SOH            ; Start of header character to send.
  12034. rsthdr:    SOH            ; Start of header character to receive.
  12035. rtchr:    0            ; Total characters received.
  12036. stchr:    0            ;  ... sent.
  12037. rtot:    0            ; Some more counters..
  12038. stot:    0            ;
  12039. otot:    0
  12040. numtry:    0            ; Number of tries on a packet.
  12041. oldtry:    0            ; Number of tries for previous packet.
  12042. maxtry:    dmxtry            ; Maximum retries for an ordinary packet.
  12043. imxtry: dimxtr            ; Maximum retries in send initiate.
  12044. pktnum:    0            ; Current packet sequence number.
  12045. num:    0            ; Number of packet just received.
  12046. type:    0            ; Type of same.
  12047. datlen:    0            ; Length of data field of same.
  12048. pktlen: 0            ;[179] Packet length.
  12049. islong:    0            ;[179] Packet is long.
  12050. datptr:    0            ; Pointer to data field of same.
  12051. gclen:    0            ; Generic command data field length.
  12052. rptot:    0            ;[4] Counter for received packets.
  12053. sptot:    0            ;[4] Counter for sent packets.
  12054. files:    0            ; File counter.
  12055. sec:    0            ; Seconds (for figuring baud rate)
  12056. eoflag:    0            ; End of file flag.
  12057. temp:    0            ; Temporary location, to be used only for
  12058. temp2:    0            ;  very brief periods.
  12059. ch:    0            ;[63] Current character.
  12060. next:    0            ;[63] Next character.
  12061. rpt:    0            ;[63] Repeat count of current character.
  12062. rptq:    drept            ;[63] Repeat count prefix.
  12063. rptflg:    0            ;[63] Repeat count processing flag.
  12064. rptfld:    drept            ;[92] Repeat count field for Send-Init.
  12065. ebq:    "Y"            ;[63] 8th-bit-on prefix.
  12066. ebqflg:    0            ;[63] 8th-bit prefixing flag.
  12067. ebqr:    0            ;[88] 8th-bit prefixing requested flag.
  12068. ebqfld:    "Y"            ;[88] 8th-bit prefix field for Send-Init.
  12069. ebqchr:    0            ;[90] Current character has 8th-bit prefix.
  12070. bctr:    "1"            ;[98] Block check type requested (character).
  12071. bctu:    1            ;[98] Block check type in use (number).
  12072. bctone:    0            ;[98] Use type 1 for this packet regardless...
  12073. bctemp:    0            ;[98] Place to store incoming block check.
  12074.     0            ;[98]
  12075.  
  12076. ; Impure Data, cont'd
  12077.  
  12078.  
  12079. xxumsg:    asciz/"x" - Unknown server command/ ; Server message (fill in the x)
  12080. xxulen=^d28            ; Number of characters in xxumsg.
  12081. xxbmsg:    asciz/"x" - Not valid as server command/ ; Another.
  12082. xxblen=^d33            ; Number of characters in xxbmsg.
  12083. xxgums:    asciz/"x" - Undefined generic command/
  12084. xxguln=^d31
  12085. xxgnms:    asciz/"x" - Unimplemented generic command/
  12086. xxgnln=^d35
  12087.  
  12088. dirbuf:    asciz/PS:</        ;[79] User's logged-in ID string.
  12089.     block ^d30        ;[79]
  12090.  
  12091. iniflg:    0            ;[83] Init file in progress.
  12092. takjfn:    0            ;[78] JFN of current TAKE command file.
  12093. takdep:    0            ;[78] Depth of TAKE file JFN stack.
  12094. takep:    0            ;[78] TAKE file JFN stack pointer.
  12095. takpdl:    block <takel+2>        ;[78] TAKE file JFN stack itself.
  12096.  
  12097. mdone:    0            ;[77] Flag for macro execution done.
  12098. macrof:    0            ;[77] Flag on if executing a SET macro.
  12099. macbp:    point 7, macbuf        ;[77] Pointer into macro text buffer.
  12100. omacbp:    0            ;[77] Previous MACBP.
  12101. macxp:    0            ;[77] Macro execution pointer.
  12102. namp:    point 7, nambuf        ;[77] Pointer into macro name buffer.
  12103. onamp:    0            ;[77] Previous NAMP.
  12104. macptr:    0            ;[77] Pointer to start of macro text in CSB.
  12105. nambuf:    block MNBLEN        ;[77] Buffer for DEFINE macro name.
  12106. namx:    block ^d10        ;[77] Some protection against spills.
  12107. filptr:    0            ;[102] Pointer into file name buffer.
  12108. fildot:    0            ;[102] Counter for dots in filename.
  12109. filbuf:    block ^d30        ; Buffer for file name building.
  12110. filbfz:    -1            ; End of same...
  12111. filcnt:    0            ; File counter for directory listings.
  12112. dirfin:    0            ; Flag for directory listing finished.
  12113.     ;...
  12114.  
  12115. ; Impure Data, cont'd -- big stuff at end.
  12116.  
  12117.  
  12118. jobtab:    block ^d30        ; Job info table for GETJI
  12119. skdblk:    block ^d20        ; Argument block for SKED% jsys.
  12120. prompx:    asciz/Kermit-20>/    ; Program prompt text (replacable)
  12121.     block ^d10        ; ...and some padding.
  12122. pasptr:    0            ; Pointer into...
  12123. pasbuf:    block MAXPKT/4+1    ; Buffer for remote password.
  12124. pasbfl==.-pasbuf        ; Length of above.
  12125.     0            ; Superstition
  12126. ttibuf:    block IOBUF/4+1        ;[180] Communications device input buffer
  12127. ttiptr:    point 8, ttibuf        ;[180] Pointer to communications input buffer
  12128. tticnt:    0            ;[180] Communications input buffer count
  12129. ttisin: 0            ;[180] Statistics counters...
  12130. ttibin:    0            ;[180]
  12131. ttildb:    0            ;[180]
  12132. ttimax: 0            ;[180]
  12133. buffer:    block MAXBUF/4+1    ; Buffer for file I/O.
  12134.     block ^d20        ; Superstition
  12135. data:    block MAXBUF/4+1    ; Data field of packet.
  12136.     block ^d20        ; Superstition
  12137. sndpkt:    block MAXBUF/4+1    ; Place for building outbound packets.
  12138.     block ^d20        ; Superstition
  12139. recpkt:    block MAXBUF/4+1    ; Place for putting incoming packets.
  12140. recpkz:    block ^d20        ; Superstition
  12141. tvtbuf:    block MAXBUF/4+1    ;[131] For doubled-iac version of send packet.
  12142.     block ^d20        ; Superstition
  12143. %%krbf:    block MAXPKT/4+1    ;[40] Place for packetized error messages.
  12144.     block ^d20        ; Superstition
  12145. macbuf:    repeat <MTBLEN>,<0>    ;[77] Macro text buffer.
  12146. macx:    block ^d20        ;[77] End of macro text buffer, with padding.
  12147. ;
  12148. ; Macro table, with one predefined macro, for Columbia's IBM system.
  12149. ; Users can remove this definition by typing "define ibm", or they can
  12150. ; replace it.  KERMIT-20 maintainers can remove it for their site by replacing
  12151. ; the contents of MACTAB (first word) with 0,,MACMAX, or can change it to be
  12152. ; anything they like.
  12153. ;
  12154. mactab:    1,,MACMAX        ;[77] Macro keyword TBLUK format table.
  12155.     [asciz/IBM/],,[asciz/parity mark, duplex half, handshake xon
  12156. /]                ;[77] Custom IBM mainframe definition.
  12157.     repeat <MACMAX-1>,<0>    ;[77] Macro keyword table.
  12158. mactbx:    repeat <100>,<0>    ; A small reserve tank...
  12159.     lit            ; Expand remaining literals here.
  12160.     0
  12161.  
  12162. strc:    0            ; Counter for, and...
  12163. strptr:    0            ; Pointer into...
  12164. strbuf:    repeat <1000>,<0>    ; String buffer for big strings.
  12165. strbf2:    repeat <1000>,<0>    ; More of string buffer for big strings.
  12166. strbln=.-strbuf            ; Length of whole thing.
  12167. strbz:    0            ; Where the padding ends.
  12168.  
  12169. getptr:    0            ; Pointer for emptying...
  12170. srvptr:    0            ; And pointer for filling...
  12171. srvbuf:    repeat <1000>,<0>    ; Big buffer for server responses.
  12172. srvbz:    repeat <100>,<0>    ; End of buffer, with some padding.
  12173. srvbzz:    0            ; Where the padding ends.
  12174.  
  12175.     end    <evlen,,kermit>
  12176.  
  12177. ;Old Edit history moved to after END statement...
  12178. ;
  12179. ;*************** Major Version 4.0 ****************
  12180. ;PS:<TIMREK>KERMIT.MAC.491,  5-Jan-84 18:49:24, Frank
  12181. ;[102] Have SFILE call GETBUF to put filename in file header packet with
  12182. ; full prefixing.  This is the first use of GETBUF/ENCODE on non-file data.
  12183. ;PS:<TIMREK>KERMIT.MAC.487,  3-Jan-84 18:42:38, Frank
  12184. ;[101] Strip ^V quote characters from outgoing file names.
  12185. ;PS:<TIMREK>KERMIT.MAC.472, 30-Dec-83 11:29:03, Frank
  12186. ;[100] More debugging of [98]; got 3-char CRC to work.  Also:
  12187. ;.Make GET command send an I packet before the R packet, to tell other side
  12188. ; what block check & other parameters to use when sending.  Replace SINFO
  12189. ; with a simple call to SINIT -- they do the same thing.
  12190. ;.New headings for SHOW PACKET display.
  12191. ;.If local, say delay is 0 in SHOW TIMING.
  12192. ;PS:<TIMREK>KERMIT.MAC.469, 29-Dec-83 20:53:36, Frank
  12193. ;[99] Debugging of [98]; Got 2-character checksum actually working.  Also:
  12194. ;.In RPACK, allow receipt of 1-char checksummed null packet, even if doing
  12195. ; 2 or 3 char block checks.  Other side might have restarted & sent a NAK.
  12196. ;.Tightened up various much-used loops.
  12197. ;.Improved packet logging -- now every character sent or received is logged.
  12198. ;PS:<SY.FDC>KERMIT.MAC.2, 28-Dec-83 09:25:32, Frank
  12199. ;[98] Added support for 2- and 3-character checksums.
  12200. ;*************  Version 3.4 **************
  12201. ;PS:<TIMREK>KERMIT.MAC.448, 23-Dec-83 13:59:52, Frank
  12202. ;[97] In INILIN, preserve TTY mode word settings that don't effect KERMIT, so
  12203. ; as not to cause undesired side effects with TACs, etc.  Fixes(?) bug reported
  12204. ; by Keith Petersen, diagnosed by Mark Crispin.
  12205. ;PS:<TIMREK>KERMIT.MAC.442, 20-Dec-83 19:47:03, Frank
  12206. ;[96] Add SEND (AS) remote-filespec when sending a single file.
  12207. ; Don't confuse user by displaying escape character in SHOW LINE when remote.
  12208. ;PS:<TIMREK>KERMIT.MAC.437, 15-Dec-83 19:20:10, Frank
  12209. ;[95] Remove SET EIGHTH-BIT-PREFIX command, always request it if parity is
  12210. ; being used.  Minor cleanups of help & program text.  Change version number
  12211. ; typeout to agree with the way the Exec now does it: major.minor(edit)-who.
  12212. ; Get rid of old GTCHR and PTCHR routines, and SET IBM routines.
  12213. ;PS:<TIMREK>KERMIT.MAC.431, 14-Dec-83 18:21:44, Frank
  12214. ;[94] Don't allow user to type RECEIVE or SERVER commands when local.
  12215. ;PS:<TIMREK>KERMIT.MAC.428, 14-Dec-83 15:18:03, Frank
  12216. ;[93] Minor corrections in ENCODE for off-by-1 errors doing repeat counts.
  12217. ;PS:<TIMREK>KERMIT.MAC.420, 14-Dec-83 12:39:32, Frank
  12218. ;[92] Add repeat count processing to SPAR, RPAR, SINIT, RINIT.
  12219. ; (It was already in the i/o routines, but never used.)
  12220. ;PS:<TIMREK>KERMIT.MAC.419, 13-Dec-83 18:25:55, Frank
  12221. ;[91] Add routine TTXON, call it whenever there's a timeout.
  12222. ; This should unstick the two sides in case of an XOFF deadlock.
  12223. ;PS:<TIMREK>KERMIT.MAC.415, 12-Dec-83 13:04:35, Frank
  12224. ;[90] Make 8th-bit prefixing work with PDP-10 36-bit binary files.
  12225. ;PS:<TIMREK>KERMIT.MAC.405,  9-Dec-83 15:15:39, Frank
  12226. ;[89] Polish up previous edit.  Turn on prefixing if using parity.
  12227. ;PS:<TIMREK>KERMIT.MAC.400,  8-Dec-83 16:40:28, Frank
  12228. ;[88] Turn on 8th-bit prefixing in RPAR & SPAR, add SET & SHOW stuff for it.
  12229. ;****************** Version 3C **********************
  12230. ;PS:<TIMREK>KERMIT.MAC.394,  2-Dec-83 14:50:55, Frank
  12231. ;[87] Fix bugs in [85]; make sure line does not change after halt/cont.
  12232. ;PS:<TIMREK>KERMIT.MAC.382,  1-Dec-83 14:15:24, Frank
  12233. ;[86] Don't send 4 extra characters if file is ITS binary.
  12234. ;PS:<TIMREK>KERMIT.MAC.381,  1-Dec-83 13:58:23, Frank
  12235. ;[85] Make rescan work even if no KERMIT.INI file.
  12236. ; Make sure line is set up correctly after exit and continue.
  12237. ;PS:<TIMREK>KERMIT.MAC.379, 25-Nov-83 17:13:16, Frank
  12238. ;[84] Add SET option to convert file names to "normal form".
  12239. ; SET FILE-BYTE-SIZE changed to SET FILE BYTESIZE to allow other file
  12240. ; options, like this new one (SET FILE NAMING).
  12241. ; Still allow "SET FILE 8", etc, for compatibility with the old way.
  12242. ;PS:<TIMREK>KERMIT.MAC.361, 25-Nov-83 11:34:54, Frank
  12243. ;[83] Return properly from SHOW ALL command.
  12244. ; Allow init file to be taken even when there is a command line argument.
  12245. ; Init file is always taken before looking at any other commands.
  12246. ;PS:<TIMREK>KERMIT.MAC.355, 11-Nov-83 19:14:43, Frank
  12247. ;[82] Clear/refuse links, system messages during file transfer.
  12248. ; Also, make sure we print the contents of any incoming error packet if
  12249. ; in local mode.  Also, don't echo back DEFINEs any more.
  12250. ;PS:<TIMREK>KERMIT.MAC.354,  9-Nov-83 18:35:53, Frank
  12251. ;[81] More miscellaneous fixes:
  12252. ; . Since CCOFF is called whenever RESLIN is called, have RESLIN call CCOFF.
  12253. ; . Don't turn ^C trap off between transactions if running in server mode.
  12254. ; . Fix broken autobyte code (skipn/skipe, sigh...)
  12255. ; . Fix broken "bit35" code in PUTCH for SOS & PDP-10 binary files.
  12256. ; . Remove debugging output for DEFINE & SET macro stuff.
  12257. ;PS:<TIMREK>KERMIT.MAC.338,  8-Nov-83 11:39:11, Frank
  12258. ;[80] Fix miscellaneous bugs:
  12259. ; . Communication line JFNs improperly juggled in $SETLN.
  12260. ; . Control-C trap was leaving an extra entry on the stack.
  12261. ; . Turn off Control-C trap after ^C out of send, receive, or server mode.
  12262. ; . Close file we're sending if other side sends an error packet.
  12263. ; . Time transfer started not always properly initialized.
  12264. ; . Remove garbage at end of set-macro body string.
  12265. ; . Clean up code at $SEND and $RECV for server entry.
  12266. ;PS:<TIMREK>KERMIT.MAC.331, 28-Oct-83 20:35:46, Frank
  12267. ;[79] Do an implicit TAKE of KERMIT.INI upon initial startup.
  12268. ;PS:<TIMREK>KERMIT.MAC.309, 28-Oct-83 15:29:45, Frank
  12269. ;[78] Add TAKE command to allow (nested) command files.
  12270. ;PS:<TIMREK>KERMIT.MAC.288, 27-Oct-83 18:55:44, Frank
  12271. ;[77] Add DEFINE command for SET macros.  Remove hardwired SET IBM.
  12272. ;PS:<TIMREK>KERMIT.MAC.268, 26-Oct-83 14:15:23, Frank
  12273. ;[76] Add SET HANDSHAKE.
  12274. ;PS:<TIMREK>KERMIT.MAC.251, 12-Oct-83 10:51:56, Frank
  12275. ;[75] Add ITS binary format file handling, as specified in KRFC #3.
  12276. ;PS:<TIMREK>KERMIT.MAC.243, 10-Oct-83 13:33:53, Frank
  12277. ;[74] Fix bug that truncated JSYS error messages in error packet text.
  12278. ;PS:<TIMREK>KERMIT.MAC.241, 10-Oct-83 13:07:33, Frank
  12279. ;[73] Make sure old JFN's on assigned TTYs are released properly.
  12280. ;PS:<TIMREK>KERMIT.MAC.240, 10-Oct-83 11:44:47, Frank
  12281. ;[72] Fix bug that made any file sent after a null file also null.
  12282. ; Fix bug in which last send from server sets byte size for next receive.
  12283. ;PS:<TIMREK>KERMIT.MAC.237,  7-Oct-83 16:47:24, Frank
  12284. ;[71] Fix SHOW DEBUG not to foul up if log JFN is .PRIOU.
  12285. ;PS:<TIMREK>KERMIT.MAC.230,  7-Oct-83 14:02:35, Frank
  12286. ;[70] Catch illegal memory references when mapping in a nonexistent page.
  12287. ; If i/o error sending a file, don't cancel, tell other side to discard.
  12288. ; This allows wildcard sends to proceed after a memory access error.
  12289. ; Also, allow ^C's to interrupt a nonworking FINISH or BYE command gracefully.
  12290. ;PS:<TIMREK>KERMIT.MAC.224,  6-Oct-83 18:56:09, Frank
  12291. ;[69] Fix bug that prevented interrupts from working after EXIT & continue.
  12292. ;PS:<TIMREK>KERMIT.MAC.219,  6-Oct-83 15:13:33, Frank
  12293. ;[68] Separate local and remote mode top-level command tables.
  12294. ; Make remote commands invisible in local mode & vice versa.
  12295. ; Move command keyword tables to where they are used.
  12296. ;PS:<TIMREK>KERMIT.MAC.212,  6-Oct-83 10:18:30, Frank
  12297. ;[67] Remove REMOTE & LOCAL commands for now -- these will be added later.
  12298. ; Update help text to reflect changes since last release, mainly ^A,^X,^Z.
  12299. ; Rename SET ABORTED-FILE to SET INCOMPLETE to avoid emotionally toned word.
  12300. ; Rename SET IBM-FLAG to SET IBM (flags are for programmers).
  12301. ; Break up help text for SET command.
  12302. ; Move help text for each command to same area as command itself.
  12303. ;PS:<TIMREK>KERMIT.MAC.202,  4-Oct-83 19:16:37, Frank
  12304. ;[66] Same deal as [63], but for file output routines.
  12305. ; Old PTCHR replaced by PUTBUF, DECODE, and PUTCH.
  12306. ; Also, include Nick Bush's CRC routine, but don't use it yet.
  12307. ;PS:<TIMREK>KERMIT.MAC.199, 30-Sep-83 19:48:52, Frank
  12308. ;[65] Clean up SEND command parsing, don't parse for initial filespec if no
  12309. ; wildcards given.
  12310. ;PS:<TIMREK>KERMIT.MAC.196, 29-Sep-83 19:13:45, Frank
  12311. ;[64] Debug the previous edit for basic service.
  12312. ;PS:<TIMREK>KERMIT.MAC.184, 28-Sep-83 18:53:21, Frank
  12313. ;[63] Rewrite file input routines to separate i/o from packet formation.
  12314. ; New routines are GETBUF to fill a packet buffer,
  12315. ; GETCH to get an input character,
  12316. ; ENCODE to process the character, performing control quoting, prefix quoting,
  12317. ;  and, if selected, 8th-bit quoting and repeat count processing.
  12318. ; GTCHR is still present, but not used at all.
  12319. ;PS:<TIMREK>KERMIT.MAC.169, 19-Sep-83 17:56:27, Frank
  12320. ;[62] Add ^X and ^Z to interrupt receiving a file or a batch, respectively.
  12321. ; Required insertion of data ("D") in ACK for data packet.
  12322. ;PS:<TIMREK>KERMIT.MAC.163, 16-Sep-83 19:19:13, Frank
  12323. ;[61] Put brief status report on ^A, like NFT has.
  12324. ;PS:<TIMREK>KERMIT.MAC.156, 16-Sep-83 15:45:56, Frank
  12325. ;[60] Add return code to SPACK to distinguish different kinds of failures.
  12326. ;PS:<TIMREK>KERMIT.MAC.151, 15-Sep-83 19:32:57, Frank
  12327. ;[59] Add ^X and ^Z to interrupt sending a file or a batch, respectively.
  12328. ; Required addition of data ("X" or "Z") to Z packet.
  12329. ;PS:<TIMREK>KERMIT.MAC.146, 15-Sep-83 16:18:26, Frank
  12330. ;[58] Add sending of "I" packets before server commands.
  12331. ;PS:<TIMREK>KERMIT.MAC.137,  8-Sep-83 20:20:28, Frank
  12332. ;[57] Add debugging log capability to server commands as well as file xfer.
  12333. ;PS:<TIMREK>KERMIT.MAC.130,  8-Sep-83 18:55:05, Frank
  12334. ;[56] Begin adding new server commands.  First, add LOCAL and REMOTE
  12335. ; top level commands, with operands like DELETE, TYPE, DISK, etc.
  12336. ; Implement DISK first, that's the easiest test of sending back info in
  12337. ; the data field of an ACK.  Also, catch a couple places where the nonskip
  12338. ; return from SPACK was not being accounted for (oops!).
  12339. ;**************** Version 3B *******************************
  12340. ;PS:<TIMREK>KERMIT.MAC.126,  8-Sep-83 15:14:37, Frank
  12341. ;[55] Add CFIBFs in BYE and FINISH; all commands to servers should do this.
  12342. ;PS:<TIMREK>KERMIT.MAC.123,  8-Sep-83 14:02:38, Frank
  12343. ;[54] Report number of NAKs and timeouts in STATISTICS command.
  12344. ;PS:<SY.FDC>KERMIT.MAC.7,  2-Sep-83 17:56:19, Frank
  12345. ;[53] When receiving a file, NAK a trashed packet immediately, don't just wait
  12346. ; for it to come again and only NAK after timeout.  This should result in a
  12347. ; major speed improvement over noisy lines.  The book has always said to do it
  12348. ; this way.  Fix is in RINIT, RFILE, RDATA.  Other KERMITs may need this too.
  12349. ;PS:<SY.FDC>KERMIT.MAC.4,  2-Sep-83 16:43:22, Frank
  12350. ;[52] Combine some common code in the send routines, and improve comments.
  12351. ;PS:<KERMIT>20KERMIT.MAC.40, 25-Aug-83 15:28:36, Frank
  12352. ;[51] Fix packet number compares for mod 64 in SFILE, SDATA, SEOF, SEOT.
  12353. ; This eliminates canceling whenever a retransmission of packet 0 occurs.
  12354. ;CU20D::PS:[SY.FDC]KERMIT.MAC.32, 29 June 1983, 5:39PM, Frank
  12355. ;[50] Change and document the calling conventions of RPAR & SPAR to eliminate
  12356. ; the mess from the last few edits.  Do even more validation in SPAR.
  12357. ;PS:<TIMREK>KERMIT.MAC.118, 29-Jun-83 14:31:52, Frank
  12358. ;[49] Fix another bug in SPAR, change method of incrementing packet numbers.
  12359. ;PS:<TIMREK>KERMIT.MAC.114, 28-Jun-83 16:43:09, Frank
  12360. ;[48] Point to data buffer correctly in SPAR & RPAR. This was lost in some
  12361. ; previous edit.
  12362. ;PS:<TIMREK>KERMIT.MAC.110, 28-Jun-83 15:10:26, Frank
  12363. ;[47] Fix bad checksum reporting, again.  Print most recent JSYS err in STAT.
  12364. ; Don't let other side's Send-Init parameters override any local SET commands.
  12365. ;PS:<TIMREK>KERMIT.MAC.104, 27-Jun-83 17:37:54, Frank
  12366. ;[46] CFIBF after timeout in RPACK.  Be more consistent about how errors
  12367. ; are handled in receive routines.  Clean up server command loop a little.
  12368. ;[PS:<TIMREK>KERMIT.MAC.101, 24-Jun-83 20:18:42, Frank
  12369. ;[45] Fix SHOW command for timing info.
  12370. ;[PS:<TIMREK>KERMIT.MAC.99, 24-Jun-83 17:54:07, Frank
  12371. ;[44] In SFILE, don't give up if OPENF failed because file already open.
  12372. ;PS:<TIMREK>KERMIT.MAC.92, 24-Jun-83 16:55:38, Frank
  12373. ;[43] Don't do timeouts if STIMOU is 0, as protocol says.  Kermit-65 was
  12374. ; sending a space (which translates to 0) in this field of the send-init by
  12375. ; mistake, and Kermit-20 was doing rapid-fire timeouts.
  12376. ;CU20D::PS:[SY.FDC]KERMIT.MAC.19, 22 Jun 83 17:12:33, Frank
  12377. ;[42] Release any piled up log jfns.  Issue KERMSGs any time we cancel.
  12378. ; Add SET ABORTED-FILE (DISPOSITION) DISCARD | KEEP
  12379. ;PS:<TIMREK>KERMIT.MAC.89, 17-Jun-83 11:48:26, Frank
  12380. ;[3A(41)] Clean up listing & help messages, declare minor version "A".
  12381. ;************************ Version 3A ******************************
  12382. ;PS:<TIMREK>KERMIT.MAC.83, 16-Jun-83 16:10:47, Frank
  12383. ;[41] Add bytesize selection option for debugging log file (7 or 8 bit),
  12384. ; for use when debugging binary file transfers.  Force debugging on
  12385. ; when log file requested.
  12386. ;PS:<TIMREK>KERMIT.MAC.75, 16-Jun-83 12:32:34, Frank
  12387. ;[40] Remove the last remaining long lines.  Get rid of hairy %CLEAR macro.
  12388. ; Don't send an error packet longer than the other side's maximum packet size.
  12389. ; Always blank out the error message packet buffer before filling.
  12390. ;PS:<TIMREK>KERMIT.MAC.71, 16-Jun-83 11:36:51, Frank
  12391. ;[39] Change STATUS to STATISTICS, give optional arguments to SHOW command.
  12392. ; Print program version upon startup.
  12393. ;CU20D::PS:<SY.FDC>KERMIT.MAC.13, 15-Jun-83 18:12:37, Frank
  12394. ;[38] Allow debugging output to go to a file.  Thus can even get debugging
  12395. ; information when running remotely.  Suggested by Dave King at CMU.
  12396. ;CU20D::PS:<SY.FDC>KERMIT.MAC.6, 15-Jun-83 14:34:19, Frank
  12397. ;[37] Add SET RETRY, fix FLDDB's so none are more than 80 chars wide.
  12398. ;PS:<TIMREK>KERMIT.MAC.68, 15-Jun-83 11:47:19, Frank
  12399. ;[36] Add SET SEND PAUSE, and include pause info in SHOW & STATUS commands.
  12400. ;PS:<TIMREK>KERMIT.MAC.64, 14-Jun-83 19:25:45, Frank
  12401. ;[35] Add SET RECEIVE PAUSE, suggested by Dave King at CMU.
  12402. ;PS:<TIMREK>KERMIT.MAC.61, 14-Jun-83 18:40:48, Frank
  12403. ;[34] In SPACK, send padding if requested.
  12404. ;PS:<KERMIT>20KERMIT.MAC.34, 10-Jun-83 12:55:42, Frank
  12405. ;[33] Cancel correctly if the output file can't be opened.
  12406. ; Enclose checksum characters in quotes in debugging messages.
  12407. ;*********** Version 3(40) Shipped to over 100 sites May 5 ************
  12408. ;PS:<TIMREK>KERMIT.MAC.56,  4-May-83 09:01:16, Frank
  12409. ;[32] Report bad checksums correctly when debugging.
  12410. ; Report error message from server & cancel if it can't get a file.
  12411. ;PS:<TIMREK>KERMIT.MAC.54, 26-Apr-83 19:08:00, Frank
  12412. ;[31] Beep when done with a transfer, if local.
  12413. ;PS:<KERMIT>20KERMIT.MAC.8, 15-Apr-83 14:45:36, Frank
  12414. ;[30] A NAK for the next packet is *not* the same as an ACK for the current
  12415. ; packet if the current packet is Send-Init.
  12416. ;PS:<TIMREK>KERMIT.MAC.42, 15-Apr-83 11:39:08, Frank
  12417. ;[29] When debugging packets, print checksum of incoming packets, and
  12418. ; print bad packets.
  12419. ;PS:<TIMREK>KERMIT.MAC.41,  8-Apr-83 19:31:28, Frank
  12420. ;[28] Add FINISH command.
  12421. ;PS:<TIMREK>KERMIT.MAC.29,  8-Apr-83 12:43:02, Frank
  12422. ;[27] Fix ^C trap to DEBRK to the right place in all cases.
  12423. ;PS:<TIMREK>KERMIT.MAC.28,  8-Apr-83 09:38:49, Frank
  12424. ;[26] Save and restore normal send timeout when going in & out of server
  12425. ; command-wait.
  12426. ;PS:<TIMREK>KERMIT.MAC.27,  7-Apr-83 20:20:15, Bill C.
  12427. ;[25] Neaten up SERVER mode time out changes.
  12428. ;PS:<TIMREK>KERMIT.MAC.20,  5-Apr-83 18:14:14, Frank
  12429. ;[24] Fix SPAR to account for the actual length of an incoming SEND-INIT.
  12430. ;PS:<TIMREK>KERMIT.MAC.19,  5-Apr-83 17:46:23, Frank
  12431. ;[23] Include both send and receieve parameters in SHOW command.
  12432. ;PS:<TIMREK>KERMIT.MAC.4, 3:20pm  Tuesday, 5 April 1983, Frank
  12433. ;[22] Add debugging options.  Remove i/o to DIAJFN and just test LOCAL and
  12434. ; DEBUG flag values.  Make DEBUG an AC, move RTOT & STOT to memory.
  12435. ;PS:<TIMREK>KERMIT.MAC.81,  1-Apr-83 15:59:19, Frank
  12436. ;[21] Change SET SEND/RECEIVE QUOTE to parse an octal number.  The hairy
  12437. ; .CMUQS/breakmask/.CMTOK parsing tended to hang the program...
  12438. ;PS:<TIMREK>KERMIT.MAC.75,  1-Apr-83 15:13:43, Bill C.
  12439. ;[20] Make packet time outs longer if in server mode awaiting commands.
  12440. ;PS:<TIMREK>KERMIT.MAC.72,  1-Apr-83 12:55:40, Frank
  12441. ;[19] Print "[OK]" for each file successfully sent or received, if local.
  12442. ;PS:<TIMREK>KERMIT.MAC.65, 31-Mar-83 16:43:20, Frank
  12443. ;[18] Expanded help text, with individual help for each command.
  12444. ; Added SET DUPLEX, SET SEND/RECEIVE START-OF-PACKET.
  12445. ;PS:<TIMREK>KERMIT.MAC.58, 31-Mar-83 13:35:57, Bill C.
  12446. ;[17] Restore CFIBFs of yore.  Clears up packet echoing and stacking.
  12447. ;PS:<TIMREK>KERMIT.MAC.52, 31-Mar-83 10:58:12, Frank
  12448. ;[16] Add SET ESCAPE (for CONNECT), try to print remote message after BYE.
  12449. ;PS:<TIMREK>KERMIT.MAC.48, 30-Mar-83 19:54:32, Frank
  12450. ;[15] Don't bomb if we can't open a file to be sent, just print nice msg.
  12451. ;PS:<TIMREK>KERMIT.MAC.47, 30-Mar-83 18:16:53, Frank
  12452. ;[14] Add code for ^B interrupts, but don't use it for anything yet.
  12453. ;PS:<TIMREK>KERMIT.MAC.45, 30-Mar-83 15:06:42, Frank
  12454. ;[13] Don't delay before send if local.
  12455. ;PS:<TIMREK>KERMIT.MAC.41, 30-Mar-83 13:52:57, Frank
  12456. ;[12] When local, print name of file being sent or received.
  12457. ;PS:<TIMREK>KERMIT.MAC.33, 29-Mar-83 17:59:47, Frank
  12458. ;[11] Talk to Kermit server.  Added BYE and GET commands.
  12459. ;************* Version 3 ****************
  12460. ;PS:<TIMREK>KERMIT.MAC.22, 28-Mar-83 14:56:39, Frank
  12461. ;[10] Enable ^C capability if not on already (reported by Willis Dair, SCU).
  12462. ; If we can't enable it, don't go on unless we're running under batch.
  12463. ;PS:<TIMREK>KERMIT.MAC.21, 20-Mar-83 17:55:27, Bill C.
  12464. ;[9] Fixed SHOW command to print number of blips correctly.
  12465. ;PS:<TIMREK>KERMIT.MAC.17, 18-Mar-83 20:31:00, Frank
  12466. ;[8] Added some help to the help text.
  12467. ;PS:<TIMREK>KERMIT.MAC.15, 18-Mar-83 19:03:51, Frank
  12468. ;[7] Assign & deassign line if not already assigned.  This prevents
  12469. ; "?Line is not active" and similar errors if Kermit is run on top of TTLINK
  12470. ; rather than vice versa, and not under DIAL (both TTLINK and DIAL will do
  12471. ; their own assigning, if necessary).  Thanks to Willis Dair, Santa Clara
  12472. ; University, for pointing out the bug.
  12473. ;PS:<TIMREK>KERMIT.MAC.14, 18-Mar-83 18:44:39, Frank
  12474. ;[6] Differentiate between remote & local timeouts in SHOW command.
  12475. ; Add version #, date/time, etc, to SHOW.
  12476. ; Replace a zillion NOUTs with NUMOUT macro.
  12477. ;PS:<TIMREK>KERMIT.MAC.12, 17-Mar-83 18:47:21, Frank
  12478. ;[5] Give error message when initial connection can't be made, if local.
  12479. ;PS:<TIMREK>KERMIT.MAC.7, 17-Mar-83 15:54:33, Frank
  12480. ;[4] When acting as local Kermit, show packet traffic by typing blips.
  12481. ;PS:<TIMREK>KERMIT.MAC.6, 17-Mar-83 15:31:30, Frank
  12482. ;[3] When comparing packet numbers, allow for wraparound.
  12483. ;PS:<TIMREK>KERMIT.MAC.3, 17-Mar-83 10:53:03, Frank
  12484. ;[2] Cont'd... Show range of timeouts in SHOW command.
  12485. ;PS:<TIMREK>KERMIT.MAC.2, 15-Mar-83 12:51:12, Frank da Cruz
  12486. ;[2] Make timeouts load-dependent.  Fix spelling of "interrupt" everywhere.
  12487. ;PS:<KERMIT>20KERMIT.MAC.22, 20-Feb-83 14:13:19, Bill C.
  12488. ;[1] Put in a CFIBF% in the INILIN code to clear the line at the beginning
  12489. ; of each send or receive of backed up NAKs.  This may not be just right.  This
  12490. ; can lose a Send Init packet some times.  This will work til the problem can
  12491. ; be looked at more closely.
  12492. ;*************************** Major Version 2 ********************************
  12493. ;PS:<SY.WBC3>KERMIT.MAC.20,  8-Feb-83 14:43:48, Bill C.
  12494. ; Put in (FINALLY!) the SHOW command.
  12495. ;PS:<SY.WBC3>KERMIT.MAC.11,  8-Feb-83 10:04:10, Bill C.
  12496. ; Add SET PARITY command.  Eliminate IGNORE-PARITY as its functionality is
  12497. ; replaced by SET PARITY SPACE.
  12498. ;PS:<KERMIT>20KERMIT.MAC.3,  4-Feb-83 11:04:08, Bill C.
  12499. ; Change TELNET to TTLINK (by FdC) and remove TELNET command.
  12500. ;PS:<SY.WBC3>KERMIT.MAC.38, 26-Jan-83 15:35:37, Bill C.
  12501. ; Make Kermit able to act as a SERVER.
  12502. ;PS:<KERMIT>20-KERMIT.MAC.29, 18-Jan-83 14:08:45, Bill C.
  12503. ; Take care of the case where user set terminal pause char to ^A.
  12504. ;PS:<KERMIT>20-KERMIT.MAC.27, 11-Jan-83 13:19:06, Bill C.
  12505. ; Fix ^C trap bug that caused illegal instruction.
  12506. ;PS:<KERMIT>20-KERMIT.MAC.22, 11-Jan-83 11:40:01, Bill C.
  12507. ; Fix bug in SET IGNORE-PARITY COMMAND.
  12508. ;PS:<KERMIT>20-KERMIT.MAC.11, 10-Jan-83 16:52:03, Bill C.
  12509. ; Add turn around char for the IBM running VM/CMS.
  12510. ;PS:<KERMIT>20-KERMIT.MAC.8,  7-Jan-83 17:59:01, Bill C.
  12511. ; Fix numerous mispellings of received.
  12512. ;PS:<KERMIT>20-KERMIT.MAC.3,  7-Jan-83 16:06:04, Bill C.
  12513. ; Clean up the diagnostic and error message code.
  12514. ;PS:<KERMIT>20-KERMIT.MAC.2,  7-Jan-83 15:06:02, Bill C.
  12515. ; Add the TELNET command (thanks to Bill Schilit.)  Change EXIT/CONT
  12516. ;    sequence to not throw away JFN.
  12517. ;PS:<KERMIT>KERMIT-20.MAC.2, 14-Dec-82 15:25:40, Bill C.
  12518. ; Be scrupulous in PMAP use after errors.  Don't make files with holes.
  12519. ;PS:<KERMIT>KERMIT.MAC.44, 28-Sep-82 09:47:32, Bill C.
  12520. ; Add ignore parity option for some UNIX systems.
  12521. ;PS:<KERMIT>KERMIT.MAC.19, 28-Apr-82 16:00:31, Bill C.
  12522. ; Big clean up.  Consolidate duplicate sections of code.  Also,
  12523. ;    no longer die on bad packet type, just NAK or retransmit.
  12524. ;    Removed empty show command.
  12525. ;PS:<KERMIT>KERMIT.MAC.18, 21-Apr-82 16:31:04, Bill C.
  12526. ; Clean up line on ^C from transfer.
  12527. ;PS:<KERMIT>KERMIT.MAC.17, 17-Feb-82 16:16:10, Bill C.
  12528. ; Add eight bit file mode.
  12529. ;PS:<KERMIT>KERMIT.MAC.16, 28-Jan-82 12:31:09, Bill C.
  12530. ; Clean up better on some error conditions.
  12531. ;PS:<KERMIT>KERMIT.MAC.15,  6-Jan-82 12:18:06, Bill C.
  12532. ; Fill out some of the SET command options.
  12533.