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

  1. $verno==^d5            ; Major version number.
  2. $mnver==^d1            ; Minor version number (minimum: 1).
  3. $edno==^d182             ; Edit number increases independent of version.
  4. $who==^d2            ; Who edited, 0=Columbia.
  5.                 ; [182] 2=ex-Columbia employees ...
  6. ;
  7. ; Copyright (C) 1981, 2001,
  8. ; The Trustees of Columbia University in the City of New York.
  9. ;
  10. ; RECENT EDIT HISTORY (more at end):
  11. ;
  12. ;[TOMMYT]STAR:<KERMIT>K20MIT.MAC.327,  3-Aug-2003 16:50:33, Edit by SLOGIN
  13. ;[182] TVT-Binary automatic mode to check if we are on a TVT
  14. ; . Change ARPAnet references in typeout to Internet since there
  15. ;   may be some children who do know what the ARPAnet was...
  16. ;[TOMMYT]STAR:<KERMIT>KERMIT.MAC.259, 30-Jul-2003 12:48:04, Edit by SLOGIN
  17. ;[181] Merge PANDA network binary mode
  18. ; . Fix reslin and subroutines to always load the terminal jfn,
  19. ;   we were trying to clear the output buffer of .FHSLF!
  20. ; . put in default EMACS editing modes
  21. ;/w/fdc/timrek/kermit.mac, Mon Aug  6 14:28:27 2001, Frank (fdc@columbia.edu)
  22. ;[180] Buffered packet input instead per-character BIN% + better statistics.
  23. ;/w/fdc/timrek/kermit.mac, Sun Jan 28 17:33:20 2001, Frank (fdc@columbia.edu)
  24. ;[179] Added Long packets:
  25. ; . Added new symbol MAXBUF (10KB)
  26. ; . Increased packet buffer sizes to MAXBUF
  27. ; . Changed .setpk to allow sizes up to 9000 (near theoretical max)
  28. ; . Added CAPAS, WINDO, MAXLX1, MAXLX2 field support to rpar and spar.
  29. ; . Added long-packet sending/reading to spack/rpack.
  30. ; . Removed hardwired ^d94 packet-length references.
  31. ; . Speed improvements by up to a factor of 20.
  32. ; Changed default delay to 1 sec.
  33. ; Increased version number from 4.2 to 5.1.
  34. ; All long-packet related lines are marked "[179]".
  35. ;
  36. ;******************** Version 5.1 ************************
  37. ;PK:<TIMREK>KERMIT.MAC.259, 26-Jan-88 10:28:51, Frank (SY.FDC@CU20B)
  38. ;[178] Allow passwords to come from TAKE files.
  39. ;PK:<TIMREK>KERMIT.MAC.259, 25-Jan-88 18:38:14, Frank (SY.FDC@CU20B)
  40. ;[177] Fix [176].  It wasn't conditioning the line correctly.
  41. ;PK:<TIMREK>KERMIT.MAC.258, 11-Dec-87 14:16:09, Frank (SY.FDC@CU20B)
  42. ;[176] Allow commands to servers to be issued from TAKE file.
  43. ; Also, pass capabilities down to inferior process correctly.
  44. ;PS:<TIMREK>KERMIT.MAC.6,  6-May-85 17:39:44, Frank (SY.FDC@CU20B)
  45. ;[175] Delete any dot at the end of outbound file names (like 'makefile.').
  46. ;PS:<KERMIT>20KERMIT.MAC.256,  2-May-85 12:21:34, Frank (SY.FDC@CU20B)
  47. ;[174] Several things:
  48. ;. Don't ACK a Z packet if the file can't be closed.
  49. ;. Fix server interpretation of remote directory command with no args.
  50. ;. Fix "push" command message to not assume connected to remote.
  51. ;. Give appropriate messages for local/remote mode server entry.
  52. ;. Recover from i/o errors in debug log writing.
  53. ;. Recover from incoming filenames that start with dot.
  54. ;PS:<TIMREK>KERMIT.MAC.1028, 11-Dec-84 19:00:29, Frank (SY.FDC@CU20B)
  55. ;[173] Display contents of any incoming X packet.
  56. ;PS:<TIMREK>KERMIT.MAC.1028, 11-Dec-84 18:37:05, Frank (SY.FDC@CU20B)
  57. ;[172] Don't use "*" for default file type in SEND command.
  58. ;PS:<TIMREK>KERMIT.MAC.1021, 15-Nov-84 15:28:26, Frank (SY.FDC@CU20B)
  59. ;[171] Fix LOCAL CWD not to ask for password unless it has to.
  60. ;PS:<TIMREK>KERMIT.MAC.1018, 15-Nov-84 11:39:00, Frank (SY.FDC@CU20B)
  61. ;[170] Don't send 4 null bytes at end of ITS binary file.
  62. ;PS:<TIMREK>KERMIT.MAC.1012, 18-Oct-84 13:20:42, Frank (SY.FDC@CU20B)
  63. ;[169] Misc small fixes:
  64. ;. Make $XHOST allow ^C interrupt to work during SINFO.
  65. ;. Allow ^C interrupt in LOCAL TYPE.
  66. ;. REMOTE CWD Password: input was erroneously saying "?Too long"
  67. ;. In RUN command, don't let inferior log out.
  68. ;PS:<TIMREK>KERMIT.MAC.1012, 18-Oct-84 13:20:42, Frank (SY.FDC@CU20B)
  69. ;[168] Fix SPAR not to overrule SET commands when entering server mode.
  70. ;PS:<TIMREK>KERMIT.MAC.1004,  3-Oct-84 15:30:24, Frank (SY.FDC@CU20B)
  71. ;[167] Add ECHO command.
  72. ;PS:<TIMREK>KERMIT.MAC.1000,  3-Oct-84 12:13:10, Frank (SY.FDC@CU20B)
  73. ;[166] Add ^M and ^P interrupts for getting unstuck from TRANSMIT
  74. ;PS:<TIMREK>KERMIT.MAC.980,  2-Oct-84 19:36:41, Frank (SY.FDC@CU20B)
  75. ;[165] Add TRANSMIT command.
  76. ;PS:<TIMREK>KERMIT.MAC.972,  1-Oct-84 22:00:43, Frank (SY.FDC@CU20B)
  77. ;[164] Make session logging work during script execution.
  78. ;PS:<TIMREK>KERMIT.MAC.966, 30-Sep-84 13:27:04, Frank (SY.FDC@CU20B)
  79. ;[163] Add PC typeout to %JSERR
  80. ;PS:<TIMREK>KERMIT.MAC.962, 28-Sep-84 16:37:25, Frank (SY.FDC@CU20B)
  81. ;[162] Add CLEAR command.
  82. ;PS:<TIMREK>KERMIT.MAC.961, 28-Sep-84 08:37:26, Frank (SY.FDC@CU20B)
  83. ;[161] If SET SPEED done, remember it!
  84. ;PS:<TIMREK>KERMIT.MAC.946, 27-Sep-84 15:15:23, Frank (SY.FDC@CU20B)
  85. ;[160] Refinements of previous edit, add SET/SHOW INPUT.
  86. ;PS:<TIMREK>KERMIT.MAC.924, 26-Sep-84 16:35:53, Frank (SY.FDC@CU20B)
  87. ;[159] INPUT, OUTPUT, and PAUSE commands to provide a simple script facility.
  88. ;******************** Version 4.2 ************************
  89. ;
  90. ;PS:<TIMREK>KERMIT.MAC.918, 18-Jul-84 13:50:17, Frank
  91. ;[158] Clear up any XOFF condition when leaving protocol mode.
  92. ;PS:<TIMREK>KERMIT.MAC.916, 13-Jul-84 17:57:24, Frank
  93. ;[157] Don't get stuck if XOFF'd while typing out server message (thanks Jeff).
  94. ;PS:<TIMREK>KERMIT.MAC.914, 11-Jul-84 19:51:24, Frank
  95. ;[156] Debug previous edits.
  96. ;PS:<TIMREK>KERMIT.MAC.899, 10-Jul-84 18:52:39, Frank
  97. ;[155] Fix recently introduced bug in INILIN that broke handshake code.
  98. ;PS:<TIMREK>KERMIT.MAC.896, 10-Jul-84 17:12:04, Frank
  99. ;[154] Fix up session logging - avoid loss of nonopen JFN.  Add CLOSE command.
  100. ;PS:<TIMREK>KERMIT.MAC.893,  9-Jul-84 18:48:42, Frank
  101. ;[153] Always convert lc letters in incoming filenames to uc (for Bernie).
  102. ;PS:<TIMREK>KERMIT.MAC.888,  6-Jul-84 16:41:26, Frank
  103. ;[152] Add PUSH, SET SPEED, and SET BREAK.
  104. ;PS:<TIMREK>KERMIT.MAC.879,  5-Jul-84 12:53:06, Frank
  105. ;[151] Integrate connect code into this program, rather than running TTLINK
  106. ; in a lower fork.  Use TELNET-style separate input & output forks with no
  107. ; interrupts.  This was done for several reasons:
  108. ; . Release 6.0 of TOPS-20 doesn't allow multiple JFNs on a single TTY.
  109. ; . TTLINK did interrupt-driven i/o in a single fork, so would not work under
  110. ;   batch, where BATCON feeds i/o depending on whether "pty hungry".
  111. ; . Fewer source files to keep track of.
  112. ;******************** Version 4.1 ************************
  113. ;
  114. ;PS:<TIMREK>KERMIT.MAC.871,  3-Jul-84 10:50:55, Frank
  115. ;[150] Add dispatch tables for server and generic commands, to force us
  116. ; to think about every case -- e.g. server shouldn't complain about NAKs.
  117. ;PS:<TIMREK>KERMIT.MAC.870, 29-Jun-84 13:28:08, Frank
  118. ;[149] Fix bug in SET SEND/RECEIVE PADCHAR parsing (thanks, Daphne)
  119. ;PS:<TIMREK>KERMIT.MAC.859, 26-Jun-84 14:26:37, Frank
  120. ;[148] Allow source & destination filespecs for GET to be given separately.
  121. ;
  122. ;PS:<TIMREK>KERMIT.MAC.855, 26-Jun-84 12:38:18, Frank
  123. ;[147] Fix various problems reported by Ken Harrenstien (KLH@SRI-NIC):
  124. ; . Allow user to include !,?,@,;, etc in GET filespec with ^V quote.
  125. ; . Refuse links on file-transfer tty, not controlling tty!
  126. ; . Restore advice and links to tty after file transfer.
  127. ;
  128. ;PS:<TIMREK>KERMIT.MAC.840, 28-May-84 17:33:56, Frank
  129. ;[146] Get monitor version number at startup.  Under V6 or later, we can tell
  130. ; the real speed of the communication line (after all these years!). Also, we
  131. ; know speed of a local line.  Account for all this in CHKLIN, and report the
  132. ; percent efficiency in STATISTICS command when baud rate is known.
  133. ;
  134. ;PS:<TIMREK>KERMIT.MAC.820, 28-May-84 14:23:45, Frank
  135. ;[145] Allow LOCAL commands to be issued without the "LOCAL" prefix.
  136. ; Change LOCAL/REMOTE "DISK" to "SPACE".  Fill in local TYPE and RUN commands.
  137. ;
  138. ;PS:<TIMREK>KERMIT.MAC.810, 28-May-84 10:06:30, Frank
  139. ;[144] Misc bugs fixed:
  140. ; . In ENCODE, fix problem when exactly two consecutive repeat prefix
  141. ;    characters appear in data.
  142. ; . In SRVCMD, decode contents of ACK (it was being displayed "bare").
  143. ; . Remove test for remote at $SERVE, let server work over asg'd tty line.
  144. ; . In DOSRV, don't allow an I packet to cause a state transition.
  145. ; . Don't create empty debugging log files.
  146. ; . Fix bytesize in OPENF in RFIL3K (cosmetic)
  147. ; . Allow SET HANDSHAKE to also accept an octal number.
  148. ;
  149. ;PS:<TIMREK>KERMIT.MAC.804, 28-May-84 09:55:50, Frank
  150. ;[143] Add SET FLOW-CONTROL, SET EXPUNGE.
  151. ; Change SET DEBUGGING LOG to LOG DEBUGGING (like other Kermits).
  152. ;PS:<TIMREK>KERMIT.MAC.803, 19-Apr-84 12:16:59, Frank
  153. ;[142] Fix broken FILCNV for normal-form (from George Boyce, Cornell).
  154. ;PS:<TIMREK>KERMIT.MAC.799, 12-Apr-84 16:29:05, Frank
  155. ;[141] Decode filename in R packet instead of taking it literally.
  156. ; Also, allow ERMSG and KERMSG macros to take addresses, like %JSERR and
  157. ; %JSKER, and make their message formats nicer and more consistent.
  158. ;PS:<TIMREK>KERMIT.MAC.792,  5-Apr-84 13:23:38, Frank
  159. ;[140] Make ^X = ^Z if we're sending a directory (or deleted file) listing.
  160. ;PS:<TIMREK>KERMIT.MAC.791,  3-Apr-84 16:40:01, Frank
  161. ;[139] Fix "help receive" (table out of order).  Fix problem where server was
  162. ; sending a directory listing, interrupted, then asked to delete files, and
  163. ; sent rest of directory listing before deleting files.
  164. ;PS:<TIMREK>KERMIT.MAC.788, 26-Mar-84 13:11:11, Frank
  165. ;[138] Make sure any logs are closed after server FIN command.
  166. ;
  167. ;PS:<TIMREK>KERMIT.MAC.783, 23-Mar-84 11:00:06, Frank
  168. ;[137] When server gets a FINISH command, exit from program rather than
  169. ; going back to KERMIT command level, as we used to before.  Also:
  170. ; . Add SET PROMPT
  171. ; . Add SET RECEIVE SERVER-TIMEOUT (for Bernie)
  172. ; . Fix password delimitation in server CWD command.
  173. ; . Fill in LOCAL CWD command.
  174. ;
  175. ;PS:<TIMREK>KERMIT.MAC.778, 19-Mar-84 19:27:57, Frank
  176. ;[136] Fix mistake in CRC calculation when parity being used.
  177. ;
  178. ;PS:<TIMREK>KERMIT.MAC.767, 15-Mar-84 16:31:22, Frank
  179. ;[135] Move handshake code from beginning of SPACK to end of RPACK.
  180. ; This allows IBM communication to work again.
  181. ; Also, handle carrier drop a little better in SPACK.
  182. ; Also, make sure we close any open file after ^C out of file transfer.
  183. ;
  184. ;PS:<TIMREK>KERMIT.MAC.752, 14-Mar-84 11:50:47, Frank
  185. ;[134] Make SHOW LINE really test carrier, rather than possibly old flag.
  186. ; Put modem/carrier checking stuff in CHKLIN routine.  Also:
  187. ; . Be more defensive about terminal modes after running TTLINK.
  188. ; . Make sure file gets closed if in cAncel state.
  189. ; . Don't assign device if own controlling TTY (even if it is a TVT).
  190. ; . In GIVEUP, obey setting of INCOMPLETE FILE DISPOSITION for incoming
  191. ;   files that ask to be discarded.
  192. ;
  193. ;PS:<SY.FDC>KERMIT.MAC.736, 13-Mar-84 16:27:08, Frank
  194. ;[133] When sending an I packet, keep trying till retry limit exceeded.
  195. ; Also, include byte count and byte size in directory listing.
  196. ;
  197. ;PS:<TIMREK>KERMIT.MAC.735,  9-Mar-84 09:49:03, Frank
  198. ;[132] In STATISTICS, only show last JSYS error if debugging.  Also:
  199. ; . QCTL field in S/I packets and their ACKs was backwards!  Fix in SPAR, RPAR.
  200. ; . Fix a couple details with timers, clear all pending before setting.
  201. ; . In the unlikely event that an incoming filename can't be dealt with, store
  202. ;   the file as -UNTRANSLATABLE-FILENAME-.KERMIT.-1 to avoid sending an error
  203. ;   packet & terminating the transfer.
  204. ;
  205. ;PS:<TIMREK>KERMIT.MAC.726,  7-Mar-84 11:52:31, Frank
  206. ;[131] Add time stamps to debugging-packets log (suggested by BillW).  Also:
  207. ; . When logging incoming data, include current load-adjusted timeout interval.
  208. ; . Try to use different timeouts for sending & receiving.
  209. ; . Double outgoing IAC bytes in SPACK if TVT-BINARY is set.
  210. ;
  211. ;PS:<TIMREK>KERMIT.MAC.716,  5-Mar-84 12:15:09, Frank
  212. ;[130] Rename SET TAC to SET TVT, because it really applies to all ARPANET
  213. ; TVTs.  If TVT, must still OPENF line in 8 bit mode.  Also:
  214. ; . In INCHAR, detect carrier loss and close, deassign line when it happens.
  215. ; . Take class scheduler into account when getting load averages.
  216. ;
  217. ;PS:<TIMREK>KERMIT.MAC.705,  2-Mar-84 10:31:44, Frank
  218. ;[129] Install ARPANET TAC support changes from Dale Chase, ISI.
  219. ; Code mostly adapted from the TOPS-20 MODEM program (Bill Westfield, SRI).
  220. ; Dale's code modified at Columbia to operate through SET TAC rather than by
  221. ; determining TVT status through a site-dependent JSYS (DEC vs BBN vs...).
  222. ;
  223. ; Important installation note from Dale:
  224. ;
  225. ; Some TOPS-20s may need a patch or two to allow user programs to send the
  226. ; necessary telnet protocol negotiations.  The monitor cell NVTDOD must contain
  227. ; "400000,,RSKP" so that TOPS-20 will accept the negotiation.  And some sites
  228. ; may have code that "doubles" any IAC (octal 377) characters sent from a
  229. ; network terminal.  We turned that off here by putting a "RET" in CHKIAC.  If
  230. ; TOPS-20 doubles IACs, this program will not be able to negotiate telnet
  231. ; binary mode.
  232. ;
  233. ;PS:<TIMREK>KERMIT.MAC.691, 29-Feb-84 17:00:05, Frank
  234. ;[128] Several final things before field-test:
  235. ; . Accept null data field in server commands.
  236. ; . In RPAR, ask other side to time us out based on our 15-min ldav rather
  237. ;   than hardwired constant, DRTIM.  New routine ADJTIM does this.
  238. ;   Also, raise DRTIM from 8 to 15 seconds, since we're probably in better
  239. ;   control of the timeouts than the KERMIT on the other side.
  240. ; . In local mode, don't mix up blips with debugging output.
  241. ; . When starting to send, check for incoming NAKs to cut short any delay.
  242. ; . Add support for LOG SESSION command.
  243. ; . Fix mistake in setting file size by clearing RCHR before entering RD state.
  244. ; . Ditto for SCHR when entering SD state.
  245. ; . Exchange parameters before sending file related commands to a server.
  246. ; . Don't send garbage in X headers after a timeout.
  247. ; . Allow RECEIVE when local, for talking to a remote non-server (undo [94]).
  248. ;PS:<TIMREK>KERMIT.MAC.659, 24-Feb-84 18:53:47, Frank
  249. ;[127] Don't assign or open comm line if it's the controlling terminal, don't
  250. ; reset line between transactions if a server.  This prevents a server that got
  251. ; detached (e.g. when carrier dropped) from making the line unavailable for
  252. ; further use.
  253. ;PS:<TIMREK>KERMIT.MAC.653, 24-Feb-84 17:14:45, Frank
  254. ;[126] Put in all the transaction logging code, show status of it in SHOW.
  255. ;PS:<TIMREK>KERMIT.MAC.641, 23-Feb-84 19:01:24, Frank
  256. ;[125] LOG command, parsing only.
  257. ;PS:<TIMREK>KERMIT.MAC.638, 23-Feb-84 17:36:40, Frank
  258. ;[124] When sending a multipacket response to a server command, start with
  259. ; an S packet unless using type 1 block check, in which case start with X.
  260. ;PS:<TIMREK>KERMIT.MAC.636, 23-Feb-84 17:10:52, Frank
  261. ;[123] Add S and N packet heuristics to RPACK to help resync when fancy
  262. ; block check types are being used, but the two sides lose track.
  263. ;PS:<TIMREK>KERMIT.MAC.631, 23-Feb-84 14:38:50, Frank
  264. ;[122] Make directory listing neater.
  265. ;PS:<TIMREK>KERMIT.MAC.629, 23-Feb-84 10:41:34, Frank
  266. ;[121] Fix turning off ^C trap after FINISH, again.
  267. ; Don't try to CLOSF or GNJFN if sending generated text rather than files.
  268. ; Restore normal i/o after sending server help message.
  269. ; Fix SRVCMD to actually do what it says it does.
  270. ; Fix problem with spurious repeat counts appearing in file headers.
  271. ;PS:<TIMREK>KERMIT.MAC.627, 24-Jan-84 18:45:56, Frank
  272. ;[120] Add REMOTE HELP and server support for it.
  273. ;PS:<TIMREK>KERMIT.MAC.617, 24-Jan-84 13:11:20, Frank
  274. ;[119] Decode incoming filenames and validate them more completely.
  275. ;PS:<TIMREK>KERMIT.MAC.613, 23-Jan-84 19:28:23, Frank
  276. ;[118] Server does file deletions.
  277. ;PS:<TIMREK>KERMIT.MAC.612, 23-Jan-84 18:01:33, Frank
  278. ;[117] Fix bugs: SEND x (INITIAL) was broken, and check for receive-packet
  279. ; buffer overflow, to prevent writing over other data (thanks to Greg Small
  280. ; of Berkeley for uncovering that one).
  281. ;PS:<TIMREK>KERMIT.MAC.603, 19-Jan-84 17:08:00, Frank
  282. ;[116] Server sends directory listings.
  283. ;PS:<TIMREK>KERMIT.MAC.570, 18-Jan-84 10:30:07, Frank
  284. ;[115] Rewrite directory listing code to allow for i/o redirection.
  285. ;PS:<TIMREK>KERMIT.MAC.566, 17-Jan-84 11:03:38, Frank
  286. ;[114] Rewrite DIAMSG to give more informative message.
  287. ; When logging packets, precede received packets by "R:", sent by "S:".
  288. ;PS:<SY.FDC>KERMIT.MAC.31, 16-Jan-84 16:31:57, Frank
  289. ;[113] Add LOCAL DELETE command.
  290. ;PS:<SY.FDC>KERMIT.MAC.30, 16-Jan-84 16:15:25, Frank
  291. ;[112] Fix server command business of ACK vs Text Header; get/send one or the
  292. ; other, but not both.
  293. ;PS:<SY.FDC>KERMIT.MAC.18, 16-Jan-84 12:15:04, Frank
  294. ;[111] Make file stepping mechanism do 1-file lookahead.  Add LOCAL DIRECTORY.
  295. ;PS:<TIMREK>KERMIT.MAC.551, 13-Jan-84 19:16:44, Frank
  296. ;[110] Release TTY JFN when ^C'd out of server mode.
  297. ; Thanks to Kimmo Laaksonen (Helsinki), Norm Kincl (HP Labs) for reporting
  298. ; this bug, which surfaced when user detached after ^C out of server mode,
  299. ; leaving TTY assigned and unavailable for new jobs.
  300. ;PS:<TIMREK>KERMIT.MAC.550, 13-Jan-84 17:36:32, Frank
  301. ;[109] Fix bad bug in 8th-bit prefixing.  Also bug in SET PARITY command that
  302. ; prevented SET PARITY NONE from ever working.
  303. ;PS:<TIMREK>KERMIT.MAC.542, 11-Jan-84 09:28:05, Frank
  304. ;[108] Add REMOTE DELETE, REMOTE DIRECTORY.  Misc cleanups, minor fixes.
  305. ; Merge SDEBUG and DIAMSG.  Better recovery from SPACK failures.
  306. ;PS:<TIMREK>KERMIT.MAC.540, 10-Jan-84 17:40:57, Frank
  307. ;[107] Added server support for remote CWD command.
  308. ;PS:<TIMREK>KERMIT.MAC.521,  9-Jan-84 18:26:43, Frank
  309. ;[106] Added REMOTE CWD command.
  310. ;PS:<TIMREK>KERMIT.MAC.512,  9-Jan-84 12:44:11, Frank
  311. ;[105] Debug [104], add REMOTE HOST command.
  312. ;PS:<TIMREK>KERMIT.MAC.500,  6-Jan-84 19:40:33, Frank
  313. ;[104] Add server and user TYPE command.
  314. ; Collapse a lot of redundant code into routines like SRVCMD and DOSRV.
  315. ;PS:<TIMREK>KERMIT.MAC.499,  6-Jan-84 11:50:51, Frank
  316. ;[103] Provide disk quota query service in server mode.
  317. ;*************** Major Version 4.0 ****************
  318. ;
  319. ;(Old Edit History moved to end of file, after END statement)
  320.  
  321. ; THINGS TO DO...
  322. ;
  323. ; * Internal cleanup -- do state transition, packet input & ACK/NAK, etc
  324. ;   globally like C-Kermit, instead of replicating the same code all over.
  325. ;
  326. ; * Check/fix bugs:
  327. ;   . Page mode on/off on assigned line (got some complaints, not verified).
  328. ;   . ^A in local mode sometimes gets lost.
  329. ;   . ^A sometimes not turned off (e.g. after ^C out of f.t., then connect)
  330. ;
  331. ; * Move receive-file opening code to RDATA (& REOF); don't open file until
  332. ;   first data packet (or EOF if null file) arrives, to prepare for attributes.
  333. ;
  334. ; * Finish adding server functions: COPY, RENAME, WHO, MESSAGE, STATUS, RUN,
  335. ;   KERMIT (e.g. "remote kermit set file bytesize 8").
  336. ;
  337. ; * Do something with the REMOTE ERROR command (like think of a better name,
  338. ;   make it visible, and document it, maybe put it on ^E).
  339. ;
  340. ; * When local and receiving a file, if ^Z has no effect, send an error packet
  341. ;   to shut down the transaction.
  342. ;
  343. ; * Add host commands.  Fork an Exec, pass commands to it in rescan, somehow
  344. ;   pipe the Exec's typeout back, packetized.  Too bad TOPS-20 isn't UNIX...
  345. ;   Maybe use LOTS's new pipe device?
  346. ;
  347. ; * Add some support for file attribute packets.
  348. ;
  349. ; * Integrate %JSERR etc with the debugging log mechanism?
  350. ;
  351. ; * When receiving a file, put the name I open the file under in the data field
  352. ;   of the ACK to the File Header.  When receiving File Headers in local mode,
  353. ;   print the contents of the data field instead of doing a JFNS if the data
  354. ;   field is not empty.
  355. ;
  356. ; * In local mode, allow running as a background fork. Or use ^P as an
  357. ;   interrupt character during file transfer to Push to an inferior exec while
  358. ;   the transfer continues above.  ^A should still give progress report.
  359. ;
  360. ; * Separate out the routines according to ISO levels.  In particular, make the
  361. ;   transport-level routines available to any other application (like mail,
  362. ;   e.g. SMTP) that may want to use them.
  363. ;
  364. ; * For various reasons, it might be nice to allow KERMIT-20 to send its
  365. ;   packets to a file, without another KERMIT to talk to.  This will translate
  366. ;   a file into all printable characters (with data compaction, etc) suitable
  367. ;   for transmission over an RJE link or other picky communication media.
  368. ;
  369. ; * Parse single characters in nicer ways, like CONTROL X, or "^X", as well
  370. ;   as octal numbers (in all the SET commands).
  371.  
  372.     Title Kermit -- That's Celtic for "free".
  373.  
  374. ; Needs only standard DEC-distributed external files MONSYM, MACSYM, CMD.
  375.  
  376.     search monsym,macsym,cmd
  377.     .require sys:macrel,sys:cmd
  378.  
  379. ; Originally written by Bill Catchings, Columbia University, April 1981.
  380. ; Taken over by Frank da Cruz, Columbia University, March 1983.
  381. ;
  382. ; This program is the DEC-20 implementation of Columbia University's KERMIT
  383. ; file transfer protocol for use over serial asynchronous communication lines.
  384. ; See the KERMIT user and protocol manuals for the specifications.
  385. ;
  386. ; Version 1,  1981-82:  Basic service (Bill)
  387. ;
  388. ; Version 2,   Feb 83:  Basic server service (Bill)
  389. ;
  390. ; Version 3,   Mar 83:  Local mode, TTLINK, talk to server (Frank)
  391. ;
  392. ; Version 3B,  Oct 83:  I packets, ^X,^Z interrupts, TAKE, DEFINE, etc (Frank)
  393. ;         3C,  Nov 83:  8th-bit prefixing, repeat counts.
  394. ;         3.4, Dec 83:  2- and 3-character block checks.
  395. ;
  396. ; Version 4,   Jan 84:  Advanced server functions, LOG, ARPAnet support (Frank)
  397. ;
  398. ; Version 4.1, Jul 84:  Integrated CONNECT code, no more TTLINK (Frank)
  399. ;
  400. ; Version 4.2, Oct 84:  Non-Protocol upload/download, login scripts (Frank)
  401.  
  402.     subttl Help Text.    ;[18] Lengthy help messages added in edit [18].
  403.  
  404. ; Overall summary, more detailed help text is with each command.
  405. ;
  406. hkermi:    asciz |
  407. KERMIT is a file transfer protocol for use over an asynchronous serial
  408. telecommunication line.  Files are broken up into "packets" with checksums and
  409. other control information to promote error-free and complete transmission.
  410.  
  411. KERMIT-20 is the KERMIT implementation for the DECSYSTEM-20.  KERMIT-20 can be
  412. run "remotely" from another computer (e.g. a microcomputer), or "locally" with
  413. a remote Kermit on the other end of an assigned TTY line (e.g. over an
  414. autodialer connection)
  415.  
  416. You can run Kermit interactively by typing repeated commands in response to
  417. its "Kermit-20>" prompt, or you can invoke it from the TOPS-20 Exec with a
  418. single command line argument (e.g. "kermit receive"), or you can run it as a
  419. remote server.
  420.  
  421. KERMIT-20 command summary -- optional parts are in [brackets]:
  422.  
  423. * For exchanging files using KERMIT protocol:
  424.     SEND file(s) [(INITIAL) file]
  425.     RECEIVE [file]
  426.     GET remote-file(s)
  427.     SERVER
  428.  
  429. * For acting as local Kermit:
  430.     CONNECT [line], INPUT, OUTPUT, CLEAR
  431.     SET: LINE, FLOW, PARITY, DUPLEX, HANDSHAKE, ESCAPE, BREAK, SPEED
  432.  
  433. * For talking to a server:
  434.     BYE, FINISH, GET remote-file(s), SEND file(s);
  435.     REMOTE: DISK-USAGE, TYPE, CWD, DIRECTORY, DELETE, HELP, HOST
  436.  
  437. * Setting nonstandard transmission and file parameters:
  438.     SET: DEBUG, DELAY, FILE, INCOMPLETE, INPUT, ITS, PROMPT, RETRY, TVT;
  439.     SET SEND (or RECEIVE): END-OF-LINE, START-OF-PACKET, PACKET-LENGTH,
  440.         PAUSE, PADDING, TIMEOUT, SERVER-TIMEOUT
  441.     DEFINE a macro for a combination of SET commands.
  442.  
  443. * For non-protocol data transfer:
  444.     INPUT, OUTPUT, PAUSE, CLEAR, TRANSMIT, LOG SESSION
  445.  
  446. * For interrupting transmission: Control-X (^X), ^Z, ^C
  447.  
  448. * Getting information:        HELP [topic], STATISTICS, SHOW, ^A
  449. * Recording information:    LOG or CLOSE TRANSACTIONS, SESSION, DEBUGGING
  450. * Executing command files:      TAKE
  451. * Leaving the program:        EXIT, QUIT, BYE, PUSH
  452.  
  453. If you have a file called KERMIT.INI in your login directory, KERMIT-20 will
  454. execute an implicit TAKE command on it upon initial startup.  KERMIT.INI may
  455. contain any KERMIT-20 commands; DEFINE and SET commands are the most useful.
  456.  
  457. For further information, type "help" for any of the above, e.g. "help set",
  458. or see the "Kermit Users Guide" and the "Kermit Protocol Manual" for complete
  459. details.
  460. |
  461.  
  462.     subttl Definitions
  463.  
  464. pdlsiz==^d200            ; Stack size, be generous.
  465. takel==^d20            ;[78] TAKE command JFN stack size.
  466.  
  467. f=0                ; AC definitions:  flag AC (not used),
  468. t4=<t3=<t2=<t1=1>+1>+1>+1    ;  temporary AC's,
  469. q4=<q3=<q2=<q1=t4+1>+1>+1>+1    ;  and preserved AC's.
  470. state=q4+1            ; State of the automaton.
  471. rchr=state+1            ; Total file characters received.
  472. schr=rchr+1            ; Total file characters sent.
  473. debug=schr+1            ;[22] Debugging (0=none, 1=states, 2=packets)
  474.  
  475. mappag==200            ; Single page window for mapping files.
  476.  
  477. SOH==^o001            ; ASCII Start of header character.
  478. XON==^o021            ; XON is defined to be Control-Q (ASCII DC1).
  479. MAXBUF==^d10240            ; Packet buffer size [179]
  480. MAXPKT==^d94            ; Packet buffer size [179]
  481. IOBUF==^d1024            ; Communications i/o buffer [180]
  482.  
  483. maxpkt=="~"-" "+2        ; Maximum size of a packet.
  484. dmxtry==5            ; Default number of retries on a packet.
  485. dimxtr==20            ; Default number of retries send initiate.
  486. drpsiz==^d80            ; Default receive packet size.
  487. dspsiz==^d80            ; Default send packet size.
  488. spmin==^d10            ;[47] Minimum size packet we want to send.
  489. spmax==^d9000            ;[47] Maximum ...
  490. dstim==^d8            ; Default send time out interval.
  491. drtim==^d13            ;[128] Default receive time out interval.
  492. dsrvtm==^d30            ;[20] Def timout when awaiting server commands.
  493. drpaus==0.0            ;[35] Default pause before ACKing packets.
  494. dspaus==0.0            ;[36] Default pause before sending packets.
  495. dspad==^o0            ; Default send padding char.
  496. drpad==^d0            ; Default receive padding char.
  497. dspadn==^d0            ; Default number of send padding chars.
  498. drpadn==^d0            ; Default number of receive padding chars.
  499. dseol==.chcrt            ; Default send EOL char.
  500. dreol==.chcrt            ; Default receive EOL char.
  501. dsquot=="#"            ; Default outbound control prefix.
  502. drquot=="#"            ; Default incoming control prefix.
  503. dqbin=="&"            ; Default 8th-bit prefix.
  504. drept=="~"            ; Default repeat count prefix.
  505. ddelay==^d1            ; Default delay before the first packet, secs.
  506. dxfull==0            ;[18] Full duplex.
  507. dxhalf==1            ;[18] Half duplex.
  508. defesc==34            ; Default CONNECT escape character is ^\.
  509. defpar==none            ; Default parity.
  510. defits==-1            ;[75] Handle ITS binary files by default.
  511. defics==0            ;[160] Default case search for INPUT commands.
  512. defita==0            ;[160] Default timeout action for INPUTs.
  513. defito==5            ;[160] Default timeout interval for INPUTs.
  514. maxtim=^d94            ;[2] Maximum timeout interval to set, secs.
  515. minlod=4.0            ;[2] Minimum ldav to consider for timeout.
  516. maxlod=50.0            ;[2] Maximum ldav to consider for timeout.
  517. blip=^d5            ;[4] Every this many packets, print a blip.
  518.  
  519. mnblen==^d200            ;[77] Macro name buffer length (words).
  520. mtblen==^d1000            ;[77] Macro text buffer length (words).
  521. macmax==^d100            ;[77] Maximum number of macros.
  522.  
  523. ;[129] ARPA definitions
  524.  
  525. ifndef STAT%,<opdef STAT% [JSYS 745]> ; So this will assemble
  526. ifndef TCP%NT,<TCP%NT==40000000> ; without symbols from BBN TCP monitor.
  527.  
  528. iac==377            ; arpanet telnet IAC
  529. will==373            ; telnet will <option>
  530. wont==374            ; telnet wont <option>
  531. do==375                ; telnet do <option>
  532. dont==376            ; telnet don't <option>
  533. trnbin==0            ; transmit binary
  534. ifdef  .MORLT,<PANDASW==1>    ;[181] Assemble if we have monitor support
  535. ifndef .MORLT,<PANDASW==0>    ;[181]   Or not...
  536. define panda <ifn PANDASW , >    ;[181]     and a handy abbreviation!
  537. ;[182] Wouldn't it be REAL nice if these fields were defined in MONSYM?
  538. ntflag==MASKB(0,8)        ;[182] Terminal flags
  539. nttype==MASKB(9,17)        ;[182] Network type
  540. ntline==MASKB(18,35)        ;[182] Line type
  541. ntblen==<.NWNU1+2>        ;[182] Minimum length
  542.  
  543.     subttl Macros
  544.  
  545.  
  546. ; ERMSG -- Type error message on local terminal, and save a pointer to the
  547. ;  error string, that can be used when querying most recent error.
  548.  
  549. define ermsg (msg,label) <
  550.      jrst [    tmsg <
  551. >
  552.         hrroi t1, [asciz/?KERMIT-20: 'msg/]
  553.         movem t1, errptr ;; Save pointer to error msg for stats.
  554.         PSOUT%
  555.         tmsg <
  556. >
  557. ifb <label>,<    jrst .+1>
  558. ifnb <label>,<    jrst label>
  559.         ]
  560. >;ermsg
  561.  
  562.  
  563. ; KERMSG -- Like ERMSG, but also send the message to the other KERMIT in
  564. ;  an error packet, which cancels the current transfer.
  565.  
  566. define kermsg (msg,label) <
  567.     $count=0
  568.     irpc msg, <$count=$count+1>
  569.      jrst [    movei t1, "E"    ;; Send an error packet to the other side.
  570.         move t2, pktnum    ;; Packet number.
  571.         movei t3, $count+^d11 ;; The count.
  572.         move t4, [point 7, [asciz/KERMIT-20: 'msg/]] ;; The msg.
  573.         movem t4, errptr ;; Save pointer to error msg for status.
  574.         call spack    ;; Send the error packet.
  575.          nop
  576.         tmsg <
  577. ?KERMIT-20: 'msg
  578. >
  579. ifb <label>,<    jrst .+1>
  580. ifnb <label>,<    jrst label>
  581.         ]
  582. >
  583.  
  584. ; Error handling macros, cont'd
  585.  
  586.  
  587. ; %JSERR -- Invoked by ERJMP after a JSYS call.  Prints the given message,
  588. ;  if any, then the JSYS error message, and then jumps to the address given
  589. ;  or else halts (continuably) if no jump address given.
  590. ;[163] Make it include the address of the failing JSYS at end of message.
  591.  
  592. define %jserr (msg, label) <    ;; Use this immediately following a JSYS.
  593.     ercal [ ttcrlf        ;; Output a crlf if necessary
  594.         tmsg <?KERMIT-20: 'msg> ;; Type given msg with our prefix,
  595. ifnb <msg>,<    call jserr0>    ;;  if given, put JSYS error after dash,
  596. ifb <msg>,<    call jsmsg0>    ;;  else right after "?KERMIT-20:  "
  597.         tmsg < at PC >    ;; Say where it happened.
  598.         pop p, t2    ;; Pop the return address off the stack.
  599.         hrrzs t2    ;; Clear out junk from left half.
  600.         subi t2, 2    ;; Adjust to point at offending JSYS.
  601.         numout t2, ^d8    ;; Type JSYS PC in octal.
  602.         tmsg <
  603. >                ;; And a trailing CR.
  604. ifb <label>,<    HALTF%        ;; Then, if no label was specified, halt
  605.         jrst .+1    ;; continuably,
  606. >;ifb
  607. ifnb <label>,<    jrst label>    ;; or if there was, go there.
  608.           ]
  609. >;%jserr
  610.  
  611.  
  612. define %ermsg (msg, label) <    ;; Use this in any skipping context.
  613.     jrst [    ttcrlf
  614.         tmsg <?KERMIT-20: 'msg> ;; Otherwise, just like %JSERR.
  615. ifnb <msg>,<    call jserr0>    ;; Except no PC typeout.
  616. ifb <msg>,<    call jsmsg0>
  617.         tmsg <
  618. >
  619. ifb <label>,<    HALTF%
  620.         jrst .+1
  621. >;ifb
  622. ifnb <label>,<    jrst label>
  623.           ]
  624. >;%ermsg
  625.  
  626. ; %JSKER -- Like %JSERR, but also sends message to other KERMIT in an error
  627. ; packet, as KERMSG does.
  628.  
  629. define %jsker (msg, label) <    ;; Use this immediately following a JSYS.
  630.     erjmp [
  631. ifb <msg>,<    move t1, [point 7, [asciz/KERMIT-20: /]] >
  632. ifnb <msg>,<    move t1, [point 7, [asciz/KERMIT-20: 'msg - /]] >
  633.         movem t1, errptr ;; Save pointer to error msg for status.
  634.         call %%krms
  635.         ttcrlf
  636.         tmsg <?KERMIT-20: 'msg> ;; Type given msg with our prefix,
  637. ifnb <msg>,<    call jserr0>    ;;  if given, put JSYS error after dash,
  638. ifb <msg>,<    call jsmsg0>    ;;  else right after "?Kermit:  "
  639.         tmsg <
  640. >                ;; And a trailing CR.
  641. ifb <label>,<    HALTF%        ;; then if no label was specified, halt,
  642.         jrst .+1    ;; continuably,
  643. >;ifb
  644. ifnb <label>,<    jrst label>    ;; or if there was, go there.
  645.           ]
  646. >;%jsker
  647.  
  648. ; Support routines for error handling macros.
  649.  
  650.  
  651. ; JSERR0 synchronizes with terminal i/o in progress before typing the
  652. ;  JSYS error message.
  653. ;
  654. ; JSMSG0 just types the JSYS error message.
  655. ;
  656. jserr0:    movei t1,.priin
  657.     CFIBF%            ; Clear typeahead.
  658.     movei t1,.priou
  659.     DOBE%            ; Wait for previous output to finish.
  660.     tmsg < - >        ; Type a dash.
  661. jsmsg0:    movei t1,.priou
  662.     hrloi t2,.fhslf        ; This fork ,, last error.
  663.     setz t3,
  664.     ERSTR%
  665.      jfcl
  666.      jfcl
  667.     ret
  668.  
  669.  
  670. ; KERMSG -- Send an error message to the KERMIT on the other side in an
  671. ;  error packet.  Invoked from %JSKER, with T1 pointing at the user-provided
  672. ;  prefix (if any), to which the JSYS error message is appended.
  673.  
  674. blanks:    repeat <maxpkt/4>,<ascii/     />
  675.  
  676. %%krms: move t3, [blanks,,%%krbf] ;[40] Fill up the msg buffer with blanks.
  677.     blt t3, <%%krbf+<maxpkt/4>-1> ;[40]
  678.     move t3, [point 7, %%krbf] ; Get a pointer to the buffer.
  679.     setz t4,        ; Zero the counter.
  680. %%krm1:    ildb t2, t1        ; Get the byte.
  681.     jumpe t2, %%krm2    ; Is it a null?
  682.     idpb t2, t3        ; Deposit the byte.
  683.     aoja t4, %%krm1
  684. %%krm2:    move t1, t3        ; Put the information into the buffer.
  685.     hrloi t2, .fhslf    ; Say:  this fork ,, last error.
  686.     movn t3, spsiz        ; Specify the maximum to send as a negative
  687.     add t3, t4        ;  number
  688.     hrlzs t3        ;[74] (ERSTR wants -n,,0)
  689.     skipge t3        ;[50] (don't bother if not negative).
  690.      ERSTR%
  691.      trn
  692.      trn
  693.     move t2, t1        ; Set up to get the new length.
  694.     move t1, [point 7, %%krbf] ; ...
  695.     call subbp        ; Subtract byte pointers.
  696.      skipa            ;[40] If there is an error assume this count.
  697.     camle t3, spsiz        ;[40] Longer than we're supposed to send?
  698.      move t3, spsiz        ;[40] If so, truncate it.
  699.     movei t1, "E"        ; An error packet.
  700.     move t2, pktnum        ; Packet number.
  701.     move t4, [point 7, %%krbf] ; Pointer to string.
  702.     call spack        ; Send the error packet.
  703.      nop
  704.     ret
  705.  
  706. ; Misc macros
  707.  
  708.  
  709. ; NUMOUT - Type a number in the desired base (decimal by default), free format.
  710.  
  711. define numout(num,base<^d10>) <
  712.     call [    saveac <t1,t2,t3>
  713.         move t2, num
  714.         movei t1, .PRIOU
  715.         movei t3, base
  716.         NOUT%
  717.          nop
  718.         ret ]    
  719. >;numout
  720.  
  721.  
  722. ; OUTCHR - Type a character at the terminal without disturbing any registers.
  723.  
  724. define    OUTCHR(char) <
  725.     jrst [    exch t1, char
  726.         PBOUT
  727.         exch t1, char
  728.         jrst .+1 ]
  729. >;OUTCHR
  730.  
  731.  
  732. ;[126] Write time-stamped file message to the transaction log file.
  733. ;
  734. ; Macro arguments are a message string and the address of a JFN
  735. ; of the filename to write, e.g.
  736. ;
  737. ;    wtlog (<Sending >,filjfn)
  738. ;
  739. define wtlog(..msg,..file) <
  740.     call [ skipn t1, tlgjfn ;; Transaction log open?
  741.          ret          ;; No, skip this.
  742.         saveac <t2,t3,t4> ;; Yes, save these AC's
  743.         seto t2,    ;; Start with time stamp, current date/time.
  744.         movx t3, ot%nda    ;; No date.
  745.         ODTIM
  746.         hrroi t2, [asciz/: /] ;; Punctuation.
  747.         setzb t3, t4
  748.         SOUT
  749.         hrroi t2, [asciz/..msg/] ;; The given message.
  750.         SOUT
  751. ifnb <..file>,<
  752.         move t3, [111110,,js%paf]
  753.         skiple t2, ..file ; File name.
  754.          JFNS
  755. >;ifnb
  756.         setz t3,
  757.         hrroi t2, crlf
  758.         SOUT
  759.         ret ]
  760. >;wtlog
  761.  
  762. ; %TABLE - Beginning of COMND/TBLUK keyword table.
  763. ;
  764. define %table <
  765.     %%tbst== .        ;; Plant start of table
  766.     exp 0            ;;  and leave a hole for %tbend to fill
  767. >
  768.  
  769. ; %TBEND - End of COMND/TBLUK keyword table.
  770. ;
  771. define %tbend <
  772.     %%tbnd==.-1        ;; Get address of last entry in table
  773.     .org %%tbst        ;; Move back to start
  774.     xwd %%tbnd-%%tbst, %%tbnd-%%tbst;;  and build table header
  775.     .org            ;; Finally, get back to the way we were
  776. >
  777.  
  778. ; %KEY - COMND or TBLUK keyword definition
  779. ;
  780. ; This macro takes three arguments: an (alphanumerics only!) keyword, the
  781. ; data to be associated with the keyword, and an (optional) flag value.  It
  782. ; creates either a flagless keyword (the normal case), or, if any flags are
  783. ; given, a keyword with flags in the first word and CM%FW set.  Thus,
  784. ; the result is a TBLUK table entry, suitable for use by the .CMKEY COMND
  785. ; JSYS function.  Note that all %KEY words in a table must be bracketed
  786. ; by %TABLE and %TBEND macros (see above).
  787. ;
  788. define %key (name, data, flags) < ;; Flags are optional
  789.    ifb <flags>, <
  790.     xwd [asciz\name\],data    ;; No-flags case
  791.    >
  792.    ifnb<flags>, <
  793.     xwd [<flags>!cm%fw    ;; Flags: first word holds them,
  794.          asciz\name\], data    ;;  second is start of name
  795.    >
  796. >
  797.  
  798. define ttcrlf <             ;; Output a CRLF if not at left margin.
  799.     call [    saveac <t1,t2>
  800.         movei t1, .priou
  801.         RFPOS%    
  802.         hrroi t1, crlf
  803.         trne t2, -1
  804.          PSOUT
  805.         ret ]
  806. >;;ttcrlf
  807.  
  808.  
  809.     subttl Command Line Processing
  810.  
  811. ;  RESCAN - Routine to check for command line arguments.
  812. ;
  813. ;[85] Returns +1 always, with F$EXIT = 0 if no args, nonzero if some args.
  814. ;
  815. rescan:    setzm f$exit        ;[85] Assume no rescan arguments.
  816.     movx t1, .rsini        ; Now check.
  817.     RSCAN%            ;  ...
  818.      erjmp r        ;[85]  If none return.
  819.  
  820.     movx t1, .rscnt        ; Get the size of the rescan.
  821.     RSCAN%            ;  ...
  822.      erjmp r        ;[85]  Return if unsucessful.
  823.     jumpe t1, r        ;[85] If the size is zero return.
  824.     
  825.     prompt <>        ; Null prompt.
  826.     movei t1, r+1        ; Get the address we want to go to on reparse.
  827.     movem t1, repara    ; Fudge it.  This is to prevent looping back
  828.                 ;  to prompt <> for ever on an error on the
  829.                 ;  rescan line.
  830.     movei t1, [flddb. (.cmkey,,<[exp <1,,1>,<[asciz/Kermit/],,0>]>)]
  831.     call rflde        ; Parse it.
  832.      ret            ;[85]  If we don't find it return.
  833.     setom f$exit        ;[85] Assume we have command line arguments.
  834.     movei t1, [flddb. (.cmcfm,cm%sdh)] ; See if we can parse a confirm.
  835.     call rflde        ;  ...
  836.      ret            ;  If not, we have a rescan argument.
  837.     setzm f$exit        ;[85] Parsed confirmation, so no arguments.
  838.     ret            ;[85] Done.
  839.  
  840.     subttl KERMIT Program entry, initialization, and exit.
  841.  
  842. kermit:    jrst start        ; Start entry.
  843.     jrst reen        ; Re-entry.
  844. versio:    byte (3)$who(9)$verno(6)$mnver(18)$edno    ; Program version.
  845. evlen==.-kermit
  846.  
  847. reen:    jrst start        ; Nothing special for now...
  848.  
  849. start:    RESET%            ; Normal startup: reset everything
  850.     setzm monv        ; See what monitor version.
  851.     move t1, [sixbit/MONVER/] ; This only works in V6 or later.
  852.     SYSGT
  853.      erjmp .+1
  854.     skipe t2        ; Got anything?
  855.      movem t1, monv        ; Yes, save it.
  856.  
  857.     move p, [iowd pdlsiz,pdl] ;  and set up a stack.
  858.     setzm ttfork        ; Clear connect receive fork handle
  859.     setzm netjfn        ; and communication line JFN
  860.     setzm f$exit        ; and exit flag, so we re-init if restarted.
  861.  
  862. ;[78] Set up a JFN stack for 'take' commands.
  863.  
  864.     move t2, [iowd takel, takpdl] ;[78] Construct TAKE jfn stack pointer.
  865.     movem t2, takep        ;[78]
  866.     setzm takdep        ;[78] Start 'take depth' out at 0.
  867.     setzm takjfn        ;[78] And no TAKE file jfn.
  868.  
  869. ; Run KERMIT...
  870.  
  871.     call main        ; The actual program.
  872. halt:    HALTF%            ; Upon return, just halt.
  873.  
  874. ; If continued, fall thru to here...
  875.  
  876. cont:    setzm f$exit        ; Turn off the exit flag.
  877.     move t1, ttynum        ;[87] Reassign the line we were using.
  878.     movem t1, pars3        ;[87] (this is the calling convention...)
  879.     call $setln        ;[85]
  880.     call prsint        ; Go to command level.
  881.     jrst halt
  882.  
  883.     subttl  KERMIT main program
  884.  
  885. main:    setzm local        ; Start off running remotely.
  886.     call pinit        ; Initialize interrupt system.
  887.     movei t1, .fhslf    ;[176] Read current process capabilities.
  888.     RPCAP%            ;[176]
  889.     movem t2, capas        ;[176]
  890.     seto t1,        ; Get job info for this job.
  891.     move t2, [-20,,jobtab]    ; Into this job table.
  892.     setzb t3, t4
  893.     GETJI
  894.      %jserr (,.+1)
  895.     dmove t3, jobtab    ; Get job & terminal numbers.
  896.     movem t3, myjob        ; Job number of my job.
  897.     movem t4, mytty        ; Remember this is my controlling terminal.
  898.     movem t4, pars3        ; Make believe we parsed terminal number
  899.     setz debug,        ; And no debugging
  900.     call $setln        ; Set the line to our own.
  901. panda <    call chknbm >        ;[181] Determine if we have network binary mode
  902.     call cmdini        ; Initialize the command package.
  903.     call inifil        ;[79] Execute commands from KERMIT.INI, if any.
  904. ccl:     call rescan        ;[85] If no .INI file, look for rescan now.
  905.     skipe f$exit        ;[85] If there was a rescan argument,
  906.      jrst parse        ;[85] go do that.
  907.     jrst @dfstrt        ; No rescan go to default: PROMPT or SERVER.
  908.  
  909. server:    jrst getcom        ; Here if starting as server by default.
  910.  
  911. ; Here if starting in command mode by default.
  912.  
  913. promp:    skipe iniflg        ;[83] Doing init file?
  914.      jrst prsint        ;[83]  Yes, don't print herald yet.
  915.     move q1, [ret]        ;[39] Hokey calling convention for routine
  916.     call $shver        ;[39]  to print current program version.
  917.  
  918. prsint:    setzm rcving        ; Indicate neither receiving nor sending.
  919.     skipe f$exit        ; Exit flag set by EXIT command or CCL entry?
  920.      jrst clenup        ;  If so, go clean up and return.
  921.     hrroi t1, prompx    ;[137] Otherwise, point to prompt text.
  922.     call dpromp        ;[137] Issue prompt.
  923.  
  924. parse:    setzm pars1        ;[40] Clean out old parse values.
  925.     move t1, [pars1,,pars2] ;[40]
  926.     blt t1, parsx        ;[40]
  927.     setzm cjfnbk+.gjgen    ; Clear the JFN bits.
  928.     movei t1, [flddb. .cmkey,,cmdtab] ; Point to command keyword table.
  929.     skipe local        ;[68] Running in local mode?
  930.      movei t1, [flddb. .cmkey,,cmdtb2] ;[68] Yes, use that table instead.
  931.     call rflde        ;[78] Parse a keyword.
  932.      jrst eoftst        ;[78] If error, test for EOF on command file.
  933.     hrrz t2, (t2)        ; Get the command routine addresses.
  934.     movem t2, pars1        ; Save into pars1.
  935.     hlrz t1, (t2)        ; Get the next level routine.
  936.     call (t1)        ; Call it.
  937.  
  938. eval:    move t2, pars1        ; Get back data value.
  939.     hrrz t1, (t2)        ; Get evaluation routine.
  940.     call (t1)        ; Call it.
  941.     jrst prsint        ; Go round again.
  942.  
  943. ;[78] EOFTST:  Command file EOF handler.
  944. ;
  945. eoftst:    push p, t2        ; Save this in case we can resume.
  946.     movei t1, .fhslf    ; Get last process error.
  947.     GETER%            ; Test for eof on COMND input file.
  948.     move t1, t2        ; Move error code from t2 to t1
  949.     pop p, t2        ;  and restore t2.
  950.     hrrzs t1        ; Erase fork handle from this.
  951.     caie t1, iox4        ; Was error EOF?
  952.      cain t1, comnx9    ; Or this kind of EOF?
  953.      jrst eofts2        ;[85] Yes, some kind of EOF.
  954.  
  955.     skipe f$exit        ;[85] Parsing rescan line?
  956.      jrst [    tmsg <?Not a KERMIT command - > ;[85] Yes, print message
  957.         hrroi t1, atmbuf ;[85]
  958.         PSOUT        ;[85]
  959.         ret ]        ;[85] And quit.
  960.  
  961. ; Not EOF, and not parsing rescan line, just enter normal parse error handler.
  962.  
  963.     jrst cmderr        ; Complain, then resume parsing.
  964.  
  965. ; EOF on command file.
  966.  
  967. eofts2:    call popjfn        ; It was EOF.  Pop the command file JFN.
  968.      jrst [    movei t1, .priin ; On any error, revert parsing to TTY.    
  969.         call setcsb    ;  ...
  970.         jrst .+1 ]
  971.     skipn iniflg        ;[83] Just closed init file?
  972.      jrst prsint        ;[83]  No, don't bother with rescan stuff.
  973.  
  974. ;[83] Just closed init file, check for command line (rescan) arguments.
  975.  
  976.     setzm iniflg        ;[83] Flag that we're done with init file.
  977.     jrst ccl        ;[85] And go check for rescan arguments.
  978.  
  979. ; Top-Level command tables.
  980.  
  981. ; Commands available to remote KERMIT.
  982.  
  983. cmdtab:    %table
  984.     %key <bye>, [xwd .bye,$bye], cm%inv ;[11]
  985.     %key <c>, %conn, cm%inv+cm%abr
  986.     %key <clear>, [xwd .clear,$clear], cm%inv ;[162]
  987.     %key <close>, [xwd .close,$close]
  988. %conn:    %key <connect>, [xwd .conne,$conne]
  989.     %key <cwd>, [xwd .ycwd,$ycwd] ;[145]
  990.     %key <define>, [xwd .defin,$defin] ;[77]
  991.     %key <delete>, [xwd .ydele,$ydele] ;[145]
  992.     %key <directory>, [xwd .ydire,$ydire] ;[145]
  993.     %key <e>, %exit, cm%inv+cm%abr
  994.     %key <echo>, [xwd .echo,$echo]
  995. %exit:    %key <exit>, [xwd .exit,$exit]
  996.     %key <finish>, [xwd .finis,$finis], cm%inv ;[28]
  997.     %key <get>,  [xwd .get,$get], cm%inv ;[11]
  998.     %key <help>, [xwd .help,$help]
  999.     %key <input>, [xwd .input,$input], cm%inv ;[159]
  1000.     %key <local>, [xwd .local,$local] ;[56]
  1001.     %key <log>, [xwd .log,$log] ;[125]
  1002.     %key <output>, [xwd .outpu,$outpu], cm%inv ;[159]
  1003.     %key <pause>, [xwd .pause,$pause], cm%inv ;[159]
  1004.     %key <prompt>, [xwd .promp,$promp], cm%inv
  1005.     %key <push>, [xwd .push,$push] ;[152]
  1006.     %key <quit>, [xwd .exit,$exit]
  1007.     %key <r>, %recv, cm%inv+cm%abr ;[56]
  1008. %recv:    %key <receive>, [xwd .recv,$recv]
  1009.     %key <remote>, [xwd .remot,$remot], cm%inv ;[56]
  1010.     %key <run>, [xwd .yrun,$yrun] ;[145]
  1011.     %key <s>, %send, cm%inv+cm%abr
  1012. %send:    %key <send>, [xwd .send,$send]
  1013.     %key <server>, [xwd .serve,$serve]
  1014.     %key <set>, [xwd .set,$set]
  1015.     %key <show>, [xwd .show,$show]
  1016.     %key <space>, [xwd .ydisk,$ydisk] ;[145]
  1017.     %key <statistics>, [xwd .stat,$stat]
  1018.     %key <take>, [xwd .take,$take] ;[78]
  1019.     %key <transmit>, [xwd .trans,$trans],cm%inv ;[165]
  1020.     %key <type>, [xwd .ytype,$ytype] ;[145]
  1021.     %tbend
  1022.  
  1023. ; Commands available to local KERMIT.
  1024.  
  1025. cmdtb2:    %table
  1026.     %key <bye>, [xwd .bye,$bye] ;[11]
  1027.     %key <c>, %conn2, cm%inv+cm%abr
  1028.     %key <clear>, [xwd .clear,$clear] ;[162]
  1029.     %key <close>, [xwd .close,$close]
  1030. %conn2:    %key <connect>, [xwd .conne,$conne]
  1031.     %key <cwd>, [xwd .ycwd,$ycwd] ;[145]
  1032.     %key <define>, [xwd .defin,$defin] ;[77]
  1033.     %key <delete>, [xwd .ydele,$ydele] ;[145]
  1034.     %key <directory>, [xwd .ydire,$ydire] ;[145]
  1035.     %key <e>, %exit2, cm%inv+cm%abr
  1036.     %key <echo>, [xwd .echo,$echo]
  1037. %exit2:    %key <exit>, [xwd .exit,$exit]
  1038.     %key <finish>, [xwd .finis,$finis] ;[28]
  1039.     %key <get>,  [xwd .get,$get]    ;[11]
  1040.     %key <help>, [xwd .help,$help]
  1041.     %key <input>, [xwd .input,$input] ;[159]
  1042.     %key <local>, [xwd .local,$local] ;[56]
  1043.     %key <log>, [xwd .log,$log] ;[125]
  1044.     %key <output>, [xwd .outpu,$outpu] ;[159]
  1045.     %key <pause>, [xwd .pause,$pause] ;[159]
  1046.     %key <prompt>, [xwd .promp,$promp], cm%inv
  1047.     %key <push>, [xwd .push,$push] ;[152]
  1048.     %key <quit>, [xwd .exit,$exit]
  1049.     %key <r>, %recv2, cm%inv+cm%abr ;[56]
  1050. %recv2:    %key <receive>, [xwd .recv,$recv]
  1051.     %key <remote>, [xwd .remot,$remot] ;[56]
  1052.     %key <run>, [xwd .yrun,$yrun] ;[145]
  1053.     %key <s>, %send2, cm%inv+cm%abr
  1054. %send2:    %key <send>, [xwd .send,$send]
  1055.     %key <server>, [xwd .serve,$serve], cm%inv
  1056.     %key <set>, [xwd .set,$set]
  1057.     %key <show>, [xwd .show,$show]
  1058.     %key <space>, [xwd .ydisk,$ydisk] ;[145]
  1059.     %key <statistics>, [xwd .stat,$stat]
  1060.     %key <take>, [xwd .take,$take] ;[78]
  1061.     %key <transmit>, [xwd .trans,$trans] ;[165]
  1062.     %key <type>, [xwd .ytype,$ytype] ;[145]
  1063.     %tbend
  1064.  
  1065.     subttl    ECHO command [167]
  1066.  
  1067. ; Help text for ECHO
  1068.  
  1069. hecho:    asciz |
  1070. ECHO text-string
  1071.  
  1072. Echoes the given text string at your terminal.  Useful in TAKE command files
  1073. and with login scripts for reporting progress or telling you what to do.
  1074. |
  1075. .echo:    noise <text at terminal> ; Issue noise words
  1076.     movei t1, [flddb. .cmtxt] ; Get the string into the atom buffer.
  1077.     call cfield
  1078.     ret
  1079.  
  1080. $echo:    hrroi t1, atmbuf    ; Point at the atom buffer.
  1081.     PSOUT            ; Type the string.
  1082.     hrroi t1, crlf        ; And a CRLF.
  1083.     PSOUT    
  1084.     ret
  1085.  
  1086.     subttl    EXIT and QUIT commands (which are the same)
  1087.  
  1088. ; Help text for QUIT.
  1089.  
  1090. hquit:    asciz |
  1091. QUIT
  1092.  
  1093. Synonym for EXIT.
  1094. |
  1095.  
  1096. ; Help text for EXIT...
  1097.  
  1098. hexit:    asciz |
  1099. EXIT
  1100.  
  1101. Exit from KERMIT-20.  You can CONTINUE the program from the TOPS-20 Exec,
  1102. provided you haven't run another program on top of it.  You can also exit from
  1103. KERMIT-20 by typing one or more control-C's, even if it's in the middle of
  1104. transferring a file.  KERMIT-20 will always restore your terminal to its
  1105. original condition, and you will be able to CONTINUE the program to get back
  1106. to KERMIT-20> command level.  When you EXIT from KERMIT-20, any open files,
  1107. including logs, will be closed.
  1108. |
  1109.  
  1110. ; Parse the rest of the EXIT or QUIT command.
  1111.  
  1112. .exit:    noise <from Kermit>
  1113.     confrm            ; Confirm.
  1114.     ret
  1115.  
  1116. ; Execute the EXIT or QUIT command.
  1117.  
  1118. $exit:    setom f$exit        ; Set exit flag.
  1119.     ret            ; (that's all)
  1120.  
  1121. ; Routine to clean up any open files or devices.
  1122.  
  1123. clenup:    move t1, netjfn        ;[127] Get communication line JFN.
  1124.     setzm netjfn
  1125.     setzm local
  1126.     caie t1, .cttrm        ;[127] Previous one was controlling terminal?
  1127.      skipn t1        ;[127] Close any assigned TTY.
  1128.      jrst clenu2
  1129.     CLOSF
  1130.      erjmp .+1        ; Ignore any error (silently).
  1131. clenu2:    skipn asgflg        ; Did I also assign the TTY?
  1132.      jrst clenu3        ; No.
  1133.     move t1, ttynum        ; Yes, so I should deassign it.
  1134.     movei t1, .ttdes(t1)
  1135.     RELD%
  1136.      erjmp .+1
  1137.     setzm asgflg
  1138.  
  1139. clenu3:    skipn t1, logjfn    ; Do we have a debugging log?
  1140.      jrst clenu4        ;  No.
  1141.     setz t2,        ;[144] Yes, any bytes written?
  1142.     RFPTR            ;[144]
  1143.      nop            ;[144]
  1144.     skipg t2        ;[144]
  1145.      txo t1, cz%abt        ;[144] None, don't bother keeping the log.
  1146.     setzm logjfn        ; Yes, forget about it,
  1147.     CLOSF            ; Close it.
  1148.      erjmp .+1
  1149.  
  1150. clenu4:    skipn t1, tlgjfn    ;[126] Transaction log was open?
  1151.      jrst clenu5
  1152.     wtlog <Closed Transaction Log>
  1153.      setzm tlgjfn
  1154.     CLOSF
  1155.      erjmp .+1
  1156.  
  1157. clenu5:    skipn t1, filjfn    ; Any file transfer JFNs hanging around?
  1158.      jrst clenu6
  1159.     setzm filjfn
  1160.     CLOSF
  1161.      erjmp .+1
  1162.  
  1163. clenu6:    skipn t1, sesjfn    ; How about a session log?
  1164.      jrst clenuz
  1165.     setzm sesjfn
  1166.     CLOSF
  1167.      erjmp .+1
  1168.  
  1169. clenuz:    ret            ; Note, we DON'T turn off interrupt system.
  1170.  
  1171.     subttl    HELP command
  1172.  
  1173. hsfdb1: flddb. .cmkey,,mactab,<SET macro,>,<summary>,hsfdb2
  1174. hsfdb2:    flddb. .cmkey,,sethlp,<SET option,>,<summary>
  1175.  
  1176. .help:    noise <about>        ;[18] HELP
  1177.     movei t1, [flddb. .cmkey,,hlptab,,<kermit>]
  1178.     call rfield        ;[67]
  1179.     move t2, (t2)        ; Get help text address.
  1180.     movem t2, pars3
  1181.     hrrzs t2        ;[67]
  1182.     caie t2, hset        ;[67] They want help for SET?
  1183.      jrst .helpx        ;[67]  No.
  1184.     noise <parameter>    ;[67] Yes, give guide word.
  1185.     movei t1, hsfdb1    ;[77] Parse from macro or SET keyword table.
  1186.     call rfield        ;[67] Get SET option they want help for.
  1187.     hrrzs t3        ;[77] Which function descriptor block was used?
  1188.     caie t3, hsfdb1        ;[77] The macro table?
  1189.      move t2, (t2)        ;[67]  Yes, don't do indirection
  1190.     movem t2, pars3        ;[67] SET...
  1191. .helpx:    confrm            ;[67]
  1192.     ret
  1193.  
  1194. hlptab:    %table            ;[18] Table of help commands.
  1195.     %key <bye>,hbye
  1196.     %key <clear>,hclear    ;[162]
  1197.     %key <close>,hclose
  1198.     %key <connect>,hconne
  1199.     %key <CWD>,hcwd
  1200.     %key <define>,hdefin    ;[77]
  1201.     %key <delete>,hdele
  1202.     %key <directory>,hdire
  1203.     %key <echo>,hecho
  1204.     %key <exit>,hexit
  1205.     %key <finish>,hfinis
  1206.     %key <get>,hget
  1207.     %key <help>,hhelp
  1208.     %key <input>,hinput    ;[159]
  1209.     %key <kermit>,hkermi
  1210.     %key <local>,hlocal
  1211.     %key <log>,hlog
  1212.     %key <output>,houtpu    ;[159]
  1213.     %key <pause>,hpause    ;[159]
  1214.     %key <prompt>,hpromp
  1215.     %key <push>,hpush
  1216.     %key <quit>,hquit
  1217.     %key <receive>,hrecei
  1218.     %key <remote>,hremot
  1219.     %key <run>,hrun
  1220.     %key <send>,hsend
  1221.     %key <server>,hserve
  1222.     %key <set>,hset
  1223.     %key <show>,hshow
  1224.     %key <space>,hspace
  1225.     %key <statistics>,hstatu
  1226.     %key <take>,htake
  1227.     %key <transmit>,htrans
  1228.     %key <type>,htype
  1229.     %tbend
  1230.  
  1231. sethlp:    %table            ;[67] Table of HELP SET commands.
  1232.     %key <break>, hsbrea
  1233.     %key <block-check>, hsbc
  1234.     %key <debugging>, hsdeb
  1235.     %key <delay>, hsdel
  1236.     %key <duplex>, hsdup
  1237.     %key <escape>, hsesc
  1238.     %key <file>, hsfil
  1239.     %key <flow-control>, hsflo ;[143]
  1240.     %key <handshake>, hshan    ;[76]
  1241.     %key <incomplete>, hsabf
  1242.     %key <input>, hsetin    ;[160]
  1243.     %key <ITS-binary>, hsits ;[75]
  1244.     %key <line>, hslin
  1245.     %key <parity>, hspar
  1246.     %key <prompt>, hsprom    ;[137]
  1247.     %key <receive>, hsrcv
  1248.     %key <retry>, hsrty
  1249.     %key <send>, hssnd
  1250.     %key <speed>, hspeed
  1251.     %key <summary>, hset
  1252.     %key <TVT-Binary>, hstac ;[129]
  1253.     %tbend
  1254.     
  1255.     ;...
  1256.  
  1257. ;...HELP command, cont'd
  1258.  
  1259.  
  1260. ; Help text for HELP command...
  1261.  
  1262. hhelp:    asciz |
  1263. HELP [topic]
  1264.  
  1265. Typing HELP alone prints a brief summary of KERMIT-20 and its commands.
  1266. You can also type
  1267.  
  1268.    HELP command
  1269.  
  1270. for any Kermit-20 command, e.g. "help send", to get more detailed information
  1271. about a specific command.  To see a list of all the available help commands,
  1272. type
  1273.  
  1274.    HELP ?
  1275.  
  1276. or consult the Kermit User Guide.
  1277. |
  1278.  
  1279. ; Execute the help command.
  1280.  
  1281. $help:    hrrz t3, pars3        ;[77] Special case for help about macro.
  1282.     cail t3, mactab+1
  1283.      caile t3, mactbx
  1284.      jrst $help2    
  1285.     tmsg <
  1286. ">
  1287.     hlro t1, (t3)
  1288.     PSOUT
  1289.     tmsg <" is a SET macro defined to be:
  1290.    >
  1291.     hrro t1, (t3)
  1292.     PSOUT
  1293.     tmsg <
  1294. >
  1295.     ret
  1296.  
  1297. $help2:    hrro t1, pars3        ;[18] Normal help text.
  1298.     PSOUT
  1299.     hrroi t1, crlf
  1300.     PSOUT
  1301.     ret
  1302.  
  1303.     subttl    INPUT, OUTPUT, and PAUSE added as edit [159].
  1304.  
  1305. hinput:    asciz |
  1306. INPUT interval string
  1307.  
  1308. INPUT is useful with OUTPUT and PAUSE for sending connect and login
  1309. sequences to a remote host, e.g. over a dialout connection.
  1310.  
  1311. On the currently selected communication line, look for the given string
  1312. for the specified time interval.  If no interval is specified, then wait
  1313. for the default interval, which is 2 seconds unless changed by SET INPUT
  1314. DEFAULT-TIMEOUT.  An interval of 0 or less means no timeout (wait
  1315. forever).
  1316.  
  1317. Characters coming in from the line will be scanned for the search string,
  1318. and when a match is found, the command will terminate successfully; if
  1319. the string is not found within the given interval, the command will
  1320. terminate unsuccessfully.  While the INPUT command is active, all
  1321. incoming characters will appear on your screen.
  1322.  
  1323. The search string may contain any printable characters.  Control or other
  1324. special characters may be included by preceding their octal ASCII value
  1325. with a backslash, for instance foo\15 is "foo" followed by a carriage
  1326. return, \100 is an atsign (@).  Alphabetic case is ignored ("a" = "A")
  1327. unless you have SET INPUT CASE OBSERVE.  If no search string is given,
  1328. then the INPUT command will keep operating until it times out.
  1329.  
  1330. If the INPUT command fails to find the requested string within the given
  1331. interval, it will "fail"; if the INPUT command was issued from a command
  1332. file (see TAKE), then the next command will be executed, unless you have
  1333. SET INPUT TIMEOUT-ACTION to QUIT, in which case the command file will be
  1334. terminated.  An INPUT command can by interrupted by typing two ^C's.
  1335.  
  1336. Type HELP SET INPUT for further information.
  1337. |
  1338. .input:    noise <interval>
  1339.     setzm buffer        ; Make dynamic default string.
  1340.     setzm buffer+1
  1341.     move t1, [point 7, buffer]
  1342.     move t2, indeft
  1343.     movei t3, ^d10
  1344.     NOUT
  1345.      erjmp .+1
  1346.     movei t1, [flddb. .cmnum,,^d10,<Number of seconds to wait,>,<5>]
  1347.     move t2, [point 7, buffer] ; The above default will be overridden
  1348.     skipe buffer        ; if there's anything in this buffer.
  1349.      movem t2, .cmdef(t1)    ; Stuff the pointer into the fdb.
  1350.     call rfield
  1351.     setzm buffer
  1352.     setzm buffer+1
  1353.     movem t2, pars2
  1354.     movei t1, [flddb. .cmtxt,cm%sdh,,<Text string to look for,
  1355. use \ooo (backslash followed by octal digits) to include control characters,
  1356. \\ to include a single backslash>]
  1357.     call cfield
  1358.     ret
  1359.  
  1360. ; INPUT command.
  1361.  
  1362. $input:    call getss        ; Get & decode search string from atom buffer.
  1363.     skipg pars2
  1364.      jrst $inpu5        ; Skip timer if interval 0 or negative.
  1365.  
  1366. ; Set the desired timeout.
  1367.  
  1368.     movei t1, .fhslf
  1369.     movx t2, 1b0        ; Turn on channel 0.
  1370.     AIC
  1371.      %jserr <Can't turn on timer channel>, <.+1>
  1372.  
  1373.     move t1, [.fhslf,,.timal] ; Remove all pending timer requests.
  1374.     setzb t2, t3
  1375.     TIMER
  1376.      %jserr <Can't clear pending timers>, <.+1>
  1377.  
  1378.     movem p, intstk        ; The timer interrupt routine needs this.
  1379.     movei t1, $inpu9    ; Where to go upon timeout
  1380.     movem t1, intpc        ;  ...
  1381.  
  1382.     move t1, [.fhslf,,.timel] ; Our process and time from now.
  1383.     move t2, pars2        ; The interval we parsed.
  1384.     imuli t2, ^d1000    ; Make time into milliseconds.
  1385.     setz t3,        ; Channel zero.
  1386.     TIMER
  1387.      %jserr <Can't set timer>, <.+1>
  1388.  
  1389. ; Try to get string from the communication line.
  1390.  
  1391. $inp4a:    call dobits        ; Condition the line for i/o.
  1392.      ret            ;  Pass along any failure.
  1393.     call ttyob        ; Put TTY in binary mode for output only.
  1394.     call ccon        ; Turn on ^C trap.
  1395.      jrst $inpuy        ; If ^C typed, go to this place.
  1396.  
  1397. $inpu5:    move t4, [point 7, strbuf] ; Point to the search string.
  1398.  
  1399. $inpu6:    skipn strc        ; Is there a search string?
  1400.      jrst $inpu7        ;  No, just go forever.
  1401.     ildb t3, t4        ; Get a character from search string.
  1402.     jumpe t3, $inpux    ; If no more, then success.
  1403.     ;...
  1404.     
  1405. ;...$INPUT, cont'd
  1406.  
  1407.  
  1408. ; Get & echo a character, compare with current position in search string.
  1409.  
  1410. $inpu7:    move t1, netjfn        ; Now get a character from the line.
  1411.     setz t2,
  1412.     BIN
  1413.      %jserr (,$inpux)
  1414.     andi t2, ^o177        ; Strip any parity.
  1415.     move t1, t2        ; Echo the character.
  1416.     PBOUT
  1417.     skiple t1, sesjfn    ; Session logging?
  1418.      jrst [    BOUT        ; Yes, record the character in the log.
  1419.          erjmp .+1
  1420.         jrst .+1 ]        
  1421.     skipn incase        ; Case-sensitive compare?
  1422.      jrst [    cail t2, "a"    ; No, is this a lower case letter?
  1423.          caile t2, "z"
  1424.          skipa        ; No.
  1425.          txz t2, 40    ; Yes, convert to upper.
  1426.         jrst .+1 ]
  1427.  
  1428.     camn t2, t3        ; Compare OK?
  1429.      jrst $inpu6        ;  Yes, get next from string and comm line.
  1430.     jrst $inpu5        ; No, rewind search string, get next from line.
  1431.  
  1432. ; Come here upon input timeout.
  1433.  
  1434. $inpu9:    hrroi t1, [asciz/
  1435. %/]                ; % message if proceeding
  1436.     skipe intima
  1437.      hrroi t1, [asciz/
  1438. ?/]                ; ? message if quitting (for batch)
  1439.     PSOUT
  1440.     hrroi t1, [asciz/KERMIT-20: INPUT timed out looking for "/]
  1441.     PSOUT
  1442.     hrroi t1, strbuf    ; Tell what string we couldn't find.
  1443.     PSOUT
  1444.     hrroi t1, [asciz/", proceeding...
  1445. /]                ; Say what we're doing, proceeding
  1446.     skipe intima
  1447.      hrroi t1, [asciz/", quitting /] ; ...or quitting.
  1448.     PSOUT
  1449.     skipn intima
  1450.      jrst $inpux        ; Proceeding, just exit from the INPUT command.
  1451.     movei t1, .priou    ; Quitting, tell which file we're quitting from
  1452.     move t2, takjfn        ;  (if any).
  1453.     setz t3,
  1454.     JFNS            ; If no TAKJFN, this will print nothing.
  1455.      erjmp .+1
  1456.     tmsg <
  1457. >
  1458.  
  1459. $inpuy:    call popjfn        ; Pop the TAKE file JFN from the TAKE stack.
  1460.     ;...
  1461.  
  1462. ;...$INPUT, cont'd
  1463.  
  1464.  
  1465. ; Exit thru here, turning off timer, restore line to previous condition.
  1466.  
  1467. $inpux:    call ccoff2        ; Turn off ^C trap.
  1468.     call unbits        ; Restore the line
  1469.     call ttyou        ; Restore controlling tty output.
  1470.     skipg pars2        ; Skip timer stuff if interval 0 or negative.
  1471.      ret
  1472.     move t1, [.fhslf,,.timbf] ; Turn off timer interrupts for this fork.
  1473.     hrloi t2, 377777    ; For all times before this (far in future).
  1474.     TIMER            ;
  1475.      erjmp .+1
  1476.     movx t1, .fhslf        ; Deactivate the channel.
  1477.     movx t2, 1b0
  1478.     DIC
  1479.      %jserr <Can't DIC>,<.+1>
  1480.     setzm strbuf        ; Leave the string buffer cleanup up
  1481.     setzm strbuf+1        ;  a bit...
  1482.     setzm strptr
  1483.     ret    
  1484.  
  1485. ; GETSS - Get & Decode a backslash-decoded search string from the atom buffer.
  1486. ; Returns +1 with 7-bit ASCIZ string in STRBUF, STRC 0 if null, else nonzero.
  1487. ;
  1488. getss:    move t1, [point 7, atmbuf] ; Copy search string from here
  1489.     move t2, [point 7, strbuf] ; ... to here
  1490.     movem t2, strptr    ; Use this pointer
  1491.     setzm strc        ;  and this counter.
  1492.  
  1493. getss2:    ildb t4, t1        ; Get a character.
  1494.  
  1495. getss3:    jumpe t4, getssx    ; If null, then done.
  1496.     aos strc        ; Got one, count it.
  1497.     cain t4, "\"        ; Backslash?
  1498.      jrst [    movei t3, ^d8    ; Yes, try to read a number.
  1499.         NIN
  1500.          nop        ; If error, just keep the backslash.
  1501.         idpb t2, strptr    ; OK, deposit ascii value of number.
  1502.         ldb t4, t1    ; Account for how NIN overshoots the pointer.
  1503.         jrst getss3 ]
  1504. getss4:    skipn incase        ; Case-sensitive compare?
  1505.      jrst [    cail t4, "a"    ; No, is this a lower case letter?
  1506.          caile t4, "z"
  1507.          skipa        ; No.
  1508.          txz t4, 40    ; Yes, convert to upper.
  1509.         jrst .+1 ]
  1510. getss5:    idpb t4, strptr        ; Deposit the result of all this.
  1511.     jrst getss2
  1512.  
  1513. getssx:    idpb t4, strptr        ; Deposit a null at the end.
  1514.     ret
  1515.  
  1516. houtpu:    asciz |
  1517. OUTPUT string
  1518.  
  1519. The given string is sent out the currently selected communication line.
  1520. Control characters may be included in \ooo format (backslash followed by
  1521. octal representation of ASCII value).  Currently selected settings for
  1522. DUPLEX, PARITY, and FLOW are used.
  1523.  
  1524. Type HELP INPUT for further information.
  1525. |
  1526. .outpu:    noise (string)        ; Parse OUTPUT command.
  1527.     movei t1, [flddb. .cmtxt,cm%sdh,,<Text string to send,
  1528. use \ooo (backslash followed by octal digits) to include control characters,
  1529. \\ to include a single backslash>]
  1530.     call cfield
  1531.     ret
  1532.  
  1533. $outpu:    move t1, [point 7, atmbuf] ; Do OUTPUT; move chars from here...
  1534.     move t2, [point 8, strbuf] ;  to here.
  1535.     movem t2, strptr
  1536.  
  1537. $outp3:    ildb t4, t1        ; Copy them
  1538. $out3x:    jumpe t4, $outp4    ;  up to a null.
  1539.     cain t4, "\"        ; Backslash?
  1540.      jrst [    movei t3, ^d8    ; Yes, read a number
  1541.         NIN
  1542.          movei t2, "\"    ; If error, keep the backslash.
  1543.         move t4, t2    ; Get ascii value into t4.
  1544.         seto t2,    ; Decrement the source byte pointer.
  1545.         adjbp t2, t1
  1546.         move t1, t2
  1547.         jrst .+1 ]
  1548.  
  1549. out3a:    exch t1, t4        ; Put character in t1, preserve source pointer.
  1550.     call @parity        ; Tack on desired parity.
  1551.     idpb t1, strptr        ; Deposit the result in the output buffer.
  1552.     move t1, t4        ; Restore the source pointer.
  1553.     jrst $outp3        ; Go back for next.
  1554.  
  1555. $outp4:    idpb t4, strptr        ; Done, deposit a null.
  1556.     move t1, netjfn        ; Comm line designator.
  1557.     move t2, [point 8, strbuf] ; Point to string.
  1558.     setzb t3, t4        ; It's null-terminated.
  1559.     SOUT            ; Send it.
  1560.      %jserr (<Can't send the string>,<.+1>)
  1561.     skipn duplex        ; Half duplex connection?
  1562.      ret            ;  No, host will echo.
  1563.     movei t1, .priou    ; Yes, do it ourselves.
  1564.     move t2, [point 8, strbuf] ; Point to string again.
  1565.     setzb t3, t4
  1566.     SOUT
  1567.      erjmp .+1
  1568.     skipn t1, sesjfn    ; Session logging?
  1569.      jrst $outpx        ; No.
  1570.     move t2, [point 8, strbuf] ; Yes, point again.
  1571.     setzb t3, t4
  1572.     SOUT
  1573.      erjmp .+1
  1574. $outpx:    ret            ; Done.
  1575.  
  1576. ; PAUSE command.
  1577.  
  1578. hpause:    asciz |
  1579. PAUSE interval
  1580.  
  1581. Pause for the given number of seconds.  Useful with INPUT and OUTPUT.
  1582. |
  1583. .pause:    noise (seconds)
  1584.     movei t1, [flddb. .cmnum,,^d10,<Number of seconds to pause>,<1>]
  1585.     call cfield
  1586.     movem t2, pars2
  1587.     ret
  1588.  
  1589. $pause:    move t1, pars2        ; Get the number that was parsed.
  1590.     imuli t1, ^d1000    ; Convert to millisecs.
  1591.     DISMS            ; Sleep.
  1592.      erjmp .+1
  1593.     ret
  1594.  
  1595.     subttl    TAKE command, added as edit 78.
  1596.  
  1597. htake:    asciz |
  1598. TAKE filespec
  1599.  
  1600. Execute KERMIT-20 commands from the specified file.  The file may contain
  1601. contain TAKE commands.  Command files may be nested up to a depth of 20.
  1602. |
  1603.  
  1604. ; Parse the rest of the TAKE command.
  1605.  
  1606. .take:    movx t1, cz%ncl!.fhslf    ; Release non-open jfn's.
  1607.     CLZFF
  1608.     noise <commands from file>
  1609.     move t1, [defbk,,cjfnbk] ; Insert our file parsing defaults.    
  1610.     blt t1, cjfnbk+defbkl
  1611.     movei t1, [flddb. .cmfil]
  1612.     call cfield
  1613.     movem t2, pars2        ; Here's the JFN just parsed.
  1614.     ret
  1615.  
  1616. ; Execute the TAKE command.
  1617.  
  1618. $take:    move t1, takdep        ; How deep are we?
  1619.     caile t1, takel        ; Too deep?
  1620.      jrst [    tmsg <?TAKE command file stack overflow> ; Yes, don't do it.
  1621.         ret ]
  1622.     move t1, takjfn        ; There's room, get current TAKE file jfn.
  1623.     move t2, takep        ; Push it on the stack
  1624.     push t2, t1        ; ...
  1625.     movem t2, takep        ; ...
  1626.     aos takdep        ; Remember what level we're on.
  1627.  
  1628.     move t1, pars2        ; Get JFN that was parsed
  1629.     movem t1, takjfn    ;  ...
  1630.     movx t2, fld(7,of%bsz)!of%rd ; 7-bit i/o, read access.
  1631.     OPENF
  1632.      %jserr (,$takex)
  1633.     callret setcsb        ; Opened OK, go set up command state block.
  1634.  
  1635. ; Error opening command file.
  1636.  
  1637. $takex: call popjfn        ; Remove offending JFN from TAKE stack.
  1638.      jrst [ tmsg <?TAKE file stack underflow>
  1639.         ret ]
  1640.  
  1641.     movx t1, cz%ncl!.fhslf    ; Release extraneous JFNs.
  1642.     CLZFF
  1643.      erjmp .+1
  1644.     ret
  1645.  
  1646. ; Default command filespec fields for .CMFIL:
  1647.  
  1648. defbk:    gj%old            ; Must be existing file.
  1649.     repeat 4,<0>        ; Normal defaults for dev:<dir>name.
  1650.     point 7, [asciz/CMD/]    ; Default extension is .CMD.
  1651.     0            ; Default protection,
  1652.     0            ;  and account.
  1653. defbkl==<.-defbk>        ; Length of this GTJFN argument block.
  1654.     
  1655. ; SETCSB - Set up Command State Block to parse from JFN in t1.
  1656. ;
  1657. setcsb:    skipg t1        ; Make sure there's a real JFN.
  1658.      movei t1, .priin    ; If not, revert.
  1659.     hrlm t1, sbk+.cmioj    ; Put the input JFN into the CSB.
  1660.     movei t2, .priou    ; Assume JFN is primary input.
  1661.     caie t1, .priin        ; Is it?
  1662.      movx t2, .nulio    ; No, it's a file, so nullify COMND output.
  1663.     hrrm t2, sbk+.cmioj    ; Put output JFN in CSB.
  1664.     ret
  1665.  
  1666.  
  1667. ; POPJFN
  1668. ; Routine to pop a command file JFN off the JFN stack.
  1669. ;
  1670. ; Enter with current command file jfn in TAKJFN.
  1671. ;
  1672. ; Returns:
  1673. ;  +1 if stack empty,
  1674. ;  +2 otherwise, with popped jfn in TAKJFN.
  1675. ;
  1676. popjfn:    skipg takdep        ; Back at top level?
  1677.      ret            ;  Yes, return silently.
  1678.  
  1679. ; Close current command file.
  1680.  
  1681.     hrrz t1, takjfn        ; No, close the current file
  1682.     CLOSF            ;  ...
  1683.      %jserr (,.+1)        ; Just print message on error.
  1684.  
  1685. ; Return to previous one.
  1686.  
  1687.     move t2, takep        ; Get the TAKE stack pointer
  1688.     pop t2, t1        ;  and the previous TAKE file JFN,
  1689.     movem t2, takep        ;  restore them,
  1690.     movem t1, takjfn    ;  ...
  1691.     call setcsb        ;  and also restore the command state block.
  1692.     sos takdep        ; Decrement the depth indicator
  1693.     retskp            ; Return successfully.
  1694.  
  1695. ;[79] INIFIL -- Process initialization file.
  1696. ;
  1697. ;[85] Returns +1 if there was no init file, +2 if there was.
  1698. ;
  1699. inifil:    move t2, jobtab+.jiuno
  1700.     move t1, [point 7, dirbuf, 27] ; Put string here.
  1701.     DIRST    
  1702.      erjmp r
  1703.     movei t3, 76        ; Right angle bracket.
  1704.     idpb t3, t1
  1705.     move t2, [point 7, [asciz/KERMIT.INI/]]    ; File name.
  1706.  
  1707. inif2:    ildb t3, t2        ; Copy file name.
  1708.     idpb t3, t1
  1709.     jumpn t3, inif2
  1710.  
  1711. inif3:    movx t1, gj%old+gj%sht    ; Get JFN on it.
  1712.     hrroi t2, dirbuf
  1713.     GTJFN
  1714.      erjmp r        ; If we can't, return silently.
  1715.     hrrzm t1, pars2        ; Got one, pretend we parsed it.
  1716.     setom iniflg        ;[83] Flag that we're doing init file.
  1717.     call $take        ; Go TAKE the file.
  1718.     retskp            ;[85]
  1719.  
  1720.     subttl    LOCAL and REMOTE commands.
  1721.  
  1722. ;[56] LOCAL and REMOTE commands added as edit 56
  1723.  
  1724. .local:    setom lcflg        ; -1 = local
  1725.     movei t1, [flddb. .cmkey,,loctab] ; LOCAL what?
  1726.     jrst .remo2        ; Go parse the rest.
  1727.  
  1728. loctab:    %table
  1729.     %key <cwd>, [xwd .ycwd,$ycwd]
  1730.     %key <delete>, [xwd .ydele,$ydele]
  1731.     %key <directory>, [xwd .ydire,$ydire]
  1732.     %key <run>, [xwd .yrun,$yrun]
  1733.     %key <space>, [xwd .ydisk,$ydisk]
  1734.     %key <type>, [xwd .ytype,$ytype]
  1735.     %tbend
  1736.  
  1737. .remot:    setzm lcflg        ; 0 = remote
  1738.     movei t1, [flddb. .cmkey,,remtab] ; REMOTE what?
  1739. .remo2:    call rfield        ; Parse a keyword.
  1740.     hrrz t2, (t2)        ; Get the command routine addresses.
  1741.     movem t2, pars2        ; Save into pars2.
  1742.     hlrz t1, (t2)        ; Get the next level routine.
  1743.     call (t1)        ; Call it.
  1744.     ret
  1745.  
  1746. remtab:    %table
  1747.     %key <cwd>, [xwd .xcwd,$xcwd]
  1748.     %key <delete>, [xwd .rmfil,$xdele]
  1749.     %key <directory>, [xwd .rmfil,$xdire]
  1750.     %key <error>, [xwd .xerr,$xerr], cm%inv
  1751.     %key <help>, [xwd .xhelp,$xhelp] ;[120]
  1752.     %key <host>, [xwd .xhost,$xhost] ;[105]
  1753. ;;;*    %key <run>, [xwd .???, $???]
  1754.     %key <space>, [xwd .xdisk,$xdisk]
  1755.     %key <type>, [xwd .rmfil,$xtype]
  1756.     %tbend
  1757.  
  1758. ; LOCAL command help text.
  1759.  
  1760. hlocal:    asciz |
  1761. LOCAL option
  1762.  
  1763. Execute a command locally.  Options include:
  1764.  
  1765.  CWD            Change Working Directory (connect to directory).
  1766.  DELETE filespec    Delete a file or file group.
  1767.  DIRECTORY filespec    Print a directory listing.
  1768.  HOST command        A command to be executed by the TOPS-20 Exec.
  1769.  RUN program            Run the specified program.
  1770.  SPACE area        Disk usage query.
  1771.  TYPE filesec        Type a local file or file group at the terminal.
  1772.  
  1773. For further information, type HELP CWD, HELP DELETE, etc.
  1774. |
  1775.  
  1776. ;[137] LOCAL CWD command parsing.
  1777. ;
  1778. hcwd:    asciz |
  1779. CWD means CHANGE WORKING DIRECTORY.  It is the same as LOCAL CWD, i.e. it is
  1780. executed on the local system.  The operation is the same as the DEC-20
  1781. CONNECT command.
  1782. |
  1783. .ycwd:    setzm pasbuf        ; Zero this out.
  1784.     setzm pasbuf+1        ;  ...
  1785.     noise <to directory>    ; Issue guide words.
  1786.     movei t1, [
  1787.         flddb. .cmdir,cm%sdh,,<directory name or logical name,
  1788.  or carriage return to connect back to your login directory>,,[
  1789.         flddb. .cmcfm,cm%sdh ]]
  1790.     call rfield        ; Parse a directory specification.
  1791.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  1792.     cain t3, .cmcfm        ; Confirmation?
  1793.      jrst [    move t2, jobtab+.jilno ; Yes, then use own logged in dir no.
  1794.         movem t2, pars3
  1795.         ret ]
  1796.  
  1797.     movem t2, pars3        ; No, directory number, save it.
  1798.     confrm            ; Get confirmation.
  1799.     ret
  1800.  
  1801. ; Execute the LOCAL CWD command.
  1802. ;
  1803. ;[171] Rewritten to only prompt for the password when necessary, as
  1804. ; the Exec CONNECT command does, and to print the name of the directory
  1805. ; connected to.
  1806. ;
  1807. ; First try to connect with no password.  This returns immediately on error.
  1808. ;
  1809. $ycwd:    move t1, [ac%con!<3>]    ; Ask for connect function, arg block length 3.
  1810.     movei t2, pars3        ; Point to argument block.
  1811.     setom pars5        ; Specify "this job".
  1812.     ACCES            ; Try to connect.
  1813.      erjmp $ycwdx        ;  If error, go prompt for password.
  1814.     jrst $ycwdz        ; Connected OK, exit.
  1815.  
  1816. ; Handle error by prompting for password and then trying to connect again.
  1817.  
  1818. $ycwdx:    setzm pars4        ; Assume no password will be given.
  1819.     call getpas        ; Ask for password.
  1820.     movem t1, pars4        ; Save pointer to (possibly null) string.
  1821.     move t1, [ac%con!<3>]    ; Try to connect again.
  1822.     movei t2, pars3        ; If this fails, monitor won't return
  1823.     ACCES            ;  for about 3 seconds.
  1824.      %jserr (,.+1)        ; On failure, give message and exit.
  1825.  
  1826. ; Done either way, exit.
  1827.  
  1828. $ycwdz:    setzm pasbuf        ; Connected, clear this out for security.
  1829.     setzm pasbuf+1
  1830.  
  1831.     tmsg <[Connected to >    ; Print what we're connected to.
  1832.     seto t1,        ; Get this job's connected directory number.
  1833.     hrroi t2, t3
  1834.     movei t3, .jidno
  1835.     GETJI
  1836.      erjmp r
  1837.     move t2, t3        ; Convert to string.
  1838.     movem t2, jobtab+.jidno    ; Remember for future reference.
  1839.     movei t1, .priou
  1840.     DIRST
  1841.      erjmp r
  1842.     movei t1, "]"
  1843.     PBOUT
  1844.     ret
  1845.  
  1846. ; GETPAS -- Get a password from the terminal
  1847. ;
  1848. ; Prompts for password, turns off echoing during typein, leaves result in
  1849. ; PASBUF, with t1 pointing to it.
  1850. ;
  1851. ; Uses t1-t4.
  1852. ;
  1853. getpas:    skipn takdep        ;[178] Do specially for TAKE files
  1854.      jrst getpa2        ;[178]  (here thru ret)
  1855.     setzm pasbuf
  1856.     move t1, takjfn        ; Read line from the TAKE file
  1857.     hrroi t2, pasbuf    ; Into here
  1858.     movei t3, pasbfl    ; This many chars, max
  1859.     movei t4, .CHLFD    ; terminate on linefeed.
  1860.     SIN
  1861.      erjmp getpax
  1862.     seto t3,        ; Decrement the returned byte pointer.
  1863.     adjbp t3, t2
  1864.     setz t4,        ; Write a zero over the terminating CR.
  1865.     dpb t4, t3
  1866.     idpb t4, t3        ; And linefeed.
  1867. getpax:    move t1, [point 7, pasbuf] ; Return pointer to password.
  1868.     ret            ;[178]
  1869.  
  1870. getpa2:    hrroi t1, [asciz/ Password: /] ; Issue first prompt.
  1871.     PSOUT    
  1872.     movei t1, .priin    ; Get TTY mode word
  1873.     setz t2,
  1874.     RFMOD
  1875.      erjmp .+1
  1876.     call [    saveac <t1,t2>    ; Save TTY info.
  1877.         txz t2, tt%eco    ; Turn off echoing.
  1878.         SFMOD
  1879.          erjmp r
  1880.         hrroi t1, pasbuf ; Ask for password.
  1881.         move t2, [rd%crf+rd%bel+pasbfl]
  1882.         hrroi t3, [asciz/ Password: /]
  1883.         RDTTY
  1884.          %jserr (,r)
  1885.         move t4, t2    ;[169] Remember flag bits that were returned.
  1886.         setz t2,    ; Write a zero over the terminating linefeed.
  1887.         dpb t2, t1
  1888.         ret ]        ; Restore TTY info.
  1889.     SFMOD            ; Restore TTY to normal echoing.
  1890.      erjmp .+1    
  1891.     tmsg <
  1892. >                ; Echo the crlf that wasn't echoed.
  1893.     txnn t4, rd%btm        ; Too long?
  1894.      jrst [    tmsg <
  1895. ?Password too long>        ;* This doesn't help, must do something better
  1896.         jrst .+1 ]    ;* later on...
  1897.     move t1, [point 7, pasbuf] ; Return pointer to result.
  1898.     ret
  1899.  
  1900. ;[111] LOCAL DIRECTORY
  1901.  
  1902. hdire:    asciz |
  1903. DIRECTORY is the same as LOCAL directory.  It produces a directory listing of
  1904. the specified files at your terminal.
  1905. |
  1906.  
  1907. ; Default wildcard filespec fields for .CMFIL:
  1908.  
  1909. dirbk:    gj%old!gj%ifg!gj%flg!.gjall ; Flag bits,,generation number.
  1910.     .priin,,.priou        ; COMND i/o.
  1911.     repeat 2,<0>        ; Normal defaults for dev:<dir> and gen.
  1912.     repeat    2,<point 7, [asciz/*/]>    ; *.* for name and type.
  1913.     0            ; Default protection,
  1914.     0            ;  and account.
  1915. dirbkl==<.-dirbk>        ; Length of this GTJFN argument block.
  1916.  
  1917. .ydire:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  1918.     CLZFF
  1919.     noise <of files>    ; Issue guide words.
  1920.     move t1, [dirbk,,cjfnbk] ; Insert our file parsing defaults.    
  1921.     blt t1, cjfnbk+dirbkl
  1922.     movei t1, [flddb. .cmfil]
  1923.     call cfield
  1924.     movem t2, pars3        ; Here's the JFN just parsed.
  1925.     ret
  1926.  
  1927. ; LOCAL DIRECTORY command execution.
  1928.  
  1929.  
  1930. ; Set up.
  1931.  
  1932. $ydire:    setzm ffunc        ; Function is "directory".
  1933. $ydir1:    move t2, pars3        ; Here's the JFN.
  1934.     setzm filjfn        ; Make sure no one thinks this is in use.
  1935.     call dirhdr        ; Do the header first.
  1936.  
  1937. ; File-listing loop
  1938.  
  1939. $ydir2:    call dmpbuf        ; Get some directory listing.
  1940.     call dirlst        ; Print it.
  1941.      jumpn t1, $ydir2    ; Go back for more.
  1942.  
  1943.     ret            ; Till done.
  1944.  
  1945. ; DIRHDR
  1946. ;
  1947. ; Put directory listing header in string buffer.
  1948. ; Initializes buffer pointers, counters, etc.
  1949. ; Call with t2/ JFN of files to list.
  1950. ; Returns +1 always.
  1951. ;
  1952. dirhdr:    movem t2, ndxjfn    ; Save wildcard bits.
  1953.     hrrzm t2, nxtjfn    ; Initialize lookahead
  1954.     setzm filcnt        ; File counter
  1955.     setom dirfin        ; Initialize directory finished flag.
  1956.  
  1957.     move t1, [point 7, srvbuf] ; Put the listing in the srving buffer.
  1958.     skipe ffunc        ; Directory listing?
  1959.      jrst dirhdx        ;  No, skip printing the heading.
  1960.  
  1961.     setom dirfin        ; Assume some error.
  1962.     move t3, [111110,,js%paf] ; dev:<dir>name.typ.gen
  1963.     JFNS
  1964.      erjmp r
  1965.     
  1966.     hrroi t2, [asciz/
  1967. Name                Pages Bytes(Size)        Creation Date
  1968. /]
  1969.     setzb t3, t4        ; Print heading.
  1970.     SOUT
  1971.  
  1972. dirhdx:    setzm dirfin        ; No error, so not finished.
  1973.     movem t1, srvptr    ; Preserve string buffer pointer.
  1974.     ret
  1975.     
  1976. ; DIRLST
  1977. ;
  1978. ; Builds a directory listing in a chunk of memory starting at
  1979. ; SRVBUF and ending at (or slightly after) SRVBZ, with pointer in SRVPTR.
  1980. ;
  1981. ; Returns +1 always, with t1/ -1 if we got some data, t1/ 0 if done.
  1982. ;
  1983. ; Keeps global file counter in FILCNT.
  1984. ;
  1985. dirlst:    setz t1,
  1986.     skipe dirfin        ; Finished?
  1987.      ret            ;  Yes.
  1988.     move t1, srvptr        ; No, there's more to do.
  1989.     hrroi t2, crlf        ; Issue a line break.
  1990.     setzb t3, t4
  1991.     SOUT
  1992.     movem t1, srvptr    ; Save the buffer pointer.
  1993.     call gtnfil        ; Get next file.
  1994.      jrst dirlsz        ;  If none, done.
  1995.     aos filcnt        ; Got one, count it.
  1996.  
  1997. ;[133] Get detailed size info from FDB.
  1998.  
  1999.     hrrzs t1, t1        ; Get rid of any flags.
  2000.     move t2, [3,,.fbbyv]    ; Get size info from FDB.
  2001.     movei t3, pagcnt    ; Put info in PAGCNT,BYTCNT,CRDATE
  2002.     GTFDB            ; which are adjacent in the data area.
  2003.      erjmp dirlsz
  2004.     move t2, t1        ; Put JFN in t2 for JFNS below.
  2005.  
  2006. ;[122] The rest of this routine rewritten to provide nice columnar listing.
  2007.  
  2008.     move t1, [ascii/     /]    ; Fill the filename buffer with blanks.
  2009.     movem t1, filbuf
  2010.     move t1, [filbuf,,filbuf+1]
  2011.     blt t1, filbfz-1
  2012.  
  2013.     move t1, [point 7, filbuf] ; Now start filling in the fields.
  2014.     move t3, [001110,,<js%tmp!js%paf>] ; First the filename.
  2015.     JFNS
  2016.      erjmp dirlsz
  2017.     skipe ffunc        ; What was the file function?
  2018.      jrst dirls2        ;  Not directory, so skip the rest.
  2019.     ;...
  2020.  
  2021. ;...DIRLST, cont'd
  2022.  
  2023.  
  2024. ; For real directory listing, include file size and creation date.
  2025.  
  2026. dirlsm:    move t4, t2        ; Save file JFN in t4 for a while...
  2027.     movei t3, 40        ; Put a blank over the null left by JFNS.
  2028.     idpb t3, t1
  2029.     hrrz t2, t1        ; Get address from updated pointer.
  2030.     caige t2, filbuf+4    ; Name stayed within its field?
  2031.      jrst [    move t1, [point 7, filbuf+4] ; Yes, advance to next field.
  2032.         movx t3, <no%lfl!no%ast!fld(5,no%col)!fld(^d10,no%rdx)>
  2033.         jrst dirlsa ]    ;  Use right-adjusted number format.
  2034.     movei t2, 40        ; No, do free format.
  2035.     idpb t2, t1        ; Deposit a blank, advance pointer.
  2036.     movei t3, ^d10        ; No fixed-field stuff on page count.
  2037.  
  2038. ;[133] More detailed info about size: pages, byte count, byte size.
  2039.  
  2040. dirlsa:    hrrz t2, pagcnt        ; Number of pages in file.
  2041.     NOUT
  2042.      erjmp dirlsz
  2043.     movei t3, 40        ; A blank
  2044.     idpb t3, t1
  2045.     move t2, bytcnt        ; Byte count, free format.
  2046.     movei t3, ^d10
  2047.     NOUT
  2048.      erjmp dirlsz
  2049.     movei t3, "("        ; Byte size, in parens.
  2050.     idpb t3, t1
  2051.     ldb t2, [pointr (pagcnt,fb%bsz)]
  2052.     movei t3, ^d10
  2053.     NOUT
  2054.      erjmp dirlsz
  2055.     movei t3, ")"
  2056.     idpb t3, t1        ;[133](end) Closing parens.
  2057.  
  2058.     hrrz t3, t1        ; Same deal to advance to date field.
  2059.     caige t3, filbuf+11
  2060.      jrst [    move t1, [point 7, filbuf+11]
  2061.         jrst dirlsb ]
  2062.     movei t2, 40        ; Put in a blank to separate.
  2063.     idpb t2, t1
  2064.  
  2065. dirlsb:    move t2, t4        ; File JFN again.
  2066.     movei t3, js%cdr    ; Get the creation date.
  2067.     JFNS
  2068.      erjmp dirlsz
  2069.  
  2070. dirls2:    setz t3,        ; Done with this line, make it asciz.
  2071.     idpb t3, t1    
  2072.     ;...
  2073.  
  2074. ; DIRLST, cont'd
  2075.  
  2076.  
  2077. ; Copy the result into the server sending buffer.
  2078.  
  2079.     move t4, [point 7, filbuf] ; Source pointer
  2080.  
  2081. dirlsc:    ildb t3, t4        ; Copy loop
  2082.     jumpe t3, dirlsx
  2083.     idpb t3, srvptr
  2084.     jrst dirlsc
  2085.  
  2086. ; Still expect to have file jfn in t2 when we get here.
  2087.  
  2088. dirlsx:    skipe t1, ffunc        ; What is the function?
  2089.      call (t1)        ;  Not directory, so go do selected function.
  2090.     move t1, srvptr
  2091.     hrrz t2, t1        ; See if buffer full.
  2092.     cail t2, srvbz
  2093.      jrst [ seto t1,    ; Return indicating we have data.
  2094.         ret ]
  2095.     jrst dirlst        ; Loop
  2096.  
  2097. ; Done, print summary.
  2098.  
  2099. dirlsz:    move t1, srvptr        ; Get the buffer pointer.
  2100.     movei t2, " "        ; Summary.  First a space.
  2101.     BOUT
  2102.     move t2, filcnt        ; Then the number of files.
  2103.     movei t3, ^d10
  2104.     NOUT
  2105.      erjmp .+1
  2106.     setzb t3, t4
  2107.     hrroi t2, [asciz/ files
  2108. /]
  2109.     sosn filcnt        ; Do singular or plural right.
  2110.      hrroi t2, [asciz/ file
  2111. /]
  2112.     SOUT
  2113.     movem t1, srvptr    ; Save pointer.
  2114.     seto t1,        ; Say we're returning data.
  2115.     setom dirfin        ; Set finished flag for next time through.
  2116.     ret
  2117.  
  2118. ;[115] DMPBUF
  2119. ;
  2120. ; Dump the buffer.
  2121. ;
  2122. ; Call with SRVPTR/ current pointer (to end of string to be dumped)
  2123. ; Returns +1 with t1/ new pointer.  Uses t2.
  2124. ;
  2125. ; Dumps the buffer starting from SRVBUF thru present position,
  2126. ; resets pointer SRVPTR to beginning of SRVBUF.
  2127. ;
  2128. dmpbuf:    move t1, srvptr        ; Get current pointer.
  2129.     setz t2,
  2130.     idpb t2, t1        ; Make sure string is asciz.
  2131.     move t1, [point 7, srvbuf] ; Point to buffer
  2132.     movem t1, srvptr    ; Save new pointer.
  2133.     skipn srvflg        ; Am I a server?
  2134.      PSOUT            ;  If not, print it.
  2135.     setzm srvbuf        ; Clear it.
  2136.     move t1, [srvbuf,,srvbuf+1]
  2137.     blt t1, srvbzz
  2138.     move t1, srvptr        ; Return pointer in t1.
  2139.     ret
  2140.  
  2141. ;[113] LOCAL DELETE
  2142. ;
  2143. ; LOCAL DELETE
  2144. ;
  2145. hdele:    asciz |
  2146. DELETE filespec
  2147.  
  2148.   DELETE is the same as LOCAL DELETE.  It works like the DEC-20 DELETE command,
  2149.   except that if you SET EXPUNGE ON, then all files that you delete with
  2150.   KERMIT, whether with interactive DELETE commands, or via REMOTE DELETE
  2151.   commands when KERMIT-20 is running as a server, will also be automatically
  2152.   expunged.
  2153. |
  2154. ; Default filespec fields for .CMFIL:
  2155.  
  2156. delbk:    gj%old!gj%ifg!gj%flg!.gjall ; Flag bits,,generation number.
  2157.     .priin,,.priou        ; COMND i/o.
  2158.     repeat 6,<0>        ; No defaults, except all generations.
  2159. delbkl==<.-delbk>        ; Length of this GTJFN argument block.
  2160.  
  2161. .ydele:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  2162.     CLZFF
  2163.     noise <files>        ; Issue guide words.
  2164.     move t1, [delbk,,cjfnbk] ; Insert our file parsing defaults.    
  2165.     blt t1, cjfnbk+delbkl
  2166.     movei t1, [flddb. .cmfil]
  2167.     call cfield
  2168.     movem t2, pars3        ; Here's the JFN just parsed.
  2169.     ret
  2170.  
  2171. ;[118] LOCAL DELETE command execution.
  2172.  
  2173. $ydele:    movei t2, delfil    ; Address of delete-file code.
  2174.     movem t2, ffunc        ; Make it the file function.
  2175.     callret $ydir1        ; Go do it like a directory.
  2176.  
  2177. ;[118] DELFIL - Routine to delete a file.
  2178.  
  2179. delfil:    move t1, t2        ; Put the JFN in the right place.
  2180.     skipe expung        ;[143] Expunging automatically?
  2181.      txo t1, df%exp        ;[143] Yes, set the bit.
  2182.     DELF            ; Try to delete it.
  2183.      jrst [    move t1, srvptr ; Error, record the message
  2184.         hrroi t2, [asciz/: /]
  2185.         setzb t3, t4
  2186.         SOUT
  2187.          erjmp .+1
  2188.         hrloi t2,.fhslf    ; This fork ,, last error.
  2189.         setz t3,
  2190.         ERSTR
  2191.          nop
  2192.          nop
  2193.         sos filcnt    ; "Uncount" this file, it wasn't deleted.
  2194.         jrst delf2 ]
  2195.     
  2196.     move t1, srvptr        ; Confirmation message.
  2197.     hrroi t2, [asciz/ [OK]/]
  2198. delf2:    setzb t3, t4
  2199.     SOUT
  2200.      erjmp r
  2201.     movem t1, srvptr    ; Update the string pointer.
  2202.     ret            ; Done
  2203.  
  2204. ; LOCAL SPACE
  2205. hspace:    asciz |
  2206. SPACE is the same as LOCAL SPACE.  It tells the number of disk pages allowed
  2207. and used in the current local directory.
  2208. |
  2209.  
  2210. .ydisk:    noise <usage query>
  2211.     confrm
  2212.     ret
  2213.  
  2214. $ydisk:    seto t1,        ; local disk usage query.
  2215.     GTDAL%
  2216.      %jserr (,r)
  2217.     dmove q1, t1
  2218.     cail t1, [^d100000000]
  2219.      jrst [    tmsg <
  2220.  Quota: +Inf>
  2221.         jrst $ydsk3 ]
  2222.  
  2223. $ydsk2:    tmsg <
  2224.  Quota: >
  2225.     numout q1
  2226.  
  2227. $ydsk3:    tmsg <, used: >
  2228.     numout q2
  2229.     tmsg < (pages)>
  2230.     ret
  2231.  
  2232. ; LOCAL RUN
  2233.  
  2234. hrun:    asciz |
  2235. RUN [filespec]
  2236.  
  2237.   RUN is the same as LOCAL RUN.  It runs the specified file as a program in a
  2238.   fork underneath KERMIT-20.  The default file type is .EXE.  When the program
  2239.   terminates, you will be back at KERMIT-20 prompt level.  If you want to issue
  2240.   Exec commands without leaving KERMIT-20, you can RUN SYSTEM:EXEC.EXE, and
  2241.   then type POP to get back to KERMIT.  If you have already RUN a program once,
  2242.   you can run it again without the overhead of fork creation by typing the RUN
  2243.   command without an argument.
  2244. |
  2245.  
  2246. ; JFN block for RUN command.
  2247.  
  2248. runbk:    gj%old!gj%ifg!gj%flg    ; Flag bits,,most recent generation.
  2249.     .priin,,.priou        ; COMND i/o.
  2250.     repeat 3,<0>        ; No defaults, except
  2251.     -1,,[asciz/EXE/]    ;  file type.
  2252.     repeat 2,<0>        ; No defaults, except
  2253. runbkl==<.-runbk>        ; Length of this GTJFN argument block.
  2254.  
  2255. ; Parse local RUN command.
  2256.  
  2257. .yrun:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  2258.     CLZFF
  2259.     noise <file>        ; Issue guide word.
  2260.     move t1, [runbk,,cjfnbk] ; Insert our file parsing defaults.    
  2261.     blt t1, cjfnbk+runbkl    ; Same as for DELETE.
  2262.     movei t1, [flddb. .cmfil]
  2263.     skipe rufork        ; Already have a fork?
  2264.      movei t1, [        ;  Yes, let them rerun it.
  2265.         flddb. .cmfil,cm%sdh,,<name of program to run,
  2266.  or carriage return to re-run the program you ran last time>,,[
  2267.         flddb. .cmcfm,cm%sdh ]]
  2268.     call rfield        ; Parse a directory specification.
  2269.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  2270.     cain t3, .cmcfm        ; Confirmation?
  2271.      jrst [    setom pars3    ; Yes, set "jfn" to -1.
  2272.         ret ]
  2273.  
  2274.     hrrzm t2, pars3        ; No, real JFN, save it.
  2275.     confrm            ; Get confirmation.
  2276.     ret
  2277.  
  2278. ; Execute local RUN command.
  2279.  
  2280. $yrun:    skipg pars3        ; Re-run current fork?
  2281.      jrst $yrun2        ;  Yes, do do that.
  2282.     skiple t1, rufork    ; No, do we have a current fork to kill?
  2283.      KFORK            ;  Yes, try to kill it.
  2284.      erjmp .+1
  2285.     setz t1,        ; Take care of capabilities below.
  2286.     setzm t2
  2287.     CFORK            ; Make a fork.
  2288.      %jserr <Can't create run fork>,r
  2289.     movem t1, rufork    ; Remember the fork handle.
  2290.     move t2, capas        ;[169] Get our capabilities.
  2291.     txz t2, sc%log        ;[169] Inferior has same ones,
  2292.     txo t2, sc%gtb        ;[169] but with GETAB capability (for Exec),
  2293.     move t3, t2        ;[169] and no logout!
  2294.     EPCAP            ;[169]  ...
  2295.      erjmp .+1        ;[169]  ...
  2296.     hrlzs t1        ; Move handle into left half.
  2297.     hrr t1, pars3        ; JFN in right half.
  2298.     setzm t2        ; Nothing special.
  2299.     GET            ; Get the file to run.
  2300.      %jserr <Can't GET program to run>,r
  2301.     move t1, pars3        ; Got the file, now can release its JFN.
  2302.     RLJFN
  2303.      erjmp .+1
  2304.  
  2305. ; Can come straight here to re-run current fork.
  2306.  
  2307. $yrun2:    skipg t1, rufork    ; Get fork handle.
  2308.      ermsg <No fork to run>,r ; Make sure it's ok.
  2309.     setz t2,        ; Primary start address.
  2310.     SFRKV            ;  Start it up.
  2311.      %jserr <Can't start run fork>,r
  2312.     WFORK            ; wait for the fork to halt.
  2313.      %jserr <Can't wait for run fork>,r
  2314.  
  2315.     ret
  2316.  
  2317. ;[165] TRANSMIT
  2318. htrans:    asciz |
  2319.  
  2320. TRANSMIT filespec [prompt]
  2321.  
  2322.   For use in local mode only.  Sends the specified text file a line at a time
  2323.   to the remote system, waiting for the specified prompt for each line.  Kermit
  2324.   protocol is not used; the file is sent "raw".  The prompt is any string, for
  2325.   instance the prompt of a line editor in text insertion mode.  The prompt
  2326.   string may include special characters by preceding their octal ASCII values
  2327.   with a backslash, e.g. \15 for carriage return.  Only a single file may be
  2328.   sent, no wildcards allowed in the filespec.
  2329.  
  2330.   If a prompt string is supplied, alphabetic case will be ignored in searching
  2331.   for it unless you SET INPUT CASE OBSERVE.  If a prompt string is not
  2332.   supplied, then linefeed will be used by default, unless you have performed
  2333.   a SET HANDSHAKE command, in which case the handshake character will be used.
  2334.   If you really want to send the entire file without looking for any prompts,
  2335.   specify a prompt of "\0" (ASCII zero, null) (not recommended).
  2336.  
  2337.   The file will be sent using the current settings for duplex, parity, and flow
  2338.   control.  There are no timeouts on input, as there are with the INPUT
  2339.   command.  The TRANSMIT command waits forever for each prompt to appear.  You
  2340.   may use the following controls during TRANSMIT:
  2341.  
  2342.   Carriage Return - Send the next line immediately, even if the prompt hasn't
  2343.             appeared.
  2344.   Control-P       - Resend the previous line.
  2345.   Control-C       - Typed two or three times will cancel the TRANSMIT command
  2346.                      and return you to the Kermit-20> prompt.
  2347. |
  2348. .trans:    noise <file>        ; Prompt for file name.
  2349.     movei t1, [flddb. .cmifi]
  2350.     call rfield
  2351.     movem t2, pars2        ; Save the JFN
  2352.     noise <using prompt>    ; Prompt for prompt...
  2353.     movei t1, [flddb. .cmtxt,cm%sdh,,<Remote system's line input prompt,
  2354. use \ooo (backslash followed by octal digits) to include control characters,
  2355. \\ to include a single backslash>] ; No default, supplied in action routine.
  2356.     call cfield        ; Get prompt string into atom buffer.
  2357.     ret
  2358.  
  2359. ; TRANSMIT command execution.
  2360.  
  2361.  
  2362. $trans:    move t1, pars2        ; First make sure we can open the file.
  2363.     movem t1, filjfn
  2364.     movx t2, fld(7,of%bsz)!of%rd ; 7-bit read access.
  2365.     OPENF
  2366.      %jserr (,r)
  2367.     call getss        ; Get & decode prompt (search) string.
  2368.     skipe strc        ; Was there one?
  2369.      jrst $tran2        ;  Yes, use it.
  2370.     setzm strbuf        ; No, then supply an appropriate default.
  2371.     move t2, [point 7, strbuf]
  2372.     skipn t1, handsh    ; Handshaking?
  2373.      movei t1, .chlfd    ;  No, then use linefeed.
  2374.     idpb t1, t2        ; Deposit what we have
  2375.  
  2376. $tran2:    call dobits        ; Condition the line.
  2377.      jrst $tranx
  2378.     call ccon        ; Turn on ^C trap
  2379.      jrst $tranx        ; Where to go upon ^C.
  2380.     call ttyob        ; Let controlling tty output binary.
  2381.     movei t1, $tran3    ; Where to go if ^M typed (send next)
  2382.     movem t1, cmloc        ;  ...
  2383.     movei t1, $tran4    ; Where to go if ^P typed (resend previous)
  2384.     movem t1, cploc        ;  ...
  2385.     call cmpon        ; Enable interrupts on ^M, ^P.
  2386.     tmsg <
  2387. [KERMIT-20: Transmitting >    ; Tell user we're starting.
  2388.     movei t1, .priou
  2389.     move t2, filjfn
  2390.     setz t3,
  2391.     JFNS
  2392.      erjmp .+1
  2393.     tmsg <
  2394.  If stuck, type:
  2395.  Carriage Return to send next line,
  2396.  ^P to resend current line,
  2397.  ^C^C to cancel.  Here goes...]
  2398. >
  2399.     ;...
  2400.  
  2401. ; Get a line from the file.
  2402.  
  2403. $tran3:    skipe cmseen        ; ^M typed?
  2404.      jrst [    tmsg < Sending next...]
  2405. >                ; Yes, type msg
  2406.         setzm cmseen    ; and unset flag.
  2407.         jrst .+1 ]
  2408.  
  2409.     move t1, filjfn        ; Input file pointer
  2410.     move t2, [point 8, strbf2] ; Where to put the line
  2411.     movei t3, ^d512        ; Maximum characters to read
  2412.     movei t4, .chlfd    ; but preferably terminate on linefeed.
  2413.     SIN
  2414.      erjmp [movei t1, .fhslf ; Get last process error.
  2415.         GETER        ; Test for eof.
  2416.         hrrzs t2    ; Erase fork handle from left half.
  2417.         caie t2, iox4    ; Was error EOF?
  2418.          %ermsg (,$tranx) ; No, give message.
  2419.         tmsg <
  2420. [KERMIT-20: Transmit Complete.]
  2421. >                ; Yes, reassure.
  2422.         jrst $tranx ]
  2423.     ldb t4, t2        ; Was last char a LF?
  2424.     caie t4, .chlfd
  2425.      ibp t2            ; If not, don't overwrite it.
  2426.     setz t4,        ; Deposit a null, overwriting
  2427.     dpb t4, t2        ;  last char if it was a LF.
  2428.     ;...
  2429.  
  2430. ; TRANSMIT, cont'd...  Echo the string if necessary.
  2431.  
  2432. $tran4:    skipe cpseen        ; ^P typed?
  2433.      jrst [    tmsg < - Resending...
  2434. >                ; Yes, type msg
  2435.         setzm cpseen    ; and unset flag.
  2436.         jrst .+1 ]
  2437.  
  2438.     move t1, [point 8, strbf2] ; Point to the string.
  2439.     move t2, t1        ; Here too.
  2440.     skipn duplex        ; Half duplex?
  2441.      jrst $tran5        ;  No.
  2442.     PSOUT            ; Yes, display it at the tty.
  2443.     movei t1, .chlfd    ; Also need to add linefeed.
  2444.     PBOUT
  2445.  
  2446. ; Tack on desired parity, in place.
  2447.  
  2448.     move t2, [point 8, strbf2] ; Point to the string.
  2449.  
  2450. $tran5:    ildb t1, t2        ; Get a byte.
  2451.     jumpe t1, $tran6    ; If null, done.
  2452.     call @parity        ; Set parity bit.
  2453.     dpb t1, t2        ; Put it back.
  2454.     jrst $tran5        ; Back for more.
  2455.  
  2456. ; Send the string
  2457.  
  2458. $tran6:    move t1, netjfn        ; ... out the communication line.
  2459.     move t2, [point 8, strbf2]
  2460.     setzb t3, t4
  2461.     SOUT
  2462.      %jserr (,$tranx)
  2463.  
  2464. ; Now wait for prompt.
  2465.  
  2466. $tran7:    move t4, [point 7, strbuf] ; Point to string buffer.
  2467.  
  2468. $tran8:    ildb t3, t4        ; Get first character of search string.
  2469.     jumpe t3, $tran3    ; If no more then we have the prompt.
  2470.     move t1, netjfn        ; Get char from line.
  2471.     setz t2,
  2472.     BIN
  2473.      %jserr (,$tranx)
  2474.     andi t2, ^o177        ; Strip any parity.
  2475.     movei t1, .priou    ; Echo it.
  2476.     BOUT
  2477.     skipn incase        ; Case sensitive compare?
  2478.      jrst [    cail t2, "a"    ;  No, fold.
  2479.          caile t2, "z"
  2480.          skipa
  2481.          txz t2, 40
  2482.         jrst .+1 ]
  2483.     camn t2, t3        ; Match?
  2484.      jrst $tran8        ;  Yes, get next.
  2485.     jrst $tran7        ; No, rewind search string, then get next.
  2486.  
  2487. ; Done, call terminal restore routines in reverse order.
  2488.  
  2489. $tranx:    call cmpoff        ; ^M, ^P interrupts off.
  2490.     call ttyou        ; Restore controlling tty.
  2491.     call ccoff2        ; ^C trap off.
  2492.     call unbits        ; Put line back to previous state.
  2493.     movei t1, .priin    ; Flush any junk they may have typed
  2494.     CFIBF
  2495.      erjmp .+1
  2496.     move t1, filjfn        ; Close the file.
  2497.     CLOSF
  2498.      %jserr (,$tranz)
  2499.     skipa
  2500. $tranz:    RLJFN            ; Release the JFN.
  2501.      erjmp .+1
  2502.     setzm filjfn        ; Zero the JFN holder.
  2503.     ret
  2504.  
  2505. ;[143] LOCAL TYPE
  2506. htype:    asciz |
  2507. TYPE filespec
  2508.  
  2509.   TYPE is the same as LOCAL TYPE.  It types the specified file or files at your
  2510.   terminal.  Unlike the DEC-20 TYPE command, it will try to do input from each
  2511.   file based on its byte size.  Also, Control-O output suppression applies only
  2512.   on a per-file basis.
  2513. |
  2514. typbk:    gj%old!gj%ifg!gj%flg    ; Flag bits,,most recent generation.
  2515.     .priin,,.priou        ; COMND i/o.
  2516.     repeat 6,<0>        ; No defaults, except all generations.
  2517. typbkl==<.-typbk>        ; Length of this GTJFN argument block.
  2518.  
  2519. .ytype:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  2520.     CLZFF
  2521.     noise <files>        ; Issue guide words.
  2522.     move t1, [typbk,,cjfnbk] ; Insert our file parsing defaults.    
  2523.     blt t1, cjfnbk+typbkl    ; Same as for DELETE.
  2524.     movei t1, [flddb. .cmfil]
  2525.     call cfield
  2526.     movem t2, pars3        ; Here's the JFN just parsed.
  2527.     ret
  2528.  
  2529. ; LOCAL TYPE command execution.
  2530.  
  2531.  
  2532. $ytype:    move t1, pars3        ; Get the JFN.
  2533.     setzm filjfn        ; Set up for file stepping.
  2534.     movem t1, ndxjfn
  2535.     hrrzm t1, nxtjfn
  2536.     call ccon        ;[169] Allow ^C out of this.
  2537.      jrst [    move t1, filjfn ;[169] Upon ^C, close the file.
  2538.         CLOSF        ;[169]
  2539.          erjmp $ytypz    ;[169]
  2540.         jrst $ytypz ]    ;[169] And quit
  2541. $ytyp2:    call gtnfil        ; Any more?
  2542.      jrst $ytypz        ;  No, done.
  2543.     push p, t1        ; Yes, save the JFN for a sec.
  2544.     tmsg <
  2545. >
  2546.     movei t1, .priou    ; Turn off any Control-O
  2547.     RFMOD
  2548.     txz t2, tt%osp
  2549.     SFMOD
  2550.     move t2, (p)        ; Say the name.
  2551.  
  2552.     setz t3,    
  2553.     JFNS
  2554.      erjmp .+1
  2555.     tmsg <
  2556.  
  2557. >
  2558.     pop p, t1        ; Restore the JFN.
  2559.     move t2, [1,,.fbbyv]    ; Get bytesize.
  2560.     movei t3, t4
  2561.     setz t4,
  2562.     GTFDB
  2563.      erjmp .+1
  2564.     movx t2, of%rd+fld(7,of%bsz) ; Assume 7-bit mode.
  2565.     ldb t3, [pointr (t4,fb%bsz)] ; Extract the bytesize.
  2566.     cain t3, ^d8        ; 8 bit?
  2567.      movx t2, of%rd+fld(^d8,of%bsz) ; Yes, 8-bit.
  2568.     OPENF            ; Open the file in appropriate mode.
  2569.      %jserr (,$ytyp2)    ; Report any errors.
  2570.     call typfil        ; Type the file
  2571.     move t1, filjfn        ; Close the file.
  2572.     CLOSF
  2573.      nop
  2574.     jrst $ytyp2        ; Go back back for another.
  2575.  
  2576. $ytypz:    tmsg <
  2577. >
  2578.     call ccoff
  2579.     ret            ; No more, done.
  2580.  
  2581. ; Routine to type a file at the local terminal.
  2582. ;
  2583. ; Type the file whose JFN is in FILJFN.  Return +1 always.
  2584. ;
  2585. typfil:    saveac<t1,t2,t3>
  2586.  
  2587.     setz t4,        ; EOF flag.
  2588.  
  2589. typfi2:    jumpl t4, r        ; EOF yet?
  2590.     move t1, filjfn        ; No, get JFN of the file.
  2591.     hrroi t2, strbuf    ; Get a bufferfull.
  2592.     movni t3, <strbln-1>    ; This many characters, leave room for null.
  2593.     setz t4,
  2594.     SIN
  2595.      erjmp [ setom t4
  2596.          jrst .+1 ]
  2597.     movei t1, .priou    ; Type what we got.
  2598.     hrroi t2, strbuf
  2599.     addi t3, <strbln-1>
  2600.     movns t3        ; Exactly this many.
  2601.     SOUT
  2602.     jrst typfi2        ; Go back for more.
  2603.  
  2604. ; REMOTE command help text.
  2605.  
  2606.  
  2607. hremot:    asciz |
  2608. REMOTE option
  2609.  
  2610. Ask the KERMIT server on the other end of the connection to execute a command
  2611. on its own system.  This command won't work unless you are running in local
  2612. mode (you have SET LINE n) and the KERMIT on the other end is running as a
  2613. server.
  2614.  
  2615. Options include:
  2616.  
  2617.  CWD            Change Working Directory (connect).
  2618.  DELETE filespec    Delete a file or file group.
  2619.  DIRECTORY filespec    Send a directory listing.
  2620.  HOST command        To be executed by remote system's command processor.
  2621.  SPACE             Disk usage query.
  2622.  TYPE filesec        Type a file or file group at the terminal.
  2623. |
  2624.  
  2625. $remot:    ; REMOTE and LOCAL command dispatcher...
  2626.  
  2627.     skipe takdep        ;[177] OK from TAKE file
  2628.      jrst $local        ;[177]
  2629.     skipn local
  2630.      jrst [    tmsg <?Must SET LINE before issuing a REMOTE command>
  2631.         ret ]
  2632.  
  2633. $local:    move t2, pars2        ; Get back data value.
  2634.     hrrz t1, (t2)        ; Get evaluation routine.
  2635.     call (t1)        ; Call it.
  2636.     ret
  2637.  
  2638. ; REMOTE CWD Parsing
  2639.  
  2640.  
  2641. .xcwd:    setzm pasbuf        ; Zero this out.
  2642.     setzm pasbuf+1        ;  ...
  2643.     noise <to directory>    ; Issue guide words.
  2644.     movei t1, [
  2645.      flddb. .cmtxt,cm%sdh,,<directory or area on server file system,
  2646.  or carriage return for default area>]
  2647.     call cfield        ; Parse a string.
  2648.     setzm pars3        ; Assume they didn't give an area.
  2649.     move t2, [point 7, atmbuf] ; Did they give one?
  2650.     ildb t1, t2
  2651.     jumpe t1, r        ; No, done.
  2652.  
  2653.     call getpas        ; They did, ask for password.
  2654.     movem t1, pars3        ; Save pointer to it.
  2655.     ret            ; Done.
  2656.  
  2657. ;[106] REMOTE CWD Execution
  2658.  
  2659.  
  2660. $xcwd:
  2661. $xcwd2:    setzm strbuf        ; Zero out old stuff
  2662.     setzm strbuf+1
  2663.     move t1, [point 7, atmbuf] ;  Copy directory name from here
  2664.     move t2, [point 7, strbuf] ;  to here.
  2665.  
  2666.     movei t4, "C"        ; CWD generic command.
  2667.     idpb t4, t2
  2668.     ibp t2            ; Leave room for length.
  2669.  
  2670.     setz t3,        ; Counter.
  2671. $xcwd3:    ildb t4, t1        ; Copy the directory string.
  2672.     jumpe t4, $xcwd4
  2673.     idpb t4, t2
  2674.     aoja t3, $xcwd3
  2675.  
  2676. ; Note that lengths here apply to UNPREFIXED values.  If a length turns out to
  2677. ; be the same as a prefix character, it will be quoted itself.
  2678.  
  2679. $xcwd4:    move t4, [point 7, strbuf, 13] ; Deposit count at head of field.
  2680.     addi t3, 40        ; Make it printable.
  2681.     dpb t3, t4
  2682.     skipn pars3        ; Got a password too?
  2683.      jrst $xcwdz        ;  No.
  2684.  
  2685. $xcwd5:    movem t2, strptr    ; Yes.  Save current pointer.
  2686.     ibp t2            ; Save a place for length of this field.
  2687.     setz t3,        ; Reset counter for new field.
  2688.     move t1, pars3
  2689.  
  2690. $xcwd6:    ildb t4, t1        ; Get a character.
  2691.     jumpe t4, $xcwd7    ; If zero, done.
  2692.     idpb t4, t2        ; Deposit it.
  2693.     aoja t3, $xcwd6        ; Count it & loop.
  2694.  
  2695. $xcwd7:    idpb t4, t2        ; Make it asciz.
  2696.     addi t3, 40        ; Make count printable.
  2697.     idpb t3, strptr        ; Deposit it at head of field.
  2698.  
  2699. $xcwdz:    move t1, [point 7, strbuf] ; Point to it.
  2700.     movei t2, "G"        ; Packet type is H.
  2701.     jrst dosrv        ; Go send it and handle the reply.
  2702.  
  2703. ; REMOTE DELETE, DIRECTORY, TYPE parsing -- Parse a remote filespec.
  2704.  
  2705. .rmfil:    noise <remote files>    ; Parse the rest of the command.
  2706.     movei t1, [flddb. .cmtxt,cm%sdh,,<remote file specification>]
  2707.     call cfield
  2708.     ret
  2709.  
  2710. ; REMOTE DELETE (Erase) execution
  2711.  
  2712. $xdele: movei t4, "E"        ; Generic command is E.
  2713.     jrst srvfil
  2714.  
  2715.  
  2716. ; REMOTE DIRECTORY execution
  2717.  
  2718. $xdire:    movei t4, "D"        ; Generic command is D.
  2719.     jrst srvfil
  2720.  
  2721.  
  2722. ; REMOTE TYPE command execution.
  2723.  
  2724. $xtype:    movei t4, "T"        ; Generic command is T.
  2725.     jrst srvfil
  2726.  
  2727.  
  2728. ; SRVFIL
  2729. ;
  2730. ; Common code to construct a generic one-field command.
  2731. ; Generic command is single character in t4.  Argument is in ATMBUF.
  2732. ; Puts a 1-character length field at the beginning.
  2733. ;
  2734. srvfil:    call sinfo        ;[128] Exchange parameters with I packet.
  2735.      ret            ;[133]  Failed, give up.
  2736.     setzm strbuf        ; Zero out old stuff
  2737.     setzm strbuf+1
  2738.     move t1, [point 7, atmbuf] ;  Copy directory name from here
  2739.     move t2, [point 7, strbuf] ;  to here.
  2740.  
  2741.     idpb t4, t2        ; Deposit generic command.
  2742.     ibp t2            ; Leave a space
  2743.  
  2744.     setz t3,        ; Initialize counter
  2745.  
  2746. srvfi2:    ildb t4, t1        ; Get next one.
  2747.     idpb t4, t2        ; Deposit this one.
  2748.      skipe t4        ; If null, done.
  2749.     aoja t3, srvfi2        ; Count it & loop.
  2750.  
  2751. ;*    jumpe t3, [        ; Make sure there was at least one character.
  2752. ;*        tmsg <?No file specified>
  2753. ;*        ret ]
  2754.  
  2755. srvfi3:    move t1, t3        ; Length
  2756.     addi t1, 40        ; CHAR of that.
  2757.     move t2, [point 7, strbuf, 13] ; Deposit count at head of field.
  2758.     dpb t1, t2
  2759.     move t1, [point 7, strbuf] ; Point to generic command.
  2760.     movei t2, "G"        ; Packet type is G.
  2761.     jrst dosrv        ; Go do it.
  2762.  
  2763. ; REMOTE SPACE parsing
  2764.  
  2765. .xdisk:    noise <usage query>
  2766.     confrm
  2767.     ret
  2768.  
  2769.  
  2770. ; REMOTE SPACE execution
  2771.  
  2772. $xdisk:    move t1, [point 7, [asciz/U/]] ; U command for data field.
  2773.     movei t2, "G"        ; Packet type is G.
  2774.     jrst dosrv
  2775.  
  2776.  
  2777. ; REMOTE HELP parsing
  2778.  
  2779. .xhelp:    noise <from KERMIT server>
  2780.     confrm
  2781.     ret
  2782.  
  2783. ; REMOTE HELP execution
  2784.  
  2785. $xhelp:    call sinfo        ; Exchange parameters.
  2786.      ret            ;[133] Failed, give up.
  2787.     move t1, [point 7, [asciz/H/]] ; H command for data field.
  2788.     movei t2, "G"        ; Packet type is G.
  2789.     jrst dosrv
  2790.  
  2791.  
  2792. ;[105] REMOTE HOST command.
  2793.  
  2794. .xhost:    noise <command>    ; Parse the rest of the REMOTE HOST command.
  2795.     movei t1, [
  2796.      flddb. .cmtxt,cm%sdh,,<command for server's host command processor>]
  2797.     call cfield
  2798.     ret
  2799.  
  2800. $xhost: skipe takdep        ;[176] Allow commands to servers from TAKE file
  2801.      jrst $xhos2
  2802.     skipe local        ; This only works if local Kermit.
  2803.      jrst $xhos2
  2804.     ermsg <Can't use REMOTE commands without prior SET LINE>,r
  2805.  
  2806. $xhos2:    move t1, [point 7, atmbuf] ; And move them from here
  2807.     move t2, [point 7, strbuf] ;  to here.
  2808.  
  2809. $xhos3:    ildb t4, t1        ; Copy the string.
  2810.     jumpe t4, $xhos4
  2811.     idpb t4, t2
  2812.     jrst $xhos3
  2813.  
  2814. $xhos4:    move t3, seolch        ; Terminate it with the host's eol character.
  2815.     idpb t3, t2
  2816.     idpb t4, t2        ; And a null.
  2817.  
  2818.     call ccon        ;[169] Enable ^C during this bit.
  2819.      jrst ccoff        ;[169]  Where to go if ^C happens.
  2820.     call sinfo        ; Exchange params.
  2821.      jrst ccoff        ;[169] Failed, give up, turn off ^C trap.
  2822.     call ccoff        ;[169]
  2823.     move t1, [point 7, strbuf] ; Point to command.
  2824.     movei t2, "C"        ; Packet type is C.
  2825.     jrst dosrv           ; Go send it and handle the reply.
  2826.  
  2827.  ; REMOTE ERROR -- a secret command to send a null error packet.
  2828.  
  2829. .xerr:    confrm
  2830.     ret
  2831.  
  2832. $xerr:    movei t1, "E"        ; Send an error packet.
  2833.     move t2, pktnum
  2834.     setzb t3, t4
  2835.     call spack
  2836.      nop
  2837.     ret
  2838.  
  2839.  
  2840.  
  2841.  
  2842. ; DOSRV
  2843. ;
  2844. ; Call this exactly like SRVCMD.
  2845. ;
  2846. ; Send a command to a server and dispatch appropriately depending on the reply.
  2847. ;
  2848. dosrv:    setzm gotx        ; Clear flags: "got X packet",
  2849.     setzm gots        ;  "got S packet".
  2850.     call srvcmd        ; Send a generic command.
  2851.      ret            ;  Didn't get good response.
  2852.     cain t1, "Y"        ; Was it an ACK?
  2853.      ret            ;  Yes, so we're done.
  2854.         
  2855. ; Come here if we're about to receive a multipacket reply.
  2856.  
  2857.     caie t1, "X"        ; Text header?
  2858.      jrst dosrv3        ;  No
  2859.     setom gotx        ; Yup, flag that we already got it.
  2860.     movei state, "F"    ; State state to file receive.
  2861.     skipn t3        ;[173](begin) Any contents?
  2862.      jrst $recvb        ; No.
  2863.     push p, t1        ; Yes, print them.
  2864.     hrroi t1, crlf
  2865.     PSOUT
  2866.     move t1, pktacs+3
  2867.     PSOUT
  2868.      erjmp $recvb
  2869.     hrroi t1, crlf
  2870.     PSOUT
  2871. dosrv2:    pop p, t1        ;[173](end)
  2872.     jrst $recvb        ; Go receive whatever is coming.
  2873.  
  2874. dosrv3:    cain t1, "S"        ; Or Send-Init?
  2875.      jrst [    setom gots    ; Yes, flag that we already got it.
  2876.         movei state, "R" ; Set state to receive init.
  2877.         jrst $recvb ]    ; Go receive what's coming.
  2878.  
  2879.     ermsg <Unexpected packet type returned by SRVCMD>,r
  2880.  
  2881. ; SRVCMD
  2882. ;
  2883. ; Routine to send a command to a server.
  2884. ; Call with:
  2885. ;  t1/ Byte pointer to string.
  2886. ;        First character is Generic Command, subsequent chars are arguments.
  2887. ;  t2/ Packet type, e.g. "G" for Generic, "C" for Host Command.
  2888. ;
  2889. ; Returns:
  2890. ;  +1 if reply was not received successfully.
  2891. ;  +2 If we got a good response, with
  2892. ;     t1/ packet type of response, "Y", "X", or "S".
  2893. ;     PKTACS/ Block of 4 words containing the data returned by RPACK.
  2894. ;
  2895. ;     If packet was ACK containing data, this routine prints it.
  2896. ;
  2897. srvcmd: skipe takdep        ;[176] Allow commands to servers from TAKE file
  2898.      jrst srvxx
  2899. srvxx:    saveac <q1,q2>        ; Preserve these work registers.
  2900.     dmove q1, t1        ; Copy arguments into them.
  2901.     skipn local        ;[177] Local Kermit?
  2902.      call inilin        ;[177] No, set TTY: up for packets.
  2903.     setzm numtry        ; Reset retry counter.
  2904.     setzm nnak        ; Init some statistics counters
  2905.     setzm ntimou        ;  ...
  2906.     setom bctone        ; Force 1-char checksum.
  2907.     move t1, netjfn        ; Clear out any stacked-up NAKs
  2908.     CFIBF%            ;
  2909.      %jserr (,.+1)        ; Give warning in case there's a problem.
  2910.     call ccon        ; Let them ^C out gracefully
  2911.      jrst srvcmx        ;  and go here if they do.
  2912.  
  2913.     call setlog        ; Set up any debugging log.
  2914.      nop
  2915.  
  2916. ; Put the command into the data field of the packet, using the normal
  2917. ; packet-filling technique, prefixing, etc.
  2918.  
  2919.     setzm data        ; Zero the buffer.
  2920.  
  2921. srvcma:    movei t1, gtsch        ; Indicate routine to be used for getting
  2922.     movem t1, source    ;  characters.
  2923.     movem q1, strptr    ; And where it should get them from.
  2924.     setom next        ; Set initial condition.
  2925.     move t1, maxdat        ; Get a buffer full of data.
  2926.     call getbuf        ; ...
  2927.      jumpn t1, srvcmx    ;  Clean up if this fails.
  2928.     setzm source        ; Got it, so put GETCH back to normal.
  2929.  
  2930.     movem t1, gclen        ; Save length.
  2931.     jumpn t1, srvcm2    ; Proceed if we got any.
  2932.  
  2933.     ermsg <No data for generic command>, srvcmx ; Do this otherwise.
  2934.     ;...
  2935.  
  2936. ;...SRVCMD, cont'd
  2937.  
  2938.  
  2939. ; Top of try-again loop.
  2940.  
  2941. srvcm2:    move q1, numtry        ; Too many tries?
  2942.     caml q1, maxtry
  2943.      ermsg <Can't send generic command, max tries exceeded>,srvcmx
  2944.     aos numtry        ; Not too many, count this try.
  2945.     move t1, q2        ; Packet type.
  2946.     setz t2,        ; Make the packet number zero.
  2947.     move t3, gclen        ; Length of data.
  2948.     move t4, [point 8, data] ; Point to data block.
  2949.     call spack        ; Send it off.
  2950.      jrst @[exp srvcm2, srvcmx](t1)    ; Handle nonfatal & fatal failures.
  2951.     setzm gotx        ; Assume it'll be an ACK.
  2952.     call rpack        ; Look for response.
  2953.      ermsg <RPACK failed>,srvcm2
  2954.  
  2955.     caie t1, "X"        ; X or Y?
  2956.      cain t1, "Y"
  2957.      jrst srvcmz        ; Good.
  2958.  
  2959.     caie t1, "S"        ; S or I?
  2960.      cain t1, "I"
  2961.      jrst srvcmz        ; That's ok too.
  2962.  
  2963.     cain t1, "E"        ; Error packet?
  2964.      jrst [    hrroi t1, [asciz/?Remote error -- /] ; Yes, print it.
  2965.         PSOUT%
  2966.         move t1, t4    ; Get pointer to it,
  2967.         PSOUT%        ; and print it.
  2968.          jrst srvcmx ]    ;[70]
  2969.     caie t1, "N"        ; NAK?
  2970.      cain t1, "T"        ; Or Timeout?
  2971.      jrst srvcm2        ;  One of those, go try again.
  2972.  
  2973.     ermsg <Invalid response from server>
  2974.  
  2975. ; Exit point for any kind of error, failure, or interruption
  2976.  
  2977. srvcmx:    call ccoff        ; Turn off ^C trap.
  2978.     call caxzof        ; Turn these interrupts off too.
  2979.     skiple filjfn        ;[135] Any file left open?
  2980.      jrst [    hrrz t1, filjfn    ;  Apparently, try to close it.
  2981.         setzm filjfn
  2982.         CLOSF
  2983.          erjmp .+1
  2984.         jrst .+1 ]    ;[135](end)
  2985.     skipn local        ;[177] Put controlling TTY back to normal
  2986.      call rrsl2        ;[177] ... (entry point to reslin)
  2987.     setzm source        ; Put things back to normal.
  2988.     seto t1,        ; Indicate no good response was received.
  2989.     ret            ; Return +1.
  2990.  
  2991.     ;...
  2992.  
  2993. ;...SRVCMD, cont'd
  2994.  
  2995.  
  2996. ; Exit here when response received successfully.
  2997.  
  2998. srvcmz:    dmovem t1, pktacs    ;[112] Save the ACs returned in RPACK
  2999.     dmovem t3, pktacs+2    ;[112]  ...
  3000.     movem t2, pktnum    ; Synchronize packet numbers.
  3001.     cain t1, "Y"        ;[121] Was the reply an ACK?
  3002.      jrst [    skipg t2, t3    ;[144] Yes, any characters?
  3003.          jrst .+1    ;[144] No.
  3004.         movei t1, puttch ;[144] Routine to display decoded characters.
  3005.         movem t1, dest    ;[144] ...
  3006.         move t1, t4    ;[144] Pointer to data buffer.
  3007.         call putbuf    ;[144] Go decode it.
  3008.          nop        ;[144]
  3009.         setzm dest    ;[144]
  3010.         jrst .+1 ]
  3011.     move t1, pktacs        ;[112] Get packet type back.
  3012.     call ccoff        ; Turn off ^C trap.
  3013.     skipn local        ;[177] Put controlling TTY back to normal
  3014.      call rrsl2        ;[177] ... (entry point to reslin)
  3015.     retskp            ; Done.
  3016.  
  3017. ;[58] SINFO added as part of edit 58.
  3018. ;
  3019. ; Call this routine before sending any server command which has a nontrivial
  3020. ; response.  For instance, it should be called before requesting a remote
  3021. ; directory listing, but need not be called before sending a CWD command,
  3022. ; which normally responds with a simple ACK.
  3023. ;
  3024. ; Action: Sends an info packet with our own parameters, waits for ACK with
  3025. ; other side's.  Uses packet number 0, does not increment the packet number.
  3026. ; If other side doesn't know about I packets, this routine returns as if a
  3027. ; an ACK was received containing all default values.
  3028. ;
  3029. ; Returns:
  3030. ;  +1 on failure, maximum tries exceeded.
  3031. ;  +2 on "success" getting a reply, even if it was an error packet,
  3032. ;     with other sides parameters set.
  3033. ;
  3034. sinfo:    saveac<t3,t4>        ;[128] Save these.
  3035.     setzm numtry        ; Give it a try,
  3036.     setzm pktnum        ;  starting out with a clean slate.
  3037.     setom bctone        ;[98] Use 1-char checksum.
  3038.  
  3039.     move t1, netjfn        ; Clear out any piled up NAKs.
  3040.     CFIBF%
  3041.      %jserr (,.+1)
  3042.     
  3043.     call setlog        ; Set up any debugging log.
  3044.      nop
  3045.     movei state, "S"    ;[133] This will be a little state switcher.
  3046.  
  3047. sinfo2:    movei t1, "I"        ;[100][133] Packet type.
  3048.     setom iflg        ;[100] Say we're doing I, not S.
  3049.     call sinit        ;[100] Let SINIT send it & get reply.
  3050.     cain t1, "E"        ; Other side doesn't know I packet?
  3051.      jrst [    setzb t3, t4    ;[133] Then set defaults this way.
  3052.         call spar    ;[133]
  3053.         jrst sinfoz ]    ;[133] And return successfully.
  3054.  
  3055. ;[133] Keep going if it doesn't get thru the first time.
  3056.  
  3057.     cain state, "F"        ; Switched into F state?
  3058.      jrst sinfoz        ;  Yes, so I was ACK'd, done.
  3059.     cain state, "S"        ; Still in S state?
  3060.      jrst sinfo2        ;  So go round again.
  3061.     
  3062. sinfox:    setzm iflg        ; Must have exceeded retry limit.
  3063.     ret            ; Fail.
  3064.  
  3065. sinfoz:    setzm iflg        ;[100] Done with sending I packet.
  3066.     retskp
  3067.  
  3068.     subttl    SET command
  3069.  
  3070.  
  3071. ; SET command help text.
  3072.  
  3073. hset:    asciz |
  3074. SET parameter [option] [value]
  3075.  
  3076.   Establish or modify various parameters for file transfer or terminal
  3077.   connection.  You can examine their values with the SHOW command.  The
  3078.   following parameters may be SET:
  3079.  
  3080.   BLOCK-CHECK error detection method
  3081.   BREAK       number of nulls at 50 baud for BREAK simulation
  3082.   DEBUGGING   mode or log file
  3083.   DELAY       how long to wait before starting to send
  3084.   DUPLEX      for terminal connection, full (remote echo) or half (local echo)
  3085.   ESCAPE      character for terminal connection
  3086.   FILE        for setting file parameters like name conversion and byte size
  3087.   FLOW-CONTROL for enabling and disabling XON/XOFF flow control
  3088.   HANDSHAKE   for turning around half duplex communication line
  3089.   INCOMPLETE  what to do with an incomplete file
  3090.   INPUT       desired behavior for INPUT command
  3091.   ITS-BINARY  special format for 8-bit binary files
  3092.   LINE        TTY line to use for terminal connection or file transfer
  3093.   PARITY      character parity to use
  3094.   PROMPT      for changing the KERMIT-20 program prompt
  3095.   RECEIVE     various parameters for receiving files
  3096.   RETRY       how many times to retry a packet before giving up
  3097.   SEND        various parameters for sending files
  3098.   SPEED       set speed (baud rate) of currently selected line
  3099.   TVT-BINARY  binary mode negotiation for Internet virtual terminals
  3100.  
  3101. For further information, type "help set" followed by one of these keywords.
  3102. Also, type "help define" to see how to define "macros" for SET commands.
  3103. |
  3104.  
  3105. ;[77] Parse SET command.  (This routine rewritten for edit 77.)
  3106.  
  3107. sfdb1:    flddb. .cmkey,,mactab,<SET macro,>,,sfdb2
  3108. sfdb2:    flddb. .cmkey,,settab
  3109.  
  3110. .set:    movei t1, sfdb2        ; Normal SET command table.
  3111.     hlrz t2, mactab        ; Anything in macro table?
  3112.     skipe t2        ; If so, include them too.
  3113.      skipe definf        ; Unless we're defining a macro.
  3114.      skipa            ; Don't allow recursive definitions!
  3115.      movei t1, sfdb1    ; Macro table is searched first.
  3116.     call rfield        ; Parse a keyword.
  3117.     ;...
  3118.  
  3119. ;...SET, cont'd
  3120.  
  3121.  
  3122. .set2:    setzm macrof        ; Assume regular SET keyword was parsed.
  3123.     hrrzs t3        ; See which function descriptor block was used.
  3124.     cain t3, sfdb1        ; The macro table?
  3125.      jrst [    hrrz t1, (t2)    ; Yes, get the data.
  3126.         hrli t1, (point 7,) ; This will be a pointer to the macro text.
  3127.         movem t1, pars2    ; Save it.
  3128.         confrm        ; Get confirmation.
  3129.         setom macrof    ; Set the macro flag.
  3130.         ret ]        ; No more to do.
  3131.  
  3132.     hrrz t2, (t2)        ; Get the command routine addresses.
  3133.     movem t2, pars2        ; Save into pars2.
  3134.     hlrz t1, (t2)    ; Get the next level routine.
  3135.     call (t1)        ; Call it.
  3136.  
  3137. ; If doing a DEFINE, loop through SET commands until CR typed.
  3138.  
  3139.     skipn definf        ; Doing DEFINE?  If so, allow comma here.
  3140.      ret
  3141.     movei t1, [flddb. .cmcma,cm%sdh,,<Comma for another SET parameter>,,[
  3142.             flddb. .cmcfm]
  3143.            ]
  3144.     call rfield
  3145.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  3146.     cain t3, .cmcma        ; Comma?
  3147.       jrst .set         ;  Yes, go back & get another SET parameter.
  3148.     ret            ; Confirmation, done.
  3149.  
  3150. ; SET keyword table.
  3151.  
  3152. settab:    %table
  3153.     %key <block-check>, [xwd .setbc,$setbc] ;[98]
  3154.     %key <break>, [xwd .setbr,$setbr]
  3155.     %key <debugging>, [xwd .setdb,$setdb]
  3156.     %key <delay>, [xwd .setdl,$setdl]
  3157.     %key <duplex>, [xwd .setdu,$setdu]
  3158.     %key <escape>, [xwd .setes,$setes]
  3159.     %key <expunge>, [xwd .setex,$setex] ;[143]
  3160.     %key <file>, [xwd .setfi,$setfi]
  3161.     %key <flow-control>, [xwd .setfl,$setfl] ;[143]
  3162.     %key <handshake>, [xwd .setha,$setha] ;[76]
  3163.     %key <incomplete>, [xwd .setab,$setab]
  3164.     %key <input>, [xwd .setin,$setrs] ;[160]
  3165.     %key <ITS-binary>, [xwd .setit,$setit]
  3166.     %key <line>, [xwd .setln,$setln]
  3167.     %key <parity>, [xwd .setpa,$setpa]
  3168.     %key <prompt>, [xwd .setpr,$setpr]
  3169.     %key <receive>, [xwd .setrc,$setrs]
  3170.     %key <retry>, [xwd .setre,$setre]
  3171.     %key <send>, [xwd .setsn,$setrs]
  3172.     %key <speed>, [xwd .setxp,$setsp]
  3173.     %key <TVT-Binary>, [xwd .setta,$setta] ;[129]
  3174.     %tbend
  3175.  
  3176. ; SET command, cont'd
  3177.  
  3178. ;[98] SET BLOCK-CHECK (This command added as part of edit 98)
  3179.  
  3180. hsbc:    asciz |
  3181.  SET BLOCK-CHECK option
  3182.  
  3183.    A block check is a quantity formed by arithmetically combining all the
  3184.    characters in a packet.  The sender of the packet appends the block check
  3185.    to it, the receiver recomputes the block check and compares it with the
  3186.    one that was received.  If they don't agree, the packet is retransmitted.
  3187.    The SET BLOCK-CHECK command is used to request one of three block check
  3188.    techniques:
  3189.  
  3190.      1-CHARACTER-CHECKSUM
  3191.         The standard KERMIT 6-bit checksum, the most efficient of the three
  3192.     options, sufficient in almost every case.  This is the default.
  3193.      2-CHARACTER-CHECKSUM
  3194.         A 12-bit checksum.  Adds transmission overhead, but catches more
  3195.     errors.
  3196.      3-CHARACTER-CRC
  3197.         A 16-bit cyclic redundancy check.  Adds even more overhead, catches
  3198.     even more errors.  Only use this for very noisy connections.
  3199.  
  3200.    KERMIT-20 will request the type of block check set by this command be used
  3201.    for a transfer.  If the other KERMIT agrees (not all KERMITs know how to
  3202.    compute the 2- and 3-character block checks), then the desired block check
  3203.    type will be used.  If not, the single character checksum will be used.
  3204. |
  3205.  
  3206. .setbc:    noise <type to>        ; Issue guide words
  3207.     movei t1, [flddb. .cmkey,,bctab,,<1>] ; Parse keyword, default is "1".
  3208.     call rfield
  3209.     hrrz t2, (t2)        ; Save the value we parsed.
  3210.     movem t2, pars3
  3211.     skipn definf        ; In a DEFINE command?
  3212.      confrm            ;  No, make them type a carriage return.
  3213.     ret
  3214.  
  3215. bctab:    %table
  3216.     %key <1-character-checksum>, "1"
  3217.     %key <2-character-checksum>, "2"
  3218.     %key <3-character-crc>, "3"
  3219.     %tbend
  3220.  
  3221. ; SET BLOCK-CHECK command execution.
  3222.  
  3223. $setbc:    move t1, pars3        ; Get what was parsed.
  3224.     movem t1, bctr        ; Save it as "block check type requested".
  3225.     ret
  3226.  
  3227. ; SET command, cont'd
  3228.  
  3229. ; SET INCOMPLETE
  3230.  
  3231. hsabf:    asciz |
  3232.  SET INCOMPLETE options
  3233.    Specify what to do when a file transfer fails before it is completed.
  3234.    The options are DISCARD (the default) and KEEP.  If you choose KEEP, then if
  3235.    a transfer fails to complete successfully, you will be able to keep the
  3236.    incomplete part that was received.
  3237. |
  3238.  
  3239. .setab:    noise <file disposition> ;[42] SET INCOMPLETE (file disposition)
  3240.     movei t1, [flddb. .cmkey,,[<2,,2>
  3241.         <[asciz/discard/],,0>
  3242.         <[asciz/keep/],,1>
  3243.         ],,<discard>]
  3244.     call rfield        ; Parse & confirm.
  3245.     hrrz t2, (t2)
  3246.     movem t2, pars3
  3247.     skipn definf        ;[77] In DEFINE?
  3248.      confrm            ;[77]  No, get confirmation.
  3249.     ret
  3250.  
  3251. ; SET command, cont'd
  3252.  
  3253.  
  3254. ; SET BREAK
  3255.  
  3256. hsbrea:    asciz |
  3257.  SET BREAK n
  3258.   Specify the number of nulls to be sent at 50 baud to simulate a BREAK
  3259.   signal when connected to a remote host via SET LINE and CONNECT.
  3260. |
  3261. .setbr:    noise (nulls)
  3262.     movei t1, [
  3263.      flddb. .cmnum,,^d10,<Number of nulls at 50 baud to simulate BREAK,>]
  3264.     call rfield
  3265.     skipge t2
  3266.      jrst [ tmsg <?Number must be positive>
  3267.         jrst cmder1 ]
  3268.     caile t2, maxnul
  3269.      jrst [    tmsg <?Too many nulls, maximum is >
  3270.         numout [maxnul]
  3271.         jrst cmder1 ]
  3272.     movem t2, pars3
  3273.     skipn definf        ;[77] In DEFINE?
  3274.      confrm            ;[77]  No, get confirmation.
  3275.     ret
  3276.  
  3277. $setbr:    move t2, pars3        ; Execute SET BREAK.
  3278.     movem t2, brk
  3279.     ret
  3280.  
  3281. ; SET DEBUG
  3282.  
  3283. hsdeb:    asciz |
  3284.  SET DEBUG options
  3285.    Show packet traffic explicitly on your terminal (if local) or in a file.
  3286.    Options are:
  3287.      STATES   Show Kermit state transitions and packet numbers (brief).
  3288.  
  3289.      PACKETS  Display each incoming and outgoing packet (lengthy).
  3290.  
  3291.      OFF      Don't display debugging information (this is the default).  If
  3292.               debugging was in effect, turn it off and close any log file.
  3293.  
  3294.    To record debugging information in a file, use LOG DEBUGGING.
  3295. |
  3296.  
  3297. .setdb:    noise <option>        ; SET DEBUGGING
  3298.     movei t1, [flddb. .cmkey,,dbgtab,,states]
  3299.     call rfield        ; Parse a keyword.
  3300.     hrrz t2, (t2)        ; Get the value for the keyword.
  3301.     movem t2, pars3        ; Save into pars3.
  3302.  
  3303. .stdbx:    skipn definf        ;[77] In DEFINE?
  3304.      confrm            ;[77]  No, get confirmation.
  3305.     ret
  3306.  
  3307. dbgtab:    %table
  3308.     %key <off>, 0
  3309.     %key <packets>, 2    ;[22]
  3310.     %key <states>, 1    ;[22]
  3311.     %tbend
  3312.  
  3313. dbstab:    %table            ;[41] (this table)
  3314.     %key <7>,7
  3315.     %key <8>,8
  3316.     %tbend
  3317.  
  3318. ;...SET command, cont'd
  3319.  
  3320.  
  3321. ; SET FILE
  3322.  
  3323. ; Help text...
  3324.  
  3325. hsfil:    asciz |
  3326.  SET FILE paramater keyword
  3327.    Establish file-related parameters:
  3328.  
  3329.    BYTESIZE keyword or number
  3330.      Byte size for DEC-20 file input/output.  The choices are SEVEN, EIGHT, and
  3331.      AUTO.  If SEVEN, do normal ASCII character i/o.  EIGHT is necessary for
  3332.      transmission of non-DEC-20 binary files, like .COM files from
  3333.      microcomputers.  AUTO is equivalent to SEVEN for incoming files, and for
  3334.      outgoing files means to use EIGHT if the DEC-20 file bytesize (as shown by
  3335.      the Exec VDIR command) is 8, otherwise use SEVEN.  The default is AUTO.
  3336.  
  3337.      SEVEN or AUTO can be used to send and receive DEC-20 binary files, such as
  3338.      .EXE or .REL files.  EIGHT is only for "foreign" 8-bit binary files.
  3339.  
  3340.    NAMING UNTRANSLATED or NORMAL-FORM
  3341.      If NORMAL-FORM the names of incoming or outgoing files will be converted
  3342.      to contain only uppercase letters, digits, and periods.  If UNTRANSLATED,
  3343.      filenames will be left alone.  If conversion is being done, all control
  3344.      and punctuation characters (other than ".") in filenames will be
  3345.      translated to "X", and lower case letters will be capitalized.
  3346.      UNTRANSLATED is the default.
  3347. |
  3348.  
  3349. ; Parse rest of SET FILE
  3350.  
  3351. sfitab:    %table            ; Table of file parameters to SET.
  3352.     %key <bytesize>,0
  3353.     %key <naming>,1
  3354.     %tbend
  3355.  
  3356. ; The following ruse using chained FDB's allows the old-style command to
  3357. ; be parsed most of the time, like "SET FILE 8".
  3358.  
  3359. sfifd1: flddb. .cmkey,,sfitab,,<bytesize>,sfifd2
  3360. sfifd2:    flddb. .cmkey,,sfbtab,<DEC-20 file byte size,>,<auto>
  3361.  
  3362. .setfi:    noise <parameter>    ;[84] SET FILE
  3363.     movei t1, sfifd1
  3364.     call rfield
  3365.     hrrz t2, (t2)
  3366.     hrrzs t3        ;[84] Which function descriptor block was used?
  3367.     setzm pars3        ;[84] Assume they specified a bytesize.
  3368.     cain t3, sfifd2        ;[84] They specified a bytesize?
  3369.      jrst .setfz        ;[84]  Yes, so don't parse it again.
  3370.     movem t2, pars3
  3371.     noise <to>
  3372.     movei t1, [flddb. .cmkey,,sfbtab,<DEC-20 file byte size,>,<auto>]
  3373.     skipe pars3        ;[84]
  3374.      movei t1, [flddb. .cmkey,,fntab,,<untranslated>] ;[84]
  3375.     call rfield        ; Parse a keyword.
  3376.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3377. .setfz:    movem t2, pars4        ;[84] Save here.
  3378.     skipn definf        ;[77] In DEFINE?
  3379.      confrm            ;[77]  No, get confirmation.
  3380.     ret
  3381.  
  3382. ; file name translation keywords.
  3383.  
  3384. fntab:    2,,2
  3385.     [asciz/normal-form/],,1
  3386.     [asciz/untranslated/],,0
  3387.  
  3388. ; file bytesize keyword table.
  3389.  
  3390. sfbtab:    %table
  3391.     %key <7-bit>, 0
  3392.     %key <8-bit>, 1
  3393.     %key <auto>, 2
  3394.     %key <eight-bit>, 1
  3395.     %key <seven-bit>, 0
  3396.     %tbend
  3397.  
  3398. ;...SET command, cont'd
  3399.  
  3400.  
  3401. ; SET PARITY
  3402.  
  3403. hspar:    asciz |
  3404.  SET PARITY keyword
  3405.    If parity is being used on the communication line, you must
  3406.    inform KERMIT-20, so it can send the desired parity on outgoing characters,
  3407.    and strip it from incoming ones.  The DEC-20 does not use parity on
  3408.    communication lines.  The choices are NONE (the default), ODD, EVEN, MARK,
  3409.    and SPACE.  NONE means no parity processing is done, and the 8th bit of
  3410.    each character can be used for data when transmitting binary files.
  3411.  
  3412.    If ODD, EVEN, MARK, or SPACE are selected, binary files will be transferred
  3413.    using 8th-bit-prefixing if the other side agrees, otherwise they cannot be
  3414.    be successfully transferred.  If NONE is specified, 8th-bit-prefixing will
  3415.    not be requested.
  3416.  
  3417.    SET PARITY should be used for communicating with hosts that require
  3418.    character parity, or through devices or networks (like TELENET) that add
  3419.    parity to characters that pass through them.  Both KERMITs should be set to
  3420.    the same parity.
  3421.  
  3422.    The specified parity is used both for terminal connection (CONNECT) and
  3423.    file transfer (SEND, RECEIVE, GET).
  3424. |
  3425.  
  3426. .setpa:    noise <to>        ; SET PARITY
  3427.     movei t1, [flddb. .cmkey,,partab,,none,]
  3428.     call rfield        ; Parse a keyword.
  3429.     hrrz t2, (t2)        ; Get the value for the keyword.
  3430.     movem t2, pars3        ; Save into pars3.
  3431.     skipn definf        ;[77] In DEFINE?
  3432.      confrm            ;[77]  No, get confirmation.
  3433.     ret
  3434.  
  3435. partab:    %table
  3436.     %key <even>, even
  3437.     %key <mark>, mark
  3438.     %key <none>, none
  3439.     %key <odd>, odd
  3440.     %key <space>, space
  3441.     %tbend
  3442.  
  3443. ;...SET command, cont'd
  3444.  
  3445.  
  3446. ;[137] SET PROMPT
  3447.  
  3448. hsprom:    asciz |
  3449.  SET PROMPT string
  3450.    Set the KERMIT-20 prompt to whatever character string you like.
  3451.    This is especially useful when connected to another DEC-20 through a
  3452.    dialer, using another KERMIT-20 on the remote system.  A unique prompt
  3453.    for each KERMIT-20 will clear up any confusion about which one you're
  3454.    talking to.
  3455. |
  3456.  
  3457. .setpr:    noise <to>        ; Parse the rest of the SET PROMPT command.
  3458.     movei t1, [
  3459.      flddb. .cmtxt,,,<KERMIT-20 command prompt>,<x>] ; Phony default.
  3460.     hrroi t2, [asciz/Kermit-20>/] ; Set up real default
  3461.     movem t2, .cmdef(t1)
  3462.     call cfield
  3463.     ret
  3464.  
  3465.  
  3466. ; Execute the SET PROMPT command.
  3467.  
  3468. $setpr:    move t1, [point 7, atmbuf] ; And move the characters from here
  3469.     move t2, [point 7, prompx] ;  to here.
  3470.  
  3471. $stpra:    ildb t4, t1        ; Copy the string.
  3472.     jumpe t4, $stprb
  3473.     idpb t4, t2
  3474.     jrst $stpra
  3475.  
  3476. $stprb:    idpb t4, t2        ; And a null.
  3477.     ret
  3478.  
  3479. ; SET command, cont'd
  3480.  
  3481. ; SET RETRY
  3482.  
  3483. hsrty:    asciz |
  3484.  SET RETRY option decimal-number
  3485.    Set the maximum number of retries allowed for:
  3486.      INITIAL CONNECTION -- How many times to try connecting before giving up.
  3487.      PACKETS -- How many times to try sending a particular packet.
  3488. |
  3489.  
  3490.  
  3491. .setre:    noise <maximum for>    ;[37] SET RETRY
  3492.     movei t1, [flddb. .cmkey,,[<2,,2>
  3493.         <[asciz/initial-connection/],,0>
  3494.         <[asciz/packets/],,1>
  3495.         ],,<packets>]
  3496.     call rfield
  3497.     hrrz t2, (t2)        ; Get the keyword index
  3498.     movem t2, pars3
  3499.     noise <to>        ; Prompt for the value
  3500.     movei t1, [flddb. .cmnum,,^d10,<times to retry before giving up,>,5]
  3501.     skipn pars3
  3502.      movei t1, [flddb. .cmnum,,^d10,<times to retry before giving up,>,16]
  3503.     call rfield
  3504.     movem t2, pars4
  3505.     skipn definf        ;[77] In DEFINE?
  3506.      confrm            ;[77]  No, get confirmation.
  3507.     ret
  3508.  
  3509. offon:    %table            ; Table for parsing ON or OFF.
  3510.     %key <off>, 0
  3511.     %key <on>, 1
  3512.     %tbend
  3513.  
  3514. ; SET command,  cont'd
  3515.  
  3516.  
  3517. ;[143] SET FLOW-CONTROL added as edit 143
  3518.  
  3519. hsflo:    asciz |
  3520.  SET FLOW-CONTROL option
  3521.    For communicating with full duplex systems.  The DEC-20 system is capable
  3522.    of regulating the flow of characters on the line using XON/XOFF flow
  3523.    control.  If characters are coming into the DEC-20 too fast, the DEC-20 will
  3524.    send an XOFF signal, Control-S, to tell the system on the other side to stop
  3525.    sending characters.  After it has finished processing the characters in its
  3526.    input buffer, it will send a Control-Q to tell the other side to resume
  3527.    sending.  The other system does the same thing when the DEC-20 is sending
  3528.    data characters.  KERMIT-20 will use XON/XOFF flow control on a full-duplex
  3529.    connection by default, and it will not use it on a half duplex connection.
  3530.    The options of the SET FLOW-CONTROL command are XON-XOFF and NONE.  If you
  3531.    SET FLOW-CONTROL to anything other than NONE, HANDSHAKE is set to NONE.
  3532. |
  3533. .setfl:    movei t1, [flddb. .cmkey,,flotab,,XON-XOFF] ; SET FLOW-CONTROL
  3534.     call rfield        ; Parse a keyword.
  3535.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3536.     movem t2, pars3        ; Save into pars3.
  3537.     skipn definf        ; In DEFINE?
  3538.      confrm            ;  No, get confirmation.
  3539.     ret
  3540.  
  3541. flotab:    %table            ; Flow-Control keywords
  3542.     %key <none>,0
  3543.     %key <XON-XOFF>,1
  3544.     %tbend
  3545.  
  3546. ;[76] SET HANDSHAKE added as edit 76.
  3547.  
  3548. hshan:    asciz |
  3549.  SET HANDSHAKE option
  3550.    For communicating with half duplex systems.  This lets you specify the line
  3551.    turnaround character sent by the half duplex host to indicate it has ended
  3552.    its transmission and is granting you permission to transmit.  When a
  3553.    handshake is set, KERMIT-20 will not send a packet until the half duplex
  3554.    host has sent the specified character.  The options are:
  3555.  
  3556.      NONE
  3557.      XOFF  (^S)
  3558.      XON   (^Q)
  3559.      BELL  (^G)
  3560.      CR    (^M, carriage return)
  3561.      LF    (^J, linefeed)
  3562.      ESC   (Escape)
  3563.      or an octal number specifying any ASCII control character.
  3564.  
  3565. If you SET HANDSHAKE to anything other than NONE, FLOW-CONTROL is set to NONE.
  3566. |
  3567.  
  3568.  
  3569. .setha:    movei t1, [flddb. .cmkey,,hshtab,,XOFF,[
  3570.      flddb. .cmnum,cm%sdh,^d8,<octal value of ASCII control character>]]
  3571.     call rfield        ; Parse a keyword.
  3572.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  3573.     caie t3, .cmnum        ; Number?
  3574.      hrrz t2, (t2)        ;  No, get the keyword's associated value.
  3575.     caile t2, 37        ; Control character?
  3576.      cain t2, 177
  3577.      skipa
  3578.      jrst [    tmsg <?Must be in ASCII control range, 0-37 or 177>
  3579.         jrst cmder1 ]
  3580.     movem t2, pars3        ; Save into pars3.
  3581.     skipn definf        ;[77] In DEFINE?
  3582.      confrm            ;[77]  No, get confirmation.
  3583.     ret
  3584.  
  3585. hshtab:    %table            ; Handshake keywords
  3586.     %key <bell>,7
  3587.     %key <CR>,15
  3588.     %key <ESC>,33
  3589.     %key <LF>,12
  3590.     %key <none>,0
  3591.     %key <XOFF>,23
  3592.     %key <XON>,21
  3593.     %tbend
  3594.  
  3595. ; SET command, cont'd
  3596.  
  3597. ;[160] SET INPUT
  3598.  
  3599. hsetin:    asciz |
  3600.  SET INPUT parameter value
  3601.    Specify how the INPUT command is to behave (see INPUT).
  3602.  
  3603.    SET INPUT DEFAULT-TIMEOUT n
  3604.       n is the number of seconds for an INPUT command to time out after
  3605.       not receiving the requested input, if no interval is explicitly
  3606.       given in the INPUT command.
  3607.  
  3608.    SET INPUT TIMEOUT-ACTION PROCEED or QUIT
  3609.       If the INPUT command comes from a command file (see TAKE command),
  3610.       then use this command to specify whether processing of the command
  3611.       file should proceed or quit after a timeout occurs.
  3612.  
  3613.    SET INPUT CASE IGNORE or OBSERVE
  3614.       Specify whether alphabetic case should be ignored ("a" matches "A")
  3615.       or observed ("a" does not match "A").
  3616. |
  3617.     ;...
  3618.  
  3619. ; SET INPUT parsing, like SET SEND/RECEIVE -- an extra level of parsing.
  3620.  
  3621.  
  3622. .setin:    movei t1, [flddb. .cmkey,,sintab] ; SET INPUT ...
  3623.     call rfield        ; Parse a keyword.
  3624.     hrrz t2, (t2)        ; Get the command routine addresses.
  3625.     movem t2, pars3        ; Save into pars3.
  3626.     hlrz t1, (t2)        ; Get the next level routine.
  3627.     call (t1)        ; Call it.
  3628.     ret
  3629.  
  3630. sintab:    %table
  3631.     %key <case>, [xwd .sinca,incase]
  3632.     %key <default-timeout>, [xwd .sindt,indeft]
  3633.     %key <timeout-action>, [xwd .sinta,intima]
  3634.     %tbend
  3635.  
  3636. .sinca:    noise <for matching>    ; SET INPUT CASE
  3637.     movei t1, [flddb. .cmkey,,castab,,<ignore>]
  3638.     jrst .sinkp        ; Go below & parse rest.
  3639.  
  3640. castab:    %table            ; Case table.
  3641.     %key <ignore>, 0
  3642.     %key <observe>, 1
  3643.     %tbend
  3644.  
  3645. .sindt:    noise <for INPUT commands> ; SET INPUT DEFAULT-TIMEOUT
  3646.     movei t1, [
  3647.      flddb. .cmnum,,^d10,<seconds,
  3648. when interval not specified in INPUT command,>]
  3649.     call rfield
  3650.     movem t2, pars4
  3651.     skipn definf        ; In DEFINE?
  3652.      confrm            ; No, get confirmation.
  3653.     ret
  3654.  
  3655. .sinta:    noise <for command file> ; SET INPUT TIMEOUT-ACTION
  3656.     movei t1, [flddb. .cmkey,,itatab,,<proceed>]
  3657.  
  3658. .sinkp:    call rfield        ; Parse keyword.
  3659.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3660.     movem t2, pars4        ; Save into pars4.
  3661.     skipn definf        ; In DEFINE?
  3662.      confrm            ; No, get confirmation.
  3663.     ret
  3664.  
  3665. itatab:    %table            ; INPUT timeout action table
  3666.     %key <proceed>, 0
  3667.     %key <quit>, 1
  3668.     %tbend
  3669.  
  3670. ; SET command, cont'd
  3671.  
  3672.  
  3673. ;[75] SET ITS-BINARY (format) ON or OFF
  3674.  
  3675. hsits:    asciz |
  3676.  SET ITS-BINARY (format) ON or OFF
  3677.    Specify whether ITS-Binary file headers are to be recognized or ignored.
  3678.    ITS binary format is a way (devised at MIT) of storing foreign 8-bit binary
  3679.    data on a 36-bit machine to allow automatic recognition of these files when
  3680.    sending them out again, so that you don't have to depend on the file byte
  3681.    size, or to issue explict SET FILE BYTESIZE commands to KERMIT.
  3682.  
  3683.    An ITS format binary file contains the sixbit characters "DSK8" left-
  3684.    adjusted in the first 36-bit word.  If ITS-BINARY is ON, then KERMIT-20 will
  3685.    send any file starting with this "header word" using 8-bit i/o, and will not
  3686.    send the header word itself, and it will store any incoming file that begins
  3687.    with that header word with 8-bit bytesize, again discarding the header word
  3688.    itself.  If ITS-BINARY is OFF, then the header word, if any, will be sent,
  3689.    and i/o will be according to the setting of FILE BYTESIZE.
  3690. |
  3691.  
  3692. .setit:    noise <format>        ; Issue guide word.
  3693.     movei t1, [flddb. .cmkey,,offon,,on] ; SET ITS-BINARY
  3694.     call rfield        ; Parse a keyword.
  3695.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3696.     movem t2, pars3        ; Save into pars3.
  3697.     skipn definf        ;[77] In DEFINE?
  3698.      confrm            ;[77]  No, get confirmation.
  3699.     ret
  3700.  
  3701. ; SET command, cont'd
  3702.  
  3703.  
  3704. ; SET LINE
  3705.  
  3706. hslin:    asciz |
  3707.  SET LINE octal-number
  3708.    Specify the octal TTY number to use for file transfer or CONNECT.
  3709.    If you issue this command, you will be running as a local Kermit, and you
  3710.    must log in to the remote system and run Kermit on that side in order to
  3711.    transfer a file.  If you don't issue this command, KERMIT-20 assumes it is
  3712.    running remotely, and does file transfer over its job's controlling
  3713.    terminal line.
  3714.  
  3715.    You can also select the line directly in the CONNECT command.
  3716. |
  3717.  
  3718. ; Parse rest of SET LINE command.
  3719.  
  3720. .setln:    noise <to tty>        ; SET LINE
  3721.     movei t1, [
  3722.      flddb. .cmnum,,^d8,<TTY to transfer files over,>,,[
  3723.      flddb. .cmcfm,cm%sdh,,<confirm to reset>]]
  3724.     call rfield        ; Parse a tty number.
  3725.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  3726.     caie t3, .cmnum        ; Is it a TTY number?
  3727.      jrst .setl1        ;  If not it must be a confirm.
  3728.     movem t2, pars3        ; Save the tty number.
  3729.     skipn definf        ;[77] In DEFINE?
  3730.      confrm            ;[77]  No, get confirmation.
  3731.     ret
  3732.  
  3733. .setl1:    move t4, mytty        ; Get the our terminal number.
  3734.     movem t4, pars3        ; Make believe we parsed it.
  3735.     ret
  3736.  
  3737. hsdel:    asciz |
  3738.  SET DELAY decimal-number
  3739.    How many seconds to wait before sending the first packet.  Use when remote
  3740.    and SENDing files back to your local Kermit.  This gives you time to
  3741.    "escape" back and issue a RECEIVE command before packets start arriving.
  3742.    The normal delay is 5 seconds.
  3743. |
  3744.  
  3745. .setdl:    noise <to>        ; SET DELAY
  3746.     movei t1, [flddb. .cmnum,,^d10,<seconds before sending first packet,>]
  3747.     call rfield        ; Parse a number.
  3748.     movem t2, pars3        ; Save the number.
  3749.     skipn definf        ;[77] In DEFINE?
  3750.      confrm            ;[77]  No, get confirmation.
  3751.     ret
  3752.  
  3753. ; SET command, cont'd
  3754.  
  3755.  
  3756. ; SET DUPLEX
  3757.  
  3758. hsdup:    asciz |
  3759.  SET DUPLEX keyword
  3760.    For use when CONNECTed to a remote system.  The choices are FULL and HALF.
  3761.    FULL means the remote system echoes the characters you type, HALF means
  3762.    the local system echoes them.  FULL is the default, and is used by most
  3763.    hosts.  HALF is necessary when connecting to IBM mainframes.
  3764. |
  3765.  
  3766. ; Parse SET DUPLEX
  3767.  
  3768. .setdu:    noise <to>        ;[18] SET DUPLEX
  3769.     movei t1, [flddb. .cmkey,,duptab,,<full>]
  3770.     call rfield
  3771.     hrrz t2, (t2)
  3772.     movem t2, pars3
  3773.     skipn definf        ;[77] In DEFINE?
  3774.      confrm            ;[77]  No, get confirmation.
  3775.     ret
  3776.  
  3777. duptab:    %table            ;[18] Table of legal duplexes
  3778.     %key <full>,dxfull
  3779.     %key <half>,dxhalf
  3780.     %tbend
  3781.  
  3782. ;[143] SET EXPUNGE
  3783. ;
  3784. hsexp:    asciz |
  3785.   SET EXPUNGE ON or OFF
  3786.     Tell whether you want a DELETE command (either the LOCAL DELETE command
  3787.     or a REMOTE DELETE command sent to a KERMIT-20 server) to expunge files as
  3788.     it deletes them.  On the DEC-20, a deleted file continues to take up space,
  3789.     and may be "undeleted" at a later time in the same session.  To expunge a
  3790.     deleted file means to remove it completely and irrevocably.  EXPUNGE is OFF
  3791.     (i.e. no automatic expunging of deleted files) by default.
  3792. |
  3793. .setex:    noise <deleted files automatically> ; SET EXPUNGE
  3794.     movei t1, [flddb. .cmkey,,offon,,on]
  3795.     call rfield        ; Parse a keyword.
  3796.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3797.     movem t2, pars3        ; Save into pars3.
  3798.     skipn definf        ;[77] In DEFINE?
  3799.      confrm            ;[77]  No, get confirmation.
  3800.     ret    
  3801.  
  3802. ; SET ESCAPE
  3803.  
  3804. hsesc:    asciz |
  3805.  SET ESCAPE octal-number
  3806.    Tell what control character you want to use to "escape" from remote
  3807.    connections.  34 (Control-Backslash ^\) by default.  The number is the octal
  3808.    value of the ASCII control character, 1 to 37.  When you type the escape
  3809.    character, you must follow it by a single-character "argument":
  3810.  
  3811.    C  Close connection
  3812.    S  Status report
  3813.    P  Push to a new Exec on the local system
  3814.    Q  If you have given a LOG SESSION command, temporarily Quit logging
  3815.    R  Resume logging to session log
  3816.    B  Attempt to send a simulated BREAK signal.
  3817.    ?  List available options
  3818.    or second copy of the escape character to send the escape character itself.
  3819. |
  3820.  
  3821. ; Parse rest of SET ESCAPE command.
  3822.  
  3823. .setes:    noise <character for connect to> ;[16] SET ESCAPE
  3824.     movei t1, [
  3825.      flddb. .cmnum,,^d8,<Value of ASCII control character,>,<34>]
  3826.     call rfield
  3827.     caile t2, 37        ; Control character?
  3828.      cain t2, 177
  3829.      skipa
  3830.      jrst [    tmsg <?Must be in ASCII control range, 0-37 or 177>
  3831.         jrst cmder1 ]
  3832.     movem t2, pars3
  3833.     skipn definf        ;[77] In DEFINE?
  3834.      confrm            ;[77]  No, get confirmation.
  3835.     ret
  3836.  
  3837. ; SET command, cont'd
  3838.  
  3839. ; SET RECEIVE parameters
  3840.  
  3841. hsrcv:    asciz |
  3842.  SET RECEIVE parameter
  3843.    Parameters to request or expect for incoming packets, as follows:
  3844.  
  3845.    END-OF-LINE octal-number
  3846.      Carriage return (15) by default.  The DEC-20 does not actually need any
  3847.      line terminator for incoming packets.
  3848.  
  3849.    PACKET-LENGTH decimal-number
  3850.      Maximum length packet for the other side to send, decimal number,
  3851.      between 10 and 9000, 80 by default.
  3852.  
  3853.    PADDING octal-number, PADCHAR octal-number
  3854.      Should never be necessary; the DEC-20 needs no padding.
  3855.  
  3856.    PAUSE floating-point-number
  3857.      How many seconds to pause before acknowledging a packet.
  3858.      Setting this to a nonzero value will slow down the rate at which
  3859.      data packets come in to the DEC-20, which may be necessary for DEC-20's
  3860.      that have "sensitive" front ends and cannot accept input at a high rate.
  3861.  
  3862.    QUOTE octal-number
  3863.      What printable character to use for quoting of control characters.
  3864.      Specify the octal ASCII value.  "#" (43) by default.  There should be no
  3865.      reason to change this.
  3866.  
  3867.    SERVER-TIMEOUT decimal-numer
  3868.      When running as a server, how often to send periodic NAKs during server
  3869.      server command wait.  0 means don't send them at all.  94 seconds maximum.
  3870.  
  3871.    START-OF-PACKET octal-number
  3872.      The control character to mark the beginning of incoming packets.  Normally
  3873.      SOH (Control-A, ASCII 1).  There should be no reason to change this.
  3874.  
  3875.    TIMEOUT decimal-number
  3876.      How many seconds the other Kermit should wait for a packet before asking
  3877.      for retransmission.  If 0, then no timing out will be done.  94 seconds
  3878.      maximum.
  3879. |
  3880.  
  3881. ; Parse rest of SET RECEIVE...
  3882.  
  3883. .setrc:    movei t1, [flddb. (.cmkey,,srtabl,,)] ; SET RECEIVE ...
  3884.     call rfield        ; Parse a keyword.
  3885.     hrrz t2, (t2)        ; Get the command routine addresses.
  3886.     movem t2, pars3        ; Save into pars3.
  3887.     hlrz t1, (t2)        ; Get the next level routine.
  3888.     call (t1)        ; Call it.
  3889.     ret
  3890.  
  3891. srtabl:    %table
  3892.     %key <end-of-line>, [xwd .seteo,reolch]
  3893.     %key <packet-length>, [xwd .setpk,rpsiz]
  3894.     %key <padchar>, [xwd .setpc,rpadch]
  3895.     %key <padding>, [xwd .setpd,rpadn]
  3896.     %key <pause>, [xwd .srpau,rpause] ;[36]
  3897.     %key <quote>, [xwd .setqu,rquote]
  3898.     %key <server-timeout>, [xwd .setim,srvtim] ;[137]
  3899.     %key <start-of-packet>, [xwd .setsp,rsthdr] ;[18]
  3900.     %key <timeout>,[xwd .setim,rtimou]
  3901.     %tbend
  3902.  
  3903. ; SET SEND parameters
  3904.  
  3905. hssnd:    asciz |
  3906.  SET SEND parameter
  3907.    Parameters for outgoing packets, as follows:
  3908.  
  3909.    END-OF-LINE octal-number
  3910.      The octal value of the ASCII character to be used as a line terminator
  3911.      for packets, if one is required by the other system.  Carriage return
  3912.      (15) by default.  You will only have to use this command for systems
  3913.      that require a line terminator other than carriage return.
  3914.  
  3915.    PACKET-LENGTH decimal-number
  3916.      Maximum packet length to send, decimal number, between 10 and 9000, 80 by
  3917.      default.  Shortening the packets might allow more of them to get through
  3918.      through without error on noisy communication lines.
  3919.  
  3920.    PADDING octal-number, PADCHAR octal-number
  3921.      How much padding to send before a packet, if the other side needs padding,
  3922.      and what character to use for padding.  Defaults are no padding, and NUL
  3923.      (0) for the padding character.
  3924.  
  3925.    PAUSE floating-point-number
  3926.      How many seconds to pause before sending each data packet.  Setting this
  3927.      to a nonzero value may allow some slow systems enough time to process
  3928.      a data packet sent by the DEC-20 before the next one arrives.  Normally,
  3929.      no per-packet pausing is done.
  3930.  
  3931.    QUOTE octal-number
  3932.      What printable character to use for quoting of control characters.
  3933.      Specify an octal ASCII value.  "#" (43) by default.  There should be no
  3934.      reason to change this.
  3935.  
  3936.    START-OF-PACKET octal-number
  3937.      The control character that marks the beginning of a packet.  Normally
  3938.      SOH (Control-A, ASCII 1).  There should be no reason to change this.
  3939.  
  3940.    TIMEOUT decimal-number
  3941.      How many seconds to wait for a packet before trying again.
  3942. |
  3943.  
  3944. .setsn:    movei t1, [flddb. (.cmkey,,sstabl,,)] ; SET SEND ...
  3945.     call rfield        ; Parse a keyword.
  3946.     hrrz t2, (t2)        ; Get the command routine addresses.
  3947.     movem t2, pars3        ; Save into pars3.
  3948.     hlrz t1, (t2)        ; Get the next level routine.
  3949.     call (t1)        ; Call it.
  3950.     ret
  3951.  
  3952. sstabl:    %table
  3953.     %key <end-of-line>, [xwd .seteo,seolch]
  3954.     %key <packet-length>, [xwd .setpk,spsiz]
  3955.     %key <padchar>, [xwd .setpc,spadch]
  3956.     %key <padding>, [xwd .setpd,spadn]
  3957.     %key <pause>, [xwd .sspau,spause] ;[35]
  3958.     %key <quote>, [xwd .setqu,squote]
  3959.     %key <start-of-packet>, [xwd .setsp,ssthdr] ;[18]
  3960.     %key <timeout>,[xwd .setim,stimou]
  3961.     %tbend
  3962.  
  3963. ;...SET command, cont'd
  3964.  
  3965.  
  3966. ; SET PACKET-LENGTH
  3967.  
  3968. .setpk:    noise <to>        ; SET SEND/RECEIVE PACKET-LENGTH
  3969.     movei t1, [
  3970.      flddb. .cmnum,cm%sdh,^d10,<Decimal number between 10 and 94>]
  3971.     call rfield        ; Parse the packet size.
  3972.     movem t2, pars4        ; Save the packet size.
  3973.     cail t2, ^d10        ; Is the number in the right range?
  3974.      caile t2, ^d9000    ;[179] (was ^d94)
  3975.       jrst [tmsg <?Illegal packet size>
  3976.         jrst cmder1 ]
  3977.     skipn definf        ;[77] In DEFINE?
  3978.      confrm            ;[77]  No, get confirmation.
  3979.     ret
  3980.  
  3981.  
  3982. .srpau:    noise <between packets to> ;[36] SET RECEIVE PAUSE
  3983.     movei t1, [
  3984.      flddb. .cmflt,,,<seconds to pause after receiving a packet,>,<0>]
  3985.     jrst .sxpau        ; Join common code.
  3986.  
  3987.  
  3988. .sspau:    noise <between packets to> ;[35] SET SEND PAUSE
  3989.     movei t1, [
  3990.      flddb. .cmflt,,,<seconds to pause before sending a packet,>,<0>]
  3991.  
  3992.  
  3993. .sxpau:    call rfield        ;[36] Common code.
  3994.     movem t2, pars4
  3995.     noise <seconds>
  3996.     skipn definf        ;[77] In DEFINE?
  3997.      confrm            ;[77]  No, get confirmation.
  3998.     skipge pars4        ; Is the number in the right range?
  3999.      jrst [    tmsg <?Must be a positive number>
  4000.         jrst cmder1 ]
  4001.     ret
  4002.  
  4003. .setpd:    noise <to>        ; SET SEND/RECEIVE PADDING
  4004.     movei t1, [
  4005.      flddb. .cmnum,,^d10,<number of padding characters, positive>,<0>]
  4006.     call rfield        ; Parse the number of padding chars.
  4007.     movem t2, pars4        ; Save the number.
  4008.     skipn definf        ;[77] In DEFINE?
  4009.      confrm            ;[77]  No, get confirmation.
  4010.     move t2, pars4        ; Get the amount of padding we parsed.
  4011.     skipge t2        ; Is the number in the right range?
  4012.      jrst [    tmsg <?Must be a positive number>
  4013.         jrst cmder1 ]
  4014.     ret
  4015.  
  4016. ;...SET command, cont'd
  4017.  
  4018.  
  4019. .setpc:    noise <to>        ; SET SEND/RECEIVE PADCHAR
  4020.     movei t1, [
  4021.      flddb. .cmnum,,^d8,<Value of ASCII character, 0 to 37, or 177,>]
  4022.     call rfield        ; Parse the padding character.
  4023.     movem t2, pars4        ; Save the padding char.
  4024.     skipn definf        ;[77] In DEFINE?
  4025.      confrm            ;[77]  No, get confirmation.
  4026.     move t2, pars4        ; Get the padding char we parsed.
  4027.     cain t2, ^o177        ;[149] Is it a DEL?
  4028.      ret            ;[149] OK.
  4029.     skipl t2        ; Is it in the control range, 0 to...
  4030.      caile t2, ^o37        ; ...37 octal?
  4031.       jrst [tmsg <?Illegal padding character> ; No, give error message
  4032.         jrst cmder1 ]    ; and allow command retry.
  4033.     ret            ; Yes, OK.
  4034.  
  4035. .seteo:    noise <to>        ; END-OF-LINE
  4036.     movei t1, [
  4037.      flddb. .cmnum,,^d8,<Value of ASCII control character, 0-37,>,<15>]
  4038.     call rfield        ; Parse the EOL char.
  4039.     skipl t2        ; Is the number in the right range?
  4040.      caile t2, ^o37        ;  Fix to compare correctly.
  4041.       jrst [tmsg <?Illegal EOL character>
  4042.         jrst cmder1 ]
  4043.     movem t2, pars4        ; Get the EOL char we parsed.
  4044.     skipn definf        ;[77] In DEFINE?
  4045.      confrm            ;[77]  No, get confirmation.
  4046.     ret
  4047.  
  4048.  
  4049. .setsp:    noise <to>        ;[18] START-OF-PACKET
  4050.     movei t1, [
  4051.      flddb. .cmnum,cm%sdh,^d8,<Octal value of ASCII control character>,<1>]
  4052.     call rfield
  4053.     skipl t2        ; Is the number in the right range?
  4054.      caile t2, ^o37        ;  Fix to compare correctly.
  4055.       jrst [tmsg <?Illegal start-of-packet character>
  4056.         jrst cmder1 ]
  4057.     movem t2, pars4
  4058.     skipn definf        ;[77] In DEFINE?
  4059.      confrm            ;[77]  No, get confirmation.
  4060.     ret
  4061.  
  4062.     ;...
  4063.  
  4064. ; More SET commands...
  4065.  
  4066. .setqu:    noise <to>        ; SET SEND/RECEIVE QUOTE
  4067.     movei t1, [
  4068.      flddb. .cmnum,,^d8,<Value of printable ASCII character,>,<43>] ;[21]
  4069.     call rfield        ;[21]
  4070.     caile t2," "        ;[21] Printable?
  4071.      caile t2, "~"        ;[21]
  4072.      jrst [    tmsg <?Must be printable character, range 41-176>
  4073.         jrst cmder1 ]    ;[21]
  4074.     movem t2, pars4        ;[21] OK, stash it.
  4075.     skipn definf        ;[77] In DEFINE?
  4076.      confrm            ;[77]  No, get confirmation.
  4077.     ret
  4078.  
  4079. .setim:    noise <to>        ; SET SEND/RECEIVE TIMEOUT
  4080.     movei t1, [
  4081.      flddb. .cmnum,,^d10,<Number of seconds before timing out, 1 to 94,>]
  4082.     call rfield        ; Parse the number.
  4083.     movem t2, pars4        ; Save the number.
  4084.     skipn definf        ;[77] In DEFINE?
  4085.      confrm            ;[77]  No, get confirmation.
  4086.     move t2, pars4        ; Get the number we parsed.
  4087.     cail t2, 0        ;[94] Is the number in the right range?
  4088.      caile t2, ^d94        ;  Fix to compare correctly.
  4089.       jrst [tmsg <?Illegal number of seconds>
  4090.         jrst cmder1 ]
  4091.     ret
  4092.  
  4093.     subttl SET command action routines.
  4094.  
  4095. ; SET ... command dispatcher.
  4096.  
  4097. $set:    skipe macrof        ;[77] Was a macro used?
  4098.      jrst $set2        ;[77] If so, go handle that.
  4099.     move t2, pars2        ; Get back data value.
  4100.     hrrz t1, (t2)        ; Get evaluation routine.
  4101.     call (t1)        ; Call it.
  4102.     ret
  4103.  
  4104.     ;...
  4105.  
  4106. ;...$SET, cont'd
  4107.  
  4108.  
  4109. ;[77] SET macro was typed.
  4110.  
  4111. $set2:    move t1, pars2         ; Pointer to macro text (SET operands)
  4112.     movem t1, macxp
  4113. ;*    PSOUT            ; echo it for debugging...
  4114.     setzm mdone        ; Say macro not done yet.
  4115.  
  4116. ; Loop to copy one set command into the command buffer.
  4117.  
  4118. $set3:    move t1, [ascii/set  /]    ; Fake a SET command
  4119.     movem t1, cmdbuf
  4120.     move t2, [point 7, cmdbuf, 27] ; Copy them to after "set "
  4121.     movem t2, sbk+.cmptr
  4122.  
  4123. ; Loop for each character.
  4124.  
  4125. $set4:    ildb t1, macxp        ; Get a character from the macro text
  4126.     aos sbk+.cminc        ; Account for it in the CSB
  4127.     sos sbk+.cmcnt        ;  ...
  4128.     jumpe t1, $set5        ; If null, done.
  4129.     cain t1, ","        ; Comma?
  4130.      jrst [    movei t1, .chcrt ; Yes, substitute a carriage return.
  4131.         idpb t1, t2
  4132.         aos sbk+.cminc
  4133.         sos sbk+.cmcnt
  4134.         movei t1, .chlfd ; And a linefeed...
  4135.         idpb t1, t2
  4136.         aos sbk+.cminc
  4137.         sos sbk+.cmcnt
  4138.         setz t1,    ; And a null...
  4139.         idpb t1, t2
  4140.         jrst $set6 ]    ; Go execute this part.
  4141.  
  4142.     idpb t1, t2        ; Not a comma, copy the character.
  4143.     jrst $set4
  4144.  
  4145. ; Get here at end of null-terminated macro body.
  4146.  
  4147. $set5:    idpb t1, t2        ;[80] Deposit the null.
  4148.     setom mdone        ; Flag that we're done interpreting the macro.
  4149.  
  4150. $set6:    move t1, sbk        ; Zero the CSB flags.
  4151.     hrrzm t1, sbk        ;  ...
  4152. ;*    hrroi t1, cmdbuf    ; Echo the command.
  4153. ;*    PSOUT            ; ...
  4154.     call .set        ; Go parse the string.
  4155.     call $set        ; Go execute what was parsed.
  4156.     skipn mdone        ; Any more?
  4157.      jrst $set3        ; Yes, go do them.
  4158.     setzm mdone        ; No, all done.
  4159.     ret
  4160.  
  4161. ;[42] SET INCOMPLETE
  4162.  
  4163. $setab:    move t1, pars3        ; Just save what we parsed.
  4164.     movem t1, abtfil
  4165.     ret
  4166.  
  4167.  
  4168. ; SET DEBUGGING
  4169.  
  4170. $setdb:    skipn t1, pars3        ;[38] See what we got.
  4171.      jrst [    setz debug,    ;[38] Turning debugging off.
  4172.         skipn t1, logjfn ;[38] Did we have a log?
  4173.          ret        ;[38] No, done.
  4174.         setz t2,    ;[144] Yes, any bytes written?
  4175.         RFPTR        ;[144]
  4176.          nop        ;[144]
  4177.         skipg t2    ;[144]
  4178.          txo t1, cz%abt    ;[144] None, don't bother keeping the log.
  4179.         setzm logjfn    ;[38] Zero this so we know...
  4180.         CLOSF        ;[38] Close it.
  4181.          erjmp .+1    ;[144] Ignore errors, may already be closed
  4182.         ret ]        ;[38]  by previous EXIT command.
  4183.  
  4184.     skipl debug, pars3    ; DEBUG. Get the value we parsed.
  4185.      caile debug, 2        ;[22] Make sure it's 0, 1, or 2.
  4186.      movei debug, 1        ;[22] ...
  4187.     ret
  4188.  
  4189. ; SET SEND/RECEIVE command dispatcher.
  4190.  
  4191. $setrs:    move t1, @pars3        ; SEND/RECEIVE.  Address of variable to set.
  4192.     move t2, pars4        ; The value that was parsed.
  4193.     movem t2, (t1)        ; Save the value.
  4194.     ret
  4195.  
  4196. ; SET DELAY
  4197.  
  4198. $setdl:    move t1, pars3        ; DELAY. Get the number of seconds to delay.
  4199.     movem t1, delay        ; Save the delay time.
  4200.     movem t1, odelay    ;[27] Here too, for saving & restoring.
  4201.     ret
  4202.  
  4203. ; SET DUPLEX
  4204.  
  4205. $setdu:    move t1, pars3        ;[18] DUPLEX.  Get what was parsed.
  4206.     movem t1, duplex
  4207.     ret
  4208.  
  4209. ; SET ESCAPE
  4210.  
  4211. $setes:    move t1, pars3        ;[16] ESCAPE.  Get what we parsed.
  4212.     movem t1, escape
  4213.     ret
  4214.  
  4215. ; SET EXPUNGE
  4216.  
  4217. $setex:    move t1, pars3        ;[143] SET EXPUNGE
  4218.     movem t1, expung
  4219.     ret
  4220.  
  4221. ; SET FILE
  4222.  
  4223. $setfi:    skipn t1, pars3        ;[84] Which file parameter are we setting?
  4224.      jrst $setf8        ;[84] Bytesize, go do that.
  4225.  
  4226. ;  ... FILE NAMING
  4227.  
  4228. $setfn:    sojn t1, [        ;[84] We'll have to get a little fancier
  4229.         tmsg <?Impossible parse value> ;[84] if more file parameters
  4230.         ret ]        ;[84] are added...
  4231.     move t1, pars4        ;[84] OK, get the value.
  4232.     movem t1, xfnflg    ;[84] Save it.
  4233.     ret            ;[84] Done.
  4234.  
  4235. ;  ... FILE BYTESIZE
  4236.  
  4237. $setf8:    move t1, pars4        ; BYTESIZE... Get the value of the flag.
  4238.     cain t1, 2        ; Is it autobyte?
  4239.      jrst [ setom autbyt    ;  If so, say so,
  4240.         setzm ebtflg    ;  and say this not so.
  4241.         ret ]
  4242.     setzm autbyt        ; Say no auto-byte.
  4243.     movem t1, ebtflg    ; Set the flag.
  4244.     ret
  4245.  
  4246. ; SET PARITY
  4247.  
  4248. $setpa:    move t1, pars3        ;[109] What did they say?
  4249.     caie t1, none        ;[109] Was the parity NONE?
  4250.      jrst [    setom ebqr    ;[89] No, so request 8th-bit prefixing.
  4251.         movei t2, dqbin    ;[89] Use the default prefix.
  4252.         movem t2, ebq    ;[89]
  4253.         tmsg <%Will request 8th-bit prefixing.
  4254. %If the other KERMIT doesn't agree,
  4255. %binary files cannot be sent correctly.
  4256. >
  4257.         jrst .+2 ]    ;[89]
  4258.      jrst [    movei t1, "Y"    ;[95] If none, just say we will do 8th-bit
  4259.         movem t1, ebq    ;[95]  prefixing if requested.
  4260.         setzm ebqr    ;[95] But we won't request it ourselves.
  4261.         jrst .+1 ]    ;[95]
  4262.     move t1, pars3
  4263.     movem t1, parity
  4264.     ret
  4265.  
  4266. ; SET RETRY
  4267.  
  4268. $setre:    move t1, pars3        ;[37] SET RETRY
  4269.     move t2, pars4
  4270.     movem t2, @[exp imxtry, maxtry](t1)
  4271.     ret
  4272.  
  4273. ;[143] SET FLOW-CONTROL
  4274.  
  4275. $setfl:    skipe t1, pars3        ; Get flow control option.
  4276.      setzm handsh        ; If nonzero, turn off handshake.
  4277.     movem t1, flow
  4278.     ret
  4279.  
  4280. ;[76] SET HANDSHAKE
  4281.  
  4282. $setha:    skipe t1, pars3        ;[143] Get the handshake option.
  4283.      setzm flow        ;[143] If nonzero, turn off flow control.
  4284.     movem t1, handsh    ; Save it.
  4285.     ret            ; Done.
  4286.  
  4287. ;[75] SET ITS-BINARY
  4288.  
  4289. $setit:    move t1, pars3        ; Just save the value in the ITS flag.
  4290.     movem t1, itsflg
  4291.     ret
  4292.  
  4293. ; SET LINE
  4294. ;
  4295. ;[87] Call with PARS3/ number of line to assign.
  4296. ;
  4297. $setln:    move t1, ttynum        ; Previous line number, if any.
  4298.     movem t1, oldnum    ; Remember it.
  4299.     move t1, pars3
  4300.     movem t1, ttynum    ;
  4301.     move t1, asgflg        ; Remember in case we already had another...
  4302.     movem t1, oasflg    ;
  4303.     move t1, netjfn        ;[80]
  4304.     movem t1, oldjfn    ;[80]
  4305.         setzm local             ; Assume we're a remote Kermit.
  4306.         move t1, ttynum         ;[80]
  4307.         came t1, mytty          ; Lines the same?
  4308.          setom local            ; No, so we're local.
  4309.  
  4310.     call chktvt        ;[182] Possibly detect if we're a TVT
  4311.  
  4312. $stln1:    move t1, ttynum        ;[182] Load the line in question
  4313.     txo t1, .ttdes        ;[182] Form device designator.
  4314.     DVCHR            ;
  4315.      erjmp asser1        ;
  4316.     hlre t1, t3        ; Who has it?
  4317.     movem t1, job        ; Job number of who has it, or -1 (or -2).
  4318.     setzm asgflg        ; Assume I don't have to assign it.
  4319.     skipn local        ; Own controlling TTY?
  4320.      jrst [    skipe tvtflg    ;[130] Yes, but is it an ARPANET TVT?
  4321.          jrst $stln2    ;[130]  If so, still have to OPENF in 8b mode.
  4322.         movei t1, .cttrm ; No, so I don't have to assign it.
  4323.         movem t1, netjfn ; Just use controlling terminal designator.
  4324.         jrst $stln3 ]
  4325.     move t3, myjob        ; My job number.
  4326.     camn t3, job        ; If I had it assigned already,
  4327.      jrst $stln2
  4328.     move t1, ttynum        ; Form device designator again,
  4329.     movei t1, .ttdes(t1)    ;  and...
  4330.     ASND            ;  give it a try.
  4331.      erjmp asser1        ; Uh oh, can't assign it.
  4332.     setom asgflg        ; Assigned it.  Set this flag to remember.
  4333.  
  4334.     ;...
  4335.  
  4336. ; $SETLN (SET LINE), cont'd
  4337.  
  4338. $stln2:    move t1, [170700,,filbuf] ; Pointer to file name buffer.
  4339.     move t2, [ascii/TTY/]    ; Build TTYn: filename.
  4340.     movem t2, filbuf    ; Into filbuf.
  4341.     move t2, ttynum        ; TTY number.
  4342.     movei t3, ^d8        ; Octal.
  4343.     NOUT%
  4344.      %jserr <Can't NOUT TTY number>,asserz
  4345.     movei t2, ":"        ; Add a colon.
  4346.     idpb t2, t1
  4347.     setz t2,
  4348.     idpb t2, t1
  4349.     movx t1, gj%sht        ; Now try to get a JFN on the TTY.
  4350.     hrroi t2, filbuf
  4351.     GTJFN%
  4352.      %jserr <Can't get JFN on TTY>,asserz ; Error, probably no such device.
  4353.     hrrzm t1, netjfn    ; Got JFN OK, save it as the "network" JFN.
  4354.     movx t2, fld(8,of%bsz)!of%wr!of%rd ; 8-bit bytes, read & write access.
  4355.     OPENF%            ; Open the device.
  4356.      erjmp asserr        ;  Can't, print informative error message.
  4357.     setzm setspd        ;[161] Flag that speed has not been SET.
  4358.  
  4359. $stln3:    move t1, oldjfn        ;[127] Get JFN of line previously used.
  4360.     skiple t1        ;[127] No previous one?
  4361.      cain t1, .cttrm    ;[127] Previous one was controlling terminal?
  4362.      jrst $stlnz        ;   One of those, nothing to do.
  4363.     CLOSF%            ; Close it.
  4364.       %jserr (,.+1)        ;
  4365.     setzm oldjfn        ; Remember that we did.
  4366.     skipe oasflg        ; Had I also assigned the old one?
  4367.      jrst [    skipg t1, oldnum ; Yes, did I remember the number?
  4368.          jrst .+1    ; No...    
  4369.         movei t1, .ttdes(t1) ; Yes, then deassign the old one.
  4370.         RELD%
  4371.          %jserr (,.+1)
  4372.         setzm oldnum    ; Set these to zero...
  4373.         setzm oasflg
  4374.         jrst .+1 ]
  4375.     ;...
  4376.  
  4377. ;...SET LINE, cont'd
  4378.  
  4379.  
  4380. ;[182] Move the TVT detection code to earlier so we side-effect the
  4381. ;[182] tvtflg variable before we check to see if we should open in 8
  4382. ;[182] bit mode
  4383.  
  4384. ;[130] See if line is remote, and if so, if carrier is up.
  4385.  
  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. ;[182] Help message updated for automatic mode
  4535. ;
  4536. hstac:    asciz |
  4537.  SET TVT-BINARY AUTOMATIC, ON or OFF
  4538.  
  4539.    Only for users running KERMIT-20 on an Internet DEC-20, signed on
  4540.    to a DEC-20 TVT (Internet virtual terminal), from either another
  4541.    Internet host or through a TAC.  Without TVT Binary mode, file
  4542.    transfer through a TVT would not work in most cases.
  4543.  
  4544.    SET TVT AUTOMATIC causes Kermit to determine your line type.  If
  4545.    you sign on from a TVT, then TVT-Binary mode will be enabled.  Any
  4546.    other type of line wil cause TVT-Binary mode to be disabled.
  4547.    SET TVT AUTOMATIC is the default.
  4548.  
  4549.    SET TVT ON overrides the automatic setting and forces KERMIT-20 to
  4550.    always negotiate TELNET binary mode during a file transfer.  This
  4551.    should ONLY be done on a line that you are sure is a TVT that
  4552.    KERMIT-20 is not recognizing as such.  This can happen on older
  4553.    pre-Release 7 monitors.
  4554.  
  4555.    If this happens and you normally use KERMIT-20 through a TVT, you
  4556.    can put the command SET TVT-BINARY ON into your KERMIT.INI file.
  4557.  
  4558.    SET TVT OFF overrides the automatic setting and forces KERMIT-20 to
  4559.    NEVER negotiate TELNET binary mode during a file transfer.  This
  4560.    should ONLY be done on a line that you are sure is NOT a TVT that
  4561.    KERMIT-20 is mistakenly identifying as a TVT.  While such a problem
  4562.    is indicative of a monitor problem, this will allow you to get
  4563.    around it until such time as the monitor is fixed.
  4564.  
  4565.    CAUTION: This facility requires certain facilities in the Release 5
  4566.    TOPS-20 Internet monitor: TELNET binary negotiations are accepted
  4567.    (bug fix), and the monitor does NOT double the TELNET attention
  4568.    character (IAC, octal 377).  This program will attempt to use
  4569.    monitor calls to enable TELNET binary mode.  If the calls fail, it
  4570.    will then send IAC escape sequences to negotiate TELNET binary
  4571.    mode, and doubles any IACs that appear in data during file
  4572.    transfer.
  4573.  
  4574.    Further caution: setting or unsetting binary mode may take up to 8
  4575.    seconds.
  4576. |
  4577.  
  4578. .setta:    noise <negotiation>     ; SET TVT-BINARY
  4579.     movei t1, [flddb. .cmkey,,tvtkey,,automatic] ;[182] 
  4580.     call rfield        ; Parse a keyword.
  4581.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  4582.     movem t2, pars3        ; Save into pars3.
  4583.     skipn definf        ;[77] In DEFINE?
  4584.      confrm            ;[77]  No, get confirmation.
  4585.     ret    
  4586.  
  4587. tvtkey:    %table            ;[182] Table for parsing TVT keywords
  4588.     %key <automatic>,[0,,1]    ;[182] Figure it out for me
  4589.     %key <off>, [0,,0]    ;[182] Override to never negotiate
  4590.     %key <on>, [1,,0]    ;[182] Override to ALWAYS negotiate
  4591.     %tbend            ;[182] Which will break on LAT, CTERM, etc..
  4592.  
  4593.  
  4594. $setta:    move t1, pars3        ; Get the value that was parsed.
  4595.     move t2,(t1)        ;[182] De-reference to get values
  4596.     hrrz t3,t2        ;[182] Right halfword is automatic mode
  4597.     hlrz t2,t2        ;[182] Left halfword is the TVT-Binary mode
  4598.      jumpn t3,$sett1    ;[182]  Setting automatic mode?
  4599.     dmovem t2,tvtflg    ;[182] No, override both TVT line
  4600.     ret            ;[182] and turn off line discovery
  4601.  
  4602. $sett1:    exch t3, tvtchk        ;[182] Update TVT checking mode, get old mode
  4603.      jumpn t3,R        ;[182]  Wants automatic and it was already set?
  4604.     call chktvt        ;[182] Went from override to automatic, check
  4605.     ret            ; Done.
  4606.  
  4607.     subttl chktvt - check to see if we are using a TVT line
  4608.  
  4609. ;[182] Begin code addition
  4610. ;
  4611. ; NTINF%, which was introduced in 6.0 series Tops-20 and is now known
  4612. ; to work in 7.0 series PANDA monitor and XKL.  I believe there are
  4613. ; also standard patches to the DEC monitor to make it work.
  4614. ;
  4615. ; We use NTINF% when the user sets TVT-Binary mode to automatic which
  4616. ; is an additional keyword (used to be just on or off).  Automatic is
  4617. ; the default, but we still allow overide.
  4618. ;
  4619. ; If the NTINF% failes, then we recover by using STAT% to try to
  4620. ; indentify whether the line is in the range of TVT's. 
  4621. ;
  4622. ; PANDA monitor verified to have 400000,,RSKP in NVTDOD (see [129])
  4623. ;
  4624. ;passed:  nothing, but check to see whether we are in automatic
  4625. ;      mode and if so, we execute our code, otherwise we are
  4626. ;      in override mode and we skip any checks
  4627. ;
  4628. ;returns: +1, always, although may complain about Jsyi errors
  4629. ;
  4630. ;      Expects to be ablt to trash t1,t2 and t3
  4631. ;      tvtflg will be side-effect by our (possible lack of) discovery
  4632.  
  4633. chktvt:    skipn tvtchk        ;[182] Are we supposed to figure out if TVT?
  4634.      ret            ;[182]  No, so skip all this cruft
  4635.  
  4636.     hrrz t1,ttynum        ;[182] Load the current line
  4637.     txo t1,.ttdes        ;[182] Convert line to a device designator
  4638.     movem t1,ntiblk+.NWLIN    ;[182] Store requested terminal
  4639.     dmove t1,[exp ntblen,.NWRRH] ;[182] Requesting remote host information
  4640.     dmovem t1,ntiblk+.NWABC    ;[182] Store length and request type
  4641.     dmove t1,[exp .NULIO,.NWRRH] ;[182] Output the node name to NUL:
  4642.     dmovem t1,ntiblk+.NWNNP    ;[182] return remote host information
  4643.     setz t1,        ;[182] Everything else is zero
  4644.     movem t1,tvtflg        ;[182] Assume not on a TVT
  4645.     movem t1,ntiblk+.NWNNU    ;[182] Initialize returned node numbers and
  4646.     move t1,[ntiblk+.NWNNU,,ntiblk+.NWNU1] ;[182] clobber everything else
  4647.     blt t1,ntiblk+ntblen-1    ;[182] Clear whatever is left in the block
  4648.  
  4649.     movei t1,ntiblk        ;[182] Load the address of the argument block
  4650.     NTINF%            ;[182] finally try to see out what's going on
  4651.      %jserr <NTINF failed>,chktv0 ;[182] Phooey, try the olde fashioned way
  4652.                 ;[182] Load network type and line type
  4653.     ldb t1,[POINTR(<ntiblk+.NWTTF>,nttype)]
  4654.     ldb t2,[POINTR(<ntiblk+.NWTTF>,ntline)]
  4655.     cain t1,NW%TCP        ;[182] Is the network type NOT TCP?
  4656.      caie t2,NW%TV        ;[182]  or is this NOT a TVT?
  4657.       ret            ;[182]   Leave line set as not a TVT
  4658.     aos tvtflg        ;[182] Okay, set TVT-BInary to ON
  4659.     ret            ;[182] 
  4660.  
  4661. ;[182] Begin moved code from before $stlnz:, above
  4662.  
  4663. ;The following code is not used because a BBN TCP jsys is called.
  4664. ;Some ARPA sites don't have the BBN jsys's any more.  Those that have them
  4665. ;keep them in different places (MONSYM, TCPSYM, etc).  Rather than make the
  4666. ;program site-dependent, this has been replaced with a SET TVT command until
  4667. ;the DEC TCP jsys's become standard and widespread, assuming there will be a
  4668. ;GETAB or other jsys to tell whether a given TTY is a TVT.
  4669.  
  4670.  
  4671. chktv0:                ;[182] Here to try to grovel over STAT
  4672.  
  4673. ;[129] The next 10 or so lines of code adapted from MODEM.MAC
  4674.  
  4675.     movx t1,tcp%nt        ;[129] Want aobjn ptr for tvts
  4676.     STAT%            ;[129] Get it
  4677.      %jserr <STAT failed>,r ;[182]  Just give up
  4678.     hrrz t3,ttynum        ;[129] Tty line we're useing
  4679.     hrrz t1,t2        ;[129] Get first tvt
  4680.     camge t3,t1        ;[129] Are we less than the first?
  4681.      ret            ;[182] Yes
  4682.     hlres t2        ;[129] Calculate last tvt
  4683.     sub t1,t2        ;[129] ...
  4684.     subi t1,1        ;[129] ...
  4685.     camg t3,t1        ;[129] Are we .le. last tvt?
  4686.      aos tvtflg        ;[182] Yes, flag for later
  4687.     ret            ;[182]
  4688.  
  4689. ;[182] End moved code from before $stlnz:, above
  4690.  
  4691.  
  4692.  
  4693.     subttl    STATISTICS command
  4694.  
  4695. ; Help text for STATISTICS
  4696.  
  4697. hstatu:    asciz |
  4698. STATISTICS
  4699.  
  4700. Give statistics about the most recent file transfer.
  4701. |
  4702.  
  4703. ; Parse rest of STATISTICS command.
  4704.  
  4705. .stat:    noise <about last file transfer> ; STATISTICS
  4706.     confrm
  4707.     ret
  4708.  
  4709. ; Execute STATISTICS command.
  4710.  
  4711. $stat:    setzm otot        ;[180]
  4712.     tmsg <
  4713.  Maximum number of characters in packet:  >
  4714.     numout rpsiz
  4715.     tmsg < received; >
  4716.     numout  spsiz
  4717.     tmsg < sent
  4718. >
  4719.     skipn t2, stdat        ;[36] If no time was spent transferring,
  4720.      jrst $statx        ;[36]  skip the rest.
  4721.     tmsg < Number of characters transmitted in >
  4722.     idivi t2, ^d3        ; Convert thirds of seconds to seconds.
  4723.     movem t2, sec        ; Save the number of seconds.
  4724.     idivi t2, ^d60        ; Divide to get minutes.
  4725.     move t4, t3        ; Save the remainder.
  4726.     jumpe t2, $stat2    ; If no minutes then don't print them.
  4727.     numout t2
  4728.     tmsg < minutes and >
  4729. $stat2:    move t2, t4        ; Get the remainder.
  4730.     jumpe t2, $stat3    ; If no seconds then don't print them.
  4731.     numout t2
  4732.     tmsg < seconds>
  4733. $stat3:    tmsg <
  4734.     Sent:      >
  4735.     numout stot
  4736.     tmsg <        Overhead:    >
  4737.     movei t1, .priou    ; Output the number of chars in decimal.
  4738.     move t2, stot
  4739.     sub t2, stchr
  4740.     addm t2, otot        ;[180]
  4741.     numout t2
  4742.     tmsg <
  4743.     Received:  >
  4744.     numout rtot
  4745.     tmsg <        Overhead:    >
  4746.     movei t1, .priou    ; Output the number of chars in decimal.
  4747.     move t2, rtot
  4748.     sub t2, rtchr
  4749.     addm t2, otot        ;[180]
  4750.     numout t2
  4751.     ;...
  4752.  
  4753. ; STATISTICS command, cont'd
  4754.  
  4755.  
  4756.     tmsg <
  4757.     Total:     >
  4758.     movei t1, .priou    ; Output the number of chars in decimal.
  4759.     move t2, rtot
  4760.     add t2, stot
  4761.     move t4, t2        ; Save the total number of chars.
  4762.     numout t2
  4763.     tmsg <        Overhead:    >
  4764.     movei t1, .priou    ; Output the number of chars in decimal.
  4765.     move t2, otot        ;[180] Get total chars.
  4766.     numout t2
  4767.     tmsg <
  4768.  Total characters transmitted per second:    >
  4769.     move t2, t4        ; Total chars transmitted.
  4770.     idiv t2, sec        ; Divided by the number of seconds.
  4771.     numout t2
  4772.     tmsg <
  4773.  Effective data rate:    >
  4774.     skipn t2, stchr        ; Is the number of chars sent zero?
  4775.      move t2, rtchr        ;  If so we were receiving.
  4776.     idiv t2, sec        ; Divided by the number of seconds.
  4777.     imuli t2, ^d10        ; Multiply chars/sec by 10 to get bits/sec.
  4778.     numout t2
  4779.     tmsg < bps>
  4780.  
  4781. ;[180]...
  4782.     tmsg <
  4783.  ILDB: >
  4784.     numout ttildb
  4785.     tmsg <  SIN:  >
  4786.     numout ttisin
  4787.     tmsg <  SIN Max:  >
  4788.     numout ttimax
  4789.     tmsg <  BIN:  >
  4790.     numout ttibin    
  4791. ;...[180]
  4792.  
  4793.     skipge speed        ;[146] Do we know the speed?
  4794.      jrst $stat4        ; No.
  4795.     fltr t2, t2        ; Yes, float the effective data rate.
  4796.     fltr t4, speed        ; And the line speed.
  4797.     fmp t2, [100.0]
  4798.     fdv t2, t4
  4799.     tmsg <
  4800.  Efficiency:            >
  4801.     movei t1, .priou    
  4802.     setz t3,
  4803.     FLOUT
  4804.      erjmp .+1    
  4805.     tmsg < per cent>
  4806. $stat4:    skipn errptr        ; Was there an error?
  4807.      jrst $statx        ;  If not, done.
  4808.     tmsg <
  4809.  Canceled by error:  >
  4810.     move t1, errptr
  4811.     PSOUT%            ; If so output it.
  4812.     hrroi t1, crlf        ;[50]
  4813.     PSOUT%
  4814.     ;...
  4815.  
  4816. ; STATISTICS command, cont'd
  4817.  
  4818.  
  4819. ;[36] Interpacket pause.
  4820.  
  4821. $statx:    tmsg <
  4822.  Interpacket pause in effect: >
  4823.     movei t1, .priou
  4824.     move t2, pause
  4825.     setz t3,
  4826.     FLOUT
  4827.      nop
  4828.     tmsg < sec
  4829.  
  4830.  Timeouts: >            ;[54] How many timeouts and NAKs.
  4831.     numout ntimou
  4832.     tmsg <
  4833.  NAKs:       >
  4834.     numout nnak
  4835.  
  4836. ;[47][132] If debugging, tell most recent JSYS error.
  4837.  
  4838.     jumpe debug, $statz    ;[132] Debugging?
  4839. $statj:    tmsg <
  4840.  Last JSYS error: >        ; Yes, tell about last error.
  4841.     movei t1, .priou
  4842.     hrloi t2, .fhslf
  4843.     setz t3,
  4844.     ERSTR
  4845.      nop
  4846.      nop
  4847.     tmsg <
  4848.  Timer errors:    >        ;[132] Also, give hints if anything is
  4849.     numout timerx        ;  going wrong with timers.
  4850.  
  4851. $statz:    tmsg <
  4852.  
  4853. >
  4854.     ret
  4855.  
  4856. ; SHOW command.
  4857.  
  4858. ; Help text...
  4859.  
  4860. hshow:    asciz |
  4861. SHOW
  4862.  
  4863. Display current SET parameters, version of KERMIT-20, or other info:
  4864.  
  4865.   DAYTIME           Current date, time, phase of moon.
  4866.   DEBUGGING         Debugging mode and log file in effect, if any.
  4867.   FILE-INFO         Byte size for DEC-20 file i/o, incomplete file disposition.
  4868.   INPUT             Parameters for INPUT command.
  4869.   LINE              TTY line, parity, duplex, handshake, escape character.
  4870.   MACROS            Definitions for SET macros.
  4871.   PACKET-INFO       For incoming and outbound packets.  Items under RECEIVE
  4872.                     column show parameters for packets KERMIT-20 expects
  4873.                     to receive, under SEND shows parameters for outgoing
  4874.                     packets.
  4875.   TIMING-INFO       Delays, retries, server NAK intervals.
  4876.   VERSION           Program version of KERMIT-20.
  4877.   ALL               (default) All of the above.
  4878. |
  4879.  
  4880. ; Parse rest of SHOW command...
  4881.  
  4882. .show:    noise <parameters>    ; SHOW command
  4883.     movei t1, [flddb. .cmkey,,shotab,,<all>] ;[39]
  4884.     call cfield        ;[39]
  4885.     hrrz t2, (t2)        ;[39]
  4886.     movem t2, pars2        ;[39]
  4887.     ret
  4888.  
  4889. shotab:    %table            ;[39] (this whole keyword table)
  4890.     %key <all>,0
  4891.     %key <daytime>,$shday
  4892.     %key <debugging>,$shdeb
  4893.     %key <file-info>,$shfil
  4894.     %key <input-info>,$shinp ;[160]
  4895.     %key <line>,$shlin
  4896.     %key <macros>,$shmac    ;[77]
  4897.     %key <packet-info>,$shpkt
  4898.     %key <timing-info>,$shtim
  4899.     %key <version>,$shver
  4900.     %tbend
  4901.     
  4902. $show:    move q1, [ret]        ;[39] Return after each piece
  4903.     skipn t2, pars2        ;[39] unless ALL was selected, in which case
  4904.      jrst [    move q1, [nop]    ;[39] fall thru from piece to piece,
  4905.         jrst $shtop ]    ;[39] starting from top.
  4906.     tmsg <
  4907. >                ;[39] Single SHOW item.  Emit blank line,
  4908.     jrst (t2)        ;[39] then go show the requested stuff.
  4909.  
  4910. $shtop: ;[39] Top of SHOW command.
  4911.  
  4912. ; SHOW VERSION
  4913.  
  4914. $shver:    tmsg <TOPS-20 Kermit version >
  4915. $shv2:    ldb t2, [301100,,versio] ; major version
  4916.     numout t2, 8
  4917.     ldb t2, [220600,,versio] ;[95]
  4918.     skipe t2        ;[95] minor version
  4919.      call [    movei t1, "."    ;[95] Use new decimal notation
  4920.         PBOUT        ;[95]
  4921.         numout t2, 8    ;[95]
  4922.         ret ]
  4923.     hrrz t3, versio        ; edit
  4924.     skipe t3
  4925.      call [    movei t1, "("
  4926.         PBOUT
  4927.         numout t3, 8
  4928.         movei t1, ")"
  4929.         PBOUT
  4930.         ret ]
  4931.     ldb t4, [410300,,versio] ; who
  4932.     skipe t4
  4933.      call [    movei t1, "-"
  4934.         PBOUT
  4935.         numout t4, 8
  4936.         ret ]
  4937.     tmsg <
  4938.  
  4939. >
  4940.     xct q1            ;[39] return or proceed...
  4941.  
  4942. ; SHOW DAYTIME
  4943.  
  4944. $shday:    movx t1, .priou        ; Current date and time.
  4945.     seto t2,        ;
  4946.     movx t3, ot%day!ot%fdy!ot%fmn!ot%4yr!ot%dam!ot%spa!ot%scl
  4947.     ODTIM%
  4948.      erjmp .+1
  4949.     call moon        ; Phase of the moon.
  4950.  
  4951.     tmsg <
  4952. >
  4953.     xct q1            ;[39] return or proceed...
  4954.  
  4955. ; SHOW LINE
  4956.  
  4957. $shlin:    tmsg <TTY for file transfer:  >
  4958.     numout ttynum, 8
  4959.     move t4, mytty        ; See whether we're local or remote...
  4960.     hrroi t1, [asciz/
  4961.  (job's controlling terminal, KERMIT-20 is REMOTE)/]
  4962.     came t4, ttynum
  4963.      hrroi t1, [asciz/
  4964.  (assigned TTY line, KERMIT-20 is LOCAL)/]
  4965.     PSOUT%
  4966.  
  4967.     move t1, netjfn        ;[130] Tell about modem control & carrier.
  4968.     call chklin
  4969.     skipn mdmlin
  4970.      jrst $show3
  4971.     tmsg <
  4972.   Line has modem control
  4973.   Carrier:          >
  4974.     hrroi t1, [asciz/On/]    ; Say it's on.
  4975.     skipn carier        ; Is it?
  4976.      hrroi t1, [asciz/Off/]    ; No.
  4977.     PSOUT            ; Tell
  4978.  
  4979. $show3:    tmsg <
  4980.   Handshake:        >        ;[76] Handshake
  4981.     skipn t1, handsh    ; Any?
  4982.      jrst [    tmsg <None>
  4983.         jrst $shw3a ]
  4984.     call putc
  4985. $shw3a:    tmsg <
  4986.   Flow-Control:     >        ;[143]
  4987.     hrroi t1, [asciz/XON-XOFF/]
  4988.     skipn flow
  4989.      hrroi t1, [asciz/None/]
  4990.     PSOUT
  4991.  
  4992. $show4:    tmsg <
  4993.   Parity:           >
  4994.     move t2, parity
  4995.     hrroi t1, [asciz/None/]
  4996.     cain t2, space
  4997.      hrroi t1, [asciz/Space/]
  4998.     cain t2, mark
  4999.      hrroi t1, [asciz/Mark/]
  5000.     cain t2, odd
  5001.      hrroi t1, [asciz/Odd/]
  5002.     cain t2, even
  5003.      hrroi t1, [asciz/Even/]
  5004.     PSOUT%
  5005.  
  5006. $sho4a:    tmsg <
  5007.   Duplex:           >        ;[18]
  5008.     move t2, duplex
  5009.     hrroi t1, [asciz/Full/]
  5010.     caie t2, dxfull
  5011.      hrroi t1, [asciz/Half/]
  5012.     PSOUT
  5013.     ;...
  5014.  
  5015. ;...SHOW LINE, cont'd
  5016.  
  5017.     tmsg <
  5018.   Speed:            >            ; Line speed.
  5019.     skipl speed        ; If negative, we don't really know it.
  5020.      numout speed
  5021.     hrroi t1, [asciz/(Unknown)/]
  5022.     skipge speed        ; If not negative, we know it.
  5023.      PSOUT
  5024.  
  5025. $sho4b:    skipn local        ;[96] Don't confuse them with this
  5026.      jrst $sho4c        ;[96]  unless they're local.
  5027.     tmsg <
  5028.   Escape:           >
  5029.     move t1, escape
  5030.     call putc
  5031.  
  5032. $sho4c:    tmsg <
  5033.   Break Simulation: >
  5034.     hrroi t1, [asciz/Enabled/]
  5035.     skipg speed
  5036.      hrroi t1, [asciz/Disabled/]
  5037.     PSOUT
  5038.     skipg speed
  5039.      jrst $sho4d
  5040.     tmsg <, >
  5041.     numout brk
  5042.     tmsg < NULs at 50 baud>
  5043.  
  5044. $sho4d: tmsg <
  5045.   TVT Binary:       >         ;[129] ARPAnet TVT binary mode.
  5046.     hrroi t1, [asciz/Off/]
  5047.     skipe tvtflg
  5048.      hrroi t1, [asciz/On/]
  5049.     PSOUT
  5050.     tmsg <
  5051.   TVT Negotiate:    >         ;[182] ARPAnet TVT discovery
  5052.     hrroi t1, [asciz/Override/]
  5053.     skipe tvtchk
  5054.      hrroi t1, [asciz/Automatic/]
  5055.     PSOUT
  5056.  
  5057. $sho4e:    tmsg <
  5058.   Log:              >
  5059.     skipg t2, sesjfn    ; are we logging?
  5060.      skipl t2, savjfn    ; or toggled off?
  5061.      skipa
  5062.      jrst [    tmsg <(none)>
  5063.         jrst $sho4f ]
  5064.     movei t1, .priou    ; so print the Log file
  5065.     setzb t3, t4        ; default format, no prefix
  5066.     JFNS            ; output it
  5067.      erjmp [tmsg <(none)>
  5068.         jrst $sho4f ]
  5069.     hrroi t1, [asciz/ (on)/] ; assume toggled on
  5070.     skipg sesjfn        ; is that correct?
  5071.      hrroi t1, [asciz/ (off)/] ; no, use other message
  5072.     PSOUT            ; output it
  5073.  
  5074. $sho4f:    ;put next one here...
  5075.  
  5076. $sho4x:    tmsg <
  5077.  
  5078. >
  5079.     xct q1            ;[39] return or proceed...
  5080.  
  5081. ; SHOW FILE-INFO
  5082.  
  5083. $shfil:    tmsg <Byte size for file I/O:  >
  5084.     hrroi t1, [ASCIZ/"Auto"/]
  5085.     skipn autbyt
  5086.      jrst [    hrroi t1, [asciz/Seven-Bit/]
  5087.         skipe ebtflg
  5088.          hrroi t1, [asciz/Eight-Bit/]
  5089.         jrst .+1 ]
  5090.     PSOUT%
  5091.     tmsg <
  5092.   File name conversion: >    ;[84]
  5093.     hrroi t1, [asciz/Off/]    ;[84]
  5094.     skipe xfnflg        ;[84]
  5095.      hrroi t1, [asciz/On/]    ;[84]
  5096.     PSOUT            ;[84]
  5097.     tmsg <
  5098.   ITS-binary-format file recognition >    ;[75]
  5099.     hrroi t1, [asciz/enabled/]    ;[75]
  5100.     skipn itsflg            ;[75]
  5101.      hrroi t1, [asciz/disabled/]    ;[75]
  5102.     PSOUT                ;[75]
  5103.     tmsg <
  5104.   Disposition for incomplete incoming files: > ;[42]
  5105.     hrroi t1, [asciz/Discard/]
  5106.     skipe abtfil        ;[42]
  5107.      hrroi t1, [asciz/Keep (whatever was received)/]
  5108.     PSOUT%            ;[42]
  5109.     tmsg <
  5110.   Deleted files are >        ;[143]
  5111.     hrroi t1, [asciz/NOT /]
  5112.     skipn expung
  5113.      PSOUT
  5114.     tmsg <expunged automatically
  5115.   Transaction log file: >    ;[126]
  5116.     skipn t2, tlgjfn    ; Any?
  5117.      jrst [    hrroi t1, [asciz/ (none)/] ; No.
  5118.         PSOUT
  5119.         jrst $shflx ]
  5120.     movei t1, .priou    ; Yes, a real file,
  5121.     setz t3,        ; Say what it is.
  5122.     JFNS
  5123.      %jserr (,.+1)
  5124. $shflx:    tmsg <
  5125.  
  5126. >
  5127.     xct q1            ;[39] return or proceed...
  5128.  
  5129. ; SHOW DEBUG
  5130.  
  5131. $shdeb:    tmsg <Debugging: >
  5132.     hrro t1, [
  5133.         [asciz/Off/]
  5134.         [asciz/States/]
  5135.         [asciz/Packets/]
  5136.         ](debug)
  5137.     PSOUT%
  5138.     jumpe debug, $shdbx    ;[38]
  5139.     tmsg <
  5140.   Debugging log file: >        ;[38]
  5141.     move t2, logjfn        ;[38] Any log file?
  5142.     cail t2, 1        ;[71] 0 or -1 means none.
  5143.      caile t2, 100        ;[71] 100 or above is .priou or whatever...
  5144.      jrst [    hrroi t1, [asciz/ (none)/] ;[38] None.
  5145.         PSOUT        ;[38]
  5146.         jrst $shdbx ]    ;[38]
  5147.     movei t1, .priou    ;[38] Yes, a real file,
  5148.     setz t3,        ;[38] Say what it is.
  5149.     JFNS            ;[38]
  5150.      %jserr (,.+1)        ;[38]
  5151.     tmsg <, bytesize >    ;[41]
  5152.     numout logbsz        ;[41]
  5153. $shdbx:    tmsg <
  5154.  
  5155. >                ;[39]
  5156.     xct q1            ;[39] return or proceed...
  5157.  
  5158. ; SHOW PACKET-INFO
  5159.  
  5160. ;[100] New headings, less confusing.
  5161. ;
  5162. $shpkt:    tmsg <Packet parameters:
  5163.  
  5164.               Inbound         Outbound
  5165.   Size:            >
  5166.     numout rpsiz,^d10
  5167.     tmsg <        >
  5168.     numout spsiz,^d10
  5169.     tmsg < characters
  5170.   Padding:         >
  5171.     numout rpadn
  5172.     tmsg <        >
  5173.     numout spadn
  5174.     tmsg <
  5175.   Pad Character:   >
  5176.     move t1, rpadch
  5177.     call putc
  5178.     tmsg <        >
  5179.     move t1, spadch
  5180.     call putc
  5181. $show8:    tmsg <
  5182.   End-Of-Line:     >
  5183.     move t1, reolch
  5184.     call putc
  5185.     tmsg <        >
  5186.     move t1, seolch
  5187.     call putc
  5188.     tmsg <
  5189.   Control Prefix:  >
  5190.     move t1, rquote
  5191.     call putc
  5192.     tmsg <        >
  5193.     move t1, squote
  5194.     call putc
  5195.     ;...
  5196.  
  5197. $showa: tmsg <
  5198.   Start-Of-Packet: >
  5199.     move t1, ssthdr        ;[18]
  5200.     call putc
  5201.     tmsg <        >
  5202.     move t1, rsthdr        ;[18]
  5203.     call putc
  5204.  
  5205. ;[100] New headings for this stuff.
  5206. $shpk2:    tmsg <
  5207.  
  5208.               Requested       Used
  5209.   8th-bit Prefix:  >        ;[88] Begin addition
  5210.     skipe ebqr        ; Did our user request 8th bit prefix?
  5211.      jrst [    move t1, ebq    ; Yes.
  5212.         call putc    ; Say what it is.
  5213.         tmsg <            >
  5214.         jrst .+1 ]
  5215.     skipn ebqr
  5216.      jrst [    tmsg <(none)       > ; No, just say we'll do it if asked.
  5217.         jrst .+1 ]
  5218.     skipe ebqflg        ; Was it used during last transfer?
  5219.      jrst [    move t1, ebq    ; Looks like it, say what prefix.
  5220.         call putc
  5221.         jrst .+1 ]    ;[88] End addition
  5222.     skipn ebqflg
  5223.      jrst [    tmsg <(none)>    ; No, just say we'll do it if asked.
  5224.         jrst .+1 ]
  5225.     tmsg <
  5226.   Repeat Prefix:   >        ;[92] Begin addition
  5227.     move t1, rptq        ; What we use to flag repeat counts.
  5228.     call putc
  5229.     tmsg <        >
  5230.     skipe rptflg        ; Was it actually used?
  5231.      jrst [    move t1, rptq
  5232.         call putc
  5233.         jrst .+1 ]    ;[92] End addition
  5234.     skipn rptflg
  5235.      jrst [    tmsg <(none)    > ; No, just say we'll do it if asked.
  5236.         jrst .+1 ]
  5237.     tmsg <
  5238.   Block Check:     >        ;[98] Block check type.
  5239.     move t1, bctr
  5240.     call putc
  5241.     tmsg <        >
  5242.     numout bctu        ;[98]
  5243.  
  5244.     tmsg <
  5245.  
  5246. >
  5247.     xct q1            ;[39] return or proceed...
  5248.  
  5249. ; SHOW TIME-INFO
  5250.  
  5251. $shtim:    tmsg <Timing parameters:
  5252.  
  5253.               Receive         Send
  5254.   Timeout:         >        ;[45]
  5255.     numout rrtimo        ;[128]
  5256.     tmsg <        >
  5257.     skipg stimou        ;[45]
  5258.      jrst [    tmsg <(none)>    ;[45]
  5259.         jrst $shpau ]    ;[45]
  5260.     numout stimou
  5261.     movei t1, "-"        ;[6]
  5262.     PBOUT%            ;[6]
  5263.     numout [maxtim]        ;[6]
  5264.     tmsg < sec>
  5265. $shpau:    tmsg <
  5266.   Pause:           >        ;[36]
  5267.     movei t1, .priou    ;[36]
  5268.     move t2, rpause        ;[36]
  5269.     setz t3,        ;[36]
  5270.     FLOUT            ;[36]
  5271.      nop            ;[36]
  5272.     tmsg <        >    ;[36]
  5273.     movei t1, .priou    ;[36]
  5274.     move t2, spause        ;[36]
  5275.     FLOUT            ;[36]
  5276.      nop            ;[36]
  5277.     tmsg < sec
  5278.  
  5279. Delay before sending first packet:  >
  5280.     move t1, delay        ;[100]
  5281.     skipe local        ;[100]
  5282.      setz t1,        ;[100]
  5283.     numout t1        ;[100]
  5284.     tmsg < sec
  5285. Packet retries before timeout:      >
  5286.     numout maxtry
  5287. $showc:    tmsg <
  5288. Number of retries for init packet:  >
  5289.     numout imxtry
  5290.     skipn srvtim
  5291.      jrst $shwc2
  5292.     tmsg <
  5293. Server sends NAKs every >
  5294.     numout srvtim
  5295.     tmsg < sec while waiting for command.>
  5296. $shwc2:    skipn debug        ; No blips if debugging.
  5297.      skipn local        ; Or if not local.
  5298.      jrst $showx        ;  ...
  5299. $showd:    tmsg <
  5300.  
  5301. "." for every >            ;[4]
  5302.     numout [blip]        ;[9]
  5303.     tmsg < packets, "%" for each NAK.>
  5304. $showx:    tmsg <
  5305.  
  5306. >                ;[4]
  5307.     xct q1
  5308.  
  5309. ;[160] Show INPUT parameters
  5310. ;
  5311. $shinp:    tmsg <Parameters for INPUT commands:>
  5312.     tmsg <
  5313.   Alphabetic Case: >
  5314.     hrroi t1, [asciz/Ignored in matching/]
  5315.     skipe incase
  5316.      hrroi t1, [asciz/Observed in matching/]
  5317.     PSOUT
  5318.     tmsg <
  5319.   Default Timeout: >
  5320.     skiple indeft
  5321.      numout indeft
  5322.     hrroi t1, [asciz/ sec/]
  5323.     skiple indeft
  5324.      PSOUT    
  5325.     hrroi t1, [asciz/Infinite/]
  5326.     skipg indeft
  5327.      PSOUT
  5328.     tmsg <
  5329.   Timeout Action:  >
  5330.     hrroi t1, [asciz/Proceed with command file
  5331.  
  5332. /]
  5333.     skipe intima
  5334.      hrroi t1, [asciz/Quit from command file
  5335.  
  5336. /]
  5337.     PSOUT    
  5338.     xct q1        
  5339.  
  5340.  
  5341. ;[77] SHOW MACRO DEFINITIONS
  5342. ;
  5343. $shmac:    tmsg <Macro definitions:>
  5344.     hlrz t4, mactab        ; Anything in macro table?
  5345.     skipg t4        ; Yes, tell what.
  5346.      jrst [    tmsg < (none)
  5347. >
  5348.         jrst $shmax ]    ; No, say so.
  5349.     tmsg <
  5350. >                ; Yes, list it/them.
  5351.     movei t3, 1
  5352.  
  5353. $shma2:    movei t1, 40        ; Space
  5354.     PBOUT
  5355.     hlro t1, mactab(t3)    ; Point to macro name.
  5356.     PSOUT            ; Print it.
  5357.     tmsg < = >
  5358.     hrro t1, mactab(t3)    ; Same deal for macro body.
  5359.     PSOUT
  5360.     aos t3            ; Bump index.
  5361.     sojg t4, $shma2        ; Do for all macros in table.
  5362.     tmsg <
  5363. >
  5364. $shmax:    ret            ;[83] Last one, always want to return.
  5365.  
  5366. ; PUTC - Routine to print a single character, using ^X notation, DEL, etc.
  5367. ;
  5368. ; Call with t1/ character to print.
  5369. ;
  5370. putc:    caile t1, "~"        ; Rubout?
  5371.      jrst [ tmsg <DEL>    ;  Yes, type this?
  5372.         ret ]
  5373.     caige t1, " "        ; Is it a control char?
  5374.      jrst [ push p, t1    ;  Save the char.
  5375.         movei t1, "^"    ;  Get the control quote.
  5376.         PBOUT%
  5377.         pop p, t1
  5378.         ori t1, ^o100    ;  Turn on the non-control bit.
  5379.         jrst .+1 ]
  5380.     PBOUT%
  5381.     ret
  5382.  
  5383.     subttl    BYE command
  5384.  
  5385. hbye:    asciz |
  5386. BYE    
  5387.  
  5388. When running as a local Kermit, talking to a KERMIT server over a TTY line
  5389. specified in a SET LINE command, use the BYE command to shut down and log out
  5390. the server.  This will also close any local debugging log file and exit from
  5391. the local KERMIT.
  5392. |
  5393.  
  5394. ; Parse rest of BYE command.
  5395.  
  5396. .bye:    noise (to remote server) ; Parse rest of BYE command.
  5397.     confrm
  5398.     ret
  5399.  
  5400. ; Execute the BYE command.
  5401.  
  5402. $bye:    move t1, [point 7, [asciz/L/]]    ; An "L" for the data field.
  5403.     movei t2, "G"        ; Packet type is G.
  5404.     call srvcmd        ;[121] Send the command.
  5405.      jrst $byez        ;  Some error, don't exit.
  5406.  
  5407. ;[16] From here to end is part of edit 16.
  5408.  
  5409. $byex:    movei q1, 5        ; Try this 5 times
  5410.     movei t1, ^d750        ; Sleep a second.
  5411.     DISMS%
  5412. $byex2:    movei t1, ^d250        ; Sleep a little bit
  5413.     DISMS%
  5414.     move t1, netjfn        ; Any messages?
  5415.     SIBE%
  5416.      skipa t3, t2        ; Yes, this many characters.
  5417.      jrst $byexx        ;  No, try again.
  5418.     hrroi t2, buffer    ; Get whatever is there.
  5419.     movei t4, .chlfd
  5420.     SIN%
  5421.     setz t3,
  5422.     idpb t3, t2
  5423.     hrroi t1, buffer    ; And print it.
  5424.     PSOUT%
  5425. $byexx: sojg q1, $byex2        ; See if we want to type some more.
  5426.  
  5427.     setzm buffer        ; Zero this out, just in case.
  5428.     tmsg <...>        ; Maybe there's more, but...
  5429.     move t1, netjfn        ;  can't wait forever for it,
  5430.     CFIBF%            ;  throw the rest away.
  5431.      erjmp .+1
  5432.     setom f$exit        ;[38] Set exit flag.
  5433.  
  5434. ; Error exit
  5435.  
  5436. $byez:    setzm f$exit        ;[70] Don't exit.
  5437.     ret            ;[70]
  5438.  
  5439.     subttl    FINISH command
  5440.  
  5441.  ;[28] The FINISH command is edit 28.
  5442.  
  5443. ; Help text for FINISH command.
  5444.  
  5445. hfinis:    asciz |
  5446. FINISH
  5447.  
  5448. When running as a local Kermit, talking to a KERMIT server over a TTY line
  5449. specified in a SET LINE command, use the FINISH command to shut down the
  5450. server without logging out the remote job, so that you can CONNECT back to it.
  5451. Also, close any local debugging log file.
  5452. |
  5453.  
  5454. ; Parse rest of FINISH command.
  5455.  
  5456. .finis:    noise (remote server operation) ; Parse rest of FINISH command.
  5457.     confrm
  5458.     ret
  5459.  
  5460.  
  5461. ; Execute FINISH command.
  5462.  
  5463. $finis:    move t1, [point 7, [asciz/F/]] ; An "F" for the data field.
  5464.     movei t2, "G"        ; Packet type is G.
  5465.     call srvcmd        ; Go send the command.
  5466.      nop            ;  Ignore any failure.
  5467.     ret            ; Done.
  5468.  
  5469. hclear:    asciz |
  5470. CLEAR
  5471.  
  5472. Clear the input and output buffers of the currently selected line;
  5473. attempt to clear any XOFF condition.  Useful in local mode, when the
  5474. connection to the remote system appears to be stuck.
  5475. |
  5476. .clear:    noise <line>
  5477.     confrm
  5478.     ret
  5479.  
  5480. $clear:    call ttxon        ; Clear output buffer, send XON, etc.
  5481.     CFIBF            ; Also clear input buffer.
  5482.      erjmp r
  5483.     ret
  5484.  
  5485. hclose:    asciz |
  5486. CLOSE keyword
  5487.  
  5488. Close the specified log file, TRANSACTION, DEBUGGING, or SESSION,
  5489. and stop recording to that file.
  5490. |
  5491. ; Parse CLOSE command.
  5492.  
  5493. .close:    noise (logging of)
  5494.     movei t1, [flddb. .cmkey,,logtab] ; Parse what kind of log.
  5495.     call cfield
  5496.     hrrz t2, (t2)
  5497.     movem t2, pars2
  5498.     ret
  5499.  
  5500. ; Execute CLOSE command.
  5501.  
  5502. $close:    move t4, pars2        ; Get dispatch table offset.
  5503.     setz t1,        ; Make a zero.
  5504.     jrst @[exp $clost, $closs, $closd](t4) ; Dispatch.
  5505.  
  5506. $clost:    exch t1, tlgjfn        ; Load transaction log JFN and zero it.
  5507.     jrst $closx
  5508.  
  5509. $closs:    exch t1, sesjfn        ; Load session log JFN and zero it.
  5510.     skipg t1        ; Were we using the saved JFN?
  5511.      move t1, savjfn    ; Try that.
  5512.     setzm savjfn        ; Also zero any saved copy.
  5513.     jrst $closx
  5514.  
  5515. $closd:    exch t1, logjfn
  5516.  
  5517. $closx:    skipg t2, t1        ; Move JFN to t2 for JFNS, check for validity.
  5518.      jrst [    tmsg <
  5519. ?Logging was not being done>
  5520.         ret ]        ;  If no valid JFN, give this message.
  5521.     movei t1, "["        ; JFN looks OK - opening bracket for message.
  5522.     PBOUT
  5523.     movei t1, .priou    ; Type the filename.
  5524.     setz t3,
  5525.     JFNS
  5526.      %jserr (,r)
  5527.     move t1, t2        ; JFN back to t1 for other JSYS's.
  5528.     move t3, t2        ; Save the JFN here, too.
  5529.     RFPTR            ; Get file position.
  5530.      seto t2,        ;  On error, substitute -1.
  5531.     CLOSF            ; Close the file.
  5532.      erjmp [hrrzs t1    ; If error, check what it was.
  5533.         caie t1, clsx1    ; Already closed?
  5534.          %ermsg (,r)    ;  No, give message.
  5535.         move t1, t3    ; Yes, get the JFN back.
  5536.         RLJFN        ; Release it.
  5537.          nop        ; Ignore any errors.
  5538.         jrst .+1 ]
  5539.     tmsg < Closed, >    ; Finish the message,
  5540.     numout t2        ; including count of bytes written.
  5541.     tmsg < Byte(s) Written]>
  5542.     ret
  5543.  
  5544.     subttl    CONNECT command
  5545.  
  5546. ; Help text for CONNECT...
  5547.  
  5548.  
  5549. hconne:    asciz |
  5550. CONNECT [number]
  5551.  
  5552. Establish a terminal connection to the system connected to the octal TTY number
  5553. specified here or in the most recent SET LINE command, using full duplex
  5554. echoing and no parity unless otherwise specified in previous SET commands, and
  5555. logging the session to the file specified in the most recent LOG SESSION
  5556. command, if any.  Get back to KERMIT-20 by typing the escape character followed
  5557. by the letter C.  The escape character is Control-Backslash (^\) by default.
  5558. When you type the escape character, several single-character commands are
  5559. possible:
  5560.  
  5561. C -- Close the connection and return to KERMIT-20.
  5562. B -- Transmit a BREAK signal.
  5563. S -- Show status of the connection.
  5564. Q -- Temporarily quit logging.
  5565. R -- Resume logging.
  5566. P -- Push to a new Exec.  POP from the Exec to get back to the connection.
  5567. ^\ (or whatever you have set the escape character to be) -- Typing the escape
  5568.  character twice sends one copy of it to the connected host.
  5569.  
  5570. You can use the SET ESCAPE command to define a different escape character.
  5571. |
  5572.     ;...
  5573.  
  5574. ;...CONNECT command, cont'd
  5575.  
  5576.  
  5577. ; Parse rest of CONNECT command...
  5578.  
  5579. .conne:    noise <to tty>
  5580.     movei t1, [
  5581.      flddb. .cmnum,cm%sdh,^d8,<octal tty number to connect to>,,[
  5582.      flddb. .cmcfm,cm%sdh,,<confirm to connect to selected line>]]
  5583.     call rfield        ; Parse a tty number.
  5584.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  5585.     caie t3, .cmnum        ; Is it a number?
  5586.      ret            ;  If not it must be a confirm.
  5587.     movem t2, pars3        ; Save the tty number.
  5588.     confrm
  5589.     ret
  5590.  
  5591. ;[151] CONNECT code totally rewritten as Edit 151.  Formerly, CONNECT was
  5592. ; accomplished by running a program TTLINK in a lower fork.  Now, the code is
  5593. ; integrated into this program.  This was done for two reasons:
  5594. ;
  5595. ; 1. V6 of TOPS-20 doesn't allow multiple JFNs on the same TTY device.
  5596. ; 2. TTLINK was interrupt-driven and therefore did not work under batch.
  5597. ;
  5598. ; This method, similar to that used in Mark Crispin's TELNET program, uses
  5599. ; separate input and output forks.  It works under batch because the "pty"
  5600. ; is always "hungry".
  5601. ;
  5602. $conne:    skipe pars3        ; Did we parse a TTY number?
  5603.      call $setln        ;  If so, use that one.
  5604.     move t4, mytty        ; Find our terminal number.
  5605.     camn t4, ttynum        ; Is this number the same as requested one?
  5606.      jrst [    tmsg <
  5607. ?You can't CONNECT to your own line.
  5608.  Please use the SET LINE n command to select another line.>
  5609.         ret ]
  5610.  
  5611. ; Set up controlling TTY for talk mode, issue connect message.
  5612.  
  5613.     call ttyini        ; Init controlling TTY.
  5614.     tmsg <[KERMIT-20: Connecting to remote host over TTY> ; Type message.
  5615.     numout ttynum,^d8
  5616.     tmsg <:, type >
  5617.     movei t1, 74        ; Left pointy bracket...
  5618.     PBOUT
  5619.     tmsg <CTRL->
  5620.     move t1, escape        ; (tell escape character)
  5621.     addi t1, "A"-1
  5622.     PBOUT
  5623.     movei t1, 76        ; ...Right pointy bracket
  5624.     PBOUT
  5625.     tmsg <C to return.]
  5626. >
  5627. ; Tell about session log, if any.
  5628.  
  5629.     skipg t2, sesjfn    ; Logging?
  5630.      jrst ttsfrk        ; No.
  5631.     tmsg <[KERMIT-20: Logging to File > ; Yes, tell them now.
  5632.     movei t1, .priou    ; Type the filename.
  5633.     setz t3,
  5634.     JFNS    
  5635.      %jserr (,.+1)
  5636.     tmsg <]
  5637. >                ; End of message.
  5638.  
  5639. ; Create and start a fork to get and display input from the remote end.
  5640.  
  5641. ttsfrk:    movx t1, <cr%map!cr%cap!cr%st!netin> ; Share our map, start at NETIN.
  5642.     CFORK
  5643.      %jserr (,r)
  5644.     movem t1, ttfork    ; It's running, save fork handle.
  5645.  
  5646. ;[151] Keyboard input loop.
  5647.  
  5648. ttinch:    skipn ttfork        ; Have a fork?
  5649.      jrst $connx        ;  No, it's gone, so disconnect.
  5650.     move t1, ttyjfn        ; Get a byte from the controlling TTY.
  5651.     BIN
  5652.      %jserr (<Can't input from tty>,<.+1>) ; What could happen?
  5653.     ldb t3, [point 7, t2, 35] ; Make copy without parity.
  5654.     camn t3, escape        ; Is it the escape character?
  5655.      jrst doesc        ; Yes, go process single-char command.
  5656.     skipe duplex        ; Have to echo locally?
  5657.      call echo        ;  Yes, do.
  5658.     move t1, t2        ; Tack on desired parity.
  5659.     call @parity        ; The parity routine wants the character in t1.
  5660.     move t2, t1
  5661.     move t1, netjfn        ; Output the character to the connected TTY.
  5662.     BOUT
  5663.      %jserr (<Can't output to line>,tterr) ; If error, go check.
  5664.     jrst ttinch        ; Go back and do it again.
  5665.  
  5666. ; Error handler for connected TTY.
  5667.  
  5668. tterr:    skipn mdmlin        ; Modem controlled line?
  5669.      jrst ttinch        ;  No, go back.
  5670.     call chkli2        ; Go check for carrier.
  5671.     skipn carier        ; Still have it?
  5672.      skipa            ;  No, close the connection.
  5673.     jrst ttinch        ; Yes, keep plugging away till they disconnect.
  5674.  
  5675. ; Lost carrier, shut down the connection.
  5676.  
  5677.     tmsg <
  5678. [KERMIT-20: Lost Carrier On Remote Connection -- Returning to DEC-20]
  5679.  
  5680. >
  5681.     jrst $connx
  5682.  
  5683. ;[151] Code for receive fork.  Runs forever, asynchronously, till killed.
  5684.  
  5685. netin:     move t1, netjfn        ; Wait for input
  5686.     BIN
  5687.      %jserr (<Can't input from line>,neterr) ; Handle any errors.
  5688.     txz t2, 200        ; Strip parity.
  5689.     move t1, ttyjfn        ; Display incoming character on screen.
  5690.     BOUT            
  5691.      %jserr (<Can't output to tty>,<.+1>)
  5692.     skipg t1, sesjfn    ; Logging?
  5693.      jrst netin        ;  No, go back for more.
  5694.     BOUT            ; Yes, do that.
  5695.      %jserr (<Can't write log>,netlgx)
  5696.     jrst netin        ; Loop forever.
  5697.  
  5698. ; Error handler for session log output.
  5699.  
  5700. netlgx:    setz t1,        ; Go shut down the session log.
  5701.     call $closs    
  5702.     jrst netin    
  5703.  
  5704. ; Error handler for network TTY.
  5705.  
  5706. neterr:    skipn mdmlin        ; Modem controlled line?
  5707.      jrst netin        ;  No, go back.
  5708.     call chkli2        ; Go check for carrier.
  5709.     skipn carier        ; Still have it?
  5710.      skipa            ;  No, close the connection.
  5711.     jrst netin        ; Yes, keep plugging away till they disconnect.
  5712.  
  5713. ; Lost carrier, shut down the connection.
  5714.  
  5715. neterx:    tmsg <
  5716. [KERMIT-20: Lost Carrier On Remote Connection -- Returning to DEC-20]
  5717.  
  5718. >
  5719.     setzm ttfork        ; Zero the fork handle/flag.
  5720.     HALTF            ; Halt this fork.
  5721.     0            ; Should never get here...
  5722.  
  5723. ;[151] Escape character was typed -- Get argument.
  5724.  
  5725. doesc:    move t1, ttyjfn
  5726.     BIN            ; Escape char was typed, get argument.
  5727.     trz t2, 200        ; Strip any parity bit.
  5728.     cail t2, "a"        ; Uppercase any letter.
  5729.      caile t2, "z"
  5730.      skipa    
  5731.      subi t2, 40
  5732.     cain t2, " "        ; The null command.
  5733.      jrst ttinch        ;  ...
  5734.     cain t2, "S"        ; Status query
  5735.      jrst [    move q1, [ret]    ; Calling convention for show line.
  5736.         call $shlin    ; Go show line parameters.
  5737.         jrst ttinch ]    ; Go back for more input.
  5738.     cain t2, "C"        ; Close connection.
  5739.      jrst $connx
  5740.     cain t2,"B"        ; is it a break?
  5741.      jrst [ call brkin0    ; yes, handle it
  5742.         jrst ttinch ]    ; then continue
  5743.     cain t2, "Q"        ; Quit logging
  5744.      jrst [    call qlog
  5745.         jrst ttinch ]
  5746.     cain t2, "R"        ; Resume logging
  5747.      jrst [ call rlog
  5748.         jrst ttinch ]
  5749.     cain t2, "?"        ; Help
  5750.      jrst [    hrroi t1, [asciz\
  5751. KERMIT-20 Single-Character CONNECT-Mode Commands:
  5752.  B - Send BREAK signal
  5753.  C - Close connection
  5754.  S - Status
  5755.  P - Push to Exec
  5756.  Q - Quit logging
  5757.  R - Resume logging
  5758.  ? - This message
  5759. Type the escape character twice to send one copy of it to the remote host.
  5760.  
  5761. Escape character is "\]
  5762.         PSOUT
  5763.         move t2, escape    ; Type the escape character.
  5764.         call echo
  5765.         tmsg <".
  5766. >
  5767.         jrst ttinch ]
  5768.     ;...
  5769.  
  5770. ;[151]...DOESC, cont'd
  5771.  
  5772.  
  5773.     camn t2, escape        ; Send escape character
  5774.      jrst [    skipe duplex    ; If local echo
  5775.          call echo    ;  take care of that.
  5776.         move t1, t2
  5777.         call @parity     ; Add desired parity to it.
  5778.         move t2, t1
  5779.         move t1, netjfn    ; Send it out the link.
  5780.         BOUT        ;
  5781.          %jserr (,tterr)
  5782.         jrst ttinch ]
  5783.     cain t2, "P"        ; PUSH to Exec
  5784.      jrst [    call fixtty    ; Put TTY in normal mode.
  5785.         call push    ; Do the pushing.
  5786.         call ttyini    ; Put back in talk mode.
  5787.         tmsg <
  5788. [KERMIT-20: Back at remote host]
  5789. >
  5790.         jrst ttinch ]
  5791.     movei t1, 7        ; Anything else, just beep
  5792.     PBOUT
  5793.     jrst ttinch
  5794.  
  5795. ; Come here to restore things.
  5796. ;
  5797. ; Take care of any session log file.  We want to close it, but leave the JFN
  5798. ; around in case the logging is resumed, the program continued, etc.
  5799. ;
  5800. $connx:    skipg t2, sesjfn    ; Is a log file open?
  5801.      jrst $conx2        ;  No, go do the rest.
  5802.     tmsg <
  5803. [KERMIT-20: Closing Log File >
  5804.     movei t1, .priou    
  5805.     setz t3,    
  5806.     JFNS
  5807.      %jserr (,.+1)
  5808.     tmsg <]
  5809. >
  5810.     move t1, t2        ; Get the JFN back into t1.
  5811.     hrli t1, (co%nrj)    ; Close, but don't release JFN.
  5812.     CLOSF%            ;  ...
  5813.      erjmp [hrrzs t1    ; If error, check what it was.
  5814.         cain t1, clsx1    ; Already closed?
  5815.          jrst .+1    ;  Yes, ignore.
  5816.         setzm sesjfn    ; Some other error, so JFNs are probably
  5817.         setzm savjfn    ; unusable, zero them out,
  5818.         %ermsg (,$conx2) ] ; complain, and return.
  5819.     movei t1, (t1)        ; Closed OK, open it again to prevent CLZFF
  5820.     movx t2, <fld(7,of%bsz)+of%app>    ; from stomping on the JFN.
  5821.     OPENF
  5822.      erjmp .+1
  5823.  
  5824. $conx2:    call fixtty        ; Put controlling tty back in data mode.
  5825.     movx t1, .priin        ; Flush any pending tty input.
  5826.     CFIBF
  5827.      erjmp .+1
  5828.     skipe t1, ttfork    ; Kill receive fork.
  5829.      KFORK%
  5830.      erjmp .+1
  5831.     setzm ttfork        ; Remember it's gone.
  5832.     movei t1, .priou    ; Output a CRLF if not at left margin.
  5833.     RFPOS%    
  5834.     hrroi t1, crlf
  5835.     trne t2, -1
  5836.      PSOUT%    
  5837.     tmsg <[KERMIT-20: Connection Closed]> ; Closed message.
  5838.     ret
  5839.  
  5840. ;[151] Character echoing routine.
  5841. ;
  5842. ; Need to do this because having tty open in binary mode overrides ccoc
  5843. ; settings.  t2 contains character to echo.
  5844. ;
  5845. echo:    saveac<t1,t2,t3>    ; Must save all ACs.
  5846.  
  5847.     trz t2, 200        ; Strip any parity.
  5848.     move t3, t2        ; Make a copy of the character.
  5849.  
  5850.     cail t3, 40        ;[18] Check most common case first,
  5851.      caile t3, 126        ;[18] namely, whether it's a printable
  5852.      skipa            ;[18] character.
  5853.      jrst echo2        ;[18] If so, just go print it.
  5854.  
  5855.     caig t3, 6        ; Check for control char, null thru ^F.
  5856.      jrst echo1
  5857.     cain t3, 13        ; ^K
  5858.      jrst echo1
  5859.     cail t3, 16        ; ^N-^Z
  5860.      caile t3, 32
  5861.      skipa
  5862.      jrst echo1
  5863.     cail t3, 34        ; ^\-^_
  5864.      caile t3, 37
  5865.      skipa
  5866.      jrst echo1
  5867.     cain t3, 33        ; ESC
  5868.      jrst [    movei t2, "$"    ; Echo as dollar sign
  5869.         jrst echo2 ]
  5870.     cain t3, 177        ; DEL
  5871.      jrst [    seto t3,     ; So it echoes as ^? (100-1=77="?")
  5872.         jrst echo1 ]
  5873.     move t2, t3        ; Anything else, just type it.
  5874.     jrst echo2
  5875.  
  5876. echo1:    skipg t1, ttyjfn    ; Echo it on the tty.
  5877.      movei t1, .priou
  5878.     movei t2, "^"        ; Print an uparrow
  5879.     BOUT
  5880.       %jserr (,.+1)
  5881.     skiple t1, sesjfn    ; Logging?
  5882.      call [    BOUT        ; Yes, do that.
  5883.          %jserr (,qlog)    ;  Error, print msg, close log, rtn from there.
  5884.         ret ]        ; No error.
  5885.     movei t2, 100(t3)    ; Convert to char to uncontrollified version.
  5886. echo2:    skipg t1, ttyjfn    ; Back to TTY.
  5887.      movei t1, .priou
  5888.     BOUT            ; Print the character itself.
  5889.      %jserr (,.+1)
  5890.     skiple t1, sesjfn    ; Logging?
  5891.      call [    BOUT        ; Yes, do that.
  5892.          %jserr (,qlog)    ;  Error, print msg, close log, rtn from there.
  5893.         ret ]        ; No error.
  5894.     ret
  5895.  
  5896. ;[151] BREAK-sending routine.  Simulate by sending some nulls at
  5897. ; a low baud rate.  Originally by Bill Schilit, Columbia.
  5898. ;
  5899. brkin0:    saveac <t1,t2,t3,t4>    ; save all used registers
  5900.     skipg speed        ; do we know about a speed?
  5901.      jrst brkin2        ; no, give a message
  5902.     move t1, netjfn        ; get the output terminal jfn
  5903.     movx t2, .mospd        ; set the speed
  5904.     hrlz t3, speed        ; same input speed
  5905.     hrri t3, ^d50        ; but output is lower (input,,output speeds)
  5906.     MTOPR
  5907.      %jserr (,r)
  5908.     skipg t3, brk        ; get count of nulls to send
  5909.      movei t3, defbrk    ; use the default
  5910.     caile t3, maxnul    ; greater than we support?
  5911.      movei t3, maxnul    ; yes, use that
  5912.     movns t3        ; make negative
  5913.     move t2, [point 7,nulls] ; point to them
  5914.     setzm t4        ; no stop char
  5915.     SOUT
  5916.      %jserr (,.+1)
  5917.     movx t2, .mospd        ; now reset speed
  5918.     move t3, speed
  5919.     hrls t3            ; make input same as output
  5920.     MTOPR
  5921.      %jserr (,r)
  5922.     ret
  5923.  
  5924. brkin2:    tmsg <
  5925. [KERMIT-20: Can't send BREAK, line speed unknown -- use SET SPEED command.]
  5926. >
  5927.     ret
  5928.  
  5929. defbrk==3            ; Default number of breaks.
  5930. maxnul==100            ; Maximum number of nulls.
  5931. nulls:    repeat <maxnul/5>+1,<0>    ; A string of nulls.
  5932.  
  5933. ;[151] Quit logging session during CONNECT.
  5934.  
  5935.  
  5936. qlog:    skipg t1, sesjfn    ; Do we have a session log?
  5937.      jrst [    tmsg <
  5938. %KERMIT-20 wasn't logging this session...
  5939. >
  5940.          ret ]
  5941.     movem t1, savjfn    ; Yes, save the JFN elsewhere.
  5942.     hrli t1, (co%nrj)    ; Close the log, but don't release JFN.
  5943.     CLOSF
  5944.      erjmp .+1
  5945.     setom sesjfn        ; Signal that we're not logging.
  5946.  
  5947. ; Open the log file again, to keep the JFN from getting flushed by CLZFF.
  5948.  
  5949.     movei t1, (t1)        ; Clear out bits from left half.
  5950.     movx t2, <fld(7,of%bsz)+of%app> ; Open for appending.
  5951.     OPENF
  5952.      %jserr (, [
  5953.         setom sesjfn
  5954.         jrst .+1 ])
  5955.     tmsg <
  5956. [KERMIT-20: Quit logging]
  5957. >
  5958.     ret
  5959.  
  5960.  
  5961. ;[151] Resume logging session after a hiatus.
  5962.  
  5963. rlog:    skiple sesjfn        ; Check for this...
  5964.      jrst [ tmsg <
  5965. %KERMIT-20 already logging...
  5966. >
  5967.         ret ]
  5968.     skipg t1, savjfn    ; Get the saved log JFN back.
  5969.      jrst [    tmsg <
  5970. %KERMIT-20 wasn't logging...
  5971. >
  5972.         ret ]
  5973.  
  5974. ; A log was selected, but not active.  Just juggle the JFNs.
  5975.  
  5976.     movem t1, sesjfn    ; Put saved JFN back as the log JFN.
  5977.     setom savjfn        ; Flag that there's no saved JFN.
  5978.     tmsg <
  5979. [KERMIT-20: Resume logging]
  5980. >
  5981.     ret
  5982.  
  5983.     subttl PUSH Command
  5984.  
  5985. ;[151] Push to Exec
  5986.  
  5987. push:    seto t1,        ; Save subsystem & program names...
  5988.     move t2, [-2,,pname]
  5989.     movei t3, .jisnm
  5990.     GETJI
  5991.      erjmp .+1
  5992.     tmsg <
  5993. [KERMIT-20: PUSHing to new EXEC.]
  5994. [POP from Exec to return.]
  5995. >
  5996.     skipe t1, execf        ; Have one already?
  5997.      jrst [    txo t1, sf%con    ;  Yes, just continue it.
  5998.         SFORK
  5999.          erjmp .+1    ;  Unless it disappeared...
  6000.         jrst push3 ]
  6001.     movx t1, cr%cap        ; No, create a fork.
  6002.     CFORK
  6003.      %jserr (,r)
  6004.     movem t1, execf        ; Save its handle.
  6005.        move t2, capas        ; Mask capas with this fork's enabled ones.
  6006.     txz t2, sc%log        ; Turn off logout capability.
  6007.     txo t2, sc%gtb        ; Turn on GETAB capability (must have it...)
  6008.     skipe jobtab+.jibat    ; Under batch?
  6009.      txz t2, sc%ctc        ;  If so, don't try to enable ^C capability.
  6010.     move t3,  t2        ; Enable capabilities.
  6011.     EPCAP
  6012.      %jserr (,r)        ;  Fail if can't, since Exec must have them.
  6013.     movx t1, gj%old+gj%sht    ; Get JFN on the Exec.
  6014.     hrroi t2, [asciz/SYSTEM:EXEC.EXE.0/]
  6015.     GTJFN
  6016.      %jserr (,r)
  6017.     move t4, t1        ; Save the JFN for a sec.
  6018.  
  6019.     hrl t1, execf        ; Get the Exec into the fork.
  6020.     GET
  6021.      %jserr (,r)
  6022.     move t1, t4        ; Release the Exec's JFN, don't need it.
  6023.     RLJFN
  6024.      nop
  6025.     move t1, execf        ; Exec fork handle.
  6026. push2:    setz t2,        ; Start up the fork.
  6027.     SFRKV
  6028.      %jserr (,r)
  6029. push3:    WFORK            ; Wait for it to halt.
  6030.     dmove t1, pname        ; Restore program/subsys name.
  6031.     SETSN
  6032.      nop
  6033.     ret
  6034.  
  6035. ; Put TTY in binary mode for output only.  Still allows normal input,
  6036. ; ^C trapping, etc.
  6037. ;
  6038. ttyob:    movei t1, .priou    ; Get CCOC words
  6039.     RFCOC
  6040.     dmovem t2, myccoc    ; Save em.
  6041.     move t2, [525252525252]    ; Make all characters output
  6042.     move t3, [525252525000]    ;  with no translation.
  6043.     SFCOC
  6044.     movei t2, .morxo    ; Get tty pause-end-of-page status.
  6045.     MTOPR%
  6046.      %jserr (,.+1)
  6047.     movem t3, ttpau        ; Save it.
  6048.     movei t2, .moxof    ; Set the terminal pause end...
  6049.     movei t3, .mooff    ; to no pause on end.
  6050.     MTOPR%
  6051.      %jserr (,.+1)
  6052.     ret
  6053.  
  6054. ; Restore TTY output to condition before TTYOB was called.
  6055.  
  6056. ttyou:    movei t1, .priou    ; Restore normal tty output.
  6057.     dmove t2, myccoc
  6058.     SFCOC
  6059.      %jserr (,.+1)
  6060.     movei t2, .moxof    ; Set terminal pause end-of-page...
  6061.     move t3, ttpau        ;  to what it used to be.
  6062.     MTOPR%
  6063.      %jserr (,.+1)
  6064.     ret
  6065.  
  6066. ;[151] Set up TTY for linking, and open any logging file.
  6067.  
  6068. ttyini:    movei t1, .fhslf    ; Read current process capabilities.
  6069.     RPCAP%
  6070.     movem t3, capas
  6071.     movei t1, .priin    ; Turn off terminal page mode and data mode.
  6072.     movem t1, ttyjfn
  6073.     RFMOD            ; Get tty mode word.
  6074.     movem t2, ttymod    ; Save it, to be restored later.
  6075. ; No echo, no data mode, full duplex.
  6076.      txz t2, <tt%eco!tt%dam!tt%dum!tt%lic> ;[129] Add TT$DUM
  6077. ; No wakeup stuff, infinite width & length.
  6078.     txz t2, <tt%wkf!tt%wkn!tt%wkp!tt%wka!tt%wid!tt%len!tt%uoc>
  6079. ; No formfeed/tab/case interpretation, use XON/XOFF.
  6080.     txo t2, <tt%mff!tt%tab!tt%lca!tt%pgm>
  6081.     skipn handsh        ;[155] Doing handshake?
  6082.      skipn flow        ;[155] Doing flow control?
  6083.      txz t2, tt%pgm        ; Handshake, or no flow - don't do XON/XOFF.
  6084.     SFMOD            ; Set the bits
  6085.      %jserr (,r)
  6086.     STPAR            ; ...and the other bits...
  6087.      %jserr (,r)
  6088.     movx t1, .fhjob        ; Turn off ^C, ^O, ^T interrupts for whole job.
  6089.     RTIW
  6090.     movem t2, tiword
  6091.     tdz t2, [1b<.ticcc>+1b<.ticco>+1b<.ticct>]
  6092.     move t3, capas        ; Do we have  ^C capability?
  6093.     txne t3, sc%ctc        ; Can't do STIW if we don't...
  6094.      STIW
  6095.      %jserr (,.+1)
  6096.     call seslog        ; Open the session log file.
  6097.     ret
  6098.  
  6099. ; Open the session log file.
  6100.  
  6101. seslog:    skipg t1, sesjfn    ; Logging?
  6102.      ret            ;  No.
  6103.     movx t2, <fld(7,of%bsz)+of%app> ; Yes, open for appending.
  6104.     OPENF
  6105.      erjmp [hrrzs t1    ; Got an error, get code.
  6106.         cain t1, opnx1    ; Already open?
  6107.          ret        ;  Ignore the error.
  6108.         setzm sesjfn    ; Real error, disable logging.
  6109.         %ermsg (,r) ]
  6110.     ret
  6111.  
  6112.  
  6113. ;[151] Restore TTY parameters, turn off interrupts, and close any log file.
  6114.  
  6115. fixtty:    move t1, ttyjfn        ; Restore mode word.
  6116.     move t2, ttymod
  6117.     SFMOD            ; Do both of these...
  6118.     STPAR
  6119.     movx t1, .fhjob        ; Put tty back the way it was.
  6120.     move t2, tiword        ; put the terminal interrupt word
  6121.     move t3, capas        ; Mask capas with this fork's enabled ones.
  6122.     txne t3, sc%ctc        ; Can't do this if no ^C capability.
  6123.      STIW            ;
  6124.      %jserr (,r)
  6125.     ret
  6126.  
  6127. ;[77] DEFINE command, added as edit 77.
  6128. ;
  6129. hdefin:    asciz |
  6130. DEFINE macroname set-parameters
  6131.  
  6132. Define a "SET macro" to allow convenient association of one or more SET
  6133. parameters with a mnemonic keyword of your choice.  The set-parameters are
  6134. a list of one or more SET options, separated by commas.  If you use KERMIT-20
  6135. to communicate with several different kinds of systems, you may set up a macro
  6136. for each, for instance:
  6137.  
  6138.   DEFINE IBM PARITY MARK, DUPLEX HALF, HANDSHAKE XON, SEND PACKET-LENGTH 80
  6139.   DEFINE UNIX PARITY NONE, DUPLEX FULL, HANDSHAKE NONE
  6140.   DEFINE TELENET PARITY MARK
  6141.  
  6142. You may then type SET IBM, SET UNIX, and so forth to set all the desired
  6143. parameters with a single command.  It is convenient to include these
  6144. definitions in your KERMIT.INI file.
  6145.  
  6146. You may redefine an existing macro in the same manner as you defined it.
  6147. You can undefine an existing macro by typing an empty DEFINE command for it,
  6148. for instance:
  6149.  
  6150.   DEFINE IBM
  6151.  
  6152. Macro definitions may not include macro names.
  6153. |
  6154.  
  6155. ;...DEFIN, cont'd
  6156.  
  6157.  
  6158. .defin:    noise <SET macro named>    ; Macro definition
  6159.     movei t1, [
  6160.      flddb. .cmfld,cm%sdh,,<new macro name for combining SET options>,,[
  6161.      flddb. .cmkey,,mactab,<old macro name to delete or redefine,>]
  6162.      ]
  6163.     call rfield        ; Get the macro name
  6164.  
  6165. ; Check on space for name string.
  6166.  
  6167. .defi2:    move t2, namp        ; Get current name buffer pointer.
  6168.     movei t3, namx        ; Is it at the end of the buffer?
  6169.     caig t3, (t2)
  6170.      jrst [    tmsg <?Macro name buffer full>
  6171.         jrst cmder1 ]
  6172.  
  6173. ; Have room, align pointer to word boundary.
  6174.  
  6175. .defi3:    hlrz t4, t2        ; Is it on a word boundary?
  6176.     caie t4, 440700    
  6177.      jrst [    aos t2        ; No, put it on one.
  6178.         hrli t2, (point 7,)
  6179.         movem t2, namp
  6180.         jrst .+1 ]
  6181.     movem t2, onamp        ; Remember pointer to beginning of string.
  6182.  
  6183. ; Copy the macro name into the macro name buffer.
  6184.  
  6185.     move t1, [point 7, atmbuf] ; Copy the string out of the atom buffer.
  6186.  
  6187. .defi4:    ildb t4, t1        ; Get a character.
  6188.     idpb t4, namp        ; Copy it.
  6189.     jumpn t4, .defi4    ; Everything up to & including the first null.
  6190.  
  6191. ; Let them type CR here to undefine the macro, or else jump into the SET
  6192. ; command parser to let them define a new macro, or redefine an old one.
  6193. ;
  6194. .defi5:    noise <to SET>        ; Prompt with guide words.
  6195.     move t1, sbk+.cmptr    ; Get current pointer from comnd state block.
  6196.     movem t1, macptr    ; Save it as pointer to macro body.
  6197.  
  6198. .defi6:    setom definf        ; Flag that we're doing a DEFINE.
  6199.     movei t1, [flddb. .cmkey,,settab,,,[
  6200.      flddb. .cmcfm,cm%sdh,,<Carriage return to undefine this macro>]
  6201.      ]
  6202.     call rfield        ; Parse a keyword or a CR.
  6203.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  6204.     setom undeff        ; Assume we're undefining?
  6205.     cain t3, .cmcfm        ; Parsed a CR?
  6206.      ret            ;  Yes, so done.
  6207.     setzm undeff        ; No, we're defining after all.
  6208.     callret .set2        ; Go parse SET commands.
  6209.  
  6210. ; DEFINE command execution.
  6211.  
  6212. ; Echo back what was typed...
  6213.  
  6214. $defin:    skipe undeff        ; Define or Undefine?
  6215.      jrst $defi7        ;  Undefine, go do that.
  6216. ;[82]    move t1, onamp        ; Name
  6217. ;[82]    PSOUT
  6218. ;[82]    tmsg < = >
  6219.     move t1, macptr        ; Text
  6220. ;[82]    PSOUT
  6221.  
  6222. ; Check for room left in macro text buffer.
  6223.  
  6224.     move t3, macbp        ; Get current macro text buffer pointer.
  6225.     movei t2, macx        ; Is it at the end of the buffer?
  6226.     caig t2, (t3)
  6227.      jrst [    tmsg <?Macro text buffer full>
  6228.         ret ]
  6229.  
  6230. ; Adjust to word boundary.
  6231.  
  6232. $defi2:    hlrz t4, t3        ; Is it on a word boundary?
  6233.     caie t4, 440700    
  6234.      jrst [    aos t3        ; No, put it on one.
  6235.         hrli t3, (point 7,)
  6236.         jrst .+1 ]
  6237.     movem t3, macbp        ; This copy is to be used.
  6238.     movem t3, omacbp    ; This points to the beginning of the result.
  6239.  
  6240. ; Copy the text out of the command buffer.
  6241.  
  6242. $defi3:    ildb t4, macptr        ; Get a character.
  6243.     idpb t4, macbp        ; Copy it.
  6244.     jumpn t4, $defi3    ; Everything up to & including the first null.
  6245.     
  6246. ; Add <address of macro name,,address of body> to macro keyword table.
  6247.  
  6248. $defi4:    movei t1, mactab    ; Stick it in the macro table.
  6249.     hrlz t2, onamp        ; Address of keyword,,
  6250.     hrr t2, omacbp        ;  argument (address of body)
  6251.     TBADD            ; ...
  6252.      erjmp $defi5        ; Handle any errors below.
  6253.     ret            ; OK, done.
  6254.  
  6255.     ;...
  6256.  
  6257. ; DEFINE command, cont'd
  6258.  
  6259.  
  6260. ; TBADD got an error.
  6261.  
  6262. $defi5:    movei t1, .fhslf    ; What was it?
  6263.     GETER
  6264.     hrrzs t2
  6265.     cain t2, taddx1        ; Table full?
  6266.      jrst [    tmsg <?Macro table is full> ; Yes, give message.
  6267.         ret ]
  6268.  
  6269. ; Duplicate entry?
  6270.  
  6271. $defi6:    caie t2, taddx2        ; Duplicate?
  6272.      callret jserr0        ; No, something unforseen.  Give message.
  6273.  
  6274. ; Come here directly to undefine an existing macro.
  6275. ; First look it up.
  6276. ;
  6277. $defi7:    movei t1, mactab    ; Yes, look up its address in the kwd table.
  6278.     move t2, onamp        ; Pointer to macro name.
  6279.     TBLUK
  6280.      %jserr (,r)
  6281.     skipn undeff        ; Were we undefining?
  6282.      jrst $defi8        ;  No, don't be beastly then...
  6283.     txnn t2, tl%exm        ; Yes, found an exact match?
  6284.      jrst [    tmsg <%">    ; No, warn.
  6285.         move t1, onamp
  6286.         PSOUT
  6287.         tmsg <" not found in SET macro table>
  6288.         ret ]
  6289.  
  6290. ; Using the table index just obtained, delete the entry.
  6291.  
  6292. $defi8:    move t2, t1        ; The address we just got.
  6293.     movei t1, mactab
  6294.     TBDEL            ; Delete the old entry.
  6295.      %jserr (,r)
  6296.     skipe undeff        ; Were we undefining, or replacing?
  6297.      ret            ; Undefining, so done.
  6298.  
  6299. ; Try to add the new definition again.
  6300.  
  6301. $defi9:    hrlz t2, onamp        ; Address of keyword,,
  6302.     hrr t2, omacbp        ;  argument (address of body)
  6303.     movei t1, mactab    ; Stick it in the macro table.
  6304.     TBADD
  6305.      %jserr (,r)        ; This time really give up on error.
  6306.     ret
  6307.  
  6308. ;[125] LOG command
  6309. ;
  6310. ; LOG help text..
  6311.  
  6312. hlog:    asciz |
  6313. LOG TRANSACTIONS or SESSION or DEBUGGING (to) filespec
  6314.  
  6315. Log files are closed upon exit from KERMIT-20, or explicitly by the CLOSE
  6316. command.
  6317.  
  6318. TRANSACTIONS:
  6319.  
  6320. Direct KERMIT-20 to log transactions, such as files successfully sent or
  6321. received, files that could not be successfully sent or received, and so forth,
  6322. to the specified file.
  6323.  
  6324. SESSION:
  6325.  
  6326. Create a transcript of a CONNECT session, when running KERMIT-20 in local
  6327. mode and connected to a remote system, in the specified file.  Log is closed
  6328. when connection is closed.  Logging can be toggled by typing the connect
  6329. escape character followed by Q (Quit logging) or R (Resume logging).
  6330.  
  6331. DEBUGGING:
  6332.  
  6333. Log the selected information (STATES or PACKETS, type HELP SET DEBUG for
  6334. further information) to the specified file.  If log file not specified, then
  6335. use TTY if local, DEBUGGING.LOG if remote.  If specified, then log STATES by
  6336. default.  Also allow specification of bytesize for log file, 7 (normal,
  6337. default), or 8 (for debugging binary transfers, use FILDDT to inspect the log).
  6338. |
  6339. logtab:    %table
  6340.     %key <debugging>,2    ;[143]
  6341.     %key <session>,1
  6342.     %key <transactions>,0
  6343.     %tbend
  6344.  
  6345. .log:    noise <what>        ; Give guide word
  6346.     movei t1, [flddb. .cmkey,,logtab,,<session>] ; Parse what kind of log.
  6347.     call rfield
  6348.     hrrz t2, (t2)
  6349.     movem t2, pars2
  6350.  
  6351.     skipe t1, pars3        ; Release any piled up JFNs from reparsing
  6352.      RLJFN
  6353.      nop
  6354.  
  6355.     noise <to file>        ; Noise
  6356.     move t2, pars2
  6357.     move t1, [
  6358.         [flddb. .cmofi,,,,<TRANSACTION.LOG.-1>] ; transaction log.
  6359.         [flddb. .cmofi,,,,<SESSION.LOG.-1>] ; Default session log,
  6360.         [flddb. .cmofi,,,,<DEBUGGING.LOG.-1>] ; & debugging log.
  6361.         ](t2)        ; Note index!
  6362.  
  6363.     call rfield        ; Parse log filespec.
  6364.     movem t2, pars3        ; Stash JFN here.
  6365.     move t2, pars2        ;[143] Debugging log?
  6366.     caie t2, 2        ;[143]
  6367.      jrst [    confrm        ;[143] No, get confirmation    
  6368.         ret ]        ;[143] and return.
  6369.     noise <with file byte size> ;[41] Yes, parse the file byte size.
  6370.     movei t1, [flddb. .cmkey,,dbstab,<log-file bits per byte,>,7] ;[41]
  6371.     call rfield        ;[41] Parse it.  Defaults to 7.
  6372.     hrrz t2, (t2)        ;[41] Get result.
  6373.     movem t2, pars4     ;[41] Save it.
  6374.     noise <bits>        ;[41] Comforting noise...
  6375.     confrm
  6376.     ret
  6377.  
  6378. ; Open the desired log.
  6379.  
  6380. $log:    move t1, pars2        ; What kind of log?
  6381.     jrst @[exp $logt, $logs, $logd](t1) ; Dispatch
  6382.  
  6383.  
  6384. ;[126] Transaction log.
  6385.  
  6386. $logt:    skipe t1, tlgjfn    ; Already had one open?
  6387.      CLOSF            ;  Close it
  6388.      nop
  6389.     setzm tlgjfn        ; In case of failure.
  6390.     move t1, pars3        ; Open the log
  6391.     movx t2, of%wr!fld(7,of%bsz) ; Write access, 7-bit bytes.
  6392.     OPENF
  6393.      %jserr (,r)
  6394.     movem t1, tlgjfn    ; Save the jfn.
  6395.     hrroi t2, [asciz/KERMIT-20 Transaction Log File, /]
  6396.     setzb t3, t4
  6397.     SOUT
  6398.     seto t2,        ; Write header in log file.
  6399.     move t3, [ot%ntm!ot%day!ot%fdy!ot%fmn!ot%4yr]
  6400.     ODTIM
  6401.     hrroi t2, crlf
  6402.     setzb t3, t4
  6403.     SOUT
  6404.     hrroi t2, crlf
  6405.     setzb t3, t4
  6406.     SOUT    
  6407.     wtlog (<Opened Log: >, tlgjfn)
  6408.     ret
  6409.  
  6410. ;[126] end of addition.
  6411.  
  6412. ; Session log.
  6413.  
  6414. $logs:    move t1, pars3        ; Get JFN we parsed.
  6415.     setzm savjfn        ; Where to put this JFN when not logging.
  6416.     movx t2, <fld(7,of%bsz)!of%wr> ;[154] 7-bit bytesize, new file.
  6417.     OPENF            ; Open now, avoid being stomped by CLZFFs.
  6418.      erjmp [movei t1, (t1)    ; Got an error, get code.
  6419.         cain t1, opnx1    ; Already open?
  6420.          ret        ;  Ignore the error.
  6421.         setzm sesjfn    ; Real error, disable logging.
  6422.         %ermsg (,r) ]    ;[154](end)
  6423.     movem t1, sesjfn    ; Save the open JFN.
  6424.     ret
  6425.  
  6426. ; Debugging log.
  6427.  
  6428. $logd:    setzm logjfn        ;[38] Zero this out.
  6429.     move t1, pars3        ;[38] Get the JFN we parsed.
  6430.     move t4, pars4        ;[41] And bytesize we want.
  6431.     movem t4, logbsz     ;[41] Save bytesize for SHOW command.
  6432.     movx t2, <fld(7,of%bsz)!of%wr> ;[41] Write access, assume 7-bit.
  6433.     cain t4, 8        ;[41] 8-bit requested?
  6434.      movx t2, <fld(8,of%bsz)!of%wr> ;[41] Yes, use 8-bit bytes.
  6435.     OPENF%            ;[38]
  6436.      %jserr <Can't open log file>,r
  6437.     movem t1, logjfn     ;[38] Opened OK, save it.
  6438.     skipn debug        ;[41] Was debugging asked for?
  6439.      movei debug, 1        ;[41] Not yet, so set default debugging.
  6440.     ret
  6441.  
  6442. ; PROMPT command
  6443.  
  6444. ; PROMPT help text...
  6445.  
  6446. hpromp:    asciz |
  6447. PROMPT
  6448.  
  6449. If KERMIT-20 runs in server mode by default, typing the following command
  6450. to the TOPS-20 Exec
  6451.  
  6452.    kermit prompt
  6453.  
  6454. will start it up in interactive mode, and leave you at the "Kermit-20>" prompt.
  6455. |
  6456.  
  6457. ; Parse the rest of the PROMPT command.
  6458.  
  6459. .promp:    confrm            ; Confirm.
  6460.     ret
  6461.  
  6462. ; PROMPT command execution.
  6463.  
  6464. $promp:    setzm f$exit        ; Reset exit flag.
  6465.     ret
  6466.  
  6467.  
  6468. hpush:    asciz |
  6469. PUSH
  6470.  
  6471. Push to a DEC-20 command processor.  Get back to KERMIT with all current
  6472. settings intact by typing the Exec POP command.
  6473. |
  6474. ; Parse & execute PUSH command.
  6475.  
  6476. .push:    confrm
  6477.     ret
  6478.  
  6479. $push:    jrst push
  6480.  
  6481. ; SERVER command
  6482.  
  6483. ; Help text.
  6484.  
  6485. hserve:    asciz |
  6486. SERVER
  6487.  
  6488. Act as a server for another Kermit.  Take all further commands only from the
  6489. other Kermit.  Only works when running remotely.  After issuing this command,
  6490. escape back to your local system and issue SEND, RECEIVE or GET, REMOTE,
  6491. FINISH, BYE, or other server-oriented commands from there.  If your local
  6492. KERMIT does not have a BYE command, it does not have the full ability to
  6493. communicate with a KERMIT server in which case you shouldn't run KERMIT-20 as a
  6494. server.  If your local KERMIT does have a BYE command, use it to shut down and
  6495. log out the KERMIT server when you are done with it; otherwise, connect back to
  6496. the DEC-20, type several Control-C's to stop the server, and logout.
  6497.  
  6498. For doing nonstandard kinds of file transfer (for instance to send binary files
  6499. from a microcomputer), you must issue the appropriate SET commands before the
  6500. SERVER command.
  6501. |
  6502.  
  6503. ; Parse rest of SERVER command.
  6504.  
  6505. .serve:    confrm            ; Confirm.
  6506.     ret
  6507.  
  6508. ; Execute the SERVER command.
  6509.  
  6510. ;[144] Remove test for remote mode operation.  KERMIT-20 works fine as a
  6511. ; server over an assigned line, although the messages may look a bit strange.
  6512. ;
  6513. $serve:    call getcom        ; Go serve.
  6514. ;[137]    setzm f$exit        ;[110] Return to command mode if they ^C out.
  6515.     ret
  6516.  
  6517. ; GET remote files
  6518. ;
  6519. ;[11] This whole command is part of edit 11
  6520.  
  6521. ; GET command help text.
  6522.  
  6523. hget:    asciz |
  6524. GET [remote-filespec]
  6525.  
  6526. For use only when talking to a remote KERMIT server.
  6527.  
  6528. When running as a local KERMIT (i.e. when communicating with a remote KERMIT
  6529. over an assigned TTY line, which you have specified with the SET LINE
  6530. command), you may use the GET command to request the remote KERMIT server to
  6531. send you the specified files.  The filespec is any string that can be a legal
  6532. file specification for the remote system; it is not parsed or validated
  6533. locally.  As files arrive, their names will be displayed on your screen, along
  6534. with "." and "%" characters to indicate the packet traffic.  You may type
  6535. Control-A to get a brief status report, ^X to request that the current incoming
  6536. file be cancelled, ^Z to request that the entire incoming batch be cancelled.
  6537.  
  6538. If the remote KERMIT is not capable of server functions, then you will probably
  6539. get an error message back from it like "Illegal packet type".  In this case,
  6540. you must connect to the other Kermit, give a SEND command, escape back, and
  6541. give a RECEIVE command.
  6542.  
  6543. Syntax:  The GET command accepts an arbitrary string, terminated by a
  6544. carriage return.  The string specifies a file or files in the syntax of the
  6545. remote system.  The normal DEC-20 command characters for help (?), comment
  6546. delimitation (! and ;), and file indirection (@) are enabled at the beginning
  6547. of the field, you can only enter filenames starting with one of these
  6548. characters by "quoting" it with a Control-V, which is discarded before
  6549. sending the string to the remote system.
  6550.  
  6551. If you want to store the incoming file name with a different name than the
  6552. remote host sends it with, just type GET alone on a line; Kermit-20 will
  6553. prompt you separately for the source (remote) and destination (local)
  6554. file specification.  If more than one file arrives, only the first one will
  6555. be stored under the given name; the rest will be stored under the names
  6556. they are sent with.
  6557. |
  6558.  
  6559. ;...GET command, cont'd
  6560.  
  6561. ;[148] Rewritten to allow source & destination files specified separately.
  6562.  
  6563. .get:    noise <remote files>    ; Parse the rest of the GET command.
  6564.     setzm pars2        ; Make sure these are zero...
  6565.     setzm pars3
  6566.  
  6567.     movei t1, [flddb. .cmcfm,cm%sdh,,,,[
  6568.  flddb. .cmtxt,cm%sdh,,<Remote file specification in remote host's own syntax
  6569.  (Use CTRL-V to quote otherwise illegal characters like "!", "?", and "@"),
  6570.  or carriage return to enter source and destination names separately.>]]
  6571.  
  6572.     call rfield
  6573.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  6574.     cain t3, .cmcfm        ; Parsed a CR?
  6575.      jrst .get2        ;  Yes, go prompt.
  6576.  
  6577.     confrm            ; No, so go GET the specified file(s).
  6578.     move t1, [point 7, atmbuf] ; Let $GET know where to find the string.
  6579.     movem t1, pars2
  6580.     setzm filjfn
  6581.     ret
  6582.  
  6583. ; Prompt separately for source and destination filespecs.
  6584.  
  6585. .get2:    hrroi t1, [asciz/ Remote Source File: /] ; Prompt for remote filespec
  6586.     PSOUT
  6587.     move t1, [point 7, buffer]
  6588.     setzm buffer
  6589.     movem t1, pars2        ; Let $GET know where to find the string.
  6590.     move t2, [rd%crf+rd%bel+<MAXBUF>]
  6591.     hrroi t3, [asciz/ Remote Source File: /]
  6592.     RDTTY
  6593.      %jserr (,r)
  6594.     setz t2,        ; Write a zero over the terminating linefeed.
  6595.     dpb t2, t1
  6596.     skipn buffer        ; If they typed nothing, then skip next part.
  6597.      ret
  6598.  
  6599. ; Now get local filespec for storing the incoming file.
  6600.  
  6601. .get3:    hrroi t1, [asciz/ Local Destination File: /]
  6602.     call dpromp
  6603.     movei t1, [flddb. .cmofi]
  6604.     call cfield
  6605.     movem t2, pars3
  6606.     ret
  6607.  
  6608. ; GET command execution.
  6609.  
  6610. $get: skipe takdep        ;[176] Allow commands to servers from TAKE file
  6611.      jrst $get2
  6612.     skipe local        ; This only works if local Kermit.
  6613.      jrst $get2
  6614.     ermsg <Can't GET without prior SET LINE>, r
  6615.  
  6616. ;[148] Check for and validate local filespec.
  6617.  
  6618. $get2:    skipn local        ;[177] If we're in remote mode...
  6619.      call inilin    
  6620.     setzm filjfn        ; Assume no local file given.
  6621.     skipn t1, pars3        ; JFN of local file, if any...
  6622.      jrst $get3        ;  If none, skip this.
  6623.     DVCHR            ; Make sure it's on disk.
  6624.     txne t2, dv%typ        ; ...
  6625.      ermsg <Destination file must be on disk>, r
  6626.     move t1, pars3        ; Get this back.
  6627.     movem t1, filjfn    ; Save it here.
  6628.  
  6629. ; Handle the remote filespec.
  6630.  
  6631. $get3:    setz t3,        ; Count the characters...
  6632.     move t1, pars2        ; And move them from here
  6633.     move t2, [point 7, strbuf] ;  to here.
  6634.  
  6635. $get4:    ildb t4, t1        ; Now copy the rest.  Get a byte.
  6636.     cain t4, 26        ;[147] Control-V?
  6637.      ildb t4, t1        ;[147]  Yes, it's a quote, get next byte.
  6638.     idpb t4, t2        ; Deposit the byte.
  6639.     skipe t4        ; Null?
  6640.      aoja t3, $get4        ; No, then keep going.
  6641.     jumpe t3, [ermsg <No remote filespec given>,r] ; Yes, done, any chars?
  6642.  
  6643.     movem t3, temp2        ; Save this till after next part.
  6644.  
  6645. ; OK, they gave a remote filespec.  Send an info packet in case we want to
  6646. ; tell them to send with nonstandard parameters, like 8bq or fancy block check.
  6647.  
  6648.     setom bctone        ;[98] Force 1-char checksum.
  6649.     call sinfo        ;[100] Go send Info packet.
  6650.      ret            ;[133] Failed, give up.
  6651.     setom bctone        ;[100] In case sinfo or sinit clears this!
  6652.  
  6653. ; Parameters exchanged (perhaps), now send the R packet.
  6654.  
  6655. $get5:    move t3, temp2        ; Restore length.
  6656.     movei t1, "R"        ; Packet type is Receive-Init.
  6657.     setz t2,        ; Packet number is zero.
  6658.     move t4, [point 7, strbuf] ; Point to remote filespec.
  6659.     call spack        ; Send the packet.
  6660.      jrst $getx
  6661.     movei state, "R"    ; Sent it ok, go into receive state.
  6662.     callret $recvb
  6663.  
  6664. $getx:    ermsg <Can't send Receive-Init>,r
  6665.  
  6666.     subttl    RECEIVE command
  6667.  
  6668. ; Help text
  6669.  
  6670. hrecei:    asciz |
  6671. RECEIVE    [filespec]
  6672.  
  6673. Receive a file or file group from the other host.  If only one file is being
  6674. received, you may include the optional filespec as the name to store it under
  6675. when it arrives; otherwise, the name is taken from the incoming file header
  6676. packet.  Even if the name in the header packet is not a legal TOPS-20 file
  6677. name, KERMIT-20 will store it under that name, in which case you can refer to
  6678. it later only by quoting the illegal characters (spaces, lowercase letters,
  6679. control characters, etc) with ^V.  (You may also use SET FILE NAMING to have
  6680. KERMIT-20 pick out a more conventional name.)
  6681.  
  6682. If a file with the same name already exists, KERMIT-20 just creates a new
  6683. generation of the same name and type.
  6684.  
  6685. If running as a local Kermit, the names of the incoming files will be
  6686. displayed on your screen, along with "." and "%" characters to indicate the
  6687. packet traffic; you can type Control-A during the transfer for a brief status
  6688. report.
  6689.  
  6690. If you are asking KERMIT-20 to receive binary files from a microcomputer or
  6691. other 8-bit system, you must first type SET FILE BYTESIZE 8.  Otherwise, the
  6692. 8th bit of each byte will be lost.  For ordinary text files, no special action
  6693. is necessary.
  6694.  
  6695. If you have SET PARITY, then 8th-bit quoting will be requested.  If the other
  6696. side cannot do this, binary files cannot be transferred correctly.  In all
  6697. cases, KERMIT-20 will request the other KERMIT to compress repeated characters;
  6698. if the other side can do this (not all KERMITs know how) there may be a
  6699. significant improvement in transmission efficiency.
  6700.  
  6701. When running locally and receiving files, you can attempt to cancel the
  6702. current file by typing Control-X; this sends a cancellation request to the
  6703. remote KERMIT.  If the remote KERMIT understands this request, it will comply;
  6704. otherwise it will continue to send.  If a file group is being sent, you can
  6705. request the entire group be cancelled by typing Control-Z.
  6706.  
  6707. If running as a remote Kermit, you should escape back to your local Kermit and
  6708. give the SEND command.
  6709. |
  6710.  
  6711. ; RECEIVE command, cont'd
  6712.  
  6713.  
  6714. ; Parse a filespec or just confirmation.
  6715.  
  6716. .recv:    noise <into file>    ; First, issue noise word.
  6717.     movei t1, [
  6718.      flddb. .cmofi,cm%sdh,,<local output file specification>,,[
  6719.      flddb. .cmcfm,cm%sdh,,<confirm to use remote filespec>]]
  6720.     call rfield        ; Parse a file spec or a confirm.
  6721.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  6722.     caie t3, .cmofi        ; Is it an input file spec?
  6723.      ret            ;  If not it must be a confirm, so done.
  6724.  
  6725.     movem t2, filjfn    ; Filespec, so save the JFN,
  6726.     movei t1, [flddb. .cmcfm] ; and parse the confirmation.
  6727.     call rflde
  6728.      skipa            ; Error, handle it.
  6729.      ret
  6730.  
  6731. ; Parse error handler.
  6732.  
  6733.     skipg t1, filjfn    ; Release any JFN.
  6734.      RLJFN%
  6735.      erjmp .+1        ; Ignore any errors.
  6736.     setzm filjfn        ; Zero the JFN to indicate we don't have one.
  6737.     tmsg <?Not confirmed>    ; Issue our own parse message
  6738.     jrst cmder1        ;  and get back inside CMD to clean up.
  6739.  
  6740. ;[57] Resolve debugging status. (This made into a separate routine in edit 57).
  6741. ;
  6742. ; Call this routine at the beginning of any packet transaction (send, receive,
  6743. ; server command, etc).
  6744. ;
  6745. ; Returns +1 if there's no debugging going on
  6746. ;         +2 if there is, with the log jfn set up correctly.
  6747. ;
  6748. setlog:    jumpe debug, r        ; Return nonskip if not debugging.
  6749.     skipe t1, logjfn    ; Yes, has a log file been specified?
  6750.      jrst [    caie t1, .priou ; Yes, but is it the terminal?
  6751.          jrst rskp    ; No, it's a file, which is always OK.
  6752.         setzm logjfn    ; It's the TTY, so say no log file,
  6753.         jrst .+1 ]    ;  and do next bit.
  6754.     movei t1, .priou    ; No log file specified.
  6755.     skipe local        ; If running in local mode,
  6756.      movem t1, logjfn    ; use the terminal.
  6757.     retskp
  6758.  
  6759. ; RECEIVE, GET, REMOTE TYPE command execution.
  6760.  
  6761.  
  6762. ; Initialization -- First, stuff only for when not being a server.
  6763.  
  6764. $recv:    movei state, "R"    ; Start out in receive init state.
  6765.  
  6766. ; Entry point for server commands.
  6767.  
  6768. $recvb:    setom $recvf        ;[88] Executing RECEIVE command,
  6769.     setzm $sendf        ;[88] not SEND command.
  6770.     setzm ttildb        ;[180] (stats)
  6771.     setzm ttibin        ;[180] (stats)
  6772.     setzm ttisin        ;[180] (stats)
  6773.     setzm ttimax        ;[180] (stats)
  6774.     call caxzon        ;[62] Turn on keyboard interrupts.
  6775.     hrroi t1, [        ;[61] Tell about terminal interrupts,
  6776.      asciz/^A for status report, ^X to cancel file, ^Z to cancel batch.
  6777. /]
  6778.     skipe local        ;[62]  if local.
  6779.      PSOUT%            ;[62]
  6780.     call inilin        ; Initialize the line.
  6781.     call ccon        ; Turn on the ^C trap.
  6782.      jrst reslin         ;[27] On ^C go reset line & return from there.
  6783.     skipn gotx        ; If I don't already have an X packet,
  6784.      setzm pktnum        ;  inititialize the packet sequence number.
  6785.  
  6786. ; Entry point for server.
  6787.  
  6788. $recvs:    GTAD            ; Current date/time for start of transaction.
  6789.     movem t1, stdat
  6790.     setzm stot        ; Initialize statistics variables.
  6791.     setzm rtot
  6792.     setzb schr, stchr
  6793.     setzb rchr, rtchr
  6794.     setzm files        ;[61] File counter
  6795.     setom rptot        ;[4]  Init received-packet counter to -1.
  6796.     setom sptot
  6797.     setzm nnak        ;[54] Init the number of NAKs
  6798.     setzm ntimou        ;[54]  and the number of timeouts.
  6799.     setzm timerx        ;[132] Timer error counter.
  6800.     setzm errptr        ; Zero the error message pointer.
  6801.     setom bctone        ;[98] Force block check type to 1 initially.
  6802.  
  6803.     skipe autbyt        ;[72] Using autobyte?
  6804.      setzm ebtflg        ;[72]  If so reset eight-bit-mode flag.
  6805.     move t1, rpause        ;[36] Get the requested receive-pause interval
  6806.     movem t1, pause        ;[36]  and make it the current one.
  6807.     setzm numtry        ; Set the number of tries to zero.
  6808.  
  6809. $recva:    call setlog        ;[57] Set up any debugging log.
  6810.      nop
  6811.     ;...
  6812.  
  6813. ; RECEIVE command, cont'd
  6814.  
  6815. ; State Table Switcher
  6816.  
  6817. $recv2:    cain state, "D"        ; Are we in the data receive state?
  6818.      jrst [    call rdata    ; Yes, go read data packets.
  6819.         jrst $recv2 ]
  6820.     cain state, "F"        ; Are we in the file receive state?
  6821.      jrst [    move t1, filjfn    ;  Get the file's JFN.
  6822.         call rfile    ;  Call receive file.
  6823.         jrst $recv2 ]
  6824.     cain state, "R"        ; Are we in the receive initiate state?
  6825.      jrst [    call rinit    ;  Call receive initiate.
  6826.         jrst $recv2 ]
  6827.     cain state, "C"        ; Are we in the receive complete state?
  6828.      jrst [    movei t1, "C"
  6829.         move t2, pktnum
  6830.         call diamsg    ;[38]
  6831.         GTAD%        ;  Get the time we ended.
  6832.         subm t1, stdat    ;  Figure how long it all took.
  6833.         movei t1, .chbel ;[31] Give a beep
  6834.         skipe local    ;[31] if local
  6835.          PBOUT        ;[31]
  6836.         jrst $recvz ]    ;[88] Done.
  6837.  
  6838.     cain state, "A"        ; Are we in the receive cAncel state?
  6839.      jrst [    movei t1, "A"    ; Print diagnostic message if debugging.
  6840.         move t2, pktnum    ;  ...
  6841.         call diamsg    ;  ...
  6842.         GTAD%        ; Get the time we ended.
  6843.         subm t1, stdat    ; Figure how long it all took.
  6844.         call giveup    ; Clean up the file if necessary.
  6845.         jrst $recvz ]    ;[88] Done.
  6846.  
  6847.     movei t1, "U"        ; Undefined...
  6848.     move t2, pktnum
  6849.     call diamsg
  6850.  
  6851. $recvz:    call caxzof        ;[62] Turn off ^A,^X,^Z traps.
  6852.     call reslin        ;[88] Put the line back the way it was.
  6853.     setzm $recvf        ;[88] RECEIVE command finished.
  6854.     ret
  6855.  
  6856.     subttl receive routines
  6857.  
  6858. ; RINIT -- Receive Initiate; get other side's Send-Init packet.
  6859. ;
  6860. rinit:    saveac <q1>        ; Save this AC.
  6861.  
  6862.     skipe gots        ; Got the S packet already?
  6863.      jrst rinit3        ;  Yes, don't try to read it.
  6864.  
  6865. ; Give up if we've tried too many times, otherwise keep trying.
  6866.  
  6867.     aos q1, numtry        ; Increment the number of tries.
  6868.     caml q1, imxtry        ; Have we reached the maximum number of tries?
  6869.      jrst [    movei state, "A" ;  Change the state to cAncel.
  6870.         kermsg <Can't receive Send-Init>,r ] ;[46]
  6871.     call rpack        ; Try to get a packet.
  6872.      jrst [    move t2, pktnum    ;[53]  Failed, NAK the one we want.
  6873.         callret nak ]    ;[53]
  6874.         
  6875. ; Got a packet.  Check the type and take appropriate action.
  6876.  
  6877. rinit2:    cain t1, "E"        ;[32] Error packet?
  6878.      jrst pxerr        ;[82]  Yes, print it & cancel.
  6879.  
  6880. ; Should have the other side's Send-Init packet at this point, with T1-T4
  6881. ; containing the various pointers, counts, etc.
  6882.  
  6883. rinit3:    setzm gots        ; Clear this flag.
  6884.     move q1, t1        ; Save the packet type.
  6885.     GTAD%            ; Get the time we start.
  6886.     movem t1, stdat        ; Save it.
  6887.     caie q1, "S"        ; Got a send-init?
  6888.      jrst [    move t2, pktnum    ;  No, something else, or timed out.
  6889.         callret nak ]    ;  Just NAK the packet we wanted.
  6890.     movem t2, pktnum    ; Yes, synchronize packet numbers.
  6891.     call spar        ; Get what the other side wants us to do.
  6892.     move t4, [point 8, data] ; Tell the other side what we want
  6893. rinit4:    call rpar        ;  it to do, by returning our Send-Init
  6894.     movei t1, "Y"        ;  parameters in our ACK to its Send-Init.
  6895.     move t2, pktnum        ; Packet number.
  6896.     move t4, [point 8, data] ; The address of the data.
  6897.     call spack        ; Send our params in the acknowledgment.
  6898.      jrst rinitx
  6899.  
  6900. rinit5: call rrinit        ; Go set things up for receiving.
  6901.     
  6902. rinitz:    movei state, "F"    ; Set the state to file receive.
  6903.     ret
  6904.  
  6905. rinitx:    movei state, "A"     ; Failed, set state to cAncel.
  6906.     ret
  6907.  
  6908. ;[126] Set things up for receiving.
  6909. ;
  6910. ; This code is used by RINIT and by XSEND.
  6911. ;
  6912. rrinit:    move t2, numtry        ; Get the number of tries.
  6913.     movem t2, oldtry    ; Save it.
  6914.     setzm numtry        ; Reset the number of tries.
  6915.     aos t2, pktnum        ; Increment the packet number,
  6916.     andi t2, 77        ; modulo 100,
  6917.     movem t2, pktnum    ; and save it back.
  6918.     call ebqmsg        ; Maybe print message about 8 bit prefix.
  6919.     setzm bctone        ; Enable fancy block checks.
  6920.  
  6921. ;[126] Log the beginning of this transaction.
  6922.  
  6923.     skipe iflg        ;[134] Is this an I packet?
  6924.      ret            ;[134]  If so, skip logging.
  6925.  
  6926.     wtlog <-- Receive Begins -->
  6927.  
  6928. ; The following can be called to log ebq & bct for either send or receive.
  6929.  
  6930. rrlog: skipn t1, tlgjfn        ; Logging transactions?
  6931.      jrst rinitz        ;  No, skip ahead.
  6932.     hrroi t2, [asciz/   8th bit prefixing: /]
  6933.     setzb t3, t4
  6934.     SOUT
  6935.     hrroi t2, [asciz/Off/]
  6936.     skipe ebqflg
  6937.      hrroi t2, [asciz/On/]
  6938.     setzb t3, t4
  6939.     SOUT
  6940.     hrroi t2, [asciz/
  6941.    Block check type: /]
  6942.     SOUT
  6943.     move t2, bctu
  6944.     movei t3, ^d10
  6945.     NOUT
  6946.      nop
  6947.     hrroi t2, crlf
  6948.     setzb t3, t4
  6949.     SOUT
  6950.     ret
  6951.  
  6952. ;[89] EBQMSG
  6953. ;
  6954. ;Print warning message if 8th bit prefixing requested but won't be done.
  6955.  
  6956. ebqmsg:    skipe local        ; Local?
  6957.      jrst [    skipn ebqr    ; Yes, wanted 8th bit quoting?
  6958.          jrst .+1     ;  No, so no message will be needed.
  6959.         hrroi t1, [asciz/
  6960. %Warning: Other side won't do 8th-bit prefixing.
  6961. %Binary files will not be transmitted correctly.
  6962. /]                ; Yes,
  6963.         skipn ebqflg    ;  will other side do it?
  6964.          PSOUT        ; No, warn.
  6965.         jrst .+1 ]
  6966.     ret
  6967.  
  6968. ; RFILE - Receive File Header
  6969.  
  6970. rfile:    saveac<q1>
  6971.     setzm cxseen        ;[62] Zero ^X,^Z flags, since they apply
  6972.     setzm czseen        ;[62] on a per-file basis.
  6973.     setzm bctone        ;[99] Can't hurt... (but why do we need it????)
  6974.     move q1, numtry        ; Have we reached the maximum number of tries?
  6975.     caml q1, maxtry        ;  ...
  6976.      jrst [ movei state, "A" ; Yes, change the state to cAncel.
  6977.         kermsg <Can't receive File-Header>,r ]
  6978.     aos numtry        ; No, count this try.
  6979.     skipe gotx        ;[112] Already got an "X" packet?
  6980.      jrst rfil3t        ;[112]  Yes, so don't need to get one.
  6981.     call rpack        ; Try to get a packet.
  6982.      jrst [    move t2, pktnum    ;[53]  Failed, NAK the one we want.
  6983.         callret nak ]    ;[53]
  6984.  
  6985. rfile1:    caie t1, "S"        ; Got a packet.  What's the type?
  6986.      jrst rfile2        ;  Send-Init?  Missed our previous ACK?
  6987. rfil1a:    move q1, oldtry        ; Yes, Send-Init.  Get the number of tries.
  6988.     caml q1, imxtry        ; How many times have we tried to ACK this?
  6989.      jrst [    movei state, "A" ; Too many, change the state to cAncel.
  6990.         kermsg <Too many Send-Inits>,r ]
  6991.     aos oldtry        ; Save the updated number of tries.
  6992.     skipg q1, pktnum    ;[3] Get the present packet number.
  6993.      movei q1, 100        ;[3]  If it just wrapped around, do this.
  6994.     caie t2, -1(q1)        ; Is the packet's number one less than now?
  6995.      ret            ;  No, fail, stay in this state, keep trying.
  6996.     setzm numtry        ; OK, it's the Send-Init again.
  6997.     move t4, [point 8, data] ;[50] ...
  6998.     call rpar        ; Put our parameters in it.
  6999.     movei t1, "Y"        ; Send the ACK with our parameters again.
  7000.     move t2, pktnum        ;[47] Not for the current packet,
  7001.     sos t2            ;[47] but the previous one.
  7002.     call spack        ;  ...
  7003.      jrst @[exp rfil1a, rinitx](t1) ; Handle failures.
  7004.     ret
  7005.     ;...
  7006.  
  7007. ; RFILE, Cont'd
  7008.  
  7009.  
  7010. rfile2:    caie t1, "Z"        ; Is the packet an EOF packet?
  7011.      jrst rfile3        ;  No, try something else.
  7012. rfil2a:    move q1, oldtry        ; Yes, EOF.  How many ACKs have we sent?
  7013.     caml q1, maxtry        ; Too many?
  7014.      jrst [    movei state, "A" ; Yes, change the state to cAncel.
  7015.         kermsg <Can't ACK EOF in RFILE>,r ]
  7016.     aos oldtry        ; Save the updated number of tries.
  7017.     skipg q1, pktnum    ;[3] Get the present packet number.
  7018.      movei q1, 100        ;[3] If it just wrapped around, do this.
  7019.     caie t2, -1(q1)        ; Is the packet's number one less than now?
  7020.      ret            ;  No, then hold out for right one.
  7021.     setzm numtry        ; OK, it's the previous packet again.
  7022.     movei t1, "Y"        ; Restart count, and re-ACK it.
  7023.     setzb t3, t4        ; No data.
  7024.     call spack        ; Send the packet.
  7025.      jrst @[exp rfil2a, rfil2x](t1)
  7026.     ret
  7027.  
  7028. rfil2x: movei state, "A"    ; Set state to cAncel.
  7029.     ret
  7030.  
  7031. ; Process the remote file header
  7032.  
  7033. rfile3:    came t2, pktnum        ; Packet number OK?
  7034.      ret            ;  No, hold out for the right one.
  7035.  
  7036. ;[104] Begin change for receiving "X" packets.
  7037.  
  7038.     cain t1, "F"        ; Start of file?
  7039.      jrst rfil3k        ;  Yes.
  7040.     caie t1, "X"        ; Text header?
  7041.      jrst rfile4        ;  No.
  7042.  
  7043. rfil3t:    setzm gotx        ;[112] Reset this flag.
  7044.     setom filjfn        ; Yes, indicate this way.
  7045.     skipn local
  7046. ;[177]     jrst [    movei state, "A"
  7047. ;[177]        kermsg <Can't receive screen text in remote mode>, r ]
  7048.     jrst rfil3c        ;[177] Let it come, just don't print it.
  7049.  
  7050. ; Local, print the file name on the screen.
  7051.  
  7052.     hrroi t1, [asciz/
  7053.  /]
  7054.     PSOUT
  7055.     move t1, t4
  7056.     PSOUT
  7057.      erjmp .+1
  7058.     hrroi t1, crlf
  7059.     PSOUT
  7060.     jrst rfil3c        ; Skip past file opening stuff.
  7061.  
  7062. ;[104] End change.
  7063.  
  7064.     ;...
  7065.  
  7066. ; RFILE, Cont'd
  7067.  
  7068.  
  7069. ; Come here with normal file header.
  7070.  
  7071. rfil3k:    move t1, t4        ; Got the header we want, point to filename.
  7072.     move t2, t3        ; Get the length of the filename string.
  7073.     call makfil        ; Go get JFN on it.
  7074.      jrst [    movei state, "A" ;  Can't, set state to cAncel.
  7075.         ret ]        ; MAKFIL has already issued appropriate E pkt.
  7076.     movem t1, filjfn    ; All OK, save the JFN.
  7077.  
  7078. ; Open the file.
  7079.  
  7080.     setzm itsfil        ;[75] Assume not ITS binary file.
  7081.     setzm itscnt        ;[75] Init counter for header char matching.
  7082.     move t1, filjfn        ; Open the file.
  7083.     movx t2, fld(36,of%bsz)!of%wr ; 36-bit bytes, write access.
  7084.     OPENF%            ; Open the file (fix bytesize later).
  7085.      %jsker <Can't open file>, rfil3a ;[42] Send this + JSYS error msg.
  7086.     wtlog <Opened: >,filjfn ;[126]
  7087.     jrst rfil3b        ;[42] Opened OK, skip error handling.
  7088.  
  7089. ; Come here if the file can't be opened.
  7090.  
  7091. rfil3a:    skipe t1, tlgjfn    ;[126] Log this failure in transaction log.
  7092.      jrst [    wtlog <Can't Receive >,filjfn
  7093.         hrroi t2, [asciz/   Because: /]
  7094.         setzb t3, t4
  7095.         SOUT
  7096.         hrloi t2, .fhslf ; Tell why.
  7097.         setz t3,
  7098.         ERSTR
  7099.          nop
  7100.          nop
  7101.         hrroi t2, crlf
  7102.         setzb t3, t4
  7103.         SOUT
  7104.         jrst .+1 ]
  7105.  
  7106.     move t1, filjfn        ; Get the output JFN.
  7107.     RLJFN%            ; Release it.
  7108.      nop            ;[33] Ignore any error.
  7109.     setzm filjfn        ; Clear the JFN.
  7110.     movei state, "A"     ; Change state to cAncel.
  7111.     ret
  7112.     ;...
  7113.  
  7114. ; RFILE, Cont'd...
  7115.  
  7116. ;[66] If outputting to a file, set up the mapping page pointers.
  7117.  
  7118. rfil3b:    skiple filjfn        ;[66] JFN on a file?
  7119.      jrst [    move t1, [point 7, mappag*1000]    ;[66] Yes, point to page.
  7120.         skipe ebtflg        ;[66] Eight bit mode?
  7121.          hrli t1, (point 8,)    ;[66] Then use 8-bit bytes.
  7122.         movem t1, pagptr    ;[66] Save it here.
  7123.         setzm pagno        ;[66] Begin at file page zero.
  7124.         jrst .+1 ]
  7125.  
  7126. ; If running locally, echo filename to screen.
  7127.  
  7128.     movei t1, 7        ;[66] Remember file byte size for reporting.
  7129.     skipe ebtflg        ;[66] (this may be revised later because
  7130.      movei t1, 8        ;[66]  of ITS binary headers or similar...)
  7131.     movem t1, bytsiz    ;[66]
  7132.  
  7133.     setom rcving        ;[62] Indicate we're receiving a file.
  7134.     skipn local        ;[12] Local Kermit?
  7135.      jrst rfil3c        ;[12]  No, no terminal messages necessary.
  7136.     movei t1, .priou    ;[12] Yes, print the file name.
  7137.     RFPOS%            ;[12] First see if we need to start a new line.
  7138.     hrroi t1, crlf        ;[12]  ...
  7139.     trne t2, -1        ;[12]  ...
  7140.      PSOUT%            ;[12]
  7141.     movei t1, .priou     ;[12] Now print the file name.
  7142.     hrrz t2, filjfn        ;[12]
  7143.     setz t3,        ;[12]
  7144.     JFNS%            ;[12]
  7145.      nop            ;[12]
  7146.     movei t1, " "        ;[12]
  7147.     PBOUT%            ;[12]
  7148.  
  7149. ; ACK file header, initialize counters and go into Receive-Data state.
  7150.  
  7151. rfil3c:    movei t1, "Y"        ; Acknowledge the packet.
  7152.     move t2, pktnum        ; This packet number.
  7153.     setzb t3, t4        ; No data.
  7154.     call spack        ; Send the packet.
  7155.      jrst rfil3x
  7156.     setzm mapflg        ; Say no pages mapped in yet.
  7157.     move t2, numtry        ; Get the number of tries.
  7158.     movem t2, oldtry    ; Save it.
  7159.     setzm numtry        ; Reset the number of tries.
  7160.     aos t2, pktnum        ; Increment the packet number,
  7161.     andi t2, 77        ; modulo 100,
  7162.     movem t2, pktnum    ; and save it back.
  7163.     setz rchr,        ;[128] Initialize file character counter.
  7164.     movei state, "D"    ; Set the state to file send.
  7165.     ret
  7166.  
  7167. rfil3x:    movei state, "A"    ; On fatal errors, set the state to cAncel.
  7168.     ret
  7169.  
  7170. ;...RFILE, cont'd
  7171.  
  7172.  
  7173. ; It wasn't a File Header or EOF packet; check for other possibilities.
  7174.  
  7175. rfile4:    caie t1, "B"        ; End of transmission?
  7176.      jrst rfile5        ;  No.
  7177.     came t2, pktnum        ; Yes, but is it the right packet number?
  7178.      ret            ;  No, hold out for the right one.
  7179.     movei t1, "Y"        ; All OK, acknowledge the EOT packet.
  7180.     setzb t3, t4        ; No data.
  7181.     call spack        ; Send the packet.
  7182.      skipa state, "A"
  7183.      movei state, "C"    ; Sent ok, set state to Complete.
  7184.     move t1, netjfn        ;[158] Wait until the packet
  7185.     DOBE            ;[158]  gets all the way out.
  7186.      erjmp .+1        ;[158]
  7187.     skiple filjfn        ;[126] Were we writing to a file?
  7188.      wtlog <Receive Complete> ;[126] Yes, record in transaction log.
  7189.     ret
  7190.  
  7191. rfile5:    cain t1, "T"        ; Timer interrupt pseudo packet?
  7192.      jrst [    move t2, pktnum    ; Yes, NAK the expected packet.
  7193.         callret nak ]
  7194.     cain t1, "E"        ;[82] Error packet?
  7195.      jrst pxerr        ;[82]  Yes, print it & cancel.
  7196.  
  7197. rfilex:    ret            ;[46] Something else, just hold out...
  7198.  
  7199. ; RDATA -- Receive Data state.
  7200.  
  7201. rdata:    saveac <q1,q2>        ; Save these
  7202.     aos q1, numtry        ;[42] Too many tries for this packet?
  7203.     camle q1, maxtry    ;[42]
  7204.      kermsg <Retry count exhausted in RDATA>, rdterr
  7205.     call rpack        ; Get a packet.
  7206.      jrst [    move t2, pktnum    ;[53] Failed, NAK the one we want.
  7207.         callret nak ]    ;[53]
  7208.     caie t1, "D"        ; Got one.  Data packet?
  7209.      jrst rdata3        ;[42] No, go see what it is.
  7210.     came t2, pktnum        ; Yes, but is it the right data packet?
  7211.      jrst rdata2        ;  No.
  7212.  
  7213. ; Process a normal data packet.
  7214.  
  7215. rdok:    move t1, t4        ; Got the one we want, point to data.
  7216.     move t2, t3        ; Get the length of the data.
  7217.     call putbuf        ;[66] Write the buffer to the output file.
  7218.      kermsg <Can't write to file>,rdterr ; This error is always fatal.
  7219.     movei t1, "Y"        ; No error, acknowledge the packet we got.
  7220.     move t2, pktnum        ; This sequence number.
  7221.     setzb t3, t4        ; Assume no data.
  7222.     skipn cxseen        ;[62] Was ^X typed?
  7223.      skipe czseen        ;[62] Or ^Z?
  7224.      jrst [    move t3, [byte(8)"Z",0]    ;[62]  Yes, put a "Z"
  7225.         skipn czseen    ;[62] or
  7226.          move t3, [byte(8)"X",0] ;[62] an "X" in the
  7227.         movem t3, data    ;[62] data field of the ACK
  7228.         movei t3, 1    ;[62] (length of data is 1)
  7229.         move t4, [point 8, data] ;[62] and point to it.
  7230.         jrst .+1 ]    ;[62]
  7231.     call spack        ; Send the packet.
  7232.      jrst @[exp r, rdterr](t1) ;[60]  Handle fatal & nonfatal errors.
  7233.     move t2, numtry        ; Get the number of tries.
  7234.     movem t2, oldtry    ; Save it.
  7235.     setzm numtry        ; Reset the number of tries.
  7236.     aos t2, pktnum        ; Increment the packet number,
  7237.     andi t2, 77        ; modulo 100,
  7238.     movem t2, pktnum    ; and save it.
  7239.     ret
  7240.  
  7241.     ;...
  7242.  
  7243. ; RDATA, cont'd
  7244.  
  7245.  
  7246. ; Got a data packet, but it's the wrong one.
  7247.  
  7248. rdata2:    move q1, oldtry        ; Get the number of tries.
  7249.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  7250.      kermsg <Too many retries in RDATA2>,rdterr ; Yes.
  7251.     aos oldtry        ; Not too many, update number of tries.
  7252.     skipg q1, pktnum    ;[3]  Get the present packet number.
  7253.      movei q1, 100        ;[3]  If it just wrapped around, do this.
  7254.     caie t2, -1(q1)        ; Is it the previous packet?
  7255.      ret            ;[46] No, fail, don't change state, retry.
  7256.     setzm numtry        ; Yes, previous packet; start count over.
  7257.     movei t1, "Y"        ; Acknowledge it again.
  7258.     setzb t3, t4        ; No data.
  7259.     call spack        ; Send the ACK.
  7260.      jrst @[exp r, rdterr](t1) ;[60]  Handle fatal & nonfatal errors.
  7261.     ret            ; Otherwise return OK.
  7262.  
  7263. rdata3:    caie t1, "F"        ; File header?
  7264.      jrst rdata4        ;  Nope, try something else.
  7265.     caie t1, "X"        ; Text header?
  7266.      jrst rdata4        ;  Not that either.
  7267.     move q1, oldtry        ; Yes, "F" or "X". Get the number of tries.
  7268.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  7269.      kermsg <Can't ACK file header in RDATA3>,rdterr ; Yes, quit.
  7270.     aos oldtry        ; Not yet, update number of tries.
  7271.     skipg q1, pktnum    ;[3]  Get the present packet number.
  7272.      movei q1, 100        ;[3]  If it just wrapped around, do this.
  7273.     caie t2, -1(q1)        ;  Is the packet's number one less than now?
  7274.      ret            ;[46] No, fail, don't change state, retry.
  7275.     setzm numtry        ; Yes, so start count over.
  7276.     movei t1, "Y"        ; Acknowledge the file header again.
  7277.     setzb t3, t4        ; No data.
  7278.     call spack        ; Send the packet.
  7279.      jrst @[exp r, rdterr](t1) ;[60]  Handle fatal & nonfatal errors.
  7280.     ret            ; else try again to get data.
  7281.  
  7282. ; RDATA, cont'd
  7283.  
  7284.  
  7285. ; End Of File.
  7286.  
  7287. rdata4:    caie t1, "Z"        ; Is it an EOF?
  7288.      jrst rdata5        ;  No, try next thing...
  7289.     came t2, pktnum        ; Yes, is the packet number correct?
  7290.      ret            ;[46] No, ignore this packet, keep trying.
  7291.     jumpn t3, [        ; Was there any data in the EOF packet?
  7292.         ildb t3, t4    ; Yes, see what it is.
  7293.         caie t3, "D"    ; Code for Discard the file?
  7294.          jrst .+1     ;  No, proceed.
  7295.         call giveup    ; Yes, go "close/cancel" this one,
  7296.         jrst rdat5a ]    ;  and then proceed normally.
  7297.  
  7298.     call rdclos        ;[42] Not discarding, close the file normally.
  7299.      jrst rdterr        ;[174] If can't give up.
  7300.  
  7301. rdat4a:    aos files        ;[61] Count the file.
  7302.     hrroi t1, [asciz/[OK]/]    ;[19] Closed the file OK, make comforting msg.
  7303.     skipe local        ;[19] Print it if local.
  7304.      PSOUT%            ;[19]
  7305.  
  7306. rdat5a:    movei t1, "Y"        ; Acknowledge the eof packet.
  7307.     move t2, pktnum
  7308.     setzb t3, t4        ; normally (no data).
  7309.     call spack        ; Send the ACK.
  7310.      nop            ; On any error, just forge ahead.
  7311.  
  7312.     addm rchr, rtchr    ; Add character count for this file to total.
  7313.     setz rchr,        ; Reset for next file.
  7314.     move t2, numtry        ; Get the number of tries.
  7315.     movem t2, oldtry    ; Save it.
  7316.     setzm numtry        ; Reset the number of tries.
  7317.     aos t2, pktnum        ; Increment the packet number,
  7318.     andi t2, 77        ; modulo 100,
  7319.     movem t2, pktnum    ; and save it.
  7320.     movei state, "F"    ; Change state to "F"
  7321.     ret            ;  and go back to the state switcher.
  7322.  
  7323. ; Come here if there was a timeout or error.
  7324.  
  7325. rdata5:    cain t1, "T"        ; Timer interrupt pseudo packet?
  7326.      jrst [    movei t1, "N"    ; Yes, send a NAK.
  7327.         move t2, pktnum ;  for the expected packet.
  7328.         setzb t3, t4    ; No data.
  7329.         call spack    ; Try to send it.
  7330.          jrst rdterr    ;[46] Can't, set state to cAncel.
  7331.         ret ]        ; Return to state switcher.
  7332.     cain t1, "E"        ;[82] Error packet?
  7333.      call pxerr        ;[82]  Yes, print it, then fall thru...
  7334.     ;...
  7335.  
  7336. ;...RDATA (cont'd)
  7337.  
  7338.  
  7339. ; Handler for fatal errors reading/storing data, cancels the transfer.
  7340.  
  7341. rdterr:    call giveup        ; Go clean up the file.
  7342.     movei state, "A"    ; Change the state to cAncel.
  7343.     ret
  7344.  
  7345. ; Come here to close a partially received file.  It will be discarded or
  7346. ; kept, depending on setting of ABTFIL, i.e. SET INCOMPLETE (FILE DISPOSTION).
  7347. ;
  7348. giveup:    skipe abtfil        ;[134] Do we discard or keep?
  7349.      jrst [    wtlog <Incomplete File Kept: >, filjfn ;[134]  Keep.
  7350.         hrroi t1, [asciz/[keeping partial file]/]
  7351.         skipe local
  7352.          PSOUT
  7353.         call rdclos    ; Go close as much of it as we have.
  7354.          jrst .+1    ; Discard it if we have some problem.
  7355.         ret ]        ; Closed partial file OK.
  7356.  
  7357.     wtlog <Incomplete File Discarded: >,filjfn ;[126] Discard.
  7358.     hrroi t1, [asciz/[discarding]/]    ; Say what we're up to.
  7359.     skipe local        ; Print message if local.
  7360.      PSOUT            ;
  7361.     skipg filjfn        ; Real file?
  7362.      jrst givexx        ;  If not, done.
  7363.     call unmapo        ; Go unmap the file
  7364.      nop            ; Don't worry if we can't.
  7365.     hrrz t1, filjfn        ; Clear out any junk from left half.
  7366.     txo t1, cz%abt        ; Discarding, so cancel the file.
  7367.     CLOSF%            ; Close it.
  7368.      erjmp [move t1, filjfn ; On any error,
  7369.         RLJFN        ;  at least try to release the JFN.
  7370.          erjmp givexx    ;  ...
  7371.         jrst givexx ]
  7372.  
  7373. givexx:    setzm filjfn        ; Say we have no file.
  7374.     ret
  7375.  
  7376. ; UNMAPO - Clean up the file mapping page for an output file.
  7377. ;
  7378. ; Returns +1 on failure, +2 on success.
  7379. ;  On failure, an error packet is sent, which cancels the transfer.
  7380. ;
  7381. ; Uses t1,t2,t3.
  7382. ;
  7383. ; Note that unmapping the memory page also makes it disappear.  The next write
  7384. ; to the page will create a fresh page with all 0's.
  7385. ;
  7386. ; The trick at the beginning catches the case where the page has already been
  7387. ; unmapped because we just filled in the last byte.  Since this routine is
  7388. ; called both by the page filler (PUTCH) and by the file closer (RDCLOS, to
  7389. ; catch a final partial page), we must worry about files that end on a page
  7390. ; boundary.  Putting an ERJMP after any instruction that references memory will
  7391. ; catch "illegal memory read" errors, and will thus prevent us from attempting
  7392. ; to unmap a page that has already been unmapped and still has not been
  7393. ; written into.
  7394.  
  7395. unmapo:    move t1, mappag        ;[66] Has the page been used at all?
  7396.      erjmp rskp        ;[66]  No, done.
  7397.  
  7398.     movx t1, <.fhslf,,mappag> ; Yes, map them out, our fork,,mapping page
  7399.     hrl t2, filjfn        ;  file JFN,,...
  7400.     hrr t2, pagno        ;  ...page file page number.
  7401.     movx t3, pm%rd!pm%wr    ; Read and write access.
  7402.     PMAP%            ; Map it out.
  7403.      %jsker (,r)        ;  Can't - fail.
  7404.     retskp
  7405.  
  7406. ; RDCLOS -- Close the output file, update the FDB, etc...
  7407. ; Return +1 on error, +2 on success.
  7408.  
  7409. rdclos:    skipg filjfn        ;[103] Output was to a real file?
  7410.      jrst rdclsz        ;[103]  No, skip all this.
  7411.     call unmapo        ; First, clean out the PMAPping page.
  7412.      ret            ;  Oops, failed, pass it along...
  7413.  
  7414. ; Now close the file.
  7415.  
  7416. rdclsa:    movx t1, co%nrj        ; Flag for not releasing JFN.
  7417.     hrr t1, filjfn        ; Get the JFN.
  7418.     CLOSF%            ; Close it.
  7419.      %jsker <Can't close file>,r ; Return error.
  7420.  
  7421. ; Update FDB information about byte size, number of bytes.
  7422.  
  7423.     hrli t1, .fbsiz        ; OK, now fix FDB.  Set the number of bytes
  7424.     txo, t1, cf%nud        ; Don't update disk yet.
  7425.     hrr t1, filjfn        ; Move in the JFN.
  7426.     seto t2,        ; Change all bits in the word.
  7427.     move t3, rchr        ; The number of bytes in the file.
  7428.     CHFDB%
  7429.      erjmp .+1        ; Keep going if we get an error.
  7430.  
  7431. rdclsb:    hrli t1, .fbbyv        ; Set the byte size.
  7432.     hrr t1, filjfn
  7433.     movx t2, fb%bsz        ; Byte size field mask.
  7434.     movx t3, fld(7,fb%bsz)    ; Value
  7435.     skipn itsfil        ;[75] ITS binary file?
  7436.      skipe ebtflg        ; Or eight-bit mode?
  7437.      movx t3, fld(8,fb%bsz)    ; Set it that way, then.
  7438.     ldb t4, [pointr (t3,fb%bsz)] ; Get the bytesize in t4 as a number.
  7439.     CHFDB%
  7440.      erjmp .+1        ; Keep going if we get an error.
  7441.     ;...
  7442.  
  7443. ;...RDCLOS, cont'd
  7444.  
  7445.  
  7446. ;[126] Take care of any transaction logging.
  7447.  
  7448.     skiple filjfn        ; Real file?
  7449.      skipg t1, tlgjfn    ; Transaction log?
  7450.      jrst rdclsc        ;  No, skip this.
  7451.     hrroi t2, [asciz/   Written: /] ; Yes, log this info.
  7452.     push p, t4
  7453.     setzb t3, t4
  7454.     SOUT
  7455.      erjmp .+1
  7456.     move t2, rchr        ; Number of bytes.
  7457.     movei t3, ^d10
  7458.     NOUT
  7459.      erjmp .+1
  7460.     movei t2, 40        ; A space
  7461.     BOUT
  7462.      erjmp .+1
  7463.     pop p, t2        ; Byte size
  7464.     NOUT
  7465.      erjmp .+1
  7466.     hrroi t2, [asciz/-bit bytes
  7467. /]
  7468.     setz t3,
  7469.     SOUT
  7470.      erjmp .+1
  7471.  
  7472. ; Finish closing the output file by releasing its JFN.
  7473.  
  7474. rdclsc:    skiple filjfn        ;[126]
  7475.      wtlog <Closed: >,filjfn ;[126] Transaction log message.
  7476.     hrrz t1, filjfn        ; Release the JFN.
  7477.     RLJFN%
  7478.      nop
  7479. rdclsz:    setzm filjfn        ; Say we have no more file.
  7480.  
  7481.     retskp
  7482.  
  7483.     subttl    Utility protocol routines
  7484.  
  7485.  
  7486. ; SPAR - Get the arguments from a Send-Init packet.
  7487. ;
  7488. ;[47] Substitute them for our own unless we have given our own SET commands.
  7489. ;[47] The way this is done here is less than perfect, but will work most of
  7490. ;[47] the time (it won't work if the user SETs a value to be the same as the
  7491. ;[47] default, or if the remote sends different parameters each time, or...
  7492. ;[47] But it's better than it was before.  If it becomes an issue, we can
  7493. ;[47] add flags for each value saying who changed it, and figure out when
  7494. ;[47] to set it back to the default, etc...
  7495. ;
  7496. ;[50] Call with:
  7497. ;[50]  t3/ Length of Send-Init packet data field (number of parameters)
  7498. ;[50]  t4/ Pointer to Send-Init packet data field.
  7499. ;[50] The ACs t3-t4 are automatically set up this way upon return from RPACK,
  7500. ;[50] provided nothing has been done to them before calling SPAR.
  7501. ;
  7502. spar:    saveac<q1>        ;[48]
  7503.  
  7504. ; Packet Size
  7505.  
  7506. spar1:    move t2, spsiz        ;[168] Get current setting.
  7507.     sojl t3, spar1a        ;[100] Make sure the field is in packet.
  7508.     ildb t2, t4        ; It is, get it.
  7509.     subi t2, " "        ; Convert it to a number.
  7510. spar1a:    move q1, spsiz        ;[47] See what we have now.
  7511.     caie q1, dspsiz        ;[47] Has default been changed already?
  7512.      jrst spar2        ;[47] Yes, probably by SET command, keep that.
  7513.     caige t2, spmin        ;[47] No, check bounds for new value.
  7514.      movei t2, spmin    ;[47] If too small, use our minimum.
  7515.     caile t2, spmax        ;[47] Or if too great,
  7516.      movei t2, spmax    ;[47] use our maximum value.
  7517.     movem t2, spsiz        ; Set the maximum packet size to send.
  7518.  
  7519. ; Timeout.
  7520.  
  7521. spar2:    move t2, stimou        ;[168] Get current setting.
  7522.     sojl t3, spar2a        ;[100] Got a packet field for this?
  7523.     ildb t2, t4        ; Yes, get it.
  7524.     subi t2, " "        ; Convert the character to a number.
  7525. spar2a:    skipge t2        ;[49][168]  Make sure it's
  7526.      setz t2,        ;[43] not negative.
  7527.     move q1, stimou        ;[47] Has the default already been changed,
  7528.     caie q1, dstim        ;[47] for instance, by a SET command?
  7529.      jrst spar3        ;[47]  Yes it has, so let that take precedence.
  7530.     cain t2, rtimou        ;[131] Same as other side's timeout?
  7531.      aos t2            ;[131] If so, make it a little bit different.
  7532.     movem t2, stimou    ; Set the time out interval.
  7533.     movem t2, otimou    ;[26] Here too, in case we want to change it.
  7534.     ;...
  7535.  
  7536. ; SPAR, cont'd
  7537.  
  7538. ; Padding
  7539.  
  7540. spar3:    move t2, spadn        ;[100][168] Set up default.
  7541.     sojl t3, spar3a        ;[100] Make sure the field is there.
  7542.     ildb t2, t4        ; Get the 3rd field.
  7543.     subi t2, " "        ; Convert it to a number.
  7544. spar3a:    move q1, spadn        ;[47][168] Check if default already changed.
  7545.     caie q1, dspadn        ;[47]
  7546.      jrst spar4        ;[50] It has, don't do this.
  7547.     skipge t2        ;[50] Make sure the number makes sense.
  7548.      movem t2, spadn    ;[50] OK, set the padding.
  7549.  
  7550. ; Pad character
  7551.  
  7552. spar4:    move t2, spadch        ;[100][168] Set up default.
  7553.     sojl t3, spar4a        ;[100] Make sure the field is there.
  7554.     ildb t2, t4        ; Get the 4th field.
  7555.     addi t2, ^o100
  7556.     andi t2, ^o177
  7557. spar4a:    move q1, spadch        ;[47][168] Check for default already changed.
  7558.     caie q1, dspad        ;[50]
  7559.      jrst spar5        ;[50]
  7560.     cain t2, 177        ;[50] DEL?
  7561.      jrst spar4a        ;[50]  Yes, can use it.
  7562.     cail t2, 0        ;[50] No, some other control character?
  7563.      caile t2, 37        ;[50]  ...
  7564.      skipa            ;[50]  Nope, reject it.
  7565.      movem t2, spadch    ; OK, set the padding char.
  7566.  
  7567. ; End Of Line
  7568.  
  7569. spar5:    move t2, seolch        ;[168] Set up default.
  7570.     sojl t3, spar5a        ;[100] Make sure the field is there.
  7571.     ildb t2, t4        ; Get the 5th field.
  7572.     subi t2, " "        ; Convert it to a number.
  7573. spar5a:    move q1, seolch        ;[47][168] Default changed already?
  7574.     caie q1, dseol        ;[47]
  7575.      jrst spar6        ;[50]  Yes, so don't do this.
  7576.     cail t2, 0        ;[50] No, did they give a control character?
  7577.      caile t2, 37        ;[50]  ...
  7578.      skipa            ;[50]  Nope, reject it.
  7579.      movem t2, seolch    ; OK, in range, set the EOL character.
  7580.  
  7581. ; Control Prefix
  7582.  
  7583. spar6:    move t2, rquote        ;[168][132][100] Get current setting.
  7584.     sojl t3, spar6a        ;[100] Make sure the field is there.
  7585.     ildb t2, t4        ; Get the 6th field.
  7586. spar6a:    move q1, rquote        ;[168][132][47] Default already changed?
  7587.     caie q1, drquot        ;[132][50]
  7588.      jrst spar7        ;[50]  Yes, don't change it again.
  7589.     caile t2, " "        ;[50] No, check for printable character
  7590.      caile t2, "~"        ;[50]  other than space.
  7591.      skipa            ;[50]  Out of range, reject it.
  7592.      movem t2, rquote    ;[132] OK, set the quote character.
  7593.     ;...
  7594.  
  7595. ;...SPAR, cont'd
  7596.  
  7597. ; [88] 8th-bit prefix support added as edit 88.
  7598.  
  7599. spar7:    sojl t3, spar7x        ; Did they give one?  If not, do default.
  7600.     ildb t2, t4        ; They did, get it.
  7601.     caie t2, "Y"        ; Is it WILL?
  7602.      jrst spar7a        ;  No, go check for WON'T.
  7603.  
  7604. ; Other side sent "Y" (WILL).
  7605.  
  7606.     skipe ebqr        ; Did our user request prefixing?
  7607.      jrst [    move t2, ebq    ;[89]  Yes, use the specified prefix.
  7608.         movem t2, ebqfld ; Put it here to be sent to other side.
  7609.         setom ebqflg    ; Flag that we're doing this.
  7610.         cain t2, "N"    ; But did she request NOT to do it?
  7611.          setzm ebqflg    ;  In that case, don't.
  7612.         jrst spar8 ]
  7613.     jrst spar7x        ; Didn't request it, so DON'T.
  7614.  
  7615. ; Other side sent "N" (WON'T).
  7616.  
  7617. spar7a:    cain t2, "N"        ; Is it WON'T?
  7618.      jrst spar7x        ;[89] Yes, so DON'T.
  7619.  
  7620. ; Not "Y" or "N".  See if it's a valid prefix character.
  7621.  
  7622. spar7b:    call prechk        ; Call the prefix checking routine.
  7623.      jrst spar7x        ;  It's not valid.
  7624.  
  7625. ; Other side sent valid prefix character.
  7626.  
  7627. spar7c:    skipe $sendf        ;[89] Sending?
  7628.      jrst [    camn t2, ebq    ;[89] Yes, matches what we said?
  7629.          jrst spar7d    ;[89]  Yes, go ahead.
  7630.         move q1, ebqfld    ;[89] No, but...
  7631.         caie q1, "Y"    ;[89]  if this was "Y", then it's still OK.
  7632.          jrst spar7x    ;[89] Otherwise, forget it.    
  7633.         jrst .+1 ]    ;[89]
  7634.  
  7635. ; Got &/Y, Y/&, or &/& combination, so may be OK to do 8-bit prefixing.
  7636.  
  7637. spar7d:    caie t2, rquote        ; Same as one of the control quotes?
  7638.     cain t2, squote
  7639.      jrst [ movei t2, "N"    ;  One of those, must refuse.
  7640.         jrst spar7y ]
  7641.     movem t2, ebq        ; Unique, so save it as the 8b prefix.
  7642.     movei t2, "Y"        ; Acknowledge that we will use it.
  7643.     movem t2, ebqfld    ;   ...
  7644.     setom ebqflg        ; Set the flag saying we must do this.
  7645.     jrst spar8        ; On to next field.
  7646.  
  7647. ; Field was none of the above.  Take default action.
  7648.  
  7649. spar7x:    movei t2, "Y"        ; What we normally say.
  7650. spar7y:    movem t2, ebqfld    ; Put it where RPAR can find it.
  7651.     setzm ebqflg        ; No 8th-bit prefixing.
  7652.  
  7653. ; [88] (End of addition) ....
  7654.  
  7655. ;...SPAR, cont'd
  7656.  
  7657. ;[98] Block check type. (This section added as part of edit 98)
  7658.  
  7659. spar8:    movei t2, "1"        ;[100] Set default, in case this field omitted.
  7660.     sojl t3, spar8a        ;[100] See if there is one.
  7661.     ildb t2, t4        ; Here it is...
  7662.     cail t2, "1"        ; Between 1
  7663.      caile t2, "3"        ;  and 3?
  7664.      movei t2, "1"        ;  No, substitute default value.
  7665.     skipe $sendf        ; I'm sending?
  7666.      jrst [    came t2, bctr    ;  Yes, does this match what I requested?
  7667.          movei t2, "1"    ;  No, so fall back to default.
  7668.         jrst .+1]
  7669. spar8a:    movem t2, bctr        ; Save as block check type requested.
  7670.     subi t2, "0"        ; Convert to a number 1-3,
  7671.     movem t2, bctu        ; and save as block check type to be used.
  7672.  
  7673. ;...SPAR, cont'd
  7674.  
  7675.     
  7676. ; [92] Repeat count prefix support added as edit 92.
  7677.  
  7678. spar9:    sojl t3, spar9x        ; If they didn't give one, don't do this.
  7679.     ildb t2, t4        ; They did, see what it is.
  7680.         
  7681. ; Is it a valid prefix character?
  7682.  
  7683. spar9b:    call prechk        ; Call the prefix checking routine.
  7684.      jrst spar9x        ;  It's not valid.
  7685.  
  7686. ; Other side sent valid prefix character.
  7687.  
  7688. spar9c:    skipe $sendf        ; I'm sending?
  7689.      jrst [    caie t2, rptq    ; Yes, see if theirs matches what I said.
  7690.          jrst spar9d    ;  It does, proceed.
  7691.         jrst spar9x ]    ; It doesn't, don't do repeat counts.
  7692.  
  7693. ; Got a valid prefix, but make sure it's not already in use.
  7694.  
  7695. spar9d:    caie t2, rquote        ; Same as one of the control quotes?
  7696.      cain t2, squote
  7697.      jrst spar9y
  7698.     skipe ebqflg        ; Doing 8th-bit prefixing?
  7699.      caie t2, ebq        ; Yes, check that prefix too.
  7700.      skipa            ; It's OK.
  7701.      jrst spar9x        ; It's the same, don't do repeat counts.
  7702.  
  7703. ; OK, it's valid, it's unique.
  7704.  
  7705. spar9e:    movem t2, rptq        ; Save it as what we'll be using.
  7706.     movem t2, rptfld    ; What we'll reply, in case we're receiving.
  7707.     setom rptflg        ; Set the flag.
  7708.     jrst spar10        ; Go on to next field.
  7709.  
  7710. ; Come here if we're not going to do repeat counts.
  7711.  
  7712. spar9x:    movei t2, " "        ; Blank means default which is no repeat count.
  7713. spar9y:    movem t2, rptfld    ; Put it here to reply in case we're receiving,
  7714.     setzm rptflg        ; and flag that we're not going to do it.
  7715.  
  7716. ; [92] (End of addition)
  7717.  
  7718.     ;...
  7719.  
  7720. ;...SPAR, cont'd
  7721.  
  7722. ; [ 179] Capabilities mask, window size (not supported), and long packet size.
  7723.  
  7724. spar10:    sojl t3, sparx        ; [179] This field present?
  7725.     ildb t2, t4        ; [179] Yes, get it.
  7726.     subi t2, " "        ; [179] Convert it to a number.    
  7727.     trnn t2, 2        ; [179] Long Packets capability on?
  7728.      jrst sparx        ; [179] No, done.
  7729.     sojl t3, sparx        ; [179] Skip Window size
  7730.     ildb t2, t4        ; [179] ...
  7731.     sojl t3, sparx        ; [179] Big part
  7732.     ildb t1, t4        ; [179] ...
  7733.     subi t1, " "        ; [179] Convert it to a number.    
  7734.     imuli t1, ^d95        ; [179] ...
  7735.     sojl t3, sparx        ; [179] small part
  7736.     ildb t2, t4        ; [179] ...
  7737.     subi t2, " "        ; [179] Convert to number
  7738.     add t1, t2        ; [179] Add to big part
  7739.     movem t1, spsiz        ; [179] New packet length.
  7740.  
  7741. ; Exit.  Set up maximum data field size based on what transpired above.
  7742.  
  7743. sparx:    move t1, spsiz        ; Get the send packet size.
  7744.     subi t1, 4        ; Deduct the constant overhead,
  7745.         sub t1, bctu        ; and the length of the checksum.
  7746.     subi t1, 2        ; Room to leave at end: 2 for possible #X,
  7747.     skipe rptflg        ; and if doing repeat counts,
  7748.      subi t1, 2        ; another 2 for repeat prefix,
  7749.     skipe ebqflg        ; and if doing 8th-bit prefixing,
  7750.      subi t1, 1        ; another one for that.
  7751.     movem t1, maxdat    ; Save max length for data field here.
  7752.     ret
  7753.  
  7754.  
  7755. ; PRECHK - Check if character in T2 is valid prefix character.
  7756. ; Return +1 if not, +2 if it is.
  7757. ;
  7758. prechk:    cail t2, ^d33        ; Is it in the 33-62 range?
  7759.      caile t2, ^d62
  7760.      skipa            ; No, see if it's in the high range.
  7761.      retskp            ; Yes, it's in range.
  7762.     cail t2, ^d96        ; Or in the 96-126 range?
  7763.      caile t2, ^d126
  7764.      ret            ; No, something else, not a valid prefix.
  7765.     retskp            ; Yes, it's valid.
  7766.  
  7767. ; RPAR
  7768. ;
  7769. ; Sets up the data field of an init packet with the our own parameters,
  7770. ; which we want the other side to honor.
  7771. ;
  7772. ; Call with:
  7773. ;  t4/ Pointer to data field for S or I packet, or its ACK.
  7774. ;  EBQFLD contains the character to send in the 8-bit-quote field.
  7775. ; Returns with:
  7776. ;  t3/ Length of data field (number of elements).
  7777. ;  t4/ Original pointer to data field.
  7778. ; The ACs t3-t4 are returned suitably for a call to SPACK.
  7779. ;
  7780. rpar:    saveac <t1,t2,t4,q1>    ; Save temp ACs, and t4 for return.
  7781.     move q1, rpsiz        ; 1 Get the packet size.
  7782.     caile q1, ^d94        ;  Fix to compare correctly.
  7783.      movei q1, ^d94        ;[179] Yes, make it 94.
  7784.     addi q1, " "        ;   Make the char printable.
  7785.     idpb q1, t4        ;   Put it in the data block.
  7786.  
  7787. ;[128] Tell the other side how to time out, based on the current 15-min ldav.
  7788.  
  7789.     movei t1, 2        ; Request 15-minute load average.
  7790.     call ldav
  7791.     move t2, rtimou        ; Other side use this timeout when I'm recving.
  7792.     cain state, "S"        ;[131] But am I sending?
  7793.      subi t2, 2        ;[131]  Make it a little different.
  7794.     call adjtim        ; Adjust based on load average.
  7795.  
  7796.     movem t2, rrtimo    ;   Save time for reporting.
  7797.     addi t2, " "        ;   Make it printable.
  7798.     idpb t2, t4        ;   Put it in the data block.
  7799.     
  7800. ; Easy fields...
  7801.  
  7802.     move q1, rpadn        ; 3 Get the padding.
  7803.     addi q1, " "        ;   Make the char printable.
  7804.     idpb q1, t4        ;   Put it in the data block.
  7805.     move q1, rpadch        ; 4 Get the padding char.
  7806.     addi q1, ^o100        ;   De-controllify it.
  7807.     andi q1, ^o177        ;
  7808.     idpb q1, t4        ;   Put it in the data block.
  7809.     move q1, reolch        ; 5 Get the EOL char.
  7810.     addi q1, " "        ;   Make the char printable.
  7811.     idpb q1, t4        ;   Put it in the data block.
  7812.     move q1, squote        ; 6 [132] Get the quote char.
  7813.     idpb q1, t4        ;   Put it in the data block.
  7814.     move q1, ebqfld        ; 7 Say what we'll do about 8th-bit quoting.
  7815.     idpb q1, t4        ;   Put in the data block.
  7816.     move q1, bctr        ; 8 Block check type requested.
  7817.     idpb q1, t4        ;   Put in the data block.
  7818.     move q1, rptfld        ; 9 The repeat-count-prefix field.
  7819.     idpb q1, t4        ;   Put in the data block.
  7820.  
  7821. ; [179] Capabilities mask
  7822.  
  7823.     movei q1, 2        ; [179] 10 Set long-packet capability bit
  7824.     addi q1, " "        ; [179] Convert to ASCII
  7825.     idpb q1, t4        ; [179] Deposit in packet
  7826.     movei t3, ^d10        ; [179] Ten bytes of data so far
  7827.     move q1, rpsiz        ; [179] RECEIVE PACKET-LENGTH
  7828.     caig q1, ^d94        ; [179] Regular (short) packet?
  7829.      ret            ; [179] Done.
  7830.  
  7831. ; [179] Long packets requested
  7832.  
  7833.     movei q1, " "        ; [179] Window size is 0 (no sliding windows)
  7834.     idpb q1, t4        ; [179] Deposit
  7835.     aos t3            ; [179] Count
  7836.     move q1, rpsiz        ; [179] RECEIVE PACKET-LENGTH
  7837.     idivi q1, ^d95        ; [179] Big part (quotient)
  7838.     addi q1, " "        ; [179] Convert to ASCII
  7839.     idpb q1, t4        ; [179] Deposit
  7840.     aos t3            ; [179] Count
  7841.     addi q2, " "        ; [179] Small part (remainder)
  7842.     idpb q2, t4        ; [179] Deposit
  7843.     aos t3            ; [179] Count
  7844.  
  7845.     ret            ; Done
  7846.  
  7847. ; Miscellaneous small routines for NAKs & Error packets.
  7848.  
  7849.  
  7850. ; Send a NAK.  Expects to find the packet number to NAK in AC2.
  7851.  
  7852. nak:    stkvar <naktry>        ; Counter for NAKs.
  7853.     setom naktry
  7854.     
  7855. nak2:    aos t1, naktry        ; Count this try.
  7856.     camle t1, maxtry    ; Less than maximum?
  7857.      jrst nakx        ;  No, fail.
  7858.     movei t1, "N"        ; Send a NAK.
  7859.     setzb t3, t4        ; No data.
  7860.     call spack        ; Send the packet.
  7861.      jrst @[exp nak2, nakx](t1) ; Handle failures.
  7862.     aos nnak        ; Sent the NAK OK, count it.
  7863.     ret
  7864.  
  7865. nakx:    movei state, "A"    ;  If we can't, set state to cancel.
  7866.     ret
  7867.  
  7868. ; Print the contents of an error packet, if local.
  7869. ;
  7870. ; t1-t4 contain the packet parameters from RPACK.
  7871. ; Sets state to cAncel.
  7872. ; Returns +1 always.
  7873.  
  7874. pxerr:    movei state, "A"    ; Set state to cAncel.
  7875.     skipe iflg        ; Doing Info packet?
  7876.      ret            ;  Skip this.
  7877.     movem t4, errptr
  7878.     hrroi t1, [asciz/?Remote error -- /] ; Yes, print message.
  7879.     PSOUT%
  7880.     move t1, errptr        ; Get pointer to it,
  7881.     PSOUT%            ; and print it.
  7882.  
  7883. ;[126] Print the error in the transaction log too.
  7884.  
  7885.     skipn t1, tlgjfn    ; (if any)
  7886.      ret
  7887.     wtlog <Transaction Cancelled by Error from Other Kermit:>
  7888.     move t2, errptr
  7889.     setzb t3, t4
  7890.     SOUT
  7891.     hrroi t2, crlf
  7892.     SOUT
  7893.     ret
  7894.  
  7895.     subttl    SEND command
  7896.  
  7897. ; Help text.
  7898.  
  7899. hsend:    asciz |
  7900. SEND filespec (AS) [target-name]
  7901. SEND wild-filespec1 (INITIAL) [initial-file]
  7902.  
  7903. Send a file or file group from the DEC-20 to the other host.  If the filespec
  7904. contains wildcard characters (* or %) then all matching files will be sent, in
  7905. alphabetical order by name.  If a file can't be opened for read access, it will
  7906. be skipped.  The name of each file is passed to the other host in a file header
  7907. packet, so that the file can be stored there with the same or similar name.
  7908.  
  7909. If a single file is specified, you may optionally specify a diffent name for it
  7910. "target-name") to be sent in the file header packet.  This name is not parsed;
  7911. it is sent to the other system as is, except any lowercase letters are raised
  7912. to upper case.
  7913.  
  7914. If a wildcard file group is specified, you may optionally specify an initial
  7915. file to send.  This is handy to continue a previously interrupted wildcard
  7916. transfer from where it left off, or to skip some files that would be
  7917. transmitted first.
  7918.  
  7919. If running as a local Kermit, the name of each file will be displayed on your
  7920. screen as the transfer begins, a "." will be displayed for every 5 data packets
  7921. sucessfully sent, and a "%" for every retransmission or timeout that occurs
  7922. you may also elect other typeout options with the SET DEBUG command).  If you
  7923. see many "%" characters, you are probably suffering from a noisy connection.
  7924. You can type Control-A at any point during the transfer to get a brief status
  7925. report.
  7926.  
  7927. When running locally and sending files, you can cancel (stop sending) the
  7928. current file by typing Control-X.  If sending a file group, Control-X will
  7929. cause the current file to be skipped, and KERMIT-20 will go on to the next
  7930. file.  Control-Z will cancel sending the entire group and return you to
  7931. KERMIT-20 command level.
  7932.  
  7933. If running as a remote Kermit, you should escape back to your local Kermit and
  7934. give the RECEIVE command.  If you don't do this fast enough, several
  7935. "send-init" packets may arrive prematurely; don't worry, KERMIT-20 will keep
  7936. sending them until it gets a response.
  7937.  
  7938. If communication line parity is being used, KERMIT-20 will request that the
  7939. other KERMIT accept a special kind of prefix notation for binary files.  This
  7940. is an advanced feature, and not all KERMITs have it; if the other KERMIT does
  7941. not agree to use this feature, binary files cannot be sent correctly.  This
  7942. includes executable programs, relocatable object modules, files with EDIT line
  7943. sequence numbers (as produced by EDIT, SOS, or OTTO), etc.
  7944.  
  7945. KERMIT-20 will also ask the other KERMIT whether it can handle a special prefix
  7946. encoding for repeated characters.  If it can, then files with long strings of
  7947. repeated characters will be transmitted very efficiently.  Columnar data,
  7948. highly indented text, and binary files are the chief beneficiaries.
  7949. |
  7950.  
  7951. ;...SEND command, cont'd
  7952.  
  7953.  
  7954. ; SEND command parsing.
  7955.  
  7956. .send:    noise <from files>    ; Issue guide words.
  7957.     move t2, cjfnbk+.gjgen    ; Get the JFN flag bits.
  7958.     txo t2, gj%ifg!gj%old    ; Old file(s), allow wild cards.
  7959.     trz t2, -1        ;[172] Default to most recent generation only.
  7960.     movem t2, cjfnbk+.gjgen    ; Return the JFN flag bits.
  7961.     setzm cjfnbk+.gjext    ;[172] No default extension.
  7962.     movei t1, [flddb. (.cmfil,cm%sdh,,<input file spec (possibly wild)>,,)]
  7963.     call rfield        ; Parse a file spec or a confirm.
  7964.     movem t2, pars2        ;[111]
  7965.     tlnn t2, 770000        ; Any wildcards in it?
  7966.      jrst [    noise <as>    ;[96] No, then let them choose a new name.
  7967.         movei t1, [    ;[96]
  7968.          flddb. .cmtxt,cm%sdh,,<Carriage return to send with this name,
  7969.  or specify file name to use on target system>]    ;[96]
  7970.         jrst .send2 ]
  7971.     noise <initial>        ; Wildcard(s) given, prompt for initial.
  7972.     movei t1, [flddb. (.cmcfm,cm%sdh,,<Carriage return to send them all>,,[
  7973.            flddb. (.cmfil,cm%sdh,,<First file to send>)])]
  7974. .send2:    call rflde        ; Parse the field.
  7975.      jrst .sende        ;[63] Handle errors explicitly.
  7976.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  7977.     movem t3, pars3        ;[96] Save it for execution.
  7978.     cain t3, .cmcfm        ; Confirmation?
  7979.      ret            ;  Yes, just return.
  7980.     cain t3, .cmfil        ;[96] File?
  7981.      jrst [    hrrm t2, pars2    ;[117] No, initial filespec - substitute it.
  7982.         movei t1, [flddb. .cmcfm] ; Get command confirmation.
  7983.         call rflde
  7984.          jrst .sende
  7985.         ret ]
  7986.  
  7987. ;[96] If they gave an alternate name, copy it out of the atom buffer.
  7988.  
  7989.     caie t3, .cmtxt        ; Text?
  7990.      jrst .sende        ;  No, error.
  7991.     move t1, [point 7, atmbuf] ; Copy the string out of the atom buffer.
  7992.     move t2, [point 7, buffer]
  7993.     setzm buffer
  7994.     call movstu
  7995.     jumpe t3, [        ; If nothing, act like we parsed a confirm.
  7996.         movei t3, .cmcfm
  7997.         movem t3, pars3
  7998.         ret ]
  7999.     ret
  8000.  
  8001. .sende:    move t1, filjfn        ; Error - get the JFN.
  8002.     RLJFN%            ; Release it.
  8003.      erjmp .+1        ;  Ignore any errors.
  8004.     setzm filjfn        ; Nullify the JFN.
  8005.     tmsg <?Not confirmed>
  8006.     jrst cmder1
  8007.  
  8008. ; MOVSTU -- Move string routine, uppercasing any lowercase letters.
  8009. ;  Eat any leading whitespace.
  8010. ;  Call with t1/ source pointer
  8011. ;            t2/ destination pointer
  8012. ;  Returns with t1, t2 updated, t3/ character count, t4/ 0.
  8013. ;
  8014. movstu:    seto t3,        ; Counter, started at -1.
  8015.  
  8016. movstx:    ildb t4, t1        ; Get a character.
  8017.     jumpn t3, movsty    ; Have we got at least one nonwhitespace?
  8018.     caie t4, 40        ; No, is this a blank?
  8019.      cain t4, 11        ;  or a tab?
  8020.      jrst movstx        ;  One of those, skip it.
  8021. movsty:    cail t4, "a"        ; Convert to upper case if necessary.
  8022.      caile t4, "z"
  8023.      skipa
  8024.      trz t4, 40
  8025.     idpb t4, t2        ; Copy it.
  8026.     aos t3            ; Count it.
  8027.     jumpn t4, movstx    ; Everything up to & including the first null.
  8028.  
  8029.     ret    
  8030.  
  8031. ; SEND command execution.
  8032.  
  8033. $send:    setom $sendf        ;[88] Executing SEND command,
  8034.     setzm $recvf        ;[88] not RECEIVE command.
  8035.     setzm ttildb        ;[180] (stats)
  8036.     setzm ttibin        ;[180] (stats)
  8037.     setzm ttisin        ;[180] (stats)
  8038.     setzm ttimax        ;[180] (stats)
  8039.     move t1, pars2        ;[111] Get JFN we just parsed.
  8040.     movem t1, ndxjfn    ;[111] Save the wildcard bits here.
  8041.     hrrzm t1, nxtjfn    ;[111] Initialize file lookahead.
  8042.     call gtnfil        ;[111] Get JFN of first file.
  8043.      ermsg <No files to send>,r ;[111] (if any).
  8044.     call caxzon        ;[59] Turn on ^A,^X,^Z interrupts.
  8045.     hrroi t1, [        ;[61] Tell about terminal interrupts,
  8046.      asciz/^A for status report, ^X to cancel file, ^Z to cancel batch./]
  8047.     skipe local        ;[61]  (if local).
  8048.      PSOUT%            ;[61]
  8049.     call inilin        ; Initialize the line
  8050.     call ccon        ;  and turn on ^C trap.
  8051.      jrst reslin        ;[10] on ^C, go reset line, return from there.
  8052.  
  8053. ; Entry point for server.
  8054.  
  8055. $sends:    setzm stot        ; Initialize statistics variables.
  8056.     setzm rtot
  8057.     setzb schr, stchr
  8058.     setzb rchr, rtchr
  8059.     setzm files
  8060.     setom sptot        ;[4] Init the sent-packet counter to -1.
  8061.     setom rptot
  8062.     setzm nnak        ;[54] Init the number of NAKs
  8063.     setzm ntimou        ;[54]  and the number of timeouts.
  8064.     setzm errptr        ; Zero the error message pointer.
  8065.     setzm timerx        ; Timer error counter.
  8066.     GTAD%            ; Get the time we start.
  8067.     movem t1, stdat        ; Save it for statistics.
  8068.  
  8069. ; Delay to give them time to escape back to other side and say "receive".
  8070.  
  8071.     skipn srvflg        ; Don't delay if server
  8072.      skipe local        ;  or if local.
  8073.      jrst $send1
  8074.     ;...
  8075.  
  8076. ;...$SEND, cont'd
  8077.  
  8078.  
  8079. ;[128] Remote, do the requested delay.
  8080.  
  8081.     move t4, delay        ; The specified delay in seconds.
  8082.     lsh t4, 1        ; Make it half seconds.
  8083.  
  8084. $sndxx:    sojl t4, $send1        ; Countdown.
  8085.     movei t1, ^d500        ; Sleep half a second.
  8086.     DISMS
  8087.  
  8088.     skipn t1, netjfn    ; Got a file transfer jfn?
  8089.      jrst $sndxx        ;  No reason why we shouldn't, but...
  8090.     SIBE            ; Anything in input buffer?
  8091.      skipa
  8092.     jrst $sndxx
  8093.  
  8094. ;[128] If user escapes back to micro & types CR to send NAK for packet 0,
  8095. ; no need to delay any longer -- start sending immediately.
  8096.  
  8097. $sndzz:    BIN            ; Just get first character.
  8098.     came t2, rsthdr        ; Start of packet?
  8099.      jrst $sndxx        ;  No, they're probably fumbling w/the keyboard
  8100.     CFIBF            ; Yes, assume it's a NAK for packet 0,
  8101.      erjmp .+1        ;  discard the rest and start sending.
  8102.  
  8103. ; We can be sending with either a File Header (F) or a Text Header (X).
  8104. ; XFLG nonzero means X header, XFLG zero means F header.
  8105. ; If sending with F header, start with the Send-Init, as packet 0.
  8106. ; If sending with X, we can skip the Send-Init and send X as packet 1.
  8107. ;
  8108. ;[124] BUT...  If type 2 or 3 block check requested and agreed upon,
  8109. ;[124] cannot skip Send-Init (even if I packet exchange just occurred).
  8110.  
  8111. $send1:    movei state, "S"    ; Set the state to Send-Initiate.
  8112.     move t1, bctu        ;[124] What kind of block check are we using?
  8113.     caie t1, 1        ;[124] 2 or 3 character block check?
  8114.      jrst [    setzm pktnum    ;[124] Yes, then must send a Send-Init.
  8115.         jrst $sendb ]    ;[124]
  8116.  
  8117. ; Type 1 block check.  Can obey XFLG.
  8118.  
  8119.     skipn xflg        ; X or F header?
  8120.      setzm pktnum        ;  F, so reset packet number.
  8121.     skipe xflg        ; X or F?
  8122.      movei state, "F"    ;  If X, go straight into file-sending state.
  8123.  
  8124. $sendb:    move t1, spause        ;[36] Get the requested send-pause interval
  8125.     movem t1, pause        ;[36]  and make it the current one.
  8126.     setzm numtry        ; Set the number of tries to zero.
  8127.  
  8128. $senda:    call setlog        ;[57] Set up any debugging log.
  8129.      nop
  8130.  
  8131. ; SEND command, cont'd...  State Table Switcher:
  8132.  
  8133.  
  8134. $send2:    cain state, "D"        ; Are we in the data send state?
  8135.      jrst [    call sdata
  8136.         jrst $send2 ]
  8137.     cain state, "F"        ; Are we in the file send state?
  8138.      jrst [    call sfile    ;  Call send file.
  8139.         jrst $send2 ]
  8140.     cain state, "Z"        ; Are we in the end of file state?
  8141.      jrst [    call seof
  8142.         jrst $send2 ]
  8143.     cain state, "S"        ; Are we in the send initiate state?
  8144.      jrst [    movei t1, "S"    ;[100] Packet type for Send-Init.
  8145.         call sinit    ; Call send-initiate routine.
  8146.         jrst $send2 ]
  8147.     cain state, "B"        ; Are we in the end of send state?
  8148.      jrst [    call seot
  8149.         jrst $send2 ]
  8150.     cain state, "C"        ; Are we in the send complete state?
  8151.      jrst [    movei t1, "C"
  8152.         move t2, pktnum
  8153.         call diamsg
  8154.         call caxzoff    ;[59] Turn off keyboard interrupts
  8155.         call reslin    ;  Restore the line.
  8156.         GTAD%        ;  Get the time we ended.
  8157.         subm t1, stdat    ;  Figure how long it all took.
  8158.         movei t1, .chbel ;[31] Give a beep
  8159.         skipe local    ;[31] if local
  8160.          PBOUT        ;[31]
  8161.         ret ]
  8162.     cain state, "A"        ; Are we in the send cAncel state?
  8163.      jrst [    movei t1, "A"
  8164.         move t2, pktnum
  8165.         call diamsg    ;[38]
  8166.         call reslin    ;  Restore the line.
  8167.         GTAD%        ;  Get the time we ended.
  8168.         subm t1, stdat    ;  Figure how long it all took.
  8169.         move t1, filjfn ;[134] Last-ditch effort to close the file.
  8170.         setzm filjfn    ;[134]
  8171.         jumple t1, r    ;[134]
  8172.          CLOSF        ;[134]
  8173.          erjmp r    ;[134]
  8174.         ret ]
  8175.     movei t1, "U"        ; Some undefined state???
  8176.     move t2, pktnum
  8177.     call diamsg        ;[38]
  8178.         call caxzof        ;[59] Turn off ^A,^X,^Z traps.
  8179.     call reslin
  8180.     ret
  8181.  
  8182.     subttl Send routines
  8183.  
  8184. ; SINIT: Call with t1/packet type, "S" for Send-Init, "I" for Init-Info.
  8185. ;
  8186. sinit:    saveac <q1>
  8187.     move q1, numtry        ; Get the number of tries.
  8188.     caml q1, imxtry        ; Have we reached the maximum number of tries?
  8189.      jrst [    skipe local    ;[5] Yes.
  8190.          ermsg <Send-Init not ACK'd>,sinitx
  8191.         jrst sinitx ]    ; Go cancel the transfer
  8192.     aos numtry        ; Save updated number of tries.
  8193.     movei t4, "Y"        ;[88] Say we agree to do 8-bit prefixing.
  8194.     skipe ebqr        ;[88] Did our user explicitly ask for it?
  8195.      move t4, ebq        ;[89] In that case, specify requested prefix.
  8196.     movem t4, ebqfld    ;[88] Put it here.
  8197.     movei t4, drept        ;[92] Want to use this as repeat count prefix.
  8198.     movem t4, rptfld    ;[92] Put it here.
  8199.     move t4, [point 8, data] ;[50] The address of the data.
  8200.     call rpar        ; Set the information.
  8201.     move t2, pktnum        ; Packet number.  T1 already has packet type.
  8202.     setom bctone        ;[98] Force single char checksums.
  8203.     call spack        ; Send the packet.
  8204.      jrst @[exp r, sinitx](t1) ; Handle errors.
  8205.     call rpack        ; Get a packet.
  8206.      ret            ;  Trashed packet don't change state, retry.
  8207.  
  8208. sinity:    caie t1, "Y"        ; Check packet type.  ACK?
  8209.      jrst sinitn        ;  No, go see if it's a NAK.
  8210.     came t2, pktnum        ; ACK.  But is it the right ACK?
  8211.      ret            ;  No, don't settle, hold out for right one.
  8212.     call spar        ; Yes, get the information.
  8213.     setzm numtry        ; Reset the number of tries.
  8214.     aos t2, pktnum        ; Increment the packet number,
  8215.     andi t2, 77        ; modulo 100,
  8216.     movem t2, pktnum    ; and save it.
  8217.     call ebqmsg        ;[89] Go warn if problem w/8-bit prefixing.
  8218.     setzm bctone        ;[98] Finished with initialization.
  8219.     movei state, "F"    ; Set the state to file send.
  8220.  
  8221. ;[126] Start entry in transaction log.
  8222.  
  8223.     skipn t1, tlgjfn    ; (if any)
  8224.      ret
  8225.     skipe iflg        ; Not an I packet, is it?
  8226.      ret
  8227.     wtlog <-- Send Begins -->
  8228.     callret rrlog        ; Go log details.
  8229.  
  8230. sinitn:    cain t1, "N"        ;[30][54] NAK?
  8231.      aosa nnak        ;[54] Yes, count it & return.
  8232. sinitt:    cain t1, "T"        ; Timer interrupt pseudo packet?
  8233.      ret            ;[30] One of those, just keep trying.
  8234.     cain t1, "E"        ; But also print message if error packet.
  8235.      jrst pxerr        ;[82]
  8236. sinitx:    movei state, "A"    ; Anything else, just cancel.
  8237.     ret
  8238.  
  8239. ; SFILE - Send File Header
  8240.  
  8241. sfile:    setzm bctone        ; Don't require single-character checksum.
  8242.     setzm cxseen        ; Zero these here, since they apply on
  8243.     setzm czseen        ;  on a per-file basis.
  8244.     move t1, numtry        ; Get the number of tries.
  8245.     caml t1, maxtry        ; Have we reached the maximum number of tries?
  8246.      jrst [    movei state, "A" ;  Change the state to cAncel.
  8247.         kermsg <Can't send file header>, r ]
  8248.     aos numtry        ; No, count this try.
  8249.     jumpg t1, sfild3    ; After first try, skip opening file, etc.
  8250.  
  8251. sfilea:    skipn local        ;[12] Local Kermit?
  8252.      jrst sfileb        ;[12] No, skip this.
  8253.     movei t1, .priou    ;[12] Yes, print the file name.
  8254.     RFPOS%            ;[12] First see if we need to start a new line.
  8255.     hrroi t1, crlf        ;[12]  ...
  8256.     trne t2, -1        ;[12]  ...
  8257.      PSOUT%            ;[12]
  8258.     movei t1, .priou    ;[12] Now print the file name.
  8259.     hrrz t2, filjfn        ;[12]
  8260.     setz t3,        ;[12]
  8261.     JFNS%            ;[12]
  8262.      erjmp .+1        ;[12]
  8263.     movei t1, pars3        ;[96] Did we have another name to use?
  8264.     cain t1, .cmtxt        ;[96]
  8265.      jrst [    tmsg < as >    ;[96] Yes, say what it was.
  8266.         hrroi t1, buffer ;[96]
  8267.         PSOUT         ;[96]
  8268.         jrst .+1]    ;[96]
  8269.     movei t1, " "        ;[12] Leave a space.
  8270.     PBOUT%            ;[12]
  8271.     ;...
  8272.  
  8273. ; SFILE, cont'd
  8274.  
  8275. sfileb:    skipn source        ; Are we getting data from a file?
  8276.      jrst sfilb2        ; Yes, go open the file, etc.
  8277.     movei t1, "X"        ; No, so send X packet.
  8278.     move t2, pktnum        ; This packet number.
  8279.     setzb t3, t4        ; No data.
  8280.     jrst sfildy        ; Skip around all the file name baloney.
  8281.     
  8282. sfilb2:    move t1, filjfn        ;[15] JFN of file
  8283.     movx t2, fld(^d36,of%bsz)+of%rd ;[15]
  8284.     OPENF%            ;[15]
  8285.      erjmp sfilec        ;[44]
  8286.     skipn xflg        ;[126]
  8287.      wtlog <Opened File: >,filjfn ;[126]
  8288.     jrst sfiled        ;[44] Opened OK, proceed.
  8289.  
  8290. sfilec:    cain t1, opnx1        ;[44] Got an error.  "File already open"?
  8291.      jrst sfiled        ;[44] Yes, so it's not really an error.
  8292.     skipe t1, tlgjfn    ;[126] Log this failure in transaction log.
  8293.      jrst [    wtlog <Can't Send >,filjfn
  8294.         hrroi t2, [asciz/   Because: /]
  8295.         setzb t3, t4
  8296.         SOUT
  8297.         hrloi t2, .fhslf ; Tell why.
  8298.         setz t3,
  8299.         ERSTR
  8300.          nop
  8301.          nop
  8302.         hrroi t2, crlf
  8303.         setzb t3, t4
  8304.         SOUT
  8305.         jrst .+1 ]
  8306.  
  8307.     skipe local        ;[15] No, really an error.  Local?
  8308.      call [    hrroi t1, [asciz/ %Not sent because: /]
  8309.         PSOUT
  8310.         movei t1, .priou
  8311.         hrloi t2, .fhslf
  8312.         setz t3,
  8313.         ERSTR%
  8314.          nop
  8315.          nop
  8316.         ret ]
  8317.     call gtnfil        ; Try to get the next file.
  8318.      jrst [    setzm filjfn
  8319.         movei state, "B" ; No more, break transmission.
  8320.         ret ]
  8321.     jrst sfilea        ; Got one, go try to open it.
  8322.     ;...
  8323.  
  8324. ;...SFILE, Cont'd
  8325.  
  8326.  
  8327. ;[96] See if user wants to send the file with a different name.
  8328.  
  8329. sfiled:    move t1, pars3        ; Use another name?
  8330.     caie t1, .cmtxt        ;
  8331.      jrst sfild2        ; No, use the file's actual name.
  8332.     move t1, [point 7, buffer] ; Yes, copy the string the user gave us,
  8333.     move t2, [point 7, filbuf] ;[102] converting to upper case.
  8334.     call movstu        ; Returns length in t3.
  8335.     jrst sfild3        ; Proceed.
  8336.  
  8337. ; Come here to use the file's actual name.
  8338.  
  8339. sfild2:    move t1, [point 7, filbuf] ;[102] Put string in file name buffer.
  8340.     move t2, filjfn        ; The file's JFN.
  8341.     movx t3, js%nam+js%typ+js%paf ; Only name, type, and punctuation.
  8342.     setzb t4, filbuf
  8343.     JFNS%            ; Get the file name.
  8344.      erjmp [move t1, [point 7, [asciz/XXXXXX.XXX/]]    ; If any error
  8345.         movei t3, ^d10    ; substitute this string.
  8346.         jrst sfild4 ]
  8347.     ldb t3, t1        ;[175] See what the last character is.
  8348.     cain t3, "."        ;[175] Dot?
  8349.      jrst [    dpb t4, t1    ;[175] Yes, zero it out.
  8350.         seto t4,    ;[175] And remember.
  8351.         jrst .+1 ]    ;[175]
  8352.     move t2, t1        ; Set up to subtract the byte pointers.
  8353.     idpb t4, t1        ; Terminate the string
  8354.     move t1, [point 7, filbuf] ;[102] Get a pointer to our data block.
  8355.     call subbp        ; Subtract the byte pointers, get length in t3.
  8356.      ret            ;  Uh oh...  this should never happen.
  8357.     skipe t4        ;[175] Last char was dot?
  8358.      sos t3            ;[175] Yes, so count one less character.
  8359.     ;...
  8360.  
  8361. ;...SFILE, cont'd.
  8362.  
  8363. ;[84] Strip out ^V's, convert filename to "normal form" if requested.
  8364. ;[102] Do this using normal packet encoding & filling technique, but calling
  8365. ;[102] an alternate GETCH routine.
  8366.  
  8367. sfild3:    skipn filjfn        ;[128] Really a file?
  8368.      jrst [    movei t1, "X"    ; No, just send an empty X header.
  8369.         move t2, pktnum    ; Current packet number.
  8370.         setzb t3, t4    ; No data.
  8371.         jrst sfildy ]
  8372.  
  8373. ; Really a file.
  8374.  
  8375.     move t1, [point 7, filbuf] ;[102] Keep file buffer pointer in memory.
  8376.  
  8377. sfild4:    movem t1, filptr    ;[102] ...
  8378.     movei t1, gtfch        ;[102] Address alternate GETCH routine
  8379.     movem t1, source    ;[102] to call while getting characters.
  8380.     setom fildot        ;[102] Initialize filename dot counter.
  8381.     setom next        ;[102] Initialize character lookahead.
  8382.     move t1, maxdat        ;[102] Set up maximum length.
  8383.     call getbuf        ;[102] Fill up the packet with the filename.
  8384.      jumpn t1, [
  8385.         movei state, "A" ;[102] Shouldn't be any error here, but...
  8386.         ret ]        ;[102]  ...
  8387.     move t3, t1        ;[102] Set up length for call to SPACK.
  8388.  
  8389. ; Send the file header packet.
  8390.  
  8391. sfildx:    setzm source        ;[102] Done with alternate GETCH routine.
  8392.     movei t1, "F"        ; Packet type is File Header.
  8393.     skipe xflg        ; Unless it's teXt header...
  8394.      movei t1, "X"        ;  ...
  8395.     move t2, pktnum        ; Packet number.
  8396.     move t4, [point 8, data] ; Get a pointer to our data block.
  8397.  
  8398. sfildy:    call spack        ; Send the file header packet.
  8399.      skipa state, "A"    ; Failed, set state to cAncel & return.
  8400.     call rpack        ; Sent the file header OK, get reply.
  8401.      ret            ;  Trashed packet, don't change state, retry.
  8402.     ;...
  8403.  
  8404. ; SFILE, cont'd
  8405.  
  8406. ; Got a response, check for & handle ACKs.
  8407.  
  8408.     caie t1, "Y"        ; Check the packet, is it an ACK?
  8409.      jrst sfile3        ;  No.
  8410.  
  8411. sfile2:    came t2, pktnum        ; Yes, but is it the right ACK?
  8412.      ret            ;   No, don't settle, hold out for right one.
  8413.     setzm rcving        ; Indicate we're sending a file.
  8414.     aos rcving        ;  ...
  8415.     setzm numtry        ; Yes, reset the number of tries.
  8416.     aos t2, pktnum        ; Increment the packet number,
  8417.     andi t2, 77        ; modulo 100,
  8418.     movem t2, pktnum    ; and save it.
  8419.     skipn xflg        ;[126] Don't log if not sending a real file.
  8420.      jrst [    skipn t1, tlgjfn ;[126] Logging transactions?
  8421.          jrst .+1
  8422.         hrroi t2, [asciz/   Sending As "/] ; Yes, log this.
  8423.         setzb t3, t4
  8424.         SOUT
  8425.         hrroi t2, filbuf
  8426.         SOUT
  8427.         hrroi t2, [asciz/"
  8428. /]
  8429.         SOUT
  8430.         jrst sfil3a ]
  8431.     jrst sfil3a        ;[52] Join common code.
  8432.  
  8433. ; Check for & handle NAKs.
  8434.  
  8435. sfile3:    caie t1, "N"        ; NAK?
  8436.      jrst sfile4        ;  No.
  8437.  
  8438.     aos nnak        ;[54] Yes, count it.
  8439.     move t1, pktnum        ;[51] Get the expected packet number.
  8440.     aos t1            ;[51] Figure out what the next one would be,
  8441.     andi t1, 77        ;[51] mod 64.
  8442.     caie t1, (t2)        ;[51] Is the NAK for the next packet?
  8443.      ret            ;  No, so must send this packet again.
  8444.     setzm numtry        ; Yes, for next, same as ACK for this.
  8445.     movem t1, pktnum    ; Save incremented packet number.
  8446.     ;...
  8447.  
  8448. ; SFILE, cont'd
  8449.  
  8450.  
  8451. ;[75] Check for ITS binary format file.
  8452.  
  8453. sfil3a:    setzm itsfil        ; Assume this isn't an ITS file.
  8454.     skipn source        ; Skip this if it's not really a file.
  8455.      skipn itsflg        ; Looking for ITS files?
  8456.      jrst sfil3b        ;  No.
  8457.     setz t2,        ; Yes, do a 36-bit BIN.
  8458.     skiple t1, filjfn    ; ...
  8459.      BIN            ; ...
  8460.      erjmp sfil3b        ;  If there's some error, catch it later.
  8461.     came t2, [sixbit/DSK8/] ; Is it an ITS binary file?
  8462.      jrst sfil3b        ; No, then handle normally.
  8463.     setom itsfil        ; Yes, flag this file as ITS.
  8464.     hrroi t1, [asciz/(ITS binary format) /]
  8465.     skipe local        ; Say what happened if local.
  8466.      PSOUT
  8467.         
  8468. ; Get first chunk of data.
  8469.  
  8470. sfil3b:    setzm mapflg        ;[52] Say no pages mapped in yet.
  8471.     setzm eoflag        ;[72] Not EOF yet.
  8472.     setom next        ;[63] Initialize input character lookahead.
  8473.     move t1, maxdat        ;[63] Maximum length for data field.
  8474.     setz schr,        ;[128] Init number of file characters sent.
  8475.     call getbuf        ;[63] Fill the first data packet.
  8476.      jrst [    movem t1, cxseen ;[70] If error, send "discard" in EOF message.
  8477.         movei state, "Z" ; Get into EOF state.
  8478.         ret ]
  8479.     movei state, "D"    ; Got data, set the state to file send.
  8480.     movem t1, size        ; Save the length of the data.
  8481.     ret            ; Back to state switcher.
  8482.  
  8483. ; Catch-all for other states.
  8484.  
  8485. sfile4:    cain t1, "T"        ; Timer interrupt pseudo packet?
  8486.      ret            ; Yes, return without changing state.
  8487.     cain t1, "E"        ;[80] Error packet?
  8488.      call pxerr        ;[82] If so, print remote error message.
  8489.     movei state, "A"    ; Cancel the transaction.
  8490.     skiple t1, filjfn    ;[80] Close the file.
  8491.      CLOSF            ;[80]
  8492.      erjmp .+1        ;[80]
  8493.     setzm filjfn        ;[80]
  8494.     ret
  8495.  
  8496. ; GETCH replacement routine for getting characters from a filename string.
  8497. ; Uses global FILPTR for input string, FILDOT for counting dots in filename.
  8498. ; Strips any ^V used as a quote, and if requested converts name to normal form.
  8499. ;
  8500. ; Returns:
  8501. ;   +1 never (no reason to fail).
  8502. ;   +2 always, with NEXT containing next character, -1 if no more.
  8503. ;
  8504. gtfch:    ildb t1, filptr        ;[102] Get next character.
  8505.     jumpe t1, gtfchz    ;[102] If zero, must be done.
  8506.     cain t1, 26        ;[84]  Control-V?
  8507.      ildb t1, filptr    ;[102]  Yes, it's just a prefix, get next char.
  8508.     skipn xfnflg        ;[101] Converting to normal form?
  8509.      jrst gtfchx        ;[101] No, skip other conversions.
  8510.     cain t1, "."        ;[84]  Yes, is this a period?
  8511.      jrst [ aose fildot    ;[84]  Yes, don't put more than one.
  8512.          movei t1, "X"    ;[84]  Substitute "X" for any extra dots.
  8513.         jrst gtfchx ]    ;[84]  ...
  8514.  
  8515. gtfchy:    move t1, xfntab(t1)    ;[84] Translate it.
  8516.  
  8517. ; Return with character like GETCH.
  8518.  
  8519. gtfchx:    movem t1, next        ;[102] Put result in NEXT, as GETCH does.
  8520.     retskp            ;[102] Done.
  8521.  
  8522. ; "EOF" return, like GETCH
  8523.  
  8524. gtfchz:    setz t1,
  8525.     setom next
  8526.     ret
  8527.  
  8528. ; SDATA - Send a data packet.
  8529.  
  8530. sdata:    skipn cxseen        ;[59] Control-X typed?
  8531.      skipe czseen        ;[59] Or Control-Z?
  8532.      jrst [    call unmapi    ;[59] Yes, must unmap current input file page.
  8533.          nop        ;[59] Ignore any errors.
  8534.         movei state, "Z" ;[59] Get into EOF state.
  8535.         ret ]        ;[59] Back to state switcher.
  8536.  
  8537.     saveac <q1>        ; ^X/^Z not typed, normal case.
  8538. sdatab:    move q1, numtry        ; Get the number of tries.
  8539.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  8540.      jrst [ movei state, "A" ;  Change the state to cAncel.
  8541.         ermsg <Too many retries>, r ]
  8542.     aos numtry        ; Increment number of tries.
  8543.     movei t1, "D"        ; File send packet.
  8544.     move t2, pktnum        ; Packet number.
  8545.     move t3, size        ; Get the data length.
  8546.     move t4, [point 8, data] ; Get a pointer to our data block.
  8547.     call spack        ; Send the data packet.
  8548.      jrst @[exp sdatab,sdatax](t1) ; Handle errors.
  8549.     call rpack        ; Get a packet.
  8550.      ret            ;  Trashed packet, don't change state, retry.
  8551.  
  8552. sdatay:    caie t1, "Y"        ; Got one, check the type.  Is it ACK?
  8553.      jrst sdatan        ;  No, go check for NAK.
  8554.     came t2, pktnum        ; Yes, but is it the right ACK?
  8555.      ret            ;  No, don't settle, hold out for right one.
  8556.     soje t3, [        ;[62] Any data (interested in one & only char)?
  8557.         ildb t3, t4    ;[62] Yes, what?
  8558.         cain t3, "X"    ;[62] Is it an "X"?
  8559.          jrst [    setom cxseen ;[140] Yes, set the C-X flag.
  8560.             move t3, source    ;[140] What's the source of our data?
  8561.             cain t3, dirch ;[140] A directory listing?
  8562.              setom czseen ;[140] If so, set C-Z flag, too.
  8563.             jrst sdaty2 ] ;[140]
  8564.         cain t3, "Z"    ;[62] Is it an "Z"?
  8565.          setom czseen    ;[62]  Yes, pretend ^Z was typed...
  8566.         jrst .+1 ]    ;[62] Go thru one more time, then out.
  8567.  
  8568. sdaty2:    setzm numtry        ; Correct normal packet, reset retry counter.
  8569.     aos t2          ;[51] Increment the packet number,
  8570.     andi t2, 77        ; modulo 100,
  8571.     movem t2, pktnum    ; and remember it.
  8572.     jrst sdata2        ;[52] Go get some more data to send.
  8573.  
  8574. sdatan:    cain t1, "N"        ; NAK?
  8575.      jrst [    move t1, pktnum    ;[51] Yes, get the expected packet number.
  8576.         aos nnak    ;[54] Count the NAK.
  8577.         aos t1        ;[51] Figure out what the next one would be,
  8578.         andi t1, 77    ;[51] mod 64.
  8579.         caie t1, (t2)    ;[51] Is the NAK for the next packet?
  8580.          ret        ;  No, then must send current one again.
  8581.         setzm numtry    ; Yes, a NAK for n+1(mod 64) = ACK for n,
  8582.         movem t1, pktnum ; so play like we got an ACK,
  8583.         jrst sdata2 ]    ;[52] and go get next packetful of data.
  8584.  
  8585.     ;...
  8586.  
  8587. ;...SDATA, cont'd
  8588.  
  8589.  
  8590. ; Handle timeout or unexpected packet types.
  8591.  
  8592. sdatat:    cain t1, "T"        ; Timer interrupt pseudo packet?
  8593.      ret
  8594.     cain t1, "E"        ;[82] Error packet?
  8595.      jrst pxerr        ;[82]  Yes, print it & cancel.
  8596. sdatax:    movei state, "A"    ; Anything else, just cancel..
  8597.     ret
  8598.  
  8599.  
  8600. ; Fill up the next buffer of data.
  8601.  
  8602. sdata2:    move t1, maxdat        ;[63] Length to work with.
  8603.     call getbuf        ;[63] Try to get next bufferful.
  8604.      jrst [    movem t1, cxseen ;[70] If error, tell other side to discard.
  8605.         movei state, "Z" ; Set state to EOF.
  8606.         ret ]        ;  Go back to state switcher.
  8607.     movem t1, size        ; Got more data, save length, and
  8608.     ret            ; return, remaining in state "D".
  8609.  
  8610. ; SEOF - Send End Of File packet.
  8611.  
  8612.  
  8613. seof:    move t1, numtry        ; No ^X/^Z, get the number of tries.
  8614.     caml t1, maxtry        ; Have we reached the maximum number of tries?
  8615.      jrst [    movei state, "A" ;  Change the state to cAncel.
  8616.         ermsg <Can't send EOF>, r ]
  8617.     aos numtry        ; Still within our limit, bump retry count.
  8618.     movei t1, "Z"        ; Send a Z (EOF) packet.
  8619.     move t2, pktnum        ; Packet number.
  8620.     skipn cxseen        ;[59] Are we discarding this file?
  8621.      skipe czseen        ;[59]
  8622.      jrst [    move t3, [point 8, data] ;[59] Yes,
  8623.         movei t4, "D"    ;[59] put a "D" for Discard in data field
  8624.         idpb t4, t3    ;[59] ...
  8625.         movei t3, 1    ;[59] Say the data length is 1
  8626.         move t4, [point 8, data] ;[59] point to it again...
  8627.         jrst .+2 ]    ;[59] Skip next instruction!
  8628.      setzb t3, t4        ; Normal case -- no data field.
  8629.     call spack        ; Send the packet.
  8630.      jrst @[exp seof, seofx](t1) ; Handle any errors.
  8631.     call rpack        ; Get a packet.
  8632.      ret            ;  Trashed packet, don't change state, retry.
  8633.  
  8634. ; Got a response.  Check for ACK and handle it.
  8635.  
  8636.     caie t1, "Y"        ;[52] Check the packet type.  Is it an ACK?
  8637.      jrst seof2        ;[52]  No...
  8638.     came t2, pktnum        ; Yes but, is it the right ACK?
  8639.      ret            ;  No, don't settle, hold out for right one.
  8640.     aos t2, pktnum        ; Increment the packet number,
  8641.     andi t2, 77        ; mod 100,
  8642.     movem t2, pktnum    ; and save it.
  8643.     jrst seof4        ;[52] Join common code.
  8644.  
  8645. ; Check for NAK and handle it.
  8646.  
  8647. seof2:    caie t1, "N"        ; NAK?
  8648.      jrst seof3        ;  No.
  8649.     aos nnak        ;[54] Yes, count it.
  8650.     move t1, pktnum        ;[51] What packet were we looking for?
  8651.     aos t1            ;[51] Is the NAK for the next packet?
  8652.     andi t1, 77        ;[51] (mod 64)
  8653.     caie t1, (t2)        ;[51]
  8654.      ret            ;  No, then must send this one again.
  8655.     movem t1, pktnum    ; Yes, behave like it was an ACK for this one.
  8656.     jrst seof4        ;[52] Join common code.
  8657.  
  8658. ; SEOF, cont'd
  8659.  
  8660.  
  8661. ; Check for other types & handle.
  8662.  
  8663. seof3:    cain t1, "T"        ; Timer interrupt pseudo-packet?
  8664.      ret            ; If so, just keep going.
  8665.     cain t1, "E"        ;[80] Error packet?
  8666.      call pxerr        ;[82] If so, print it.
  8667.     skiple t1, filjfn    ;[80] Close the file.    
  8668.      CLOSF            ;[80]
  8669.      erjmp .+1        ;[80]
  8670.     setzm filjfn        ;[80]
  8671. seofx:    movei state, "A"    ; Otherwise cancel.
  8672.     ret
  8673.  
  8674. ; EOF packet was ACK'd OK, close the file, get the next one (if any).
  8675.  
  8676. seof4:    skipn xflg        ;[126] Sending a real file?
  8677.      jrst [    skipn t1, tlgjfn ;[126] Transaction log?
  8678.          jrst .+1
  8679.         hrroi t2, [asciz/   Sent: /] ; Yes, log this info.
  8680.         setzb t3, t4
  8681.         SOUT
  8682.         move t2, schr    ; Number of bytes.
  8683.         movei t3, ^d10
  8684.         NOUT
  8685.          nop
  8686.         movei t2, 40    ; A space
  8687.         BOUT
  8688.         movei t2, 7    ; Bytesize
  8689.         skipe ebtflg
  8690.          aos t2
  8691.         NOUT
  8692.          nop
  8693.         hrroi t2, [asciz/-bit bytes
  8694. /]
  8695.         setzb t3, t4
  8696.         SOUT
  8697.         jrst .+1 ]
  8698.  
  8699.     setzm numtry        ;[52] Reset the retry counter.
  8700.     addm schr, stchr    ; Add the last file's size to the total.
  8701.     setz schr,        ; Zero the present count.
  8702.     aos files        ;[61] Count the file.
  8703.     skipn source        ;[128] Sending a file?
  8704.      jrst [    skipg t1, filjfn ;[128] Yes, get the JFN of the file just sent.
  8705.          jrst .+1    ;[128]  If no valid JFN, don't bother closing.
  8706.         txo t1, co%nrj    ; Don't release it, GNJFN still needs it.
  8707.         CLOSF%        ; Close the file.
  8708.          %jserr (,.+1)    ;[59] Print msg but continue if error.
  8709.         jrst .+1 ]    ;[121]
  8710.     ;...
  8711.  
  8712. ;...SEOF, cont'd
  8713.  
  8714.  
  8715. ; Messages to screen and transaction log.
  8716.  
  8717.     skiple filjfn        ;[127] Transaction log stuff.
  8718.      skipe xflg        ;[126]  Don't bother if not a real file.
  8719.      skipa            ;[126]
  8720.      wtlog <Closed >,filjfn    ;[126]
  8721.     hrroi t1, [asciz/[OK]/]    ; Normal comforting message.
  8722.     skipe cxseen        ; But was sending interrupted this way?
  8723.      hrroi t1, [asciz/[interrupted]/] ; Yes, say so.
  8724.     skipe czseen        ; Or this way?
  8725.      hrroi t1, [asciz/[group interrupted]/] ; Yes, say so.
  8726.     move t4, t1        ; Keep for log.
  8727.     skipe local        ; Local use?
  8728.      PSOUT            ; Yes, print selected message.
  8729.     skipe t1, tlgjfn    ;[126] If we have a transaction log, there too.
  8730.      jrst [    move t2, t4
  8731.         setz t3,
  8732.         skipn cxseen
  8733.          skipe czseen
  8734.         SOUT        
  8735.         jrst .+1 ]
  8736.  
  8737. seof5:    skipn source        ;[121] Really doing files?
  8738.      call gtnfil        ; If so, get the next file to send.
  8739.      jrst [    setzm filjfn    ;  If not, or if no more, zero the JFN,
  8740.         movei state, "B" ; set state to complete,
  8741.         ret ]        ;[59]  and return to state switcher.
  8742.     movei state, "F"    ; OK, switch to File-send state.
  8743.     ret
  8744.  
  8745. ; SEOT -- Send End Of Transmission packet.
  8746.  
  8747.  
  8748. seot:    saveac <q1>
  8749. seotb:    move q1, numtry        ; Get the number of tries.
  8750.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  8751.      jrst [    movei state, "A" ;  Change the state to cAncel.
  8752.         ermsg <Can't send EOT>, r ]
  8753.     aos numtry        ; Increment number of tries.
  8754.     movei t1, "B"        ; Packet type is Break (EOT).
  8755.     move t2, pktnum        ; Packet number.
  8756.     setzb t3, t4        ; No data.
  8757.     call spack        ; Send the packet.
  8758.      jrst @[exp seotb, seotx](t1) ; Handle any errors.
  8759.     call rpack        ; Get a packet.
  8760.      ret            ;  Trashed packet don't change state, retry.
  8761.     cain t1, "Y"        ; Check the packet.
  8762.      jrst [    came t2, pktnum    ;  Is it the right ACK?
  8763.          ret        ;   No, don't settle, hold out for right one.
  8764.         setzm numtry    ;  Reset the number of tries.
  8765.         aos t2, pktnum    ; Increment packet number
  8766.         andi t2, 77    ; mod 100
  8767.         movem t2, pktnum ; save it back.
  8768.         movei state, "C" ;  Complete state.
  8769.         skipn xflg    ;[126] Put message in transaction log,
  8770.          wtlog <Send Complete> ;[126] if it was a real file transfer.
  8771.         ret ]
  8772.     cain t1, "N"        ; NAK?
  8773.      jrst [    aos nnak    ;[54] Yes, count the NAK.
  8774.         move t1, pktnum    ;[51] Is the NAK for the next packet?
  8775.         aos t1        ;[51]
  8776.         andi t1, 77    ;[51]
  8777.         caie t1, (t2)    ;[51]
  8778.          ret        ;  No, must send current one again.
  8779.         movem t1, pktnum ; Yes, behave like it was an ACK for this one.
  8780.         setzm numtry    ; Reset the number of tries.
  8781.         movei state, "C" ; Complete state.
  8782.         ret ]
  8783.     cain t1, "T"        ; Timer interrupt pseudo packet?
  8784.      ret
  8785.     cain t1, "E"        ;[82] Error packet?
  8786.      jrst pxerr        ;[82]  Yes, print it & cancel.
  8787. seotx:    movei state, "A"    ; Otherwise cancel.
  8788.     ret
  8789.  
  8790. ;[63] Rewrite file routines.
  8791. ;
  8792. ; GETBUF - Get buffer (i.e. packet) full of characters from input file.
  8793. ;
  8794. ; Call with
  8795. ;  AC1/ desired number of characters to get (i.e. data buffer size)
  8796. ; Returns:
  8797. ;  +1, failure, with AC1/ 0 if end of input file, or nonzero if other error.
  8798. ;  +2, success, with AC1/ number of characters actually gotten, and
  8799. ;      the result accessible by [point 8, data].
  8800. ;
  8801. getbuf:    saveac<q1,q2,q3,q4>
  8802.  
  8803.     skipg t1         ; Make sure the number is not 0 or negative.
  8804.      ret            ;  This gives the right return code.
  8805.     caile t1, ^d9000    ; Make sure the number is not too big.
  8806.      movei t1, ^d9000
  8807.     move q4, t1        ; Maximum number of characters to return.
  8808.     setz q2,        ; Counter for actual characters returned.
  8809.     move q3, [point 8, data] ; Where to put the result.
  8810.     setzm rpt        ;[126] Clear leftover repeat counts from last.
  8811.  
  8812. getbfa:    skipge next        ; First time through, get first character.
  8813.      jrst [    call getch
  8814.          jumpn t1, r    ;[64] Pass along any failure
  8815.         setz t1,    ; Since GETCH puts the character it got in NEXT
  8816.         exch t1, next    ; it has to be moved to CH, just this once.
  8817.         movem t1, ch
  8818.         jrst .+1 ]
  8819.     
  8820. getbfb:    skipl ch        ; Do we have one?  If not, must be EOF.
  8821.      caml q2, q4        ; Or buffer full?
  8822.      jrst getbfx        ; If so, return it.
  8823.  
  8824. ; Get next character for lookahead.
  8825.  
  8826. getbfc:    call getch        ; Get next one.
  8827.      jumpn t1, r        ;[64] Pass along any failure
  8828.     call encode        ; Go do any prefixing.
  8829.     skipge t1, next        ; Set up for next time through.
  8830.      jrst getbfx        ;  If no next, we're done.
  8831.     movem t1, ch        ; Otherwise next is now current.
  8832.     jrst getbfa        ; Loop till done.
  8833.  
  8834. ; Return the buffer.
  8835.  
  8836. getbfx:    skipg t1, q2        ; Return length of data
  8837.     ret            ; +1 if 0 (= EOF)
  8838.     retskp            ; +2 if greater than zero.
  8839.  
  8840. ;[63] This routine added as part of edit 63.
  8841. ;
  8842. ; ENCODE - Process a character -- do any prefixing, etc, necessary to
  8843. ; insert the character into a data packet.
  8844. ;
  8845. ; Call with character in global CH, global RPTFLG and EBQFLG indicating
  8846. ; whether repeat and 8th-bit prefixing are to be done.
  8847. ;
  8848. ; Returns:
  8849. ;  +1 always, with CH unmodified, q2/ updated packet length.
  8850. ;  Uses t2-t4.
  8851. ;
  8852. encode:    move t4, ch        ; Get current character.
  8853.     skipn rptflg        ; Doing repeat count prefixing?
  8854.      jrst enco8        ;  No, skip to next part.
  8855.  
  8856. ; Repeat count processing.  Check if this character same as next.
  8857.  
  8858. encor:    camn t4, next        ; Same as next one?
  8859.      jrst [    aos t2, rpt    ; Yes, just count it.
  8860.         caige t2, ^d94    ; Count within bounds?
  8861.          ret        ;  Yes, done.
  8862.         sos t2        ;[93] No, adjust as though next char different.
  8863.         jrst encor4 ]    ; Go emit a repeat sequence for this much.
  8864.  
  8865. ; Different, see if there were any repeats.
  8866.  
  8867. encor2:    skipg t2, rpt        ; CH not same as next.  Any repeats?
  8868.      jrst enco8        ; No, on to next part.
  8869.     caige q2, (q4)        ;[93] Yes, near end of buffer?
  8870.      cain t2, 1        ; Or only repeated once?
  8871.      jrst [    setzm rpt    ;[144] Set all the repeat count back to zero.
  8872.         call enco8    ;[144] Call self, skipping around this part,
  8873.         move t4, ch    ;[144] and again.
  8874.         call enco8    ;[144]
  8875.         ret ]        ;[93] and return.
  8876.  
  8877. ; Repeated more than once -- general case.
  8878.  
  8879. encor4:    move t3, rptq        ; Emit a repeat sequence --
  8880.     idpb t3, q3        ; the repeat prefix character,
  8881.     addi t2, <40+1>        ;[93] followed by 'tochar(count+1)'
  8882.     idpb t2, q3        ;  because if it's repeated 1x there are 2...
  8883.     addi q2, 2        ; Account for these prefix characters.
  8884.     setzb t2, rpt        ; Clear repeat count.
  8885.  
  8886.     ;...
  8887.  
  8888. ;...ENCODE, cont'd
  8889.  
  8890.  
  8891. ; 8th-bit prefixing.
  8892.  
  8893. enco8:    setz t2,        ; Bit-8 flag.
  8894.     trzn t4, 200        ; Test & clear parity bit.
  8895.      jrst encoc        ;  Not set, on to next part.
  8896.     seto t2,        ; Remember it was on.
  8897.     skipn ebqflg        ; Doing 8th-bit quoting?
  8898.      jrst encoc        ;  No, so skip this.
  8899.     move t3, ebq        ; Yes, stick in an 8th-bit prefix.
  8900.     idpb t3, q3    
  8901.     aos q2            ; Count it.
  8902.  
  8903. ; Control prefixing.
  8904.  
  8905. encoc:    cail t4, 40        ; Control character
  8906.      cain t4, .chdel    ; or DEL?
  8907.      jrst [ xori t4, 100    ; Yes, convert to printable
  8908.         jrst encoc4 ]    ; and go insert a control prefix.
  8909.  
  8910. ; Prefix prefixing.
  8911.  
  8912. encoc1:    camn t4, squote        ; Control Prefix?
  8913.      jrst encoc4        ;  Yes.
  8914.  
  8915. encoc2:    skipn rptflg        ; Repeat processing?
  8916.      jrst encoc3        ;  No.
  8917.     camn t4, rptq        ; Yes, is the character the repeat prefix?
  8918.      jrst encoc4        ;  Yes, insert a control prefix before it.
  8919.  
  8920. encoc3:    skipe ebqflg        ; Eighth-bit prefixing?
  8921.     came t4, ebq        ; Is the character the 8th-bit prefix?
  8922.      jrst encocx
  8923.  
  8924. encoc4:    move t3, squote        ; Insert a control prefix.
  8925.     idpb t3, q3
  8926.     aos q2            ; Count it.
  8927.  
  8928. ; Now, finally, insert the character itself.
  8929.  
  8930. encocx:    skipe t2        ; Was 8th bit on originally?
  8931.      skipe ebqflg        ;[109] Yes, but did we quote it already?
  8932.      skipa            ;[109] In that case, don't put it back.
  8933.      tro t4, 200        ;  It was on & wasn't quoted so put it back.
  8934.     idpb t4, q3        ; Deposit it.
  8935.     aos q2            ; Count it.
  8936.  
  8937.     ret
  8938.  
  8939.     subttl File routines
  8940.  
  8941. ;[63] This routine added as part of edit 63.
  8942. ;
  8943. ; GETCH - Get a character from the disk file.
  8944. ; If global SOURCE is nonzero, it is assumed to contain an address of a
  8945. ; routine to be used instead of this one.
  8946. ;
  8947. ; Returns:
  8948. ;  +1 on failure, with t1/0 if EOF, t1/-1 if real error getting character.
  8949. ;  +2 on success, with global NEXT containing the character, -1 if EOF.
  8950. ;
  8951. getch:    skipe t1, source    ;[102] Alternate routine to call?
  8952.      jrst (t1)        ;[102]  Yes, go there instead.
  8953.     saveac <q1,q2,q3>    ; Save permanent ACs.
  8954.     skipe eoflag        ; Is the end of file flag set?
  8955.      jrst [    setzm eoflag    ; Yes, reset EOF flag for next time,
  8956.         jrst getchz ]    ;  and return EOF.
  8957.     skipe mapflg        ; Do we have anything mapped in?
  8958.      jrst getch3        ;  Yes, don't have to do mapping.
  8959.  
  8960. getch1:    move t1, filjfn        ; No, must do mapping, here's the JFN.
  8961.     movx t2, <2,,.fbbyv>    ; Get number of pages and bytes
  8962.     movei t3, pagcnt    ;  into pagcnt and bytcnt,
  8963.     GTFDB%            ;  from the file descriptor block.
  8964.      %jsker <Can't get file length>,getchx ; Return error.
  8965.     skipn bytcnt        ; Any bytes in the file?
  8966.      jrst [    setom eoflag    ;  No, set end-of-file flag.
  8967.         jrst getchz ]    ;  And return EOF.
  8968.     ldb t2, [point 6, pagcnt, 11] ; Get the file byte size.
  8969.     movem t2, bytsiz    ; Save it.
  8970.  
  8971. ; 7- or 8-bit input from the file?  First, check for ITS binary format.
  8972.  
  8973.     skipe itsfil        ;[75] ITS binary format file?
  8974.      jrst getcha        ;[75] Yes, then skip "autobyte" stuff.
  8975.  
  8976. ; Next, if doing "autobyte", use the file byte size.
  8977.  
  8978.     skipe autbyt        ;[81] Are we using autobyte?
  8979.      jrst [    setzm ebtflg    ; Yes, assume seven-bit bytes.
  8980.         cain t2, ^d8    ; Really 8-bit?
  8981.          setom ebtflg    ;  Yes, act like user requested 8-bit.
  8982.         jrst .+1 ]
  8983.  
  8984. ; Now, if we're to do 8-bit input, convert the byte count if necessary.
  8985.  
  8986. getcha:    skipn itsfil        ; ITS binary file?
  8987.      skipe ebtflg        ; Or eight bit mode?
  8988.      jrst [    cain t2, ^d8    ; Yes, is the byte size 8?
  8989.           jrst getchb    ;[170] If so go adjust byte count if necessary.
  8990.         movei t3, ^d36    ; Get the size of a word.
  8991.         idiv t3, t2    ; Divide by the byte size.
  8992.         move q1, bytcnt    ; Get the number of bytes in file.
  8993.         idiv q1, t3    ; Divide by the bytes/word to get words.
  8994.         imuli q1, 4    ; Multiply by 4 (as if 8-bit bytes).
  8995.         movem q1, bytcnt ; Save the new byte count.
  8996.         jrst getchb ]    ;[170] Go adjust byte count.
  8997.     ;...
  8998.  
  8999. ;...GETCH, cont'd
  9000.  
  9001. ; Or, if we're to do 7-bit input, fix the byte count for that.
  9002.  
  9003.     caie t2, 7        ; If the bytesize is not 7 or 8, treat as 7.
  9004.      cain t2, ^d8        ;[170] (don't do this to 8-bit files!
  9005.      skipa            ;[170]  ...)
  9006.      jrst [    movei t3, ^d36    ; Must convert, get the size of a word.
  9007.         idiv t3, t2    ; Divide by the byte size.
  9008.         move q1, bytcnt    ; Get the number of bytes in file.
  9009.         idiv q1, t3    ; Divide by the bytes/word to get words.
  9010.         imuli q1, 5    ; Multiply by 5 (as if 7bit bytes).
  9011.         movem q1, bytcnt ; Save the new byte count.
  9012.         jrst getch2 ]    ; Go map in page.
  9013.  
  9014. getchb:    skipn itsfil        ;[86][170] ITS binary file?
  9015.      jrst getch2        ;[86]  No, proceed.
  9016.     move q1, bytcnt        ;[86] Yes, get byte count.
  9017.     subi q1, 4        ;[86] Subtract 4 to account for header.
  9018.     movem q1, bytcnt    ;[86] Save it back.
  9019.  
  9020. ; Byte size figured out, now map in the first page.
  9021.  
  9022. getch2:    hrlzs t1        ; Form file JFN,, page 0
  9023.     hrlm t1, pagcnt        ; Zero the left half of pagcnt.
  9024.     call mapi        ; Map it in.
  9025.      jrst getchx        ;  Pass along any failure.
  9026.     skipe itsfil        ;[75] ITS binary file?
  9027.      aos pagptr        ;[75] Yes, skip first word of it.
  9028.     setzm pagno        ; Present page is zero.
  9029.     setom mapflg        ; Say we've got a page mapped in.
  9030.  
  9031. ; Come here if/when/after page is mapped in...
  9032.  
  9033. getch3:    caml schr, bytcnt    ; Any more bytes in file?
  9034.      jrst [    setom eoflag    ; No, Set the end of file flag.
  9035.         call unmapi    ; Unmap the input file page.
  9036.          ret        ;  Fail if we can't
  9037.         setzm mapflg    ; Say nothing mapped in.
  9038.         jrst getchz ]    ; Return EOF.
  9039.  
  9040.     ildb t2, pagptr        ; There are more; get the next one.
  9041.      erjmp getch%        ;[70] (illegal memory read, hole in file...)
  9042.     aos schr        ;[64] Got it OK, count it.
  9043.     ;...
  9044.  
  9045. ;...GETCH, cont'd
  9046.  
  9047. getch4:    hrrz t1, pagptr        ; Are we at the end of the page yet?
  9048.     caige t1, <mappag+1>*1000 ;[64]...
  9049.      jrst getch5        ; No, go return the character.
  9050.     call unmapi        ; Yes, unmap the input page.
  9051.      jrst getchx        ;  Pass along any failure.
  9052.     move t1, pagno        ; Get the present page number.
  9053.     aos t1            ; Increment it.
  9054.     caml t1, pagcnt        ; Any more pages?
  9055.      jrst [    setom eoflag    ; No, set the end of file flag for next time.
  9056.         setzm mapflg    ; Say nothing mapped in,
  9057.         jrst getch6 ]    ; and return normally with the char we got.
  9058.     movem t1, pagno        ; Save the new number.
  9059.     hrl t1, filjfn        ;  <file JFN,, page 0>
  9060.     call mapi        ; Map in the page.
  9061.      jrst getchx        ;  Pass along any failure.
  9062.     ildb t2, pagptr        ; Get the next character.
  9063.      erjmp getch%        ;[70] (Illegal memory read, hole in file...)
  9064.  
  9065. ; Got the character in t2.  Worry about bit 35 if doing 7-bit i/o.  The trick
  9066. ; is to set the parity bit ("b8") of every 5th character to the value of b35
  9067. ; of the PDP-10 word it came from.  The same trick is used by TOPS-20 when
  9068. ; writing ANSI-ASCII tapes.  This allows DEC-10/20 .EXE and other 36-bit binary
  9069. ; files, and SOS-line numbered files, to be sent to 8-bit systems and retrieved
  9070. ; intact.  No adverse effects are suffered by ordinary text files.
  9071.  
  9072. getch5:    move q1, schr        ;[64] Count the character.
  9073.     skipn itsfil        ;[75] ITS binary file?
  9074.      skipe ebtflg        ; Eight bit mode?
  9075.      jrst getch6        ;  One of those, no need to do this.
  9076.                 ;
  9077.     idivi q1, 5        ; No, 7-bit, divide character number by 5.
  9078.     skipn q2        ; Last character of word if remainder is 0.
  9079.      jrst [    move q1, pagptr ;  In that case, get the entire contents.
  9080.         move q1, (q1)    ;
  9081.         trne q1, 1    ; Bit 35 on?
  9082.          tro t2, 200    ; Yes, turn on bit 8 of this character.
  9083.         jrst .+1 ]
  9084.  
  9085. getch6:    movem t2, next        ; Return the character.
  9086.     retskp
  9087.  
  9088. ; EOF return.
  9089.  
  9090. getchz:    setz t1,        ; Return zero error code,
  9091.     setom next        ; and character -1.
  9092.     ret
  9093.     ;...
  9094.  
  9095. ;...GETCH, cont'd
  9096.  
  9097.  
  9098. ; Error return.
  9099.  
  9100. getch%:    skipe local        ;[70]
  9101.      ermsg <Illegal memory read> ;[70]
  9102.  
  9103. getchx:    setob t1, next        ; Return -1 error code, and character -1.
  9104.     movx t2, <.fhslf,,mappag> ;[70] Unmap any page that's still mapped in.    
  9105.     setz t3,        ;[70]
  9106.     PMAP%            ;[70]
  9107.      erjmp .+1        ;[70] Ignore errors.
  9108.     setzm mapflg        ;[70]
  9109.     ret
  9110.  
  9111.  
  9112. ; MAPI - Map in file page.
  9113. ;
  9114. ; Call with
  9115. ;  t1/ jfn,,page number.
  9116. ;
  9117. ; Returns
  9118. ;  +1 on failure.
  9119. ;  +2 on success, with PAGPTR adjusted to point back to beginning of page.
  9120. ;
  9121. mapi:    movx t2, <.fhslf,,mappag> ; Form our fork,,mapping page
  9122.     movx t3, pm%rd        ; Just want to read it.
  9123.     PMAP%            ; Map it in.
  9124.      %jsker <Can't map in file page>,r ;  Error, fail.
  9125.     move t3, [point 7, mappag*1000]    ; Success, get a pointer to the page.
  9126.     skipn itsfil        ;[75] An ITS binary file?
  9127.      skipe ebtflg        ; Or eight bit access?
  9128.      hrli t3, (point 8,)    ; Yes, then use 8-bit pointer.
  9129.     movem t3, pagptr
  9130.     retskp            ; Return successfully.
  9131.  
  9132.  
  9133. ; UNMAPI -- Unmap an input file page.
  9134. ;
  9135. ; Returns +1 on error, +2 on success.
  9136.  
  9137.  
  9138. ; First check to see where we're getting our input from.
  9139. ;
  9140. unmapi:    skipn t1, source    ;[139] But are we really reading from a file?
  9141.      jrst unmap3        ;[139]  Yes, really unmap.
  9142.     caie t1, dirch        ;[139] No, is it a directory listing?
  9143.      jrst unmap2        ;[139] No, something else.
  9144.  
  9145. ; From a directory listing buffer.  Clear it & reset pointers for next time.
  9146.  
  9147.     call dmpbuf        ;[139] Yes, directory listing; clear buffer.
  9148.     setzm source        ;[139] Indicate no more alternate source.
  9149.     ret            ;[139] Done.
  9150.  
  9151. ; From some other source (add others here).
  9152.  
  9153. unmap2:    ret
  9154.  
  9155. ; Source is really a file, unmap the current file page.
  9156.  
  9157. unmap3:    seto t1,        ; Indicate unmap.
  9158.     movx t2, <.fhslf,,mappag> ; This process.
  9159.     setz t3,
  9160.     PMAP%            ; Unmap the page.
  9161.      %jsker <Error unmapping page>,r
  9162.     retskp
  9163.  
  9164. ;[66] PUTBUF -- Write the contents of the data field of a packet out to a file.
  9165. ;
  9166. ; Call with:
  9167. ;  t1/ pointer to data buffer.
  9168. ;  t2/ number of characters.
  9169. ;  pagptr/ output file page byte pointer.
  9170. ; Returns:
  9171. ;  +1: Failure, Couldn't write the whole buffer, Error packet already sent.
  9172. ;  +2: Success
  9173. ;
  9174. putbuf:    saveac <q1,q2>        ; Preserve these ACs.
  9175.     dmove q1, t1        ; Save the arguments.
  9176.  
  9177. putbf2:    jumple q2, rskp        ; Are we done?
  9178.     ildb t2, q1        ; Not yet, get the next character from the pkt.
  9179.     call decode        ; Go decode and store it.
  9180.      ret            ;  Pass along any error.
  9181.     cain rchr, 4        ;[75] Just finished 4th character?
  9182.      call itschk        ;[75]  Yes, see if it was the ITS binary hdr.
  9183.     soja q2, putbf2        ; Loop.
  9184.  
  9185.  
  9186. ;[75] ITSCHK -- See if first 4 bytes of file are ITS binary file header.
  9187. ;
  9188. ; Uses t1-t3.
  9189. ; Returns +1 always, with ITSFIL set if the first 4 bytes are the ITS binary
  9190. ;  file header, sixbit/DSK8/, and with the various pointers and counters
  9191. ;  adjusted appropriately.  By the way, since this routine sets RCHR back to
  9192. ;  zero, it gets called again 4 characters later -- this should do no harm.
  9193. ;
  9194. itschk: skiple itscnt        ; No header characters counted?
  9195.      skipn itsflg        ; Is ITS checking enabled?
  9196.      ret            ;  No, forget it.
  9197.     move t1, itscnt        ; We were counting the matching characters...
  9198.     setzm itscnt        ; Reset the counter.
  9199.     caie t1, 4        ; The four characters matched?
  9200.      ret            ;  No, done.
  9201.     setom itsfil        ; Yes, flag it.
  9202.     move t1, [point 8, <mappag*1000>] ; Set up page pointer for 8 bit.
  9203.     movem t1, pagptr
  9204.     setz rchr,        ; Rewind the character counter.
  9205.     movei t1, 8        ; Record file bytesize correctly
  9206.     movem t1, bytsiz    ;  ...
  9207.     hrroi t1, [asciz/(ITS binary format) /]
  9208.     skipe local        ; Say what happened if local.
  9209.      PSOUT
  9210.     ret
  9211.  
  9212. ;[66] DECODE -- Convert data in Kermit packet to its original form.
  9213. ;
  9214. ; Call with:
  9215. ;  t2/ Character to decode
  9216. ;  q1/ Buffer pointer
  9217. ;  q2/ Position in buffer
  9218. ; Returns:
  9219. ;  +1: Failure, if output could not be done.
  9220. ;  +2: Success, with q1,q2 updated.
  9221. ;
  9222. ; Note: If the input character is a prefix of any kind, this routine
  9223. ; will input all further characters necessary to complete the prefixed
  9224. ; sequence, and update the counts and pointers appropriately.
  9225. ;
  9226. decode:    saveac<q4>        ; Preserve this one.
  9227.  
  9228. decod0:    move t3, t2        ; Make a copy with the parity bit intact.
  9229.     andi t2, 177        ; And without, so comparisons will work.
  9230.  
  9231. decod1:    setzm rpt        ; Reset repeat count.
  9232.     skipn rptflg        ; Repeat count processing?
  9233.      jrst decod2        ;  No.
  9234.     camn t2, rptq        ; Yes.  Is this the repeat prefix?
  9235.      jrst [    ildb t2, q1    ; Yes.  Get the count.
  9236.         andi t2, 177    ; Let's be cautious...
  9237.         subi t2, 40    ; Convert from character to number.
  9238.         movem t2, rpt    ; Save the repeat count.
  9239.         ildb t2, q1    ; Get the next character.
  9240.         move t3, t2    ; Copy with parity (in case it's not a prefix)
  9241.         trz t2, 200    ;  and without...
  9242.         subi q2, 2    ; Account for the repeat prefix sequence.
  9243.         jrst .+1 ]
  9244.     ;...
  9245.  
  9246. ;...DECODE, cont'd
  9247.  
  9248.  
  9249. decod2:    setzm ebqchr        ;[90] Say no 8th-bit prefix on this character.
  9250.     skipn ebqflg        ; Doing 8th-bit quoting?
  9251.      jrst decod3        ;  No.
  9252.     camn t2, ebq        ; Yes, is this the 8th-bit prefix?
  9253.      jrst [    ildb t2, q1    ; Yes, get the character it is prefix of.
  9254.         move t3, t2    ; Copy with parity in case not ctl prefix
  9255.         tro t3, 200    ;  ...
  9256.         trz t2, 200    ;  and without (this shouldn't anyway, but...)
  9257.         setom ebqchr    ;[90] Flag that we did this.
  9258.         sos q2        ; Account for it.
  9259.         jrst .+1 ]
  9260.  
  9261. decod3:    came t2, rquote        ; Control Prefix?
  9262.      jrst decod4        ;  No...
  9263.     ildb t2, q1        ; Yes, get its argument.
  9264.     move t3, t2        ; Copy with parity
  9265.     trz t2, 200        ;  and without...
  9266.     skipe ebqchr        ;[90] Was there an 8th-bit prefix?
  9267.      tro t3, 200        ;[90]  If so, set the 8th bit.
  9268.     sos q2            ; Account for the ctl prefix.
  9269.     cail t2, "@"        ; Check if the character is in the sequence
  9270.      caile t2, "_"        ;  "@ABC...XYZ[\]^_"
  9271.      skipa            ;  No, take it literally.
  9272.      xori t2, 100        ; Yes, controllify.
  9273.     cain t2, "?"        ; Or is it a question mark?
  9274.      movei t2, 177        ; Yes, then it's really a DEL.
  9275.  
  9276. decod4:    trne t3, 200        ; 8th bit was on?
  9277.      tro t2, 200        ;  Yes, then put it on in the result.
  9278.  
  9279. decod5:    skipn q4, rpt        ; Repeat Count.
  9280.      movei q4, 1        ; If zero, make it 1.
  9281.  
  9282. decod6:    jumple q4, decodz    ; Loop for repeat count.
  9283.     aos rchr        ; Count the data character.
  9284.     
  9285. ; The following check must be done here.  We can't look directly at RECPKT,
  9286. ; because it will contain quoting characters which must be evaluated by this
  9287. ; routine.  We can't do it by looking at the result in MAPPAG after calling
  9288. ; PUTCH, because we might be writing to MAPPAG with a 7-bit pointer.
  9289.  
  9290.     caile rchr, 4        ;[75] Check for the ITS header in 1st 4 chars.
  9291.      jrst decod7        ;[75] If past first 4, don't check.
  9292.     camn t2, [exp 0, 223, 72, 330, 0](rchr) ;[75] Check this character.
  9293.      aos itscnt        ;[75] If it matches, count it.
  9294.  
  9295. decod7:    call putch        ; Output the character.
  9296.      ret            ; Pass along any failure.
  9297.     soja q4, decod6        ; Until done.
  9298.     
  9299. decodz:    retskp            ; Success.
  9300.  
  9301. ;[66] PUTCH -- Output a character to a file.
  9302. ;
  9303. ; Call with:
  9304. ;  t2/ Character to output.
  9305. ;  pagptr/ Pointer to where to put it (if disk file).
  9306. ; Returns:
  9307. ;  +1: Failure (disk full, etc).
  9308. ;  +2: Success, pagptr updated. (Uses t1-t4)
  9309. ;
  9310. putch:    skipe t1, dest        ; Alternate PUTCH routine?
  9311.      jrst (t1)        ;  Yes, go to it.
  9312.     skiple filjfn        ;[177] To file?
  9313.      jrst putch2        ;[177] Yes, go do that.
  9314.     skipn local        ;[177] No, to screen.
  9315.      retskp            ;[177] But if remote, skip it.
  9316.     move t1, t2        ; No, then just put it on the screen.
  9317.     PBOUT            ;* Pretty dumb, make this more efficient
  9318.     retskp             ;* later...
  9319.  
  9320. ; File output.  Test to see if page is full.
  9321.  
  9322. putch2:    move t1, pagptr        ; Copy the byte pointer.
  9323.     ibp t1            ; Increment the copy.
  9324.     hrrzs t1        ; Clear out the LH.
  9325.     caig t1, <<<mappag+1>*1000>-1> ; At the end yet?
  9326.      jrst putch5        ;  No, proceed.
  9327.  
  9328. ; A page is filled up -- map it out.
  9329.  
  9330. putch3:    move t4, t2        ; Yes, save the character around this.
  9331.     call unmapo        ; Go unmap the current page.
  9332.      ret            ;  Pass along any failure.
  9333.     move t2, t4        ; Get back the character.
  9334.     aos pagno        ; Advance the file page number.
  9335.  
  9336. ; Rewind the memory page back to word 0.
  9337.  
  9338. putch4:    move t1, [point 7, mappag*1000]    ; Success, make a pointer
  9339.     skipn itsfil        ;[75]
  9340.      skipe ebtflg        ; of the appropriate
  9341.      hrli t1, (point 8,)    ; byte size.
  9342.     movem t1, pagptr    ; Store it.
  9343.  
  9344. ; Deposit the character into the memory page.
  9345.  
  9346. putch5:    idpb t2, pagptr        ; Put it in the page.
  9347.     ;...
  9348.  
  9349. ;...PUTCH, cont'd
  9350.  
  9351.  
  9352. ; Worry about bit 35.
  9353.  
  9354. putch6: skipe itsfil        ;[75][81] ITS binary file?
  9355.      retskp            ;[75]  Yes, don't worry about this.
  9356.     skipn ebtflg        ; Output to 7-bit file?
  9357.      trnn t2, 200        ; AND parity bit is on?
  9358.      retskp            ; No, done.
  9359.  
  9360. putch7:    move t3, rchr        ; Yes, both, get the char count,
  9361.     idivi t3, 5        ; modulo 5.
  9362.     jumpg t4, rskp        ; Is this the last char in the word?
  9363.  
  9364. putch8:    move t3, pagptr        ; Yes, get its contents.
  9365.     move t4, (t3)        ; ...
  9366.     tro t4, 1        ; Turn on bit 35.
  9367.     movem t4, (t3)        ; Put it back.
  9368.     retskp            ; Done.
  9369.  
  9370.     subttl File Routines
  9371.  
  9372. ; GTNFIL - Get next file from wild file specification.
  9373. ; Return +1 with AC1/0 if no more, or +2 with JFN of next file in AC1.
  9374. ;
  9375. ;[111] Rewritten to do 1-file lookahead as part of edit 111.
  9376. ;
  9377. gtnfil:    move t1, filjfn        ; Release the JFN of the previous file.
  9378.     RLJFN
  9379.      erjmp .+1
  9380.     setzm filjfn
  9381.  
  9382. ; Check to see if we really want to or can get the next file.
  9383.  
  9384.     setz t1,        ; Assume no more files.
  9385.     skipn czseen        ;[59] If CTRL-Z seen, then get no more files.
  9386.      skipn t1, nxtjfn    ; No CTRL-Z.  Get next JFN.
  9387.      ret            ; None, so we're done.
  9388.  
  9389. ; Make a separate JFN for the file so that wildcard stepping won't be wiped
  9390. ; out by anything we do to it, like deleting it, renaming it, etc.
  9391.  
  9392.     hrrz t2, t1        ; Get the filename string.
  9393.     hrroi t1, strbuf
  9394.     setz t3,
  9395.     JFNS
  9396.      erjmp r
  9397.     movx t1, gj%old!gj%sht    ; Get a new JFN on it.
  9398.     hrroi t2, strbuf
  9399.     GTJFN
  9400.      erjmp r
  9401.     hrrzm t1, filjfn    ; Save it here.
  9402.     setzm strbuf
  9403.  
  9404. ; Get new next JFN.
  9405.  
  9406.     move t1, nxtjfn        ; Get the JFN again.
  9407.     hll t1, ndxjfn        ; Get wildcard flags into left half.
  9408.     GNJFN            ; Get the next JFN.
  9409.      setz t1,        ; If no more, set this to zero.
  9410.     movem t1, nxtjfn    ; Save result for next time.
  9411.  
  9412. ; Return with current JFN.
  9413.  
  9414.     move t1, filjfn        ; Return JFN of current file in t1.
  9415.     retskp            ; Return +2 indicating another file was found.
  9416.  
  9417. ;[119] MAKFIL - Rewritten as part of edit 119.
  9418. ;
  9419. ; Construct an output filespec from name given in file header packet.
  9420. ;
  9421. ; Call with:
  9422. ;  T1/ Pointer to a file name from packet.
  9423. ;  T2/ Number of characters.
  9424. ;
  9425. ; Return:
  9426. ;  +1: Failure
  9427. ;  +2, Success, with JFN in T1.
  9428. ;
  9429. makfil:    skipe filjfn        ; Do we have a file yet?
  9430.      jrst [ move t1, filjfn    ;  If so just return its JFN.
  9431.         retskp ]
  9432.     skipg t2        ; Are there at least a few chars?
  9433.      jrst [    setz t1,
  9434.         kermsg <File name not specified>, r ]
  9435.  
  9436.     call decodf        ;[141] Decode the file name.
  9437.      kermsg <Can't decode filename>, r
  9438.  
  9439. ; Now fix up the name, if desired, and get a JFN on it.
  9440.  
  9441.     call filfix        ; Go check & fix the filename syntax.
  9442.     movx t1, gj%sht!gj%fou    ; Short form.
  9443.     GTJFN%
  9444.      erjmp makfix        ;[132] On error, go do something else.
  9445.     retskp
  9446.  
  9447. ;[132] Despite all efforts, couldn't construct legal name for file.
  9448.  
  9449. makfix:    movx t1, gj%sht!gj%fou    ; Get a JFN for...
  9450.     hrroi t2, [asciz/-UNTRANSLATABLE-FILENAME-.KERMIT.-1/]    ; ...this.
  9451.     GTJFN    
  9452.      %jsker <Can't get JFN in MAKFIL>,r ; This should never fail, but...
  9453.     move q1, t1        ; Log what happened.
  9454.     wtlog <Illegal incoming name changed to >,q1
  9455.     move t1, q1        ; Get this back.
  9456.     retskp
  9457.  
  9458. ;[141] Moved to separate routine as part of edit 141.
  9459. ;
  9460. ; Decode a file found in the data field of a KERMIT packet.
  9461. ; Call with:
  9462. ;  t1/ pointer to data field.
  9463. ;  t2/ number of characters in data field.
  9464. ;
  9465. ; Returns:
  9466. ;  +1 on failure,
  9467. ;  +2 on success, with pointer to decoded filename in t1.
  9468. ;
  9469. decodf:    saveac <q1>        ; Preserve this.
  9470.     move q1, t1        ; Save argument for a sec.
  9471.     move t1, [point 7, strbuf] ; Build decoded name here.
  9472.     movem t1, strptr
  9473.     setzm strbuf        ; Clear out the string buffer
  9474.         move t1, [strbuf,,strbuf+1] ; so result will be asciz.
  9475.     blt t1, strbz        ; ...
  9476.  
  9477.     movei t1, putsch    ; Routine to deposit decoded characters.
  9478.     movem t1, dest        ; ...
  9479.     move t1, q1        ; Get argument back.
  9480.     call putbuf        ; Decode the file name string.
  9481.      ret            ;  Failed for some reason, pass it along.
  9482.     setzm dest        ; Decoded OK, restore normal destination.
  9483.     move t1, [point 7, strbuf] ; Return pointer to decoded file name.
  9484.     retskp            ; +2.
  9485.  
  9486. ; FILFIX - Fix incoming file names by quoting illegal characters with ^V.
  9487. ;*(Should also make sure length is no greater than 39.39)
  9488. ;
  9489. ; Call with t1/ Pointer to filename
  9490. ; Returns +1 always, with t2 pointing to legal TOPS-20 filename.
  9491. ;
  9492. filfix:    skipe xfnflg        ;[84] Doing filename conversion?
  9493.      jrst filcnv        ;[84]  Yes, then go do that.
  9494.     move t3, [point 7, filbuf] ; No, but still have to quote funnies.
  9495.     setzm filbuf        ;[174]
  9496.     setom fildot        ; Count dots.
  9497.  
  9498. filfx2:    ildb t2, t1        ; Get the next character.
  9499.     jumpe t2, [        ; No more, done.
  9500.         idpb t2, t3    ; Put the null in.
  9501.         move t2, [point 7, filbuf] ; Return a pointer to the filename.
  9502.         ret ]
  9503.  
  9504. ; Got a character, validate it.
  9505.  
  9506.     cail t2, "A"        ; Upper case letters are legal.
  9507.      caile t2, "Z"    
  9508.      skipa
  9509.      jrst filfx4
  9510.     cail t2, "0"        ; Digits are legal.
  9511.      caile t2, "9"
  9512.      skipa
  9513.      jrst filfx4
  9514.     caie t2, "$"        ; Dollar sign is legal
  9515.      cain t2, "-"        ; So is dash.
  9516.      jrst filfx4
  9517.     caie t2, "_"        ; Underscore is legal.
  9518.      cain t2, 73        ; Allow semicolon for attributes.
  9519.      jrst filfx4
  9520.     cain t2, "."        ; Dot?
  9521.      jrst [    aosg fildot    ; Yes, count it.
  9522.          jrst filfx4    ; First dot, ok to use it.
  9523.         jrst filfx3 ]    ; Not first, go prefix it.
  9524.     cail t2, "a"        ;[153] A lower case letter?
  9525.      caile t2, "z"        ;[153] ...
  9526.      skipa            ;[153]  No, something very illegal then.
  9527.      jrst [    trz t2, 40    ;[153] Yes, convert to upper and
  9528.         jrst filfx4 ]    ;[153] use it.
  9529.  
  9530. ; Get here with illegal character that must be prefixed with control-V.
  9531.  
  9532. filfx3:    movei t4, ^o26        ; Control-V.
  9533.     idpb t4, t3        ; Insert it before the character.
  9534.  
  9535. ;[174] Deposit the character, but if first and a dot, insert an X before it.
  9536.  
  9537. filfx4:    skipn filbuf        ; Something in buffer already?
  9538.      caie t2, "."        ; No, first character is a dot?
  9539.      jrst filfxx        ; OK to go ahead.
  9540.     movei t4, "X"        ; 1st char would be a dot, so...    
  9541.     idpb t4, t3        ;[174]
  9542.  
  9543. filfxx:    idpb t2, t3        ; Now deposit the actual character.
  9544.     jrst filfx2        ; Loop till done.
  9545.  
  9546. ;[84] Convert incoming filename to "normal form".
  9547. ; This routine added as part of edit 84.
  9548.  
  9549. filcnv:    move t3, [point 7, filbuf] ; Where to put new file name.
  9550.     setzm filbuf        ;[174]
  9551.     movei q1, 1        ; Dot counter.
  9552.  
  9553. filcn2:    ildb t4, t1        ; Get next character.
  9554.     jumpe t4, filcnx    ;[142] If null, done.
  9555.     caie t4, "."        ; Dot?
  9556.      jrst filcn4        ;  No.
  9557.  
  9558. ;[174] check for names starting with dot.
  9559.  
  9560.     skipn filbuf        ; Anything in name yet?
  9561.      jrst [    movei t4, "X"    ;  No, insert an X.
  9562.         idpb t4, t3
  9563.         movei t4, "."
  9564.         jrst .+1 ]    ;[174]
  9565.      soje q1, filcn4        ; Yes, make sure there's only one dot.
  9566.     movei t4, "X"        ; If more, translate extra dots to X's.
  9567.     jrst filcn5
  9568.  
  9569. filcn4:    move t4, xfntab(t4)    ; Translate it.
  9570. filcn5:    idpb t4, t3        ; Put it back.
  9571.     jrst filcn2        ; Loop till done.
  9572.  
  9573. filcnx:    setz t2,        ; Put a null at the end.
  9574.     idpb t2, t3
  9575.     move t2, [point 7, filbuf] ; Return a pointer to the file.
  9576.     ret
  9577.  
  9578. ; Translate table to turn funny characters into X's, raise lower case
  9579. ; letters, leave upper case letters and digits, and periods alone.
  9580. ; For translating file names to "normal form".
  9581.  
  9582. xfntab:    repeat <^d46>,<exp "X">
  9583.     exp ".","X"
  9584.     exp "0","1","2","3","4","5","6","7","8","9"
  9585.     repeat <7>,<exp "X">
  9586.     exp "A","B","C","D","E","F","G","H","I","J","K","L","M","N"
  9587.     exp "O","P","Q","R","S","T","U","V","W","X","Y","Z"
  9588.     repeat <6>,<exp "X">
  9589.     exp "A","B","C","D","E","F","G","H","I","J","K","L","M","N"
  9590.     exp "O","P","Q","R","S","T","U","V","W","X","Y","Z"
  9591.     repeat <5>,<exp "X">
  9592.     0
  9593.  
  9594.     subttl    Line routines
  9595.  
  9596.  
  9597. ; INILIN -- Initialize the communication line for file transfer.
  9598. ;
  9599. inilin:    skipe inited        ;[177] Already init'd?  Don't do it again.
  9600.      ret            ;[177]
  9601.     call gtclas        ;[130] Check status of class scheduler.
  9602.  
  9603. ; Set all the terminal mode bits for transparent i/o.
  9604.  
  9605. inil2:    call dobits        ; Go do the bits.
  9606.      ret            ;  Pass along any failures.
  9607.     call doarpa        ; Set up any Arpanet stuff.
  9608.  
  9609. ; Clear the comm line's input buffer.
  9610.  
  9611.     move t1, netjfn        ;[82] Clear the line in case a bunch of NAKs
  9612.     CFIBF            ;[1]  have piled up.
  9613.      erjmp .+1        ;[147] Ignore any errors.
  9614.     setom inited        ;[177] Flag we've done this.
  9615.     ret
  9616.  
  9617. ; Get Scheduler Class information.
  9618. ;
  9619. gtclas:    setzm class        ; Start out assuming scheduler class 0.
  9620.     movei t1, .skrcv    ; Class scheduler on?
  9621.     movei t2, t3
  9622.     movei t3, 2        ; Just want 2 words.
  9623.     SKED%
  9624.      erjmp gtclsa        ; Not R4 or above?  Say it's not on.
  9625.     txnn t4, sk%stp        ; Class scheduler on?
  9626.      skipa            ; Yes, it's on - t4 nonzero.
  9627. gtclsa:     setz t4,        ; No, it's off - t4 zero.
  9628.     movem t4, skdflg    ; Set scheduler flag accordingly.
  9629.     jumpe t4, r        ; If no scheduler, go on to next part.
  9630.  
  9631. ;[130] Scheduler is on, get my scheduler class.
  9632.  
  9633.     movei t2, skdblk    ; Get job's scheduler class.  Here's arg block.
  9634.     movei t1, 5        ; Store length of arg block
  9635.     movem t1, .sacnt(t2)    ;  in arg block.
  9636.     move t1, myjob        ; My job number.
  9637.     movem t1, .sajob(t2)    ; Also into arg block.
  9638.     movx t1, .skrjp        ; Function code for getting job class info.
  9639.     SKED%
  9640.      erjmp .+2        ; Leap frog
  9641.      skipa            ;  to set class to -1 if there was an error.
  9642.      setom .sajcl(t2)    ;
  9643.     move t1, skdblk+.sajcl    ; Now get class.
  9644.     movem t1, class        ; Save it here.
  9645.     ret
  9646.  
  9647. ; Set communication line bits for transparent i/o.
  9648. ; Returns +1 on failure, +2 on success.
  9649. ;
  9650. dobits:    move t1, netjfn        ; JFN for connection to other system.
  9651.     movx t2, .mornt        ; Read system message status.
  9652.     MTOPR
  9653.      %jserr (,dobit2)
  9654.     movem t3, sysmsg    ; Save here for later restoral.
  9655.     movx t2, .mosnt        ; Now refuse system messages.
  9656.     movx t3, .mosmn
  9657.     MTOPR
  9658.      %jserr (,dobit2)
  9659.  
  9660. dobit2:    movx t1, <tl%cro!tl%cor!tl%sab!tl%sta> ;[147] Clear/Refuse links,
  9661.     hrr t1, ttynum        ;[147]  on the line used for file transfer.
  9662.     txo t1, .ttdes        ;[147] (TLINK wants a device designator.)
  9663.     seto t2,
  9664.     TLINK
  9665.      erjmp dobit3        ;[147] Ignore any failure.
  9666.  
  9667. dobit3:    move t1, netjfn        ; JFN for the file transfer line.
  9668.     movei t2, .morxo    ; Get terminal pause end-of-page status.
  9669.     MTOPR%
  9670.      %jserr (,r)
  9671.     movem t3, oldpau    ; Save the old pause mode.
  9672.     movei t2, .moxof    ; Now set to...
  9673.     movei t3, .mooff    ;  no pause on end.
  9674.     MTOPR%
  9675.      %jserr (,r)
  9676.     RFMOD%            ; Get current mode for this line.
  9677.      %jserr (,r)
  9678.     setom carier
  9679.     setzm mdmlin        ;[130] Assume line not modem-controlled.
  9680.     txne t2, tt%car        ;[130] Is it?
  9681.      setom mdmlin        ;[130]  Yes, flag.
  9682.     movem t2, oldmod    ; Save the present mode.
  9683.  
  9684. ;[97] Turn off undesired bits (program echoing, links, translation).
  9685. ;[97] Turn on desired bits (full duplex; TTY has form feed, tab, lowercase).
  9686. ;[97] Note that any other settings are left intact, in particular TT%ECM, which
  9687. ;[97] can cause a TAC to do its own echoing if turned off.
  9688.  
  9689. dobit4:    ; No echo, no links, no advice, no data mode, full duplex.
  9690.     txz t2, <tt%eco!tt%alk!tt%aad!tt%dam!tt%dum!tt%lic> ;[129] Add TT$DUM
  9691. ; No wakeup stuff, infinite width & length.
  9692.     txz t2, <tt%wkf!tt%wkn!tt%wkp!tt%wka!tt%wid!tt%len!tt%uoc> ;[127]
  9693. ; No formfeed/tab/case interpretation, use XON/XOFF.
  9694.     txo t2, <tt%mff!tt%tab!tt%lca!tt%pgm> ;[129] REMOVE TT%DUM!!!
  9695.  
  9696.     skipn handsh        ;[155] Doing handshake?
  9697.      skipn flow        ;[155] Doing flow control?
  9698.      txz t2, tt%pgm        ; Handshake, or no flow - don't do XON/XOFF.
  9699.     SFMOD%            ; Set the bits.
  9700.      %jserr (,.+1)
  9701.     STPAR%
  9702.      %jserr (,.+1)
  9703.     retskp
  9704.  
  9705. ;[181] PANDA Network Binary Mode routines
  9706.  
  9707. panda <                ;[181] Only if doing Panda
  9708.  
  9709. ;[181] Returns true if we have network binary mode MTOPR%
  9710. ;[181] Preserves ACs, always returns +1, havnbm: is side-effected
  9711.  
  9712. chknbm:    saveac <t1,t2,t3>    ;[181] Save the registers that MTOPR% trashes
  9713.     dmove t1,[ exp .CTTRM,.MORLT ] ;[181] Read local status
  9714.     MTOPR%            ;[181] Can the monitor process this request?
  9715.      erjmp [ setzm havnbm    ;[181]  No, assume this isn't in the monitor
  9716.          setzm setlts    ;[181]   so don't try to use it
  9717.              ret ]        ;[181]   and never try to restore status
  9718.     setom havnbm        ;[181] Otherwise, we have winning 
  9719.     ret            ;[181] Panda Network Binary Mode!
  9720.  
  9721. ;[181] Sets network binary mode
  9722. ;[181] Assumes it can stomp acumulators t1 through t3
  9723. ;[181] Returns to doarpa's caller on success
  9724. ;[181] on failure, assumes we don't have network binary mode,
  9725. ;[181] clears the flag and tries it the old way
  9726.  
  9727. setnbm:    skipe setlts        ;[181] Did we already sucessfully set this?
  9728.      ret            ;[181]  Yes, why bother doing it twice?
  9729.     move t1,netjfn        ;[181] Use current line
  9730.     movx t2,.MORLT        ;[181] Read local status
  9731.     MTOPR%
  9732.      erjmp nbmerr
  9733.     movem t3,OLDLTS        ;[181] save old terminal status
  9734.     txo t3,MO%NBI!MO%NBO    ;[181] network binary mode (input AND output)
  9735.     movx t2,.MOSLT        ;[181] want to set it
  9736.     MTOPR%
  9737.      erjmp nbmerr
  9738.     movx t2,.MORLT        ;[181] now see what actually happened
  9739.     MTOPR%
  9740.      erjmp nbmerr
  9741.     xorx t3,MO%NBI!MO%NBO    ;[181] flip binary mode status
  9742.     txne t3,MO%NBI!MO%NBO    ;[181] they should have been BOTH set ...
  9743.      jrst nbmerr
  9744.     aos setlts        ;[181] flag that we set terminal line status
  9745.     ret
  9746.  
  9747. nbmerr:    setzm havnbm        ;[181] We don't have network binary mode
  9748.      callret doarpa        ;[181]  Maybe the olde fashioned way works?
  9749.  
  9750.  
  9751. ;[181] un-Sets network binary mode
  9752. ;[181] Assumes it can stomp acumulators t1 through t3
  9753. ;[181] Returns to unarpa's caller on success
  9754. ;[181] on failure, assumes we don't have network binary mode,
  9755. ;[181] clears the flag and tries it the old way
  9756.  
  9757. unsnbm:    setz t1,        ;[181] whatever the current state is,
  9758.     exch t1,setlts        ;[181] say that it is no longer set
  9759.      jumpe t1,r        ;[181]  However: did we ever set nbm??
  9760.  
  9761.     move t1,netjfn        ;[181] Use current line
  9762.     movx t2,.MOSLT        ;[181] Read local status
  9763.     move t3,OLDLTS        ;[181] get former status
  9764.     MTOPR%            ;[181] try to restore it
  9765.      erjmp [ setzm havnbm      ;[181]  Use this no longer
  9766.              callret unarpa ] ;[181]  How could this have failed?
  9767.     ret
  9768.  
  9769. >                ;[181] End Panda conditional
  9770. ;[129] Do any required ARPAnet stuff.
  9771. ;
  9772. ; Important Note: The ability to send binary mode telnet negotiations
  9773. ; depends on the monitor NOT doubling IACs on TVT lines.  Some versions of
  9774. ; TOPS-20 (particularly BBN's TCP monitor) will do this.
  9775. ;
  9776. ;[181] Use SOUTR% instead of SOUT% to ensure that 
  9777. ;[181] we flush the data to the TAC
  9778. ;
  9779. ; Returns +1 always, but prints warning on failure.
  9780. ;
  9781. doarpa:    skipn tvtflg        ; Are we on tvt?
  9782.      ret
  9783.  
  9784. panda <    skipe havnbm        ;[181] Does the monitor support network
  9785.      callret setnbm >    ;[181]  binary mode?
  9786.  
  9787.     move t1,netjfn        ; Yes, talk binary.
  9788.     dmove t2,[exp <point 8,[byte(8) iac,will,trnbin]>,-3]
  9789.     SOUTR%            ;[181] This code adapted from MODEM.MAC
  9790.      %jserr(,doarpx)
  9791.     movei t1,^d4000        ; Sleep four seconds.
  9792.     DISMS%
  9793.     move t1,netjfn        ;[181] Tell TVT "do binary".
  9794.     dmove t2,[exp <point 8,[byte(8) iac,do,trnbin]>,-3]
  9795.     SOUTR%
  9796.      %jserr(,doarpx)
  9797.     movei t1,^d4000
  9798.     DISMS
  9799.     ret
  9800.  
  9801. doarpx:    tmsg <
  9802. %KERMIT-20: Warning -- Can't negotiate binary mode with TAC
  9803. >
  9804.     ret
  9805.  
  9806. ; RESLIN -- Reset/Restore the communications line.
  9807. ;
  9808. ; Restore old terminal modes, links, length & width, etc.
  9809. ; Turn off control-C trap.
  9810. ;
  9811. ; CALL RESLIN does nothing if server.
  9812. ; CALL RRSLIN restores the line even if server.
  9813. ;
  9814. reslin: skipe srvflg        ; Server?
  9815.      ret            ;  Yes, forget it.
  9816.  
  9817. rrslin:    call ccoff2        ; REALLY reset the line.
  9818. rrsl2:    skiple filjfn        ; Were we doing something with a file?
  9819.      jrst [    hrrz t1, filjfn    ; If so, try to close it.
  9820.         setzm filjfn
  9821.         CLOSF
  9822.          erjmp .+1
  9823.         jrst .+1 ]
  9824.  
  9825.     call unarpa        ; Undo Arpanet TAC binary mode.
  9826.     call unbits        ; Restore terminal bits.
  9827.     call ttxon        ; Clear up any XOFF condition.
  9828.     move t1,netjfn        ;[181] TLINK leaves trash in AC1
  9829.     CFIBF%            ; Also clear out any piled up junk.
  9830.      erjmp .+1
  9831.     setzm inited        ;[177] Flag we're back to normal.
  9832.     ret
  9833.  
  9834. ; Undo the effect of DOBITS -- restore all the communication line's
  9835. ; old bits & modes.
  9836. ;
  9837. unbits:    move t1, netjfn        ; Get the line.
  9838.     movei t2, .moxof    ; Set the terminal pause on end mode...
  9839.     move t3, oldpau        ;  to what it was before.
  9840.     MTOPR%
  9841.      %jserr (,.+1)
  9842.     move t1, netjfn        ; Communication line JFN.
  9843.     move t2, oldmod        ; Get the previous mode.
  9844.     SFMOD%
  9845.      %jserr (,.+1)
  9846.     STPAR%
  9847.      %jserr (,.+1)
  9848.     movx t2, .mosnt        ; Restore system msg refuse/accept.
  9849.     move t3, sysmsg
  9850.     MTOPR
  9851.      %jserr (,.+1)
  9852.  
  9853. ; Restore links and advice if necessary.
  9854.  
  9855.     setz t1,         ; Restore links & advice.
  9856.     move t2, oldmod        ; From old tty mode word.
  9857.     txne t2, tt%alk        ; Was receiving links before?
  9858.      txo t1, <tl%sab!tl%abs> ; Yes, so receive links.
  9859.     txne t2, tt%aad        ; Was receiving advice before?
  9860.      txo t1, <tl%sta!tl%aad> ; Yes, so receive links.
  9861.     jumpe t1, r        ; Skip to next part if no bits to set.
  9862.     hrr t1, ttynum        ; Must set bits, form tty designator
  9863.     txo t1, .ttdes        ;  ...
  9864.     setz t2,        ; Don't leave garbage in here...
  9865.     TLINK            ; Restore the settings.
  9866.      erjmp .+1        ; Ignore any errors.
  9867.     ret
  9868.  
  9869. ; Turn off Arpanet TAC binary mode.
  9870.  
  9871. unarpa:    skipn tvtflg        ; Are we on a tvt?
  9872.      ret            ; No, skip this.
  9873.     
  9874. panda <    skipe havnbm        ;[181] Does the monitor support network
  9875.      callret unsnbm >    ;[181]  binary mode?
  9876.  
  9877.     move t1, netjfn        ;[181] Get the line.
  9878.     dmove t2, [exp <point 8,[byte(8) iac,wont,trnbin]>,-3]
  9879.     SOUT%            ; Yes, turn off binary mode.
  9880.      %jserr(,unarpx)
  9881.     movei t1, ^d4000    ; Wait 4 secs.
  9882.     DISMS%
  9883.     move t1, netjfn        ; Send the command.
  9884.     dmove t2, [exp <point 8,[byte(8) iac,dont,trnbin]>,-3]
  9885.     SOUT%
  9886.      %jserr(,unarpx)
  9887.     movei t1, ^d4000    ; Wait another 4 secs.
  9888.     DISMS%
  9889.     ret            ; Done.
  9890.  
  9891. unarpx:    tmsg <
  9892. %KERMIT-20: Warning -- Can't clear binary mode with TAC
  9893. >                ;[129] Error message for any of the above.
  9894.     ret
  9895.  
  9896. ;[91] Routine to unstop an XOFF'd line, added as edit 91.
  9897.  
  9898. ttxon:    saveac <t1,t2,t3>    ; Save these.
  9899.     move t1, netjfn        ; In case line was XOFF'd, this will
  9900.     CFOBF%            ;  turn it back on (see monitor source).
  9901.      erjmp r
  9902.  
  9903. ;[157] If we're doing flow control, send a ^Q (XON) to unstick the other side.
  9904.  
  9905.     skipn flow        ; Doing flow control?
  9906.      ret            ;  No, done.
  9907.     RFMOD            ; Yes, get terminal mode.
  9908.      erjmp r        
  9909.     move t3, t2        ; Save it.
  9910.     txzn t2, tt%dam        ; Data mode?
  9911.      jrst ttxon3        ;  No, binary, just send it.
  9912.  
  9913. ttxon2:    SFMOD            ; Put in binary mode.
  9914.      erjmp r
  9915.     call ttxon3        ; Send the XON.
  9916.     move t2, t3
  9917.     SFMOD            ; Put back in data mode.
  9918.      erjmp r
  9919.     ret
  9920.  
  9921. ttxon3:    movei t2, xon        ; Send an XON.
  9922.     BOUT
  9923.      erjmp r
  9924.     ret
  9925.  
  9926.     subttl Packet routines
  9927.  
  9928.  
  9929. ;[114] DIAMSG
  9930. ;
  9931. ; Print packet type and number if debugging "states".
  9932. ; Enter with:
  9933. ;   t1/ packet type
  9934. ;   t2/ packet number
  9935. ;   t4/ pointer to data
  9936. ;   logjfn/ debugging log file jfn
  9937. ; Returns +1 always, with all ACs unchanged.
  9938. ;
  9939. diamsg:    cain debug, 1        ; Only for protocol debugging.
  9940.      skipn logjfn        ; Got a log JFN?
  9941.      ret            ;  Nope, forget it.
  9942.     saveac <t1,t2,t3>    ; Save these.
  9943.     push p, t1        ; Save this for sec.
  9944.     move t1, logjfn        ; Get debugging log file JFN.
  9945.     movei t3, ^d10        ; in decimal.
  9946.     NOUT%
  9947.      erjmp deberr        ;[174]
  9948.     pop p, t2        ; Pop packet type
  9949.     BOUT
  9950.      erjmp deberr        ;[174]
  9951.     cain t2, "G"        ; Generic command?
  9952.      jrst [    move t3, t4    ; Log the first character of the data packet.
  9953.         ildb t2, t3
  9954.         BOUT
  9955.          erjmp deberr    ;[174]
  9956.         jrst .+1 ]
  9957. diamsz:    movei t2, " "        ; A space for delimitation.
  9958.     BOUT
  9959.      erjmp deberr        ;[174]
  9960.     ret
  9961.  
  9962. ;[174] Handle i/o errors writing to debugging log file.
  9963.  
  9964. deberr:    tmsg <
  9965. %KERMIT-20: Error writing debug log file - >
  9966.     movei t1, .priou
  9967.     hrloi t2, .fhslf
  9968.     setz t3,
  9969.     ERSTR
  9970.      nop
  9971.      nop
  9972.     tmsg <
  9973. >
  9974.     setz t1,        ; Close the log file if possible
  9975.     call $closd        ; and turn off debug log.
  9976.     ret
  9977.  
  9978. ; SPACK (Send-Packet)
  9979. ;
  9980. ; Assembles & sends a packet from the given arguments.   Assumes all quoting,
  9981. ; prefixing, condensing, etc, already done.  Sends the fields in the proper
  9982. ; order, validating the control fields to some extent, adding desired parity
  9983. ; (if any) to each character, calculates and appends the checksum, appends any
  9984. ; desired padding or eol characters, and does any required pause or handshake.
  9985. ;
  9986. ; Call with:
  9987. ;    AC1 - Type of packet (D,Y,N,S,R,E,F,Z,T,I, or any uppercase letter)
  9988. ;    AC2 - Packet sequence number (binary)
  9989. ;    AC3 - Number (binary) of characters in data field
  9990. ;    AC4 - 8-bit byte pointer to data characters
  9991. ; Returns: +1 on failure, with:
  9992. ;          AC1 - 0: SOUT failed or timeout on handshake (can retry).
  9993. ;              1: invalid argument (no point retrying).
  9994. ;          (These values are suitable indexes for a jump table)
  9995. ;       +2 on success, with ACs 1-4 unchanged.
  9996. ;
  9997. spack:    saveac <q1,q2,q3>    ; Preserve us!
  9998.  
  9999. ; Set things up.
  10000.  
  10001.     dmovem t1, actmp    ; Save what we were called with in a way that
  10002.     dmovem t3, actmp+2    ;  that they only are restored if we want to.
  10003.     movem t1, type        ; Save the type.
  10004.     call diamsg        ; Print diagnostic if desired.
  10005.     setz q2,        ; Zero the checksum AC.
  10006.     move q1, [point 8, sndpkt] ; Get a byte pointer to the send packet.
  10007.  
  10008. ; Start of packet.
  10009.  
  10010.     move t1, ssthdr        ;[18] Get the start of header char.
  10011.     call @parity        ; Call the appropriate parity routine.
  10012.     idpb t1, q1        ; Put in the packet.
  10013.  
  10014. ; Packet length.
  10015. ;
  10016. ;[98] This section changed to allow for different block check types.
  10017.  
  10018.     movem t3, datlen    ; Remember data length for later.
  10019.     skipe bctone        ; Forcing single-character checksum?
  10020.      aosa t3        ;  Yes, then always use type 1.
  10021.      add t3, bctu        ;  Otherwise add the block check length.
  10022.     addi t3, 2        ;[179] Account for SEQ and TYPE.
  10023.     movem t3, pktlen    ;[179] Remember value of packet length field.
  10024. ;[179]    cail t3, 5        ; Does the packet have the minimum length?
  10025.      camle t3, spsiz    ;  And is it below the maximum?
  10026.       kermsg <SPACK: Illegal message length>,spxx2 ; No, fatal.
  10027.     addm t3, stot        ;[22] It's OK, account for the whole packet.
  10028.  
  10029.     setzm islong        ;[179] Assume regular (short) packet
  10030.     caile t3, ^d94        ;[179] Long packet?
  10031.      setom islong        ;[179] Set flag.
  10032.  
  10033.     addi t3, " "        ;[179] Convert to ASCII.
  10034.     skipe islong        ;[179] Long?
  10035.      movei t3, " "        ;[179] Put a blank here
  10036.  
  10037.     add q2, t3        ; Add the LEN field to the checksum.
  10038.     move t1, t3
  10039.     call @parity        ; Call the appropriate parity routine.
  10040.     idpb t1, q1        ; Put the LEN field into the packet.
  10041.     ;...
  10042.  
  10043. ; SPACK, cont'd
  10044.  
  10045.  
  10046. ; Packet sequence number.
  10047.  
  10048.     skipl t1, t2        ; Is the sequence number valid? (0-64)?
  10049.      cail t2, ^o100
  10050.      ermsg <SPACK: Illegal packet sequence number>,spxx2 ; No, fatal.
  10051.     addi t1, " "        ; Add a space so the number is printable.
  10052.     add q2, t1        ; Add the number to the checksum.
  10053.     call @parity        ; Call the appropriate parity routine.
  10054.     idpb t1, q1        ; Put the sequence number into the packet.
  10055.  
  10056. ; Packet type.
  10057.  
  10058.     move t1, type        ; Get the type.
  10059.     cail t1, "A"        ; Check if the type is a capital letter.
  10060.      caile t1, "Z"
  10061.      ermsg <SPACK: Illegal message type>, spxx2 ;[60] Not, fatal.
  10062.     add q2, t1        ; Add in the message type to the checksum.
  10063.     call @parity        ; Call the appropriate parity routine.
  10064.     idpb t1, q1        ; Put the type into the packet.
  10065.     skipg t3, datlen    ; Is there any data?
  10066.      jrst spack3        ;  No, finish up.
  10067.  
  10068. ;[179] Extended header for long packet.
  10069.  
  10070.     skipn islong        ;[179] Long packet?
  10071.      jrst spack2        ;[179] No
  10072.     move t1, pktlen        ;[179] Yes, length
  10073.     subi t1, 2        ;[179] This time we only count data + checksum
  10074.     idivi t1, ^d95        ;[179] Big part of length (quotient)
  10075.     addi t1, " "        ;[179] Convert to ASCII
  10076.     add q2, t1        ;[179] Add to checksum
  10077.     call @parity        ;[179] Tack on parity
  10078.     idpb t1, q1        ;[179] Deposit in packet
  10079.     addi t2, " "        ;[179] Same deal for small part (remainder)
  10080.     add q2, t2        ;[179] Add to checksum
  10081.     move t1, t2        ;[179] Move remainder to t1 for parity routine
  10082.     call @parity        ;[179]
  10083.     idpb t1, q1        ;[179]
  10084.     push p, q2         ;[179] Save current packet checksum
  10085.     move t2, q2        ;[179] Form header checksum
  10086.     andi q2, ^o300        ;[179] ...
  10087.     lsh q2, -6        ;[179]
  10088.     add q2, t2        ;[179]
  10089.     ldb t1, [point 6, q2, 35] ;[179]
  10090.     addi t1, " "        ;[179]
  10091.     pop p, q2        ;[179] Restore packet checksum
  10092.     add q2, t1        ;[179] Include header checksum in it
  10093.     call @parity        ;[179] Add parity to header checksum
  10094.     idpb t1, q1        ;[179] Put it in the packet
  10095.     move t3, datlen        ;[179] Set t3 as spack2 expects to find it.
  10096.  
  10097. ; Loop to put each data character in the packet.
  10098.  
  10099. spack2:    ildb t1, t4        ; Get the next character.
  10100.     add q2, t1        ; Add it to the checksum.
  10101.     call @parity        ; Call the appropriate parity routine.
  10102.     idpb t1, q1        ; Put the character into the packet.
  10103.     sojg t3, spack2        ; Loop for all characters.
  10104.     ;...
  10105.  
  10106. ; SPACK, cont'd.
  10107.  
  10108. ;[98] SPACK3-SPAK3X rewritten as part of edit 98.
  10109.  
  10110.  
  10111. ; Done with the data, now append the appropriate kind of block check.
  10112.  
  10113. spack3:    skipe bctone        ; Doing send-init exchange?
  10114.      jrst spak3a        ;  Then always use type 1.
  10115.     move t1, bctu        ; Get block check type,
  10116.     jrst @[exp spxx2, spak3a, spak3b, spak3c](t1) ; and do it.
  10117.  
  10118. ; Single-character 6-bit checksum.
  10119.  
  10120. spak3a:    move t3, q2        ; Make an extra copy of the checksum.
  10121.     andi q2, ^o300        ; AND out all but 2 bits.
  10122.     lsh q2, -6        ; Shift them to the far right.
  10123.     add q2, t3        ; Add in the original value.
  10124.     ldb t1, [point 6, q2, 35] ; Take modulo 64.
  10125.     addi t1, " "        ; Add a space so the result is printable.
  10126.     call @parity        ; Call the appropriate parity routine.
  10127.     idpb t1, q1        ; Put the checksum into the packet.
  10128.     jrst spak3x        ; Done with checksum.
  10129.  
  10130. ; 2-Character 12-bit checksum.
  10131.  
  10132. spak3b:    ldb t1, [point 6, q2, 29] ; Get bits 24-29 (high order 6 bits).
  10133.     addi t1, " "        ; CHAR of that.
  10134.     call @parity        ; Do any parity.
  10135.     idpb t1, q1        ; Deposit this as first character of checksum.
  10136.     ldb t1, [point 6, q2, 35] ; Get bits 30-35 (low order 6 bits).
  10137.     addi t1, " "        ; CHAR of that.
  10138.     call @parity        ; Do any parity.
  10139.     idpb t1, q1        ; Deposit this as second checksum character.
  10140.     jrst spak3x        ; Done with checksum.
  10141.  
  10142. ; 3-character 16-bit CRC CCITT.
  10143.  
  10144. spak3c:    move t1, datlen        ; Length of the data field.
  10145.     addi t1, 3        ; Plus LEN, SEQ, and TYPE fields.
  10146.     skipe islong        ;[179] Long packet?
  10147.      addi t1, 3        ;[179] Add length of header.
  10148.     move t2, [point 8, sndpkt, 7] ; Point to packet starting at LEN field.
  10149.     call crcclc        ; Go compute the CRC.
  10150.     move q2, t1        ; Here it is.
  10151.     ldb t1, [point 4, q2, 23] ; Get bits 20-23 (high order 4 bits).
  10152.     addi t1, " "        ; CHAR of that.
  10153.     call @parity        ; Do any parity.
  10154.     idpb t1, q1        ; Deposit this as first CRC character.
  10155.     jrst spak3b        ; Go back and do other two CRC characters.
  10156.     ;...
  10157.  
  10158. ; SPACK, cont'd
  10159.  
  10160.  
  10161. ; Supply requested End-of-Line.
  10162.  
  10163. spak3x:    move t1, seolch        ; Get the requested EOL char.
  10164.     call @parity        ; Call the appropriate parity routine.
  10165.     idpb t1, q1        ; Add it to the packet.
  10166.     setz t1,        ; Get a null.
  10167.     idpb t1, q1        ; Put it at the end.
  10168.  
  10169. ;[36] Do any requested interpacket pausing.
  10170.  
  10171. spack5:    skipe t1, pause        ; Pausing?
  10172.      jrst [    fmp t1, [1000.0] ; Yes, convert to milliseconds.
  10173.         fixr t1, t1    ; And then to an integer.
  10174.         DISMS        ; Sleep for that long.
  10175.         jrst .+1 ]
  10176.  
  10177. ; Do any requested padding.
  10178.  
  10179. spak5a:    skipg t4, spadn        ;[34] Sending pad characters?
  10180.      jrst spack6        ;[34]  No, just send the packet.
  10181.     move t1, spadch        ;[34] Yes, this is the character.
  10182.     call @parity        ;[34] Tack on desired parity.
  10183.     move t2, t1        ;[34] Shuffle ACs...
  10184.     move t1, netjfn        ;[34] Where to send the padding.
  10185. spak5b:    BOUT            ;[34] Output the padding character.
  10186.      %jserr <SPACK: Can't send padding>,spack6 ;[34] Warn about errors.
  10187.     sojg t4, spak5b        ;[34] This many pad characters.
  10188.  
  10189.     ;...
  10190.  
  10191. ; SPACK, cont'd
  10192.  
  10193. ;[131] If ARPANET TVT then must double any hex FF's (TELNET IAC).
  10194. ; Note, since IAC is DEL with parity bit on, we should never see one, right?
  10195. ;
  10196. spack6:    move t2, [point 8, sndpkt] ; The address of the packet.
  10197.     skipn tvtflg        ; TVT-Binary mode?
  10198.      jrst spak6x        ; No, just go send it.
  10199.  
  10200.     move t2, [point 8, sndpkt] ; Yes, must double any IACs.
  10201.     move t3, [point 8, tvtbuf] ; Copy data field to this place.
  10202. spak6a:    ildb t1, t2        ; Byte loop.  Get one.
  10203.     jumpe t1, spak6b    ; Done?
  10204.     idpb t1, t3        ; No, copy it.
  10205.     cain t1, iac        ; IAC?
  10206.      idpb t1, t3        ;  Yes, copy it again.
  10207.     jrst spak6a        ; Till done.
  10208. spak6b:    setz t1,        ; Done, make result asciz.
  10209.     idpb t1, t3        ;  ...
  10210.     move t2, [point 8, tvtbuf] ; Point to result.
  10211.  
  10212. ;[131] End.  Now, finally send the packet.
  10213.  
  10214. spak6x:    move t1, netjfn        ; JFN for sending the packet.
  10215.     setzb t3, t4        ; Terminate on a null.
  10216.     SOUT%            ; Send the string.
  10217.      erjmp spxx1        ;  JSYS error, go handle.
  10218.  
  10219. spak6y:    aos sptot        ;[4] Count the packet we sent.
  10220.     skipn debug        ;[128] Debugging?
  10221.      jrst spackb        ;  No, how about blips?
  10222.     caie debug, 2        ;[128] Yes, packets?
  10223.      jrst spackz        ; No, states, that's taken care of elsewhere.
  10224.  
  10225. ; Debugging -- Log the packet.
  10226.  
  10227.     skipn t1, logjfn    ; Yes, but make sure we have a destination.
  10228.      jrst spackz        ;  We don't, skip this.
  10229.     hrroi t2, [asciz/
  10230. S,/]                ; We do, give a crlf and "S," first.
  10231.     setzb t3, t4
  10232.     SOUT
  10233.      erjmp spkder
  10234.     seto t2,        ; Include time stamp, current date/time.
  10235.     movx t3, ot%nda        ; But no date.
  10236.     ODTIM
  10237.      erjmp spkder
  10238. spackd:    movei t2, ","        ; Comma,
  10239.     BOUT
  10240.      erjmp spkder
  10241.     setzb t3, t4
  10242.     move t2, [point 8, sndpkt] ; Now the packet itself.
  10243.     SOUT
  10244.      erjmp spkder
  10245.     hrroi t2, crlf        ; Another crlf
  10246.     SOUT
  10247.      erjmp spkder
  10248.     jrst spackz
  10249.     ;...
  10250.  
  10251. ;...SPACK, cont'd
  10252.  
  10253. ;[174] Recover from errors writing to debugging log.
  10254.  
  10255. spkder:    call deberr
  10256.     jrst spackz
  10257.  
  10258. ;[4] Put blips on user's screen if local.
  10259.  
  10260. spackb:    skipl filjfn        ;[106] No blips if output is to TTY.
  10261.      skipn local        ; Not debugging, but still local?
  10262.      jrst spackz        ;  Remote, don't make blips.
  10263.     move t3, type        ; Local, am I sending a NAK packet?
  10264.     movei t1, "%"        ; Print a "%" for each one I send.
  10265.     move t2, numtry        ; Or each resend I have to do.
  10266.     caig t2, 1        ;
  10267.      cain t3, "N"        ;
  10268.      jrst spackx        ;
  10269.     setz t3,        ; Not a NAK, is it time to blip?
  10270.     move t4, sptot        ; Check the absolute packet number.
  10271.     divi t3, blip        ; We do it every "blip" packets.
  10272.     jumpn t4, spackz    ; Not time for a blip.
  10273.     movei t1, "."        ; It's time, here's the blip.
  10274. spackx:    PBOUT%            ; "."
  10275.  
  10276. ; Common exit point for successful exit.
  10277.  
  10278. spackz:    dmove t1, actmp        ;[60] Restore what we were called with
  10279.     dmove t3, actmp+2    ;[60]
  10280.     retskp
  10281.  
  10282. ; Exit point for nonfatal errors.
  10283.  
  10284. spxx1:    skipe mdmlin        ; Modem line?
  10285.      jrst [    move t1, netjfn    ;  Yes, see if we just dropped carrier.
  10286.         call chkli2
  10287.         skipn carier    ; Still have it?
  10288.          jrst spxx2    ;  No, then fatal.
  10289.         jrst .+1 ]    ; Yes, can continue trying.
  10290.     setz t1,        ;[60] Indicate nonfatal.
  10291.     ret
  10292.  
  10293. ; Exit for fatal errors.
  10294.  
  10295. spxx2:    movei t1, 1        ;[60] Indicate fatal.
  10296.     ret
  10297.  
  10298. ; RPACK -- Receive-Packet
  10299. ;
  10300. ; This routine waits for a packet to arrive.  It reads characters until it
  10301. ; finds the start-of-packet character, normally SOH.  It then reads the packet
  10302. ; into RECPKT based on the length supplied in the length field (no termination
  10303. ; character necessary).
  10304. ;
  10305. ; Returns:
  10306. ;   +1 failure (if the checksum is wrong or the packet trashed)
  10307. ;   +2 success with:
  10308. ;       t1/ Packet type
  10309. ;       t2/ Packet number
  10310. ;       t3/ Length of data field
  10311. ;       t4/ 8-bit byte pointer to data field
  10312. ;
  10313. rpack:    saveac <q1,q2,q3>    ; Save these ACs.
  10314.     stkvar <pktbct>        ; Block check type for this packet.
  10315.  
  10316.     setzm islong        ;[179] Assume packet is not long.
  10317.  
  10318.     cain debug, 2        ; Logging packets?
  10319.      skipn t1, logjfn    ; Yes, make sure there's a log.
  10320.      jrst rpackb
  10321.  
  10322.     hrroi t2, [asciz/
  10323. R,/]                ; "R" for Receive
  10324.     setzb t3, t4
  10325.     SOUT
  10326.      erjmp [call deberr    ;[174] Recover from debug log errors.
  10327.         jrst rpacka ]
  10328.     seto t2,        ; Time stamp, current date/time.
  10329.     movx t3, ot%nda        ; But no date.
  10330.     ODTIM
  10331.      erjmp [call deberr    ;[174]
  10332.         jrst rpacka ]
  10333.     movei t2, "/"        ; Current timeout interval.
  10334.     BOUT
  10335.      erjmp [call deberr    ;[174]
  10336.         jrst rpacka ]
  10337.     movei t1, tmout        ; Place to go on timeout.
  10338.     call timeit        ; Set the timer
  10339.     move t1, logjfn
  10340.     move t2, curtim        ; Log current time interval
  10341.     movei t3, ^d10
  10342.     NOUT
  10343.      erjmp [call deberr    ;[174]
  10344.         jrst rpacka ]
  10345.  
  10346. rpacka:    movei t2, ","
  10347.     BOUT
  10348.      erjmp [call deberr    ;[174]
  10349.         jrst rpackb ]
  10350.     move t1, netjfn        ; JFN of the communication line.
  10351.     jrst rpack0        ; Already set timer...
  10352.  
  10353. ; Here if not logging packets.
  10354.  
  10355. rpackb:    movei t1, tmout        ; Place to go on timeout.
  10356.     call timeit        ; Time out if it takes too long.
  10357.     move t1, netjfn        ; JFN of the communication line.
  10358.     ;...
  10359.  
  10360. ;...RPACK, cont'd
  10361.  
  10362. ; Eat interpacket garbage, read up to start-of-packet character.
  10363.  
  10364. rpack0:    call inchar        ; Get a character from the line.
  10365.      jrst rperr        ;  If we can't, go fail.
  10366.     came t2, rsthdr        ;[18] Is the char the start of header char?
  10367.      jrst rpack0        ;  No, go until it is (or we are timed out).
  10368.  
  10369. ; Now read the packet.
  10370.  
  10371. rpack1:    move q1, [point 8, recpkt] ; OK, now point to the packet buffer.
  10372.     idpb t2, q1        ; Put the start character into the packet.
  10373.  
  10374.  
  10375. ; Packet length field = number of characters to follow the length field,
  10376. ; up to and including the last block check character.
  10377.  
  10378.     call inchar        ; Get next character from the line.
  10379.      jrst rperr
  10380.     camn t2, rsthdr        ;[18] Is the char the start of header char?
  10381.      jrst rpack1        ;  Yes, then go start over.
  10382.     idpb t2, q1        ; Copy character to packet buffer.
  10383.     move q2, t2        ; Start the checksum.
  10384.     move q3, t2        ; Save the length here for later.
  10385.  
  10386. ; Packet sequence number.
  10387.  
  10388.     call inchar        ; Get the next character
  10389.      jrst rperr
  10390.     camn t2, rsthdr        ;[18] Start of header?
  10391.      jrst rpack1        ;  Yes, go start over.
  10392.     idpb t2, q1        ; No, put it in the packet.
  10393.     add q2, t2        ; Add it to the checksum.
  10394.     subi t2, " "        ; Get the real packet number.
  10395.     movem t2, num        ; Save it for later.
  10396.  
  10397. ; Packet type.
  10398.  
  10399.     call inchar        ; Next character.
  10400.      jrst rperr
  10401.     camn t2, rsthdr        ;[18] SOH?
  10402.      jrst rpack1        ;  Yes, go back.
  10403.     idpb t2, q1        ; Not SOH, keep it.
  10404.     add q2, t2        ; Add it to the checksum.
  10405.     movem t2, type        ; It's the message type, remember it.
  10406.     ;...
  10407.  
  10408. ;...RPACK, cont'd
  10409.  
  10410.  
  10411. ;[123] Beginning of change
  10412. ;
  10413. ; Now determine block check type for this packet.  Here we violate the layered
  10414. ; nature of the protocol by inspecting the packet type in order to detect when
  10415. ; the two sides get out of sync.  Two heuristics allow us to resync here:
  10416. ;
  10417. ;   a. An S packet always has a type 1 checksum.
  10418. ;   b. A NAK never contains data, so its block check type is LEN-2.
  10419.  
  10420.     subi q3, " "        ;[179] Convert ASCII length to number.
  10421.     skipn q3        ;[179] Is it zero?
  10422.      setom islong        ;[179] Yes - long packet.
  10423.     skipn islong        ;[179] Long?
  10424.      subi q3, 2        ;[179] No, subtract 2 for SEQ & TYPE fields.
  10425.     move t1, bctu        ; Expected block check type.
  10426.     skipn bctone        ; But if type 1 is required,
  10427.      cain t2, "S"        ; or if this is an S packet,
  10428.      movei t1, 1        ; then force the type to 1.
  10429.     cain t2, "N"        ; But, is this a NAK?
  10430.      move t1, q3        ; Yes, so this must be the block check type.
  10431.     movem t1, pktbct    ; Save the block check type we have determined.
  10432.  
  10433.     skipn islong        ;[179] Long packet?
  10434.      jrst rpackc        ;[179] No, go get data.
  10435.     move t1, netjfn        ;[179] Set up for inchar.
  10436.     call inchar        ;[179] Get next character.
  10437.      jrst rperr        ;[179]
  10438.     idpb t2, q1        ;[179] Save it.
  10439.     add q2, t2        ;[179] Add to checksum.
  10440.     subi t2, " "        ;[179] Convert to number.
  10441.     move q3, t2        ;[179] Set to make...
  10442.     imuli q3, ^d95        ;[179] big part of length.
  10443.     call inchar        ;[179] Get next character.
  10444.      jrst rperr        ;[179]
  10445.     idpb t2, q1        ;[179] Save it.
  10446.     add q2, t2        ;[179] Add to checksum.
  10447.     subi t2, " "        ;[179] Convert to number.
  10448.     add q3, t2        ;[179] Add to big part of length.
  10449.     call inchar        ;[179] Get next character (header checksum)
  10450.      jrst rperr        ;[179]
  10451.     idpb t2, q1        ;[179] Save it.
  10452.     add q2, t2        ;[179] Add to checksum.
  10453.  
  10454. ; [179] HERE WE SHOULD CHECK THE HEADER CHECKSUM...
  10455. ; [179] But no big deal since overall checksum will catch any errors later.
  10456.  
  10457. ; Now subtract the block check length from the packet length, which gives the
  10458. ; length of the data field.
  10459.  
  10460. rpackc:    sub q3, pktbct        ; Calculate the data length.
  10461.     movem q3, datlen    ; Save it.
  10462.  
  10463. ; Take in the data field.
  10464.  
  10465.     move t1, netjfn        ; Get the packet input jfn back again.
  10466.  
  10467. ;[123] End of change.
  10468.  
  10469.     movem q1, datptr    ; Return pointer to the data buffer.
  10470.     skipg q3, datlen    ; Use character count for loop control.
  10471.      jrst rpbc        ;[99] If none, go get the block check.
  10472.  
  10473. ; Loop to get the specified number of data characters.
  10474.  
  10475. rpack2:    hrrz t2, q1        ;[117] Check for buffer overflow.
  10476.     cail t2, recpkz        ;[117] If we're past the end, go back and
  10477.      jrst rpack0        ;[117]  eat characters until a ^A.
  10478.     call inchar        ; Get a character from the line.
  10479.      jrst rperr        ;  Oops, can't.
  10480.     camn t2, rsthdr        ; Is the char the start of header char?
  10481.      jrst rpack1        ;  Yes, then go start over.
  10482.     idpb t2, q1        ; Put the char into the packet.
  10483.     add q2, t2        ; Add it to the checksum.
  10484.     sojg q3, rpack2        ; Get next character, if any.
  10485.     ;...
  10486.  
  10487. ;...RPACK, cont'd
  10488.  
  10489.  
  10490. ; Count exhausted, next characters will be the block check.
  10491. ;
  10492. ;[98] This section, thru RPACK4, mostly rewritten as part of edit 98.
  10493.  
  10494. rpbc:    movem q1, bctemp    ; Save pointer to block check.
  10495.     move q3, pktbct        ;[123] Length of block check for this packet.
  10496.  
  10497. ;[123]    skipl datlen        ;[99] If data len negative, must be type 1 NAK!
  10498. ;[123]     skipe bctone        ;  or if this flag is set,
  10499. ;[123]     movei q3, 1        ;  must look for single-character checksum.
  10500.  
  10501. ; Get the checksum bytes and add them up.
  10502.  
  10503.     setz t3,        ; Accumulator for checksum.
  10504. rpack3:    call inchar        ; Get a character.
  10505.      jrst rperr
  10506.     camn t2, rsthdr        ;[18] Is the char the start of header char?
  10507.      jrst rpack1        ;  Yes, then go start over.
  10508.     idpb t2, q1        ; Got one, deposit it.
  10509.     lsh t3, 6        ; Accumulate numeric value
  10510.     addi t3, -40(t2)    ;  ...
  10511.     sojg q3, rpack3        ; Go back and get the rest.
  10512.     
  10513.     setz t1,        ; Make the string ASCIZ.
  10514.     idpb t1, q1
  10515.  
  10516. ;[135] If doing handshake, look for that now.
  10517. ;[135] (This code moved from beginning of SPACK)
  10518.  
  10519. rpakh1:    skipn handsh        ; Doing handshake?
  10520.      jrst rpakcc        ;  Nope.
  10521. rpakh2:    move t1, netjfn        ; Try to get a character
  10522.     call inchar        ;  from the line.
  10523.      jrst rpakhx        ; If there was an error, try to proceed
  10524.     andi t2, 177        ; Strip the high bit.
  10525.     came t2, handsh        ; Is it the handshake character?
  10526.      jrst rpakh2        ;  No, keep going till it is.
  10527. rpakhx:    ;...
  10528.  
  10529. ;[135](end of change)
  10530.  
  10531. ;...RPACK, cont'd
  10532.  
  10533.  
  10534. ; Check the checksum.
  10535.  
  10536. rpakcc:    skipl datlen        ;[99] If negative data length, or
  10537.      skipe bctone        ;  explicitly requested to,
  10538.      jrst rpak3a        ;  then compute 1 character checksum.
  10539.     move t1, bctu        ; Otherwise get the type which we're using.
  10540.     jrst @[exp rperr, rpak3a, rpak3b, rpak3c](t1)
  10541.  
  10542. ; Here for single-character 6-bit checksum.
  10543.  
  10544. rpak3a:    move q3, q2        ; Make a copy of the arithmetic checksum.
  10545.     andi q2, ^o300        ; And out all but 2 bits.
  10546.     lsh q2, -6        ; Shift them to the far right.
  10547.     add q2, q3        ; Add in the original value.
  10548.     andi q2, 77        ; Get the modulo 64 of the char total.
  10549.     jrst rpak3x        ; Go check it.
  10550.  
  10551. ; Two-character 12-bit checksum.
  10552.  
  10553. rpak3b:    andi q2, 7777        ;[100] Mask out all but 12 bits.
  10554.     jrst rpak3x        ; Go compare.
  10555.  
  10556. ; 3-character 16-bit CRC CCITT.
  10557.  
  10558. rpak3c:    move t1, datlen        ; Get the data length.
  10559.     addi t1, 3        ; Account for LEN, SEQ, and TYPE fields.
  10560.     skipe islong        ;[179] Long packet?
  10561.      addi t1, 3        ;[179] Also account for extended header.
  10562.     move t2, [point 8, recpkt, 7] ; Point to packet starting at LEN field.
  10563.     call crcclc        ; Compute CRC.
  10564.     ldb q2, [point 16, t1, 35] ;[100] Get exactly 16 bits worth.
  10565.     ;...
  10566.  
  10567. ;...RPACK, cont'd
  10568.  
  10569.  
  10570. ; Compare the two block checks.
  10571.  
  10572. rpak3x:    caie t3, (q2)        ; Are they equal?
  10573.      jrst badbc        ;  No, bad block check.
  10574.  
  10575. ; All OK, turn off timer, flush buffer.
  10576.  
  10577. rpack4:    call timoff        ; Got packet OK, turn off the timer.
  10578.     move t1, netjfn        ;[17] Clear out any further junk from input
  10579.     CFIBF%            ;[17] buffer, there should be nothing there
  10580.      erjmp .+1        ;[17] till after we reply.
  10581.  
  10582. ; Set up ACs 1-4 with results and return successfully.
  10583.  
  10584. rpackx:    aos rptot        ; Count the packet we received.
  10585.     move q1, bctemp        ; Pointer to first character of block check.
  10586.     setz t1,        ; Terminate the data string, nullifying
  10587.     idpb t1, q1        ;  the block check.
  10588.  
  10589.     move t1, type        ; Return the packet type in T1,
  10590.     move t2, num        ;  the sequence number in T2,
  10591.     call diamsg        ; Log the packet type & number if desired.
  10592.     skipge t3, datlen    ;  the number of data characters in T3,
  10593.      setz t3,        ;***
  10594.     move t4, datptr        ; and a pointer to the data in t4.
  10595.     retskp            ; Return +2.
  10596.  
  10597. ; Come here if block checks don't compare.
  10598.  
  10599. badbc:    skipn t1, logjfn    ;[38] No, do we have a debugging log?
  10600.      jrst rperr        ;[38]  No, skip messages.
  10601.     setzb t3, t4        ;[38] Yes, say checksum was bad.
  10602.     hrroi t2, [asciz/
  10603. %chksum /]            ;[29]
  10604.     SOUT
  10605.      erjmp [call deberr    ;[174]
  10606.         jrst .+1 ]
  10607.  
  10608. ; Exit thru here upon any kind of error except a timeout.
  10609.  
  10610. rperr:    call timoff        ; Cancel the time out.
  10611.     move t1, netjfn        ;[17] Flush any stacked up packets from the
  10612.     CFIBF%            ;[17] input buffer.  If anything's there, we
  10613.      erjmp .+1        ;[17] don't want it!
  10614.     ret            ; Return unsuccessfully.
  10615.  
  10616.     subttl Support Routines for RPACK.
  10617.  
  10618.  
  10619. ; INCHAR -  Get a character from the communication line.
  10620. ;
  10621. ; Call with:
  10622. ;  t1/ JFN of comm line.
  10623. ;
  10624. ; Returns:
  10625. ;  +1 on failure, with state set to "A" if carrier dropped.
  10626. ;  +2 on success with:
  10627. ;     t1/ unchanged
  10628. ;     t2/ character, with parity bit stripped if parity is being used.
  10629. ;
  10630. inchar:    saveac <t1>        ; Save the JFN.
  10631.  
  10632. ;[180] Begin buffering communications input change.
  10633.  
  10634.     skiple tticnt        ; Something in buffer?
  10635.      jrst [    sos tticnt    ; Yes, decrement count
  10636.         ildb t2, ttiptr    ; Load next byte.
  10637.         aos ttildb    ; (stats)
  10638.         jrst inch3 ]    ; Go handle byte.
  10639.     SIBE%            ; Buffer empty - see if anything is waiting.
  10640.      jrst [ caile t2, IOBUF     ; Adjust if more than buffer size.
  10641.          movei t2, IOBUF
  10642.         movem t2, tticnt ; Remember how many we asked for
  10643.         movn t3, t2     ; Negative version for SIN
  10644.         move t2, [point 8, ttibuf] ; Where to put them
  10645.         movem t2, ttiptr ; Reset buffer pointer
  10646.         SIN%         ; Try to read
  10647.          erjmp inchxx     ; Error...
  10648.         aos ttisin     ; Number of SINs for stats
  10649.         add t3, tticnt     ; How many we got (t3 is negative)
  10650.         camle t3, ttimax ; Maximum size of a SIN for stats
  10651.          movem t3, ttimax
  10652.         movem t3, tticnt ; Save the input byte count
  10653.         skipg tticnt     ; More than zero
  10654.          jrst inch2     ; Less than one - go do blocking BIN
  10655.         sos tticnt     ; Decrement count
  10656.         ildb t2, ttiptr     ; Load next byte.
  10657.         aos ttildb     ; (stats)
  10658.         jrst inch3 ]     ; Go handle byte.
  10659.  
  10660. ; Do BIN if SIBE sees nothing waiting or if SIN gets nothing.
  10661. ;[180] End buffering change.
  10662.  
  10663. inch2:    setzm tticnt        ;[180]
  10664.     setz t2,        ; (in case of error)
  10665.     BIN%            ; Get a character from the line.
  10666.      erjmp inchxx        ;[130] Error, go see what.
  10667.     aos ttibin        ;[180] (stats)
  10668. inch3:                ;[180] (label added).
  10669.     cain debug, 2        ; Logging packets?
  10670.      call [    skipn t1, logjfn ; Yes, make sure there's a log.
  10671.          ret
  10672.         BOUT        ; Record the character.
  10673.          erjmp deberr    ;[174]
  10674.         ret ]
  10675.     aos rtot        ; Increment total character count.
  10676.     move t1, parity        ; What type of parity?
  10677.     caie t1, none        ; If none, don't touch the parity.
  10678.      andi t2, ^o177        ;  Else, take out parity.
  10679.     retskp            ; Done, return successfully.
  10680.  
  10681. ;[130] Error handler to check for carrier dropped.
  10682.  
  10683. inchxx:    skipn mdmlin        ; Modem controlled line?
  10684.      ret            ;  No, just return +1 to indicate error.
  10685.     move t1, netjfn        ; Yes, see if we still have carrier
  10686.     call chkli2        ; ...
  10687.     skipe carier        ; Do we?
  10688.      ret            ;  Yes, so some other error, handle normally.
  10689.     wtlog <Carrier Dropped, Connection Terminated> ; No, lost it.  Log.
  10690.     movei state, "A"    ; Cancel this transaction.
  10691.     setzm carier        ; Say no more carrier.
  10692.      ret
  10693.  
  10694.  
  10695. ; Come here on timeout, via interrupt handler.
  10696.  
  10697. tmout:    call rperr        ;[46] Clean up timers & buffer...
  10698.     call ttxon        ;[91] Unstop the line in case it was XOFF'd.
  10699.     movei t1, "T"        ; Make believe we got a "Timeout" packet
  10700.     move t2, pktnum
  10701.     setzb t3, t4        ; No data.
  10702.     call diamsg
  10703.     retskp            ; Return successfully as if with real packet.
  10704.  
  10705.     subttl CRC and Parity Routines
  10706.  
  10707.  
  10708. ;[66] CRC calculation
  10709. ;
  10710. ; This routine will calculate the CRC for a string, using the
  10711. ; CRC-CCITT polynomial.
  10712. ;
  10713. ; The string should be the fields of the packet between but not including
  10714. ; the <mark> and the block check, which is treated as a string of bits with
  10715. ; the low order bit of the first character first and the high order bit of the
  10716. ; last character last -- this is how the bits arrive on the transmission line.
  10717. ; The bit string is divided by the polynomial
  10718. ;
  10719. ;  x^16+x^12+x^5+1
  10720. ;
  10721. ; The initial value of the CRC is 0.  The result is the remainder of this
  10722. ; division, used as-is (i.e. not complemented).
  10723. ;
  10724. ; Contributed by Nick Bush, Stevens Institute of Technology.
  10725. ;
  10726. ; Call with
  10727. ;  t1/ length of string
  10728. ;  t2/ 8-bit byte pointer to string
  10729. ; Returns +1 always, with t1/ 16-bit CRC, t2 unchanged.
  10730. ;
  10731. ; AC usage:
  10732. ;    t1/ Accumulated CRC
  10733. ;    q4/ Remaining length
  10734. ;    q3/ Byte pointer to string
  10735. ;    q2/ temp
  10736. ;    q1/ temp
  10737. ;
  10738. crcclc:    saveac <q1,q2,q3,q4,t2>    ; Save q1-q4, and t2.
  10739.     dmove q3,t1        ; Get arguments.
  10740.     setz t1,        ; Initial CRC is 0.
  10741.     move t2, parity        ;[136] Get parity.
  10742.  
  10743. crcc.1:    ildb q1, q4        ; Get a character.
  10744.     caie t2, none        ;[136] Parity = NONE?
  10745.      andi q1, ^o177        ;[136] No, doing parity, strip parity bit.
  10746.     xori q1, (t1)        ; Add in with current CRC.
  10747.     ldb q2, [point 4,q1,31]    ; Get high 4 bits.
  10748.     andi q1, ^o17        ; And low 4 bits.
  10749.     move q1, crctb2(q1)    ; Get low portion of CRC factor.
  10750.     xor q1, crctab(q2)    ; Plus high portion.
  10751.     lsh t1, -^d8        ; Shift off a byte from previous CRC.
  10752.     xor t1, q1        ; Add in new value.
  10753.     sojg q3, crcc.1        ; Loop for all characters.
  10754.     
  10755.     ret            ; Done, return +1 with CRC in t1.
  10756.  
  10757. ; Data tables for CRC-CCITT generation
  10758.  
  10759. crctab:    oct    0
  10760.     oct    10201
  10761.     oct    20402
  10762.     oct    30603
  10763.     oct    41004
  10764.     oct    51205
  10765.     oct    61406
  10766.     oct    71607
  10767.     oct    102010
  10768.     oct    112211
  10769.     oct    122412
  10770.     oct    132613
  10771.     oct    143014
  10772.     oct    153215
  10773.     oct    163416
  10774.     oct    173617
  10775.  
  10776. crctb2:    oct    0
  10777.     oct    10611
  10778.     oct    21422
  10779.     oct    31233
  10780.     oct    43044
  10781.     oct    53655
  10782.     oct    62466
  10783.     oct    72277
  10784.     oct    106110
  10785.     oct    116701
  10786.     oct    127532
  10787.     oct    137323
  10788.     oct    145154
  10789.     oct    155745
  10790.     oct    164576
  10791.     oct    174367
  10792.  
  10793.     subttl    Parity routines
  10794.  
  10795. ; Default, don't touch the eighth bit.
  10796.  
  10797. none:    ret
  10798.  
  10799. ; Mark, bit 8 is always 1.
  10800.  
  10801. mark:    ori t1, ^o200        ; Turn on the parity bit.
  10802.     ret
  10803.  
  10804. ; Space, opposite of mark, bit 8 is always zero.
  10805.  
  10806. space:    andi t1, ^o177        ; Turn off the parity bit.
  10807.     ret
  10808.  
  10809. ; Even, the total number of on bits should be even.
  10810.  
  10811. even:    saveac <t2>
  10812.     andi t1, ^o177        ; Start off with bit 8 = 0.
  10813.     move t2, t1
  10814.     jrst evnodd
  10815.  
  10816. ; Odd, the total number of on bits should be odd.
  10817.  
  10818. odd:    saveac <t2>
  10819.     andi t1, ^o177        ; Turn off the parity bit.
  10820.     movei t2, ^o200(t1)    ; Start off with bit 8 = 1.
  10821.  
  10822. evnodd:    lsh t2, -4        ; Get high order 4 bits of character
  10823.     xori t2, (t1)        ; Fold into 4 bits.
  10824.     trce t2, 14        ; Left two bits both 0 or 1?
  10825.      trnn t2, 14        ;  or both 1?
  10826.      xori t1, 200        ; Yes, set parity
  10827.     trce t2, 3        ; Right two bits both 0?
  10828.      trnn t2, 3        ;  or both 1?
  10829.      xori t1, 200        ; Yes, set parity.
  10830.     ret
  10831.  
  10832.     subttl Server Operation
  10833.  
  10834. ; GETCOM
  10835. ;
  10836. ; We come here if we are in server mode.  We just wait for a packet of one of
  10837. ; the following types:
  10838. ;
  10839. ;    S    Send init - just follow the normal path from here
  10840. ;    R    Receive init - like a local "send filespec"
  10841. ;    I    Init (all-purpose exchange of parameters)
  10842. ;    G    Generic command:
  10843. ;        L    Logout - the other side is done, log out this job
  10844. ;        F    Finish - exit from Kermit
  10845. ;        U    Disk Usage query
  10846. ;        T    Type a file
  10847. ;        etc
  10848. ;
  10849. ; First, issue a message telling the user what to do.
  10850. ;
  10851. getcom:    movei t1, [        ;[157] In case line gets XOFF'd while
  10852.         call ttxon    ;[157] typing the message, unstick it,
  10853.         jrst getcm2 ]    ;[157] and proceed.
  10854.     call timeit        ;[157] Set the timer.
  10855.     skipe local        ;[174] Local mode?
  10856.      jrst [    tmsg <
  10857.  Entering server mode on TTY>    ;[174] Yes, give appropriate message.
  10858.         numout ttynum, 8
  10859.         skipl speed
  10860.          jrst [    tmsg <, >
  10861.             numout speed
  10862.             tmsg < baud>
  10863.             jrst getcmm ]
  10864.         jrst getcmm ]    ;[174]
  10865.     tmsg <
  10866.  Kermit Server running on DEC-20 host.  Please type your escape
  10867.  sequence to return to your local machine.  Shut down the server by
  10868.  typing the BYE command to KERMIT on your local machine.>
  10869.  
  10870. getcmm:    tmsg <
  10871. >
  10872. getcm2:    call timoff        ;[157] Turn off timer.
  10873.     setom srvflg        ; Flag that we are serving.
  10874.     call inilin        ; Initialize the line.
  10875.     call ccon        ; Don't let someone ^C without reseting line.
  10876.      jrst xgfin2        ;  On control-C, go "finish".
  10877.     setzm delay        ; No delay in server mode.
  10878.     setzb t3, t4        ; Set default parameters in case we get some
  10879.     call spar        ;  command before first Send-Init or Info.
  10880.     jrst xxwait        ; Go wait for a command packet.
  10881.  
  10882. ; Server command loop.  Server commands should always jrst back to here,
  10883. ; even upon error, except for those that specify exit from server mode.
  10884. ;
  10885. xxwait:    skipe mdmlin        ;[130] Modem line?
  10886.      skipe carier        ;[130] Did carrier drop?
  10887.      skipa            ;[130] No.
  10888.      jrst xgfin2        ;[130] Yes, go clean up.
  10889.  
  10890.     setom sptot        ;[134] Clear packet statistics counters
  10891.     setom rptot        ;[134] ...
  10892.     setzm xflg        ; Clear the server "type" flag.
  10893.     setzm source        ; Ditto for GETCH source.
  10894.     setzm dest        ; Ditto for PUTCH destination.
  10895.     setzm ffunc        ; And for file function.
  10896.     move t1, srvtim        ; Get the default server packet time out.
  10897.     movem t1, stimou    ; Set it so we don't time out as often.
  10898. xxwt2:    setom bctone        ;[98] Set this so we use type 1 checksum.
  10899.     setzm pktnum        ; Initial packet sequence number.
  10900.     call rpack        ; Get a packet.
  10901.      skipa            ;  On error, NAK what we're looking for.
  10902.     cain t1, "T"        ; Timer interrupt pseudo packet?
  10903.      jrst [    move t2, pktnum    ; Yes, NAK that "packet".
  10904.         call nak    ;
  10905.          jrst xxwt2    ; Go round again.
  10906.         jrst xxwt2 ]    ; (no matter what)
  10907.     cail t1, "A"        ;[150] Packet type in range?
  10908.      caile t1, "Z"        ;[150]
  10909.      kermsg <Packet type out of range>,xxwait ;[150] No.
  10910.  
  10911. ; Got a real command.  Restore the normal timeout interval and do the command.
  10912.  
  10913.     movem t2, pktnum    ; Save packet number.
  10914.     push p, t1        ; We can't use any normal AC's here...
  10915.     move t1, otimou        ; Put normal timeout back.
  10916.     movem t1, stimou
  10917.     pop p, t1
  10918.     jrst @<xxcmd-<"A">>(t1)    ;[150] Go do the indicated command.
  10919.  
  10920. ;[150] Server command dispatch table and error message routines.
  10921.  
  10922.  
  10923. xxcmd:    xxinv            ; A - Attributes, shouldn't come now
  10924.     xxinv            ; B - EOT, shouldn't come now
  10925.     xhost            ; C - Host Command
  10926.     xxinv            ; D - Data, shouldn't come now
  10927.     xxwait            ; E - Error, just ignore
  10928.     xxinv            ; F - File header, shouldn't come now
  10929.     xgen            ; G - Generic Command
  10930.     xxunk            ; H - Undefined
  10931.     xinfo            ; I - Info Packet
  10932.     xxunk            ; J - Undefined
  10933.     xxunk            ; K - Undefined
  10934.     xxunk            ; L - Undefined
  10935.     xxunk            ; M - Undefined
  10936.     xxwait            ; N - NAK, ignore
  10937.     xxunk            ; O - Undefined
  10938.     xxunk            ; P - Undefined
  10939.     xxunk            ; Q - Undefined
  10940.     xrecv            ; R - Receive (GET), server sends
  10941.     xsend            ; S - Send, server receives
  10942.     xxwait            ; T - (Already handled specially above)
  10943.     xxunk            ; U - Undefined
  10944.     xxunk            ; V - Undefined
  10945.     xxunk            ; W - Undefined
  10946.     xxinv            ; X - Text Header, shouldn't come now
  10947.     xxwait            ; Y - ACK, ignore
  10948.     xxinv            ; Z - EOF, shouldn't come now
  10949.     0            ; (superstition)
  10950.  
  10951. ; Routine to issue informative error messages.
  10952.  
  10953. xxunk:    move t4, [point 7, xxumsg] ; Get "unknown command" message.
  10954.     movei t3, xxulen    ; And its length
  10955.     jrst xxmsg
  10956.     
  10957. xxinv:    move t4, [point 7, xxbmsg] ; Get "invalid use of..." message.
  10958.     movei t3, xxblen    ; And its lentgh.
  10959.  
  10960. xxmsg:    push p, t4        ; Save msg pointer.
  10961.     ibp t4            ; Point past opening quote.
  10962.     idpb t1, t4        ; Deposit the packet type.
  10963.     movei t1, "E"        ; Send an Error packet.
  10964.     move t2, pktnum        ; This is the packet number.
  10965.     pop p, t4        ; Get original pointer back.
  10966.     call spack        ; Send the error packet.
  10967.      nop
  10968.     jrst xxwait        ; Go back to command wait.
  10969.  
  10970.     subttl Server commands.
  10971.  
  10972. ; Server SEND command (i.e. send to me, I'm the server, I receive the files.)
  10973. ;
  10974. ; We've just received a Send-Init.
  10975. ;
  10976. xsend:    setzm numtry        ; Packet retry counter.
  10977.     movem t2, pktnum    ; Synchronize packet numbers.
  10978.     call spar        ; Get the Send-Init parameters.
  10979.     move t4, [point 8, data] ;[50] Now send back our own,
  10980.     call rpar        ; which we put in the data field of our ACK.
  10981.     movei t1, "Y"        ; Set up the ACK.
  10982.     move t2, pktnum        ; Packet number.
  10983.     call spack        ; Send the packet.
  10984.      jrst xxwait        ;* Give up if we can't.(?)
  10985.     call rrinit        ;[126] Set things up for receiving.
  10986.     movei state, "F"    ; Set the state to file send.
  10987.     call $recvs        ;[42] Go look like we're receiving.
  10988.      nop            ;
  10989.     jrst xxwait        ; Get another command when done.
  10990.  
  10991.  
  10992.  
  10993. ; Server RECEIVE (or GET) command -- Server sends files.
  10994. ;
  10995. ; We've just received a Receive-Init packet, containing a filename.
  10996. ; (Or a remote TYPE command).  T1-T4 contain packet parameters returned
  10997. ; by RPACK.
  10998. ;
  10999. xrecv:    move t1, t4        ;[141] Pointer to encoded filespec.
  11000.     move t2, t3        ;[141] Number of characters.
  11001.     call decodf        ;[141] Decode it.
  11002.      kermsg <Can't decode filename>, xxwait ;[141] Can't? Give message.
  11003.     move t2, t1        ;[141] Decoded OK, point to decoded filespec.
  11004.  
  11005. ; Entry point when filespec already decoded.
  11006.  
  11007. xrecv2:    movx t1, gj%sht!gj%old!gj%ifg ; Old file and allow wildcarding.
  11008.     GTJFN%            ; Get a JFN.
  11009.      %jsker (,xxwait)    ; Can't, send error packet and loop.
  11010.     movem t1, ndxjfn    ;[111] Got JFN, save wildcard bits here.
  11011.     hrrzm t1, nxtjfn    ;[111] Initialize file lookahead.
  11012.     call gtnfil        ;[111] Get next (in this case, first) file.
  11013.      nop            ;[111] Could never fail, right?
  11014.     call $sends        ; Go send the file(s).
  11015.      nop            ;  (in case it skips for some reason...)
  11016.     jrst xxwait        ; Go back & get another command.
  11017.  
  11018.  
  11019. ; HOST command.
  11020.  
  11021. xhost:    kermsg <Host commands not implemented>, xxwait
  11022.  
  11023. ;[150] Server GENERIC command.  Get the subcommand and execute it.
  11024.  
  11025.  
  11026. xgen:    ildb t1, t4        ; Get the first character of the data field.
  11027.     cail t1, "A"        ; Validate.
  11028.      caile t1, "Z"
  11029.      kermsg <Generic command out of range>, xxwait ; Bad.
  11030.     sos t3            ; Command in range, account for it.
  11031.     jrst @<xxgcmd-<"A">>(t1) ; Dispatch to it.
  11032.  
  11033.  
  11034. ;[150] Server generic command dispatch table.
  11035.  
  11036. xxgcmd:    xgundf            ; A - Undefined
  11037.     xgundf            ; B - Undefined
  11038.     xgcwd            ; C - CWD
  11039.     xgdir            ; D - Directory
  11040.     xgdel            ; E - Erase (delete)
  11041.     xgfin            ; F - Finish
  11042.     xgundf            ; G - Undefined
  11043.     xghelp            ; H - Help
  11044.     xgnyi            ; I - Login (not yet implemented)
  11045.     xgnyi            ; J - Journal control (nyi)
  11046.     xgnyi            ; K - Copy (nyi)
  11047.     xglogo            ; L - Logout, Bye
  11048.     xgnyi            ; M - Short message
  11049.     xgundf            ; N - Undef
  11050.     xgundf            ; O - Undef
  11051.     xgnyi            ; P - Program invocation (nyi)
  11052.     xgnyi            ; Q - Server status query (nyi)
  11053.     xgnyi            ; R - Rename (nyi)
  11054.     xgundf            ; S - Undef
  11055.     xgtype            ; T - Type
  11056.     xgdisk            ; U - Disk Usage
  11057.     xgnyi            ; V - Variable Set/Query
  11058.     xgnyi            ; W - Who (Finger)
  11059.     xgundf            ; X - Undef
  11060.     xgundf            ; Y - Undef
  11061.     xgundf            ; Z - Undef
  11062.     0
  11063.  
  11064. xgundf:    move t4, [point 7, xxgums] ; Issue message for undefined command.
  11065.     movei t3, xxguln
  11066.     jrst xxmsg
  11067.  
  11068. xgnyi:    move t4, [point 7, xxgnms] ; Issue msg for unimplemented command.
  11069.     movei t3, xxgnln
  11070.     jrst xxmsg
  11071.  
  11072. ; Generic commands...
  11073.  
  11074.  
  11075. ; FINISH.  Shut down the server, but don't log out.
  11076.  
  11077. xgfin:    movei t1, "Y"        ;  Acknowledge packet.
  11078.     setzb t3, t4        ;  No data.
  11079.     call spack        ;  Send the packet.
  11080.      nop            ;[56]
  11081.     move t1, netjfn        ;[158] Wait for the ACK to get there.
  11082.     DOBE            ;[158] ...
  11083.      erjmp .+1        ;[158] ...
  11084.     setom f$exit        ;[137] Say we want to go back to command level.
  11085.  
  11086. xgfin2:    call rrslin        ;[121] Put line back in interactive state.
  11087.     move t1, odelay        ;[27] Restore normal delay
  11088.     movem t1, delay        ;[27]
  11089.     move t1, otimou        ;[27] and timout interval
  11090.     movem t1, stimou    ;[27]
  11091.     setzm srvflg        ;[27] and reset the server flag
  11092.     skipe t1, logjfn    ;[38] If we were logging,
  11093.      CLOSF            ;[38]  close the log.
  11094.      erjmp .+1        ;[38]  (Ignore any errors here.)
  11095.     setzm logjfn        ;[38]
  11096.     ret            ; Done
  11097.  
  11098. ; LOGOUT (or BYE) -- Shut down the server and log out.
  11099.  
  11100. xglogo:    movei t1, "Y"        ; Acknowledge the command.
  11101.     setzb t3, t4        ; No data.
  11102.     call spack        ; Send the packet.
  11103.      nop            ;
  11104.     move t1, netjfn        ;[158] Wait for the packet to arrive.
  11105.     DOBE            ;[158]...
  11106.      erjmp .+1        ;[158]...
  11107.     call rrslin        ; Restore the line for interactive use.
  11108.     move t1, odelay        ; Restore normal delay
  11109.     movem t1, delay        ;
  11110.     move t1, otimou        ; and timout interval
  11111.     movem t1, stimou    ;
  11112.     setzm srvflg        ; and reset the server flag.
  11113.     wtlog <BYE Received>    ;[126] Log the BYE.
  11114.     call clenup        ;[126] Close all logs.
  11115.     setom f$exit        ; Just in case we can't logout, set exit flag.
  11116.     seto t1,        ; -1 = Myself.
  11117.     LGOUT%            ; Log me out.
  11118.     %jsker (,r)        ; If this fails, print msg & go back.
  11119.  
  11120. ; Command to TYPE a file.  Just like sending a file, except must send "X"
  11121. ; packet instead of file header.
  11122.  
  11123. xgtype:    call getarg        ; Get the argument.
  11124.     setom xflg        ; Send file with X header.
  11125.     move t2, t4        ;[141] Point to filespec.
  11126.     jrst xrecv2        ;[141] Do like when we get an R packet.
  11127.  
  11128. ;[58] Init-Info mechanism added as edit 58.
  11129. ;
  11130. ; Get an "I" parameters packet from the user, record the parameters, and send
  11131. ; our own back in return.  This exchange is optional, but should take place
  11132. ; before any server/user transaction except file transfer, where it is required
  11133. ; and always takes place via the Send-Init mechanism.
  11134. ;
  11135. xinfo:    movem t2, pktnum    ; Set the parameters we just got.
  11136.     call spar
  11137.     setzm numtry
  11138.     move t4, [point 8, data] ; Respond with ours.
  11139.     call rpar
  11140.     movei t1, "Y"
  11141.     move t2, pktnum
  11142.     call spack
  11143.      nop            ; If they don't get it, they'll ask again...
  11144.     jrst xxwait
  11145.  
  11146. ; GTSCH -- Get String Character
  11147. ;
  11148. ; Alternate GETCH routine for getting a character from an ASCIZ string in
  11149. ; memory.  Uses global STRPTR for input string.
  11150. ;
  11151. ; Returns:
  11152. ;   +1 if no more characters left in string.
  11153. ;   +2 always, with NEXT containing next character, -1 if no more.
  11154. ;
  11155. gtsch:    ildb t1, strptr        ; Get next character.
  11156.     jumpe t1, gtschz    ; If zero, must be done.
  11157.  
  11158. ; Return with character like GETCH.
  11159.  
  11160. gtschx:    movem t1, next        ; Put result in NEXT, as GETCH does.
  11161.     retskp            ; Done.
  11162.  
  11163. ; "EOF" return, like GETCH
  11164.  
  11165. gtschz:    setz t1,
  11166.     setom next
  11167.     ret
  11168.  
  11169. ; PUTSCH
  11170. ;
  11171. ; Alternate PUTCH routine.  Just writes the character to a string in memory.
  11172. ; Call with t2/ character to write.
  11173. ;
  11174. putsch:    idpb t2, strptr        ; Here's the alternate PUTCH routine.
  11175.     retskp            ; It always succeeds.
  11176.  
  11177.  
  11178. ; PUTTCH
  11179. ;
  11180. ; Another alternate PUTCH routine.  Writes the character to the terminal.
  11181. ; Call like PUTCH and PUTSCH.
  11182. ;
  11183. puttch:    skipe local        ;[177] But only if in remote mode.
  11184.      retskp            ;[177]  ...
  11185.     push p, t1
  11186.     movei t1, .priou
  11187.     BOUT    
  11188.      erjmp .+1
  11189.     pop p, t1
  11190.     retskp
  11191.  
  11192.  
  11193. ; GETARG
  11194. ;
  11195. ; Decode server command packet, set up pointers, get first argument.
  11196. ;
  11197. ; Return +1 with:
  11198. ;  t3/ Length of first argument
  11199. ;  t4/ pointer to first argument
  11200. ;
  11201. getarg:    movei t1, putsch    ; Address of alternate PUTCH routine.
  11202.     movem t1, dest
  11203.     setzm strbuf        ; Clear decoding area.
  11204.     move t1, [strbuf,,strbuf+1]
  11205.     blt t1, strbz
  11206.     move t1, [point 7, strbuf] ; Where to put the decoded string.
  11207.     movem t1, strptr
  11208.     move t1, t4        ; Pointer to data to decode.
  11209.     move t2, t3        ; Length.
  11210.     call putbuf        ; Go decode the packet.
  11211.      jrst [    setzm dest
  11212.         kermsg <Can't decode server command>, xxwait ]
  11213.     setzm dest        ; Put PUTCH back to normal.
  11214.     move t4, [point 7, strbuf] ; Point to decoded string.
  11215.     ildb t3, t4        ; Get CHAR(length) of directory string.
  11216.     caige t3, 40        ;[128] If null, no need to convert.
  11217.      movei t3, 40        ;[128] This also catches funny cases.
  11218.     subi t3, 40        ; UNCHAR of that to make a number.
  11219.     ret
  11220.  
  11221. ;[107] CWD server command (Connect to directory in DEC-20 parlance).
  11222. ;
  11223. ; Changes Working Directory, sends new directory name back in ACK, or else
  11224. ; error packet if there's a problem.
  11225. ;
  11226. ; Arrive here with t4 containing pointer to argument string of form
  11227. ;  <length><directory><length><password>
  11228. ; where <length> is a single character (offset by CHAR),
  11229. ; and t3 containing the length of the string.
  11230. ;
  11231. xgcwd:    call getarg        ; Get the first argument.
  11232.     jumpg t3, xgcwd3    ; If positive, go handle string.
  11233.     jumpe t3, xgcwd5    ; If null, go connect back to own directory.
  11234.  
  11235.     kermsg <Bad length field in CWD packet>,xxwait ; Negative length???
  11236.  
  11237. ; Set up argument block for ACCES
  11238.  
  11239. xgcwd3:    move q1, t4        ; Byte pointer to directory string.
  11240.     adjbp t3, t4        ; Now point to password.
  11241.     ildb t4, t3        ; Get its length.
  11242.     move q2, t3        ; Put pointer in ACCES arg block.
  11243.     subi t4, 40        ; UNCHAR to make it a number.
  11244.     skipge t4        ; Normal kind of number?
  11245.      setz t4,        ;  No, must have fallen off end, so no pswd.
  11246.     setz t2,        ; Zero the length to make directory asciz.
  11247.     dpb t2, t3        ;  ...
  11248.     adjbp t4, t3        ; Make sure password is asciz.
  11249.     idpb t2, t4
  11250.  
  11251. ; Access the directory. ** Maybe should also mount structure if necessary?
  11252.  
  11253. xgcwd4:    move t1, [ac%con!<3>]    ; Function is Connect, arg block has 2 words.
  11254.     movei t2, q1        ; Address of argument block.
  11255.     seto q3,        ; Own job.
  11256.     ACCES
  11257.      %jsker (,xxwait)    ; Send any error message in error packet.
  11258.     jrst xgcwdz        ; Done connecting, go send ACK.
  11259.  
  11260. ;...XGCWD, cont'd
  11261.  
  11262.  
  11263. ; Come here to connect to own directory.
  11264.  
  11265. xgcwd5:    seto t1,        ; This job.
  11266.     hrroi t2, q1        ; Want one word, put it in q1.
  11267.     movei t3, .jilno    ; Logged-in directory number.
  11268.     GETJI
  11269.      %jsker (,xxwait)
  11270.     move t1, [ac%con!<3>]    ; Function is connect.
  11271.     setz q2,        ; No password needed
  11272.     seto q3,        ; Own job.
  11273.     movei t2, q1        ; Address of arg block.
  11274.     ACCES            ; Connect to own directory.
  11275.      %jsker (,xxwait)
  11276.     ;...
  11277.  
  11278. ;...XGCWD, cont'd
  11279.  
  11280.  
  11281. ; Done, send back ACK with directory string in it.
  11282.  
  11283. xgcwdz:    GJINF
  11284.     move t1, [point 7, strbuf]
  11285.     movem t1, strptr
  11286.     DIRST
  11287.      %jsker (,xxwait)
  11288.  
  11289.     movei t1, gtsch        ; Indicate routine to be used for getting
  11290.     movem t1, source    ;  characters.
  11291.     setom next        ; Set initial condition.
  11292.     move t1, maxdat        ; Get a buffer full of data.
  11293.     call getbuf        ; ...
  11294.      jumpn t1, xxwait    ;
  11295.     setzm source        ; Put GETCH back to normal.
  11296.     move t3, t1        ; Length
  11297.     movei t1, "Y"        ; Y for Yes (ACK)
  11298.     setz t2,        ; Packet number 0.
  11299.     move t4, [point 8, data] ; Point to string built by getbuf.
  11300.     call spack        ; Send the ACK.
  11301.      nop            ;  Nothing much we can do here...
  11302.     jrst xxwait        ; Done.
  11303.  
  11304. ;[56] Disk USAGE server query added in edit 56.
  11305. ;
  11306. ; Assumes reply will fit in data field of ACK packet; does not use
  11307. ; text header ("X") protocol.  Sends as much of reply as will fit.
  11308. ;
  11309. xgdisk:    seto t1,        ; Get disk usage of connected directory.
  11310.     GTDAL%
  11311.      %jsker <Can't get disk usage>,r
  11312.     dmove q1, t1        ; Save the numbers in q1,q2.
  11313.  
  11314.     move t1, [point 7, strbuf] ;[103] String pointer to data field.
  11315.     movem t1, strptr    ;[103]
  11316.     hrroi t2, [asciz/Quota: /]
  11317.     setzb t3, t4        ; Source string is null-terminated.
  11318.     SOUT%
  11319.      erjmp xgdis2
  11320.  
  11321.     move t2, q1        ; Quota, or "+Inf"
  11322.     cail t2, [^d100000000]
  11323.      jrst [    hrroi t2, [asciz/+Inf/]
  11324.         SOUT
  11325.         jrst xgdsk2 ]
  11326.  
  11327.     movei t3, ^d10        ;  in decimal
  11328.     NOUT%
  11329.      erjmp xgdis2
  11330.  
  11331. xgdsk2:    hrroi t2, [asciz/, used: /]
  11332.     setzb t3, t4
  11333.     SOUT%
  11334.      erjmp xgdis2
  11335.     move t2, q2        ; Pages used,
  11336.     movei t3, ^d10        ;  in decimal
  11337.     NOUT%
  11338.      erjmp xgdis2
  11339.     hrroi t2, [asciz/ (pages)/] ; Specify units
  11340.     setzb t3, t4
  11341.     SOUT%
  11342.      erjmp xgdis2
  11343.  
  11344. xgdis2:    move t2, strptr        ;[103] Check length
  11345.     exch t1, t2
  11346.     call subbp
  11347.      %jsker <subbp foulup>,r
  11348.     idpb t4, t2        ; Done constructing string, make it asciz
  11349.     move q1, spsiz        ; Is the string bigger than max size to send?
  11350.     subi q1, 5
  11351.     caig q1, (t3)        ; (it should always fit).
  11352.      move t3, q1        ;  Yes, so cut it off at the limit.
  11353.     ;..
  11354.  
  11355. ;...XGDISK, cont'd
  11356.  
  11357.  
  11358. ;[103] Begin Change: Use standard packet filling technique to send this.
  11359.  
  11360.     movei t1, gtsch        ; Indicate routine to be used for getting
  11361.     movem t1, source    ;  characters.
  11362.     setom next        ; Set initial condition.
  11363.     move t1, maxdat        ; Get a buffer full of data.
  11364.     call getbuf        ; ...
  11365.      jumpn t1, xxwait    ;
  11366.     move t3, t1        ; Set up length.
  11367.     setzm source        ; Put GETCH back to normal.
  11368.  
  11369. ;[103] End Change.   Now send the packet.
  11370.  
  11371. xgdisz:    movei t1, "Y"        ; Formulate the ACK
  11372.     setz t2,        ; (Packet number should be 0, right?)
  11373.     move t4, [point 8, data] ; The data itself
  11374.     call spack        ; Send it off.
  11375.      nop            ;* What if it fails?
  11376.     jrst xxwait
  11377.  
  11378. ;[120] HELP server command.
  11379.  
  11380. srvhlp:    asciz /
  11381. The DECSYSTEM-20 KERMIT server is capable of the following:
  11382.  
  11383.                                     Command you would normally type to your
  11384.   Server Function:                  local KERMIT to invoke the server function:
  11385.  
  11386.   Receive a file or file group      SEND filespec
  11387.   Send a file or file group         GET filespec
  11388.   Logout                            BYE
  11389.   Exit to TOPS-20                   FINISH
  11390.   Delete a file or file group       REMOTE DELETE filespec
  11391.   List file(s) at the terminal      REMOTE TYPE filespec
  11392.   Provide a directory listing       REMOTE DIRECTORY filespec
  11393.   Change working directory          REMOTE CWD directory [password]
  11394.   Report disk usage                 REMOTE SPACE
  11395.   Send this message                 REMOTE HELP
  11396. /
  11397. srvhz:    0
  11398.     0            ; This padding seems to be necessary...
  11399.  
  11400. xghelp:    move t1, [point 7, srvhlp] ; Point to help text.
  11401.     movem t1, strptr    ; Put pointer here, where
  11402.     movei t1, gtsch        ;  routine for getting chars from a string
  11403.     movem t1, source    ;  can find it.
  11404.     setom next        ; Init char lookahead
  11405.     setom xflg        ; Send with X rather than F header.
  11406.     call $sends        ; Go send the text like a file
  11407.      nop
  11408.     setzm source        ;[121] Put send source back to normal.
  11409.     jrst xxwait
  11410.  
  11411. ;[116] DIRECTORY server command.
  11412.  
  11413. ; DIRCH
  11414. ;
  11415. ; Alternate GETCH routine for getting characters from a directory listing
  11416. ; in a memory buffer, and for refilling the buffer when it gets empty.
  11417. ;
  11418. dirch:    ildb t1, getptr        ; Get character.
  11419.     skipe t1        ; Null?
  11420.      jrst dirchx        ;  No, return the character.
  11421.  
  11422. ; No characters in buffer, try to refill.
  11423.  
  11424. dirch2:    call dmpbuf        ; If so, reset the buffer pointers, etc.
  11425.     call dirlst        ; And try to fill the listing buffer again.
  11426.     jumpe t1, dirchz    ; No more, done.
  11427.     move t1, [point 7, srvbuf] ; Get new listing buffer pointer.
  11428.     movem t1, getptr    ; Save it for getting characters.
  11429.     ildb t1, getptr        ; Get first character of new buffer.
  11430.     jumpe t1, dirchz    ; This shouldn't happen...
  11431.  
  11432. ; Return with character like GETCH.
  11433.  
  11434. dirchx:    movem t1, next
  11435.     retskp
  11436.  
  11437. ; "EOF" return, like GETCH.
  11438.  
  11439. dirchz:    setz t1,
  11440.     setom next
  11441.     ret
  11442.  
  11443. ; XGDIR - Server provides directory listing.
  11444.  
  11445. xgdir:    call getarg        ; Get the first (& only) argument
  11446.     jumpg t3, xgdir2    ; Got something, go do it.
  11447.     jumpe t3, [        ; Got nothing, do default directory.
  11448.         move t4, [point 7, [asciz/*.*.*/]] ;[174] (not hrroi!)
  11449.         jrst xgdir2 ]
  11450.  
  11451.     kermsg <Bad length field in DIRECTORY command>,xxwait ; Got junk.
  11452.  
  11453. ; Get JFN on the string we got, supply normal defaults like Exec does.
  11454.  
  11455. xgdir2:    move t2, t4        ; Point to filespec
  11456.     adjbp t3, t4        ; Make it asciz
  11457.     setz t4,
  11458.     idpb t4, t3
  11459.     movei t1, sdirbk    ; JFN block containing flags & defaults.
  11460.     GTJFN            ; Do long form GTJFN.
  11461.      %jsker (,xxwait)    ; Send error packet if we can't.
  11462.     move t2, t1        ; Construct heading in string buffer.
  11463.     setzm ffunc        ; Function is "directory".
  11464.     call dirhdr
  11465.     move t1, [point 7, srvbuf] ; Point to beginning of text buffer.
  11466.     movem t1, getptr    ; This is where we'll get characters from.
  11467.     movei t1, dirch        ; And this routine will do the getting.
  11468.     movem t1, source    ;  ...
  11469.     setom next        ; Initialize character lookahead.
  11470.     setom xflg        ; This produces some desired effects...
  11471.     call $sends        ; Go send the listing like it's a file.
  11472.      nop            ;  Ignore any skipping...
  11473.     jrst xxwait
  11474.  
  11475. sdirbk:    gj%old!gj%ifg!.gjall    ; Flags,,All generations.
  11476.     .nulio,,.nulio        ; No i/o.
  11477.     repeat <2>,<0>        ; Default device and directory.
  11478.     repeat <2>,<-1,,[asciz/*/]> ; Default name is "*.*"
  11479.     repeat <4>,<0>        ; Nothing special for the rest.
  11480.  
  11481.  
  11482. ;[118] XGDEL - Server provides file deletion.
  11483.  
  11484. xgdel:    call getarg        ; Get the first (& only) argument
  11485.     jumpg t3, xgdel2    ; Got something, go do it.
  11486.  
  11487.     kermsg <No file specified for deletion>,xxwait
  11488.  
  11489. ; Get JFN on the string we got, supply normal defaults like Exec does.
  11490.  
  11491. xgdel2:    move t2, t4        ; Point to filespec
  11492.     adjbp t3, t4        ; Make it asciz
  11493.     setz t4,
  11494.     idpb t4, t3
  11495.     movei t1, sdelbk    ; JFN block containing flags & defaults.
  11496.     GTJFN            ; Do long form GTJFN.
  11497.      %jsker (,xxwait)    ; Send error packet if we can't.
  11498.     move t2, t1        ; Construct heading in string buffer.
  11499.     movei t1, delfil    ; Routine for deleting a file.
  11500.     movem t1, ffunc        ; Make it the file function.
  11501.     call dirhdr        ; Start things off.
  11502.     move t1, [point 7, srvbuf] ; Point to beginning of text buffer.
  11503.     movem t1, getptr    ; This is where we'll get characters from.
  11504.     movei t1, dirch        ; And this routine will do the getting.
  11505.     movem t1, source    ;  ...
  11506.     setom next        ; Initialize character lookahead.
  11507.     setom xflg        ; This produces some desired effects...
  11508.     call $sends        ; Go send the listing like it's a file.
  11509.      nop            ;  Ignore any skipping...
  11510.     jrst xxwait
  11511.  
  11512. sdelbk:    gj%old!gj%ifg!.gjall    ; Flags,,All generations.
  11513.     .nulio,,.nulio        ; No i/o.
  11514.     repeat <^d8>,<0>    ; No other defaults.
  11515.  
  11516.     subttl    Timer Routines
  11517.  
  11518. ; Set a timer.  Call with t1/ Address of where to go upon timout.
  11519.  
  11520. timeit:    skipg stimou        ;[43] Doing timeouts?
  11521.      ret            ;[43]  No, skip this.
  11522.     pop p, t2        ; Get the return address off the stack.
  11523.     movem p, intstk        ; Save the stack.
  11524.     push p, t2        ; Restore stack.
  11525.     hrr t2, t1        ; Make interrupt PC point to time out addr.
  11526.     movem t2, intpc        ; Save the PC.
  11527.     movei t1, .fhslf
  11528.     movx t2, 1b0        ; Turn on channel 0.
  11529.     AIC
  11530.      %jserr <TIMEIT - Can't turn on timer channel>, <.+1>
  11531.  
  11532. ;[132] Remove any pending timer requests.
  11533.  
  11534. timei2:    move t1, [.fhslf,,.timal] ; Remove all pending timer requests.
  11535.     setzb t2, t3
  11536.     TIMER
  11537.      aos timerx        ; If we get a timer error, just count it.
  11538.  
  11539. timei3:    setz t1,        ;[130] Get 1-minute load average.
  11540.     call ldav        ;[130]
  11541.     move t2, stimou        ;[130] Minimum acceptable.
  11542.     call adjtim        ;[128] Adjust based on load average.
  11543.     move t1, [.fhslf,,.timel] ; Our process and time from now.
  11544.     movem t2, curtim    ;[131] Remember this for reporting.
  11545.     imuli t2, ^d1000    ; Make time into milliseconds.
  11546.     setz t3,        ; Channel zero.
  11547.     TIMER
  11548.      aos timerx        ; If we get an error, count it.
  11549.     ret
  11550.  
  11551. ; TIMOFF -- Turn off timer.
  11552.  
  11553. timoff:    skipg stimou        ;[43] Doing timeouts?
  11554.      ret            ;[43]  No, skip this.
  11555.     saveac <t1,t2>        ; Yes, save these ACs.
  11556.     move t1, [.fhslf,,.timbf] ; Turn off timer interrupts for this fork.
  11557.     hrloi t2, 377777    ; For all times before this (far in future).
  11558.     TIMER            ;
  11559.      aos timerx        ;  Count any error.
  11560.     movx t1, .fhslf        ; Deactivate the channel.
  11561.     movx t2, 1b0
  11562.     DIC
  11563.     ret
  11564.  
  11565. ; TMTRAP -- Timer interrupt handler.
  11566.  
  11567. tmtrap:    push p, t1        ; Get a work AC.
  11568.     move t1, intpc        ; Get the PC we want.
  11569.     hrli t1, (1b5)        ;[132] Set user mode to escape from any jsys.
  11570.     movem t1, pc1        ; Restore as if we came from there.
  11571.     pop p, t1
  11572.     move p, intstk        ; Pop any junk off the stack.
  11573.     aos ntimou        ; Count the timeout.
  11574.     DEBRK
  11575.  
  11576. ;[128] Make this a separate routine.
  11577. ;
  11578. ; ADJTIM -- Adjust timeout interval based on load average (ldav).
  11579. ;
  11580. ; Calculate Timeout = mintim + (ldav-MINLOD)*((MAXTIM-mintim)/MAXLOD)
  11581. ; If the load is low, this gives the minimum acceptable timeout, mintim.
  11582. ; If the load is very high, this gives the maximum timeout, MAXTIM.
  11583. ; In between, the timeout goes up linearly with given load average.
  11584. ; MINLOD, MAXLOD, and MAXTIM are defined as global symbols.
  11585. ;
  11586. ; Call with:
  11587. ;  t1/ 1, 5, or 15 minute ldav, floating point number as returned by GETAB.
  11588. ;  t2/ minimum acceptable timeout (mintim), seconds (integer).
  11589. ; Returns +1 always, with
  11590. ;  t2/ adjusted timeout interval, in seconds (integer).
  11591. ;
  11592. adjtim:    stkvar <mintim>        ; Local storage for second argument.
  11593.     movem t2, mintim    ; Save the minimum for later.
  11594.     fsb t1, [minlod]    ; Adjust load by subtracting the minimum.
  11595.     skipg t1        ; If negative, make it zero.
  11596.      setz t1,
  11597.     caml t1, [maxlod]    ; If too big, cut it off.
  11598.      move t1, [maxlod]
  11599.     movei t2, maxtim    ; Maximum timeout, seconds.
  11600.     sub t2, mintim        ; Less specified timeout interval.
  11601.     fltr t2, t2        ; Floated.
  11602.     fdv t2, [maxlod]    ; Divided by maximum load.
  11603.     fmp t1, t2        ; Multiplied by actual (adjusted) load.
  11604.     fixr t2, t1        ; Fixed & rounded.
  11605.     add t2, mintim        ; Add in requested minimum timeout.
  11606.     ret            ; Return with result in t2.
  11607.  
  11608. ;[130] This routine added as part of edit 130.
  11609. ;
  11610. ; LDAV -- Get the current load average.  Takes class scheduling into account.
  11611. ;
  11612. ; Call with
  11613. ;  t1/ 0 for 1-min, 1 for 5-min, 2 for 15-min ldav.
  11614. ;  SKDFLG/ -1 for class scheduler running, 0 for no class scheduler.
  11615. ;  CLASS/  This job's scheduler class.
  11616. ;
  11617. ; Returns +1 always, with requested load average in t1.
  11618. ;
  11619. ldav:    saveac <q1>        ; Save this.
  11620.     cail t1, 0        ; Argument in range?
  11621.      caile t1, 2
  11622.      setz t1,        ; Force to 0.
  11623.     move q1, t1        ; Save argument here.
  11624.     skipe skdflg        ; Class scheduler on?
  11625.      jrst ldav3        ;  Yes, go do it the special way.
  11626.  
  11627. ; Class scheduler off, use GETAB for system-wide load average.
  11628.  
  11629. ldav2:    hrlz t1, q1        ; Desired load average.
  11630.     add t1, [14,,.systa]    ; Scheduler off,
  11631.     GETAB            ;  use load avg from SYSTAT monitor table.
  11632.      erjmp ldavx
  11633.     ret
  11634.  
  11635. ; Class scheduler on, get load avg for this class from SKED%.
  11636.  
  11637. ldav3:    skipge t1, class    ; This job's scheduler class.
  11638.      jrst ldav2        ; Unless there was some error getting it...
  11639.  
  11640.     movem t1, skdblk+.sacls    ; Put it in the SKED% arg block.
  11641.     movei t1, 10        ; Arg block length
  11642.     movem t1, skdblk+.sacnt
  11643.     movei t1, .skrcs    ; Function is read class parameters.
  11644.     movei t2, skdblk    ;  into this arg block.
  11645.     SKED%
  11646.      %jserr (,ldavx)
  11647.     move t1, skdblk+.sa1ml(q1) ; Return the desired value.
  11648.     ret
  11649.  
  11650. ldavx:    move t1, [minlod]    ; Return this in case of any error.
  11651.     ret
  11652.  
  11653.     subttl    Interrupt Routines
  11654.  
  11655.  
  11656. ; Initialize the Priority Interrupt system.
  11657.  
  11658. pinit:    movei t1, .fhslf    ; This fork.
  11659.     move t2, [levtab,,chntab] ; Say where our tables are.
  11660.     SIR
  11661.     EIR            ; Enable the interrupt system.
  11662.     ret
  11663.  
  11664.  
  11665. ; Turn Control-C trap on.  Sets things up so that ^C will return control
  11666. ; to the instruction FOLLOWING the the call to this routine, with the
  11667. ; stack fixed up appropriately, e.g.
  11668. ;
  11669. ;    call ccon        ; Turn on ^C trap
  11670. ;     jrst foo        ; What to do if ^C is typed.
  11671. ;    move x, y        ; Execute this after the call to CCON.
  11672. ;
  11673. ; Returns +2 always.
  11674. ;    
  11675. $ccn==2                ; Number of ^C's to get out of ^C trap.
  11676.  
  11677. ccon:    movei t1, .fhslf    ; Read current process capabilities.
  11678.     RPCAP%
  11679.  
  11680. ;[10] Try to enable ^C capabilities unless under batch.
  11681.  
  11682.     tloe t3, (sc%ctc)    ; Do we have Control-C capas?
  11683.      jrst ccon2        ;  Yes, go on.
  11684.     EPCAP%            ; Nope, try to get them.
  11685.     RPCAP%            ; Did we?
  11686.     skipn jobtab+.jibat    ; Under batch?
  11687.      tloe t3, (sc%ctc)    ; Check the ^C bit.
  11688.      jrst ccon2        ;  If under batch
  11689.     ermsg <Can't enable ^C capability>,r ; Not under batch, give up.
  11690.  
  11691. ccon2:    movem t3, capas        ; Save them.
  11692.     movei t1, $ccn         ; Initialize ^C count to this.
  11693.     movem t1, ccn
  11694.     movem p, psave        ;[27] Save stack pointer.
  11695.     move t1, (p)        ;[27] And what it points to...
  11696.     movem t1, psave2    ;[27]
  11697.     movx t1, .fhslf        ; Now, for this fork,
  11698.     movx t2, 1b1        ;  activate channel 1
  11699.     AIC            ;  ...
  11700.      erjmp .+1        ;[10]
  11701.     move t1, [.ticcc,,1]    ;  for ^C.
  11702.     ATI            ;
  11703.      erjmp .+1        ;[10]
  11704.     retskp
  11705.  
  11706. ; Turn Control-C trap off.
  11707.  
  11708. ccoff:    skipe srvflg        ;[81] Being a server?
  11709.      ret            ;[81] Yes, so don't turn off the ^C trap.
  11710.  
  11711. ; Entry point for REALLY turning it off, even if server.
  11712.  
  11713. ccoff2:    saveac <t1,t2,t3>    ; Save these.
  11714.     setzm ccn        ; Put ^C count back to 0.
  11715.     movx t1, .fhslf        ; This fork.
  11716.     movx t2, 1b1        ; Deactivate channel 1.
  11717.     DIC
  11718.     RTIW            ; Fix up the interrupt mask
  11719.     tlz t2, (1b3)        ;  for ^C... (^C = ASCII 3 = bit 3)
  11720.     STIW            ;  ...
  11721.     move t3, capas        ; Restore capabilities.
  11722.     EPCAP
  11723.      erjmp .+1
  11724.     ret
  11725.  
  11726. ;[59] ^A, ^X, and ^Z interrupt control added as part of edit 59.
  11727.  
  11728. caxzon:    Remark - Turn on ^A, ^X, and ^Z interrupts.
  11729.  
  11730.     setzm cxseen        ; Say we haven't seen a ^X yet,
  11731.     setzm czseen        ; nor a ^Z.
  11732.     setzm caseen        ;  ...
  11733.     skipn local        ; Only do this if local!
  11734.      ret
  11735.     movei t1, .fhslf    ; This fork.
  11736.     movx t2, 1b<cachan>!1b<cxchan>!1b<czchan> ; Turn on the channels.
  11737.     AIC%
  11738.     move t1, [.ticca,,cachan] ; Put ^A on its channel.
  11739.     ATI%
  11740.     move t1, [.ticcx,,cxchan] ; Put ^X on its channel.
  11741.     ATI%
  11742.     move t1, [.ticcz,,czchan] ; And ^Z on its.
  11743.     ATI%
  11744.     ret
  11745.  
  11746. cmpon:    Remark - ^M, ^P interrupts on.
  11747.     movei t1, .fhslf    ; This fork.
  11748.     movx t2, 1b<cmchan>!1b<cpchan> ; These channels.
  11749.     AIC            ; Activate interrupt system.
  11750.     move t1, [.ticcm,,cmchan] ; Assign ^M to this channel.
  11751.     ATI
  11752.     setzm cmseen
  11753.     move t1, [.ticcp,,cpchan] ; Assign ^P to this one.
  11754.     ATI
  11755.     setzm cpseen
  11756.     ret
  11757.  
  11758. caxzof: Remark - Turn off ^A,^X,^Z interrupts.
  11759.  
  11760.     setzm cxseen        ; Turn off the flags
  11761.     setzm czseen        ;  ...
  11762.     setzm caseen        ;  ...
  11763.     skipn local        ; Nothing to do if remote, the interrupts
  11764.      ret            ;  weren't on anyway.
  11765.     movx t1, .fhslf        ; Turn off ^A,^X,^Z traps.
  11766.     movx t2, 1b<cachan>!1b<cxchan>!1b<czchan> ; Turn off these channels.
  11767.     DIC%            ; ...
  11768.     RTIW%            ; Fix up the interrupt mask
  11769.     tdz t2, [<1b1+1b24+1b26>] ; for ^A,^X,^Z
  11770.     STIW%            ;  ...
  11771.      %jserr (,.+1)
  11772.     ret
  11773.  
  11774. ; ^M, ^P interrupts off.
  11775.  
  11776. cmpoff:    setzm cmseen
  11777.     setzm cpseen
  11778.     movx t1, .fhslf        ; Turn off ^M trap.
  11779.     movx t2, 1b<cmchan>!1b<cpchan> ; Turn off channels.
  11780.     DIC            ; ...
  11781.     RTIW            ; Fix up the terminal interrupt mask
  11782.     tdz t2, [<1b13>!<1b16>]    ; for ^M, ^P
  11783.     STIW
  11784.      %jserr (,.+1)
  11785.     ret
  11786.  
  11787. cctrap:    sosle ccn        ; Count the ^C's.
  11788.      DEBRK%            ; If they haven't typed enough, just resume.
  11789.     call timoff        ; Turn off any timer.
  11790.     hrroi t1, [asciz/^C
  11791. /]
  11792.     PSOUT%            ; Echo the ^C.
  11793.  
  11794.     move p, psave        ;[27] Make sure stack pointer is right.
  11795.     move t1, psave2        ;[27] And stack top.
  11796.     movem t1, (p)        ;[27]
  11797.     hrli t1, (1b5)        ;[27] Get into user mode.
  11798.     movem t1, pc1        ; Put this place into our PC.
  11799.     pop p, t1        ;[80] Don't need it on the stack any more.
  11800.     DEBRK%            ; Resume where stack pointer points.
  11801.  
  11802. ;[61] Control-A trap handler.  Give brief progress report at terminal.
  11803. ;
  11804. catrap:    push p, t1        ; Save all ACs we might use.
  11805.     push p, t2
  11806.     push p, t3
  11807.     skipn rcving        ; Sending or receiving a file?
  11808.      jrst catrp1        ;  No.
  11809.     hrroi t1, [asciz/^A
  11810.  Sending /]            ; Yes, one...
  11811.     skipg rcving
  11812.      hrroi t1, [asciz/^A
  11813.  Receiving /]            ; ...or the other.
  11814.     PSOUT%
  11815.     movei t1, .priou    ; Say the filename
  11816.     setz t3,
  11817.     skipe t2, filjfn
  11818.      JFNS%
  11819.      erjmp .+1
  11820.     tmsg <, file bytesize >    ; File bytesize
  11821.     numout bytsiz
  11822.     skipl rcving        ; I/O bytesize, only if sending
  11823.      jrst [    tmsg <, i/o bytesize >
  11824.         movei t2, 7
  11825.         skipn itsfil    ;[75]
  11826.          skipe ebtflg
  11827.          movei t2, 8
  11828.         numout t2
  11829.         jrst .+1 ]
  11830.     tmsg <
  11831. >                ;[92]
  11832.     hrroi t1, [asciz/ (ITS binary)/] ;[75]
  11833.     skipe itsfil        ;[75]
  11834.      PSOUT            ;[75]
  11835.     hrroi t1, [asciz/ (8th-bit prefixing)/] ;[88]
  11836.     skipe ebqflg        ;[88]
  11837.      PSOUT            ;[88]
  11838.     hrroi t1, [asciz/ (compression)/] ;[92]
  11839.     skipe rptflg        ;[92]
  11840.      PSOUT            ;[92]
  11841.     hrroi t1, [asciz/ (block check type /] ;[98]
  11842.     PSOUT
  11843.     numout bctu        ;[98]
  11844.     movei t1, ")"        ;[98]
  11845.     PBOUT            ;[98]
  11846.     tmsg <
  11847.  At page >            ; What page we're at.
  11848.     move t2, pagno
  11849.     aos t2
  11850.     numout t2
  11851.     skipl rcving        ; Out of how many
  11852.      jrst [    tmsg < of >    ; (which we know only if we're sending)
  11853.         numout pagcnt
  11854.         jrst .+1 ]
  11855.  
  11856.     ;...
  11857.  
  11858. ;...CATRAP, cont'd
  11859.  
  11860.  
  11861. catrp1:    tmsg <
  11862.  Files: >            ; Say how many files,
  11863.     numout files
  11864.     tmsg <, packets: >    ; packets,
  11865.     skipl rcving
  11866.      numout sptot
  11867.     skipg rcving
  11868.      numout rptot
  11869.     tmsg <, chars: >    ; characters,
  11870.     move t2, stchr
  11871.     add t2, schr
  11872.     skipl rcving
  11873.      numout t2
  11874.     move t2, rtchr
  11875.     add t2, rchr
  11876.     skipg rcving
  11877.      numout rtot
  11878.     tmsg <
  11879.  NAKs: >            ; NAKS & timeouts.
  11880.     numout nnak
  11881.     tmsg <, timeouts: >
  11882.     numout ntimou
  11883.     tmsg <
  11884. >                ; End up with a CRLF
  11885.  
  11886.     pop p, t3        ; Restore ACs.
  11887.     pop p, t2
  11888.     pop p, t1
  11889.  
  11890.     DEBRK%            ; Resume.
  11891.  
  11892. ;[59] Control-X trap handler.
  11893.  
  11894. cxtrap:    setom cxseen        ; Just set the flag & echo the character.
  11895.     push p, t1
  11896.     move t1, source        ;[140] What's the source of our data?
  11897.     cain t1, dirch        ;[140] Is it a directory listing?
  11898.      setom czseen        ;[140] If so, set C-Z flag, too.
  11899. cxtrp2:    hrroi t1, [asciz\^X// \]
  11900.     PSOUT%
  11901.     pop p, t1
  11902.     DEBRK%
  11903.  
  11904.  
  11905. ;[59] Control-Z trap handler.
  11906.  
  11907. cztrap:    setom czseen        ; Just set the flag & echo the character.
  11908.     push p, t1
  11909.     hrroi t1, [asciz\^Z// \]
  11910.     PSOUT%
  11911.     pop p, t1
  11912.     DEBRK
  11913.  
  11914.  
  11915. ;[165] Control-M and -P trap handlers
  11916.  
  11917. cmtrap:    setom cmseen        ; Set ^M flag
  11918.     push p, t1        ; Echo CRLF
  11919.     tmsg <
  11920. >
  11921.     move t1, cmloc        ; Get place to resume.
  11922.     jrst cmptr2
  11923.  
  11924. cptrap:    setom cpseen        ; Set ^P flag
  11925.     push p, t1        ; Echo ^P
  11926.     tmsg <
  11927. ^P>
  11928.     move t1, cploc        ; Get place to resume.
  11929.  
  11930. cmptr2:    hrli t1, (1b5)        ; Get into user mode.
  11931.     movem t1, pc2        ; Resume at desired PC.
  11932.     pop p, t1
  11933.     DEBRK
  11934.  
  11935.  
  11936.     subttl subbp - Subtract two arbitrary byte pointers
  11937.  
  11938. ; Subroutine to subtract two byte pointers in current section.
  11939. ; The two byte pointers must point to bytes of the same size.
  11940. ;
  11941. ; Call with:
  11942. ;   t1/ First byte pointer.
  11943. ;   t2/ Second byte pointer.
  11944. ;    CALL SUBBP
  11945. ;
  11946. ; Returns:
  11947. ;   +1 if the byte sizes are different, with t1-t3 unchanged, or else
  11948. ;   +2 with:
  11949. ;      t1,t2/ Unchanged.
  11950. ;      t3/ The number of bytes of the specified bytesize in the string pointed
  11951. ;          to by the first byte pointer (in t1) up to, but not including, the
  11952. ;          byte pointed to by the second byte pointer (in t2).
  11953.  
  11954. subbp:    saveac    <q1,q2,q3,q4>    ; Save permanent regs for work below.
  11955.     ldb q1, [point 6, t1, 11] ; q1 := bytesize 1.
  11956.     ldb q2, [point 6, t2, 11] ; q2 := bytesize 2.
  11957.     came q1, q2        ; Are they equal?
  11958.      ret            ; No, failure
  11959.  
  11960. ; Byte sizes are equal, can do arithmetic.
  11961.  
  11962.     movei q2, @t1        ; Do address calculation for t1
  11963.     movei q4, @t2        ;  and t2.
  11964.     sub q4, q2        ; q4 := (A1 - A2) = N words.
  11965.     movei q2, ^d36        ; q2 := bits/word.
  11966.     idiv q2, q1        ; q2 := bytes/word.
  11967.     imul q4, q2        ; q4 := bytes in N words.
  11968.     move q2, q4        ; (to leave q3-q4 free for IDIV)
  11969.     ldb q3, [point 6, t2, 5] ; q3 := Q2
  11970.     ldb t3, [point 6, t1, 5] ; t3 := Q1
  11971.     sub t3, q3        ; t3 := (Q1 - Q2)
  11972.     idiv t3, q1        ; t3 := (Q1 - Q2) / S
  11973.     add t3, q2        ; Adjust previous count.
  11974.     retskp            ; And return, with success.
  11975.  
  11976. ;[6] (this whole routine, just for fun...)
  11977.  
  11978. moon:    saveac <5,6>
  11979.  
  11980. ; This code stolen from MOON.MAC (anybody know who wrote it?).
  11981. ; Just changed OUTCHR's to PBOUT%'s via a macro.  - Frank.
  11982. ;
  11983.     setzb 3,4
  11984.     seto 2,
  11985.     ODCNV%
  11986.      erjmp r
  11987.     tlz 4,77
  11988.     IDCNV%
  11989.      erjmp r        ; Return upon any error.
  11990.     tmsg <, Moon: >        ; OK so far, say what we're doing.
  11991.  
  11992. ; AC2= Universal time adjusted for time zone.
  11993.  
  11994.     move 1,2        ; Right place.
  11995.     sub 1,newmn        ; Sub off base new moon
  11996.     idiv 1,period        ; Divide by the period
  11997.     idiv 2,perio4        ; Get fractions of a period
  11998.     camg 3,perio8        ; Check for pahse + or -
  11999.      jrst moon1        ; Not more than 3+ days
  12000.  
  12001.     sub 3,perio4        ; Make it next phase -n days
  12002.     cain 2,3        ; Is it LQ+3D+?
  12003.      tdza 2,2        ; It is
  12004.      aoj 2,            ; Increment phase
  12005.  
  12006. moon1:    hllz 1,table(2)        ; Get SIXBIT phase
  12007.     skipge 3        ; 3 < 0 then minus phase output
  12008.      tloa 1,'-'        ; -
  12009.      tloa 1,'+'        ; +
  12010.      movms 3        ; Fix mag of 3
  12011.     move 2,[point 6,1]    ; Byte pointer
  12012.     movei 5,2        ; Loop 3 times
  12013.  
  12014. moon2:    ildb 4,2        ; Get a character
  12015.     addi 4," "        ; Make ASCII
  12016.     OUTCHR 4        ; Type it
  12017.     sojge 5,moon2        ; Loop
  12018.  
  12019.     movsi 4,-4        ; Make aobjn pointer
  12020.     ;...
  12021.  
  12022. moon3:    hrrz 2,table(4)        ; Get a multiplier
  12023.     trz 2,774000        ; Strip off ascii character
  12024.     imuli 3,(2)        ; Get the value decoded
  12025.     hlrz 1,3        ; Get value
  12026.     tlz 3,-1        ; Zap old LH
  12027.     move 5,1        ; Use 5 & 6 here
  12028.     idivi 5,12        ; Radix 10
  12029.     addi 5,60        ; Make ASCII
  12030.     caile 5,60        ; Check for leading zero
  12031.      OUTCHR 5        ;  Type it.
  12032.     addi 6,60        ; Make ASCII
  12033.     OUTCHR 6
  12034.     ldb 5,[point 7,table(4),24] ; Get d/h/m/s
  12035.     OUTCHR 5        ; Type it.
  12036.     OUTCHR ["."]        ; Follow with a dot.
  12037.     aobjn 4,moon3        ; Loop.
  12038.  
  12039.     tmsg <
  12040. >                ; A CRLF at the end.
  12041.     ret            ; Done, return.
  12042.  
  12043.     subttl Pure Data
  12044.  
  12045.  
  12046. ; Pure data for moon.
  12047.  
  12048. newmn:    125575,,34343        ; 28-jan-79 0120 est
  12049. per==35,,422752            ; 29d.12h.53m.19s
  12050. period:    per
  12051. perio4:    per/4
  12052. perio8:    per/10
  12053.  
  12054. table:    byte(18)'NM '(7)"d"(11)^D1 ; New moon - days - 1
  12055.     byte(18)'FQ '(7)"h"(11)^D24 ; First quarter - hours - 24
  12056.     byte(18)'FM '(7)"m"(11)^D60 ; Full moon - minutes - 60
  12057.     byte(18)'LQ '(7)"s"(11)^D60 ; Last quarter - seconds - 60
  12058.  
  12059.  
  12060.  
  12061. ; Some other miscellaneous pure data
  12062.  
  12063. crlf:    asciz/
  12064. /                ; A carriage-return-linefeed.
  12065.  
  12066.     Remark    Interrupt storage (pure)
  12067.  
  12068. levtab:    pc1
  12069.     pc2
  12070.     pc3
  12071.  
  12072. chntab:    phase 0
  12073. tmchan:    1,,tmtrap        ; Timer trap on channel 0, priority 1.
  12074. ccchan:    1,,cctrap        ; ^C trap on channel 1, same priority.
  12075. cachan:    2,,catrap        ; ^A trap on channel 2, lower priority.
  12076. cxchan:    2,,cxtrap        ; ^X trap on channel 3...
  12077. czchan:    2,,cztrap        ; ^Y trap ....       4
  12078. cmchan:    2,,cmtrap        ; ^M trap ....       5
  12079.     repeat <^d23-.>,<0>    ; (Skip reserved area, can't use these)
  12080. cpchan:    2,,cptrap        ; ^P trap on channel 6
  12081.     block ^d36-.
  12082.     dephase
  12083.     0            ; (superstition)
  12084. lits:    lit            ; Assemble literals here.
  12085.  
  12086.     subttl    Impure data storage
  12087.  
  12088. CMDSTG                ; Allocate COMND JSYS storage
  12089. pdl:    block pdlsiz        ;  and stack.
  12090. pc1:    0            ; Interrupt PC storage, levels 1,
  12091. pc2:    0            ;  2,
  12092. pc3:    0            ;  and 3.
  12093. intpc:    0            ; PC to restore on timer interrupt.
  12094. intstk:    0            ; Stack pointer to restore on timer interrupt.
  12095. ccn:    0            ; Number of ^C's typed.
  12096. caseen:    0            ; Flag for ^A trap.
  12097. psave:    0            ; Stack pointer for ^C interrupt.
  12098. psave2:    0            ; Stack top for ^C interrupt.
  12099. tsave:    0            ;[132] Same as above, but for timer interrupts.
  12100. tsave2:    0            ;[132]  ...
  12101. cmseen:    0            ;[165] Flag for ^M interrupt seen.
  12102. cmloc:    0            ;[165] Where to go on ^M interrupt.
  12103. cpseen:    0            ;[165] Flag for ^P interrupt seen.
  12104. cploc:    0            ;[165] Where to go on ^P interrupt.
  12105. cxseen:    0            ;[59] Flag for ^X interrupt seen.
  12106. czseen:    0            ;[59] Flag for ^Z interrupt seen.
  12107. capas:    0            ; Process capabilities.
  12108. inited:    0            ;[177] inilin/reslin flag.
  12109.  
  12110. pars1:    0            ; Data from first parse.
  12111. pars2:    0            ; Data from second parse.
  12112. pars3:    0            ; Data from third parse.
  12113. pars4:    0            ; Data from fourth parse.
  12114. pars5:    0            ;[41] ...
  12115. srvflg:    0            ; Are we serving?  Erase if we go for command.
  12116. iflg:    0            ;[100] -1 if sending INFO packet, else 0.
  12117. lcflg:    0            ;[56] LOCAL command (-1 = LOCAL, 0 = REMOTE).
  12118. definf:    0            ;[77] DEFINE flag nonzero if parsing DEFINE.
  12119. undeff:    0            ;[77] UNDEFF flag nonzero if DEFINE x <cr>.
  12120. source:    0            ;[102] Source routine for GETCH.
  12121. dest:    0            ;[107] Destination routine for PUTCH.
  12122. ffunc:    0            ;[118] File function (dir, del, ren, etc).
  12123. parsx==.-1            ; For zeroing the above.
  12124.     
  12125. dfstrt:    PROMP            ; Are we to be a SERVER or go to the PROMPT?
  12126.                 ;  (PROMP not PROMPT, which CMD package uses)
  12127. f$exit:    0            ; Exit flag for EXIT command or rescan entry.
  12128. ttyjfn:    .priin            ; JFN for controlling terminal.
  12129. logjfn:    0            ;[38] Debugging log file JFN.
  12130. tlgjfn:    0            ;[126] Transaction log file JFN.
  12131. sesjfn:    0            ;[128] Session log file JFN.
  12132. savjfn:    0            ; Place to save session log JFN.
  12133. logbsz:    0            ;[41] Log file byte size.
  12134. filjfn:    0            ; JFN of file being sent.
  12135. ndxjfn:    0            ; Indexable JFN, for wildcard stepping.
  12136. nxtjfn:    0            ;[111] JFN of next file to be sent.
  12137. netjfn:    0            ; Line for packet transmission.
  12138. ttymod:    0            ; Current mode word for controlling tty.
  12139. oldjfn:    0            ; JFN on previous line.
  12140. oldmod:    0            ; Previous mode of the line.
  12141. oldpau:    0            ; Previous terminal pause on end mode.
  12142. tiword:    0            ; Terminal interrupt word
  12143. sysmsg:    0            ;[82] Accept/refuse system message status.
  12144. ttynum:    0            ; Number of the TTY being used.
  12145. oldnum:    0            ;[7] Number of previous TTY in case of change.
  12146. mytty:    0            ;[4] TTY number of job's controlling terminal.
  12147. myccoc:    0            ;[161] CCOC words for my tty.
  12148.     0            ;[161] (two of them)
  12149. ttpau:    0            ;[161] Controlling TTY's pause chars.
  12150. myjob:    0            ;[7] My job number.
  12151. skdflg:    0            ;[130] Nonzero if class scheduler on.
  12152. class:    0            ;[130] My scheduler class.
  12153. job:    0            ;[7] Number of job that has TTY I want.
  12154.     ;...
  12155.  
  12156. ; Impure Data, cont'd
  12157.  
  12158. pname:    0            ; Name of this process
  12159.     0            ;  (need 2 words)
  12160. ttfork:    0            ; Fork number of the connect receive fork.
  12161. rufork:    0            ; Fork number for LOCAL RUN program fork.
  12162. rujfn:    0            ; JFN for LOCAL RUN program.
  12163. execf:    0            ; Fork number of PUSH (to Exec) fork.
  12164. errptr:    0            ; Pointer to most recent error string.
  12165. atmptr:    0            ; Atom buffer pointer.
  12166. xfnflg:    0            ;[84] Flag for file name conversion.
  12167. xflg:    0            ;[104] Flag for sending with X header.
  12168. ebtflg:    0            ; One if file is to be used in 8-bit mode.
  12169. autbyt:    1            ; One if auto-byte is to be used.
  12170. handsh:    0            ;[76] Handshake.
  12171. flow:    1            ;[143] Flow-Control (nonzero = XON/XOFF)
  12172. itsflg:    defits            ;[75] Flag for handling ITS-binary format files
  12173. itsfil:    0            ;[75] Flag for this file is ITS format.
  12174. itscnt:    0            ;[75] Counter for ITS header chars matched.
  12175. tvtflg:    0            ;[129] Negotiate binary mode on ARPANET TVT.
  12176. tvtchk: 1            ;[182] TVT discovery (MUST BE AFTER tvtflg!)
  12177. ntiblk: block ntblen        ;[182] NTINF% block for TVT
  12178. panda <                ;[181] PANDA monitor TVT support
  12179. havnbm:    0            ;[181] Non-zero if we have network binary mode
  12180. setlts:    0            ;[181] set if we set terminal status
  12181. oldlts:    0 >            ;[181] Old terminal status
  12182. incase:    defics            ;[160] Case conversion flag for INPUT search.
  12183. indeft:    defito            ;[160] Default timeout for INPUT search.
  12184. intima:    defita            ;[160] Timeout action for INPUT search.
  12185. asgflg:    0            ;[7] -1 if I asg'd the TTY, 0 if already asg'd.
  12186. oasflg:    0            ;[7] Same, but for previous TTY.
  12187. actmp:    block 20        ;[59] A place for short-term saving of ACs.
  12188. pktacs:    block 6            ;[112] Place to save RPACK/SPACK ACs.
  12189. parity: defpar            ; Type of parity to use.
  12190. gotx:    0            ; Flag for "already got an X-packet".
  12191. gots:    0            ; Flag for "already got an S-packet".
  12192. mapflg:    0            ; One if a page is mapped in.  (Init to 0.)
  12193. mdmlin:    0            ;[130] -1 = modem-controlled line, 0 = not.
  12194. carier:    0            ;[130] Flag for carrier dropped.
  12195. monv:    0            ;[146] Monitor version (0 if less than 6.0).
  12196. speed:    0            ;[130] Ostensible line speed -- input,,output.
  12197. setspd:    0            ;[161] Flag speed was explicitly SET.
  12198. defbrk==3            ;[16] default nulls to send on break
  12199. brk:    defbrk            ;[16] nulls to send on BREAK key
  12200. local:    0            ; -1 = local Kermit, 0 = remote.
  12201. rcving:    0            ; -1=actually recving, +1=sending, 0=neither.
  12202. $sendf:    0            ; SEND command in progress.
  12203. $recvf:    0            ; RECEIVE command in progress.
  12204. pagptr:    0            ; Pointer into the page.
  12205. ;**************
  12206. pagcnt:    0            ; Number of pages in the file,
  12207. bytcnt:    0            ; and byte count
  12208. crdate:    0            ; and creation date (these 3 must be adjacent!)
  12209. ;**************
  12210. bytsiz:    0            ; Byte size of file.
  12211. abtfil:    0            ;[42] 0 = discard incomplete file, -1 = keep.
  12212. expung:    0            ;[143] Automatically expunge when deleting.
  12213. pagno:    0            ; Present page number.
  12214. stdat:    0            ; Time taken in transmitting.
  12215. size:    0            ; Size of the present data.
  12216. spsiz:    dspsiz            ; Maximum size packet to send.
  12217. rpsiz:    drpsiz            ; Maximum size packet to receive.
  12218. maxdat:    dspsiz-5        ;[63] Max length for data field.
  12219. srvtim:    dsrvtm            ;[137] Server command wait timeout interval.
  12220. stimou:    dstim            ; Interval for my own timer.
  12221. otimou:    dstim            ;[26] Place to save old timout interval.
  12222. rtimou:    drtim            ; Minimum timeout interval I need.
  12223. rrtimo:    drtim            ;[128] Above, adjusted for 15-min load avg.
  12224. ntimou:    0            ;[54] Timeout counter.
  12225. curtim:    0            ;[131] Current load-adjusted timeout interval.
  12226. timerx:    0            ;[132] Counter for timer errors.
  12227. nnak:    0            ;[54] NAK counter.
  12228.     ;...
  12229.  
  12230. ; Impure Data, cont'd
  12231.  
  12232. rpause:    drpaus            ;[35] Pause before ACKing data packet.
  12233. spause: dspaus            ;[36] Pause before sending data packet.
  12234. pause:    0            ;[36] Pause currently in effect.
  12235. spadch:    dspad            ; Pad char micro wants.
  12236. rpadch:    drpad            ; Pad char I want.
  12237. spadn:    dspadn            ; Number of pad chars for micro.
  12238. rpadn:    drpadn            ; Number for me.
  12239. seolch:    dseol            ; EOL char micro needs.
  12240. reolch:    dreol            ; EOL I need.
  12241. squote:    dsquot            ; Quote character micro wants.
  12242. rquote:    drquot            ; Quote character I want.
  12243. delay:    ddelay            ; How long before I send the first packet.
  12244. odelay:    ddelay            ;[27] For saving & restoring delay.
  12245. escape:    defesc            ; Escape character for connecting (default ^Y).
  12246. duplex:    dxfull            ; Duplex for connecting.
  12247. ssthdr:    SOH            ; Start of header character to send.
  12248. rsthdr:    SOH            ; Start of header character to receive.
  12249. rtchr:    0            ; Total characters received.
  12250. stchr:    0            ;  ... sent.
  12251. rtot:    0            ; Some more counters..
  12252. stot:    0            ;
  12253. otot:    0
  12254. numtry:    0            ; Number of tries on a packet.
  12255. oldtry:    0            ; Number of tries for previous packet.
  12256. maxtry:    dmxtry            ; Maximum retries for an ordinary packet.
  12257. imxtry: dimxtr            ; Maximum retries in send initiate.
  12258. pktnum:    0            ; Current packet sequence number.
  12259. num:    0            ; Number of packet just received.
  12260. type:    0            ; Type of same.
  12261. datlen:    0            ; Length of data field of same.
  12262. pktlen: 0            ;[179] Packet length.
  12263. islong:    0            ;[179] Packet is long.
  12264. datptr:    0            ; Pointer to data field of same.
  12265. gclen:    0            ; Generic command data field length.
  12266. rptot:    0            ;[4] Counter for received packets.
  12267. sptot:    0            ;[4] Counter for sent packets.
  12268. files:    0            ; File counter.
  12269. sec:    0            ; Seconds (for figuring baud rate)
  12270. eoflag:    0            ; End of file flag.
  12271. temp:    0            ; Temporary location, to be used only for
  12272. temp2:    0            ;  very brief periods.
  12273. ch:    0            ;[63] Current character.
  12274. next:    0            ;[63] Next character.
  12275. rpt:    0            ;[63] Repeat count of current character.
  12276. rptq:    drept            ;[63] Repeat count prefix.
  12277. rptflg:    0            ;[63] Repeat count processing flag.
  12278. rptfld:    drept            ;[92] Repeat count field for Send-Init.
  12279. ebq:    "Y"            ;[63] 8th-bit-on prefix.
  12280. ebqflg:    0            ;[63] 8th-bit prefixing flag.
  12281. ebqr:    0            ;[88] 8th-bit prefixing requested flag.
  12282. ebqfld:    "Y"            ;[88] 8th-bit prefix field for Send-Init.
  12283. ebqchr:    0            ;[90] Current character has 8th-bit prefix.
  12284. bctr:    "1"            ;[98] Block check type requested (character).
  12285. bctu:    1            ;[98] Block check type in use (number).
  12286. bctone:    0            ;[98] Use type 1 for this packet regardless...
  12287. bctemp:    0            ;[98] Place to store incoming block check.
  12288.     0            ;[98]
  12289.  
  12290. ; Impure Data, cont'd
  12291.  
  12292.  
  12293. xxumsg:    asciz/"x" - Unknown server command/ ; Server message (fill in the x)
  12294. xxulen=^d28            ; Number of characters in xxumsg.
  12295. xxbmsg:    asciz/"x" - Not valid as server command/ ; Another.
  12296. xxblen=^d33            ; Number of characters in xxbmsg.
  12297. xxgums:    asciz/"x" - Undefined generic command/
  12298. xxguln=^d31
  12299. xxgnms:    asciz/"x" - Unimplemented generic command/
  12300. xxgnln=^d35
  12301.  
  12302. dirbuf:    asciz/PS:</        ;[79] User's logged-in ID string.
  12303.     block ^d30        ;[79]
  12304.  
  12305. iniflg:    0            ;[83] Init file in progress.
  12306. takjfn:    0            ;[78] JFN of current TAKE command file.
  12307. takdep:    0            ;[78] Depth of TAKE file JFN stack.
  12308. takep:    0            ;[78] TAKE file JFN stack pointer.
  12309. takpdl:    block <takel+2>        ;[78] TAKE file JFN stack itself.
  12310.  
  12311. mdone:    0            ;[77] Flag for macro execution done.
  12312. macrof:    0            ;[77] Flag on if executing a SET macro.
  12313. macbp:    point 7, macbuf        ;[77] Pointer into macro text buffer.
  12314. omacbp:    0            ;[77] Previous MACBP.
  12315. macxp:    0            ;[77] Macro execution pointer.
  12316. namp:    point 7, nambuf        ;[77] Pointer into macro name buffer.
  12317. onamp:    0            ;[77] Previous NAMP.
  12318. macptr:    0            ;[77] Pointer to start of macro text in CSB.
  12319. nambuf:    block MNBLEN        ;[77] Buffer for DEFINE macro name.
  12320. namx:    block ^d10        ;[77] Some protection against spills.
  12321. filptr:    0            ;[102] Pointer into file name buffer.
  12322. fildot:    0            ;[102] Counter for dots in filename.
  12323. filbuf:    block ^d30        ; Buffer for file name building.
  12324. filbfz:    -1            ; End of same...
  12325. filcnt:    0            ; File counter for directory listings.
  12326. dirfin:    0            ; Flag for directory listing finished.
  12327.     ;...
  12328.  
  12329. ; Impure Data, cont'd -- big stuff at end.
  12330.  
  12331.  
  12332. jobtab:    block ^d30        ; Job info table for GETJI
  12333. skdblk:    block ^d20        ; Argument block for SKED% jsys.
  12334. prompx:    asciz/Kermit-20>/    ; Program prompt text (replacable)
  12335.     block ^d10        ; ...and some padding.
  12336. pasptr:    0            ; Pointer into...
  12337. pasbuf:    block MAXPKT/4+1    ; Buffer for remote password.
  12338. pasbfl==.-pasbuf        ; Length of above.
  12339.     0            ; Superstition
  12340. ttibuf:    block IOBUF/4+1        ;[180] Communications device input buffer
  12341. ttiptr:    point 8, ttibuf        ;[180] Pointer to communications input buffer
  12342. tticnt:    0            ;[180] Communications input buffer count
  12343. ttisin: 0            ;[180] Statistics counters...
  12344. ttibin:    0            ;[180]
  12345. ttildb:    0            ;[180]
  12346. ttimax: 0            ;[180]
  12347. buffer:    block MAXBUF/4+1    ; Buffer for file I/O.
  12348.     block ^d20        ; Superstition
  12349. data:    block MAXBUF/4+1    ; Data field of packet.
  12350.     block ^d20        ; Superstition
  12351. sndpkt:    block MAXBUF/4+1    ; Place for building outbound packets.
  12352.     block ^d20        ; Superstition
  12353. recpkt:    block MAXBUF/4+1    ; Place for putting incoming packets.
  12354. recpkz:    block ^d20        ; Superstition
  12355. tvtbuf:    block MAXBUF/4+1    ;[131] For doubled-iac version of send packet.
  12356.     block ^d20        ; Superstition
  12357. %%krbf:    block MAXPKT/4+1    ;[40] Place for packetized error messages.
  12358.     block ^d20        ; Superstition
  12359. macbuf:    repeat <MTBLEN>,<0>    ;[77] Macro text buffer.
  12360. macx:    block ^d20        ;[77] End of macro text buffer, with padding.
  12361. ;
  12362. ; Macro table, with one predefined macro, for Columbia's IBM system.
  12363. ; Users can remove this definition by typing "define ibm", or they can
  12364. ; replace it.  KERMIT-20 maintainers can remove it for their site by replacing
  12365. ; the contents of MACTAB (first word) with 0,,MACMAX, or can change it to be
  12366. ; anything they like.
  12367. ;
  12368. mactab:    1,,MACMAX        ;[77] Macro keyword TBLUK format table.
  12369.     [asciz/IBM/],,[asciz/parity mark, duplex half, handshake xon
  12370. /]                ;[77] Custom IBM mainframe definition.
  12371.     repeat <MACMAX-1>,<0>    ;[77] Macro keyword table.
  12372. mactbx:    repeat <100>,<0>    ; A small reserve tank...
  12373.     lit            ; Expand remaining literals here.
  12374.     0
  12375.  
  12376. strc:    0            ; Counter for, and...
  12377. strptr:    0            ; Pointer into...
  12378. strbuf:    repeat <1000>,<0>    ; String buffer for big strings.
  12379. strbf2:    repeat <1000>,<0>    ; More of string buffer for big strings.
  12380. strbln=.-strbuf            ; Length of whole thing.
  12381. strbz:    0            ; Where the padding ends.
  12382.  
  12383. getptr:    0            ; Pointer for emptying...
  12384. srvptr:    0            ; And pointer for filling...
  12385. srvbuf:    repeat <1000>,<0>    ; Big buffer for server responses.
  12386. srvbz:    repeat <100>,<0>    ; End of buffer, with some padding.
  12387. srvbzz:    0            ; Where the padding ends.
  12388.  
  12389.     end    <evlen,,kermit>
  12390.  
  12391. ;Old Edit history moved to after END statement...
  12392. ;
  12393. ;*************** Major Version 4.0 ****************
  12394. ;PS:<TIMREK>KERMIT.MAC.491,  5-Jan-84 18:49:24, Frank
  12395. ;[102] Have SFILE call GETBUF to put filename in file header packet with
  12396. ; full prefixing.  This is the first use of GETBUF/ENCODE on non-file data.
  12397. ;PS:<TIMREK>KERMIT.MAC.487,  3-Jan-84 18:42:38, Frank
  12398. ;[101] Strip ^V quote characters from outgoing file names.
  12399. ;PS:<TIMREK>KERMIT.MAC.472, 30-Dec-83 11:29:03, Frank
  12400. ;[100] More debugging of [98]; got 3-char CRC to work.  Also:
  12401. ;.Make GET command send an I packet before the R packet, to tell other side
  12402. ; what block check & other parameters to use when sending.  Replace SINFO
  12403. ; with a simple call to SINIT -- they do the same thing.
  12404. ;.New headings for SHOW PACKET display.
  12405. ;.If local, say delay is 0 in SHOW TIMING.
  12406. ;PS:<TIMREK>KERMIT.MAC.469, 29-Dec-83 20:53:36, Frank
  12407. ;[99] Debugging of [98]; Got 2-character checksum actually working.  Also:
  12408. ;.In RPACK, allow receipt of 1-char checksummed null packet, even if doing
  12409. ; 2 or 3 char block checks.  Other side might have restarted & sent a NAK.
  12410. ;.Tightened up various much-used loops.
  12411. ;.Improved packet logging -- now every character sent or received is logged.
  12412. ;PS:<SY.FDC>KERMIT.MAC.2, 28-Dec-83 09:25:32, Frank
  12413. ;[98] Added support for 2- and 3-character checksums.
  12414. ;*************  Version 3.4 **************
  12415. ;PS:<TIMREK>KERMIT.MAC.448, 23-Dec-83 13:59:52, Frank
  12416. ;[97] In INILIN, preserve TTY mode word settings that don't effect KERMIT, so
  12417. ; as not to cause undesired side effects with TACs, etc.  Fixes(?) bug reported
  12418. ; by Keith Petersen, diagnosed by Mark Crispin.
  12419. ;PS:<TIMREK>KERMIT.MAC.442, 20-Dec-83 19:47:03, Frank
  12420. ;[96] Add SEND (AS) remote-filespec when sending a single file.
  12421. ; Don't confuse user by displaying escape character in SHOW LINE when remote.
  12422. ;PS:<TIMREK>KERMIT.MAC.437, 15-Dec-83 19:20:10, Frank
  12423. ;[95] Remove SET EIGHTH-BIT-PREFIX command, always request it if parity is
  12424. ; being used.  Minor cleanups of help & program text.  Change version number
  12425. ; typeout to agree with the way the Exec now does it: major.minor(edit)-who.
  12426. ; Get rid of old GTCHR and PTCHR routines, and SET IBM routines.
  12427. ;PS:<TIMREK>KERMIT.MAC.431, 14-Dec-83 18:21:44, Frank
  12428. ;[94] Don't allow user to type RECEIVE or SERVER commands when local.
  12429. ;PS:<TIMREK>KERMIT.MAC.428, 14-Dec-83 15:18:03, Frank
  12430. ;[93] Minor corrections in ENCODE for off-by-1 errors doing repeat counts.
  12431. ;PS:<TIMREK>KERMIT.MAC.420, 14-Dec-83 12:39:32, Frank
  12432. ;[92] Add repeat count processing to SPAR, RPAR, SINIT, RINIT.
  12433. ; (It was already in the i/o routines, but never used.)
  12434. ;PS:<TIMREK>KERMIT.MAC.419, 13-Dec-83 18:25:55, Frank
  12435. ;[91] Add routine TTXON, call it whenever there's a timeout.
  12436. ; This should unstick the two sides in case of an XOFF deadlock.
  12437. ;PS:<TIMREK>KERMIT.MAC.415, 12-Dec-83 13:04:35, Frank
  12438. ;[90] Make 8th-bit prefixing work with PDP-10 36-bit binary files.
  12439. ;PS:<TIMREK>KERMIT.MAC.405,  9-Dec-83 15:15:39, Frank
  12440. ;[89] Polish up previous edit.  Turn on prefixing if using parity.
  12441. ;PS:<TIMREK>KERMIT.MAC.400,  8-Dec-83 16:40:28, Frank
  12442. ;[88] Turn on 8th-bit prefixing in RPAR & SPAR, add SET & SHOW stuff for it.
  12443. ;****************** Version 3C **********************
  12444. ;PS:<TIMREK>KERMIT.MAC.394,  2-Dec-83 14:50:55, Frank
  12445. ;[87] Fix bugs in [85]; make sure line does not change after halt/cont.
  12446. ;PS:<TIMREK>KERMIT.MAC.382,  1-Dec-83 14:15:24, Frank
  12447. ;[86] Don't send 4 extra characters if file is ITS binary.
  12448. ;PS:<TIMREK>KERMIT.MAC.381,  1-Dec-83 13:58:23, Frank
  12449. ;[85] Make rescan work even if no KERMIT.INI file.
  12450. ; Make sure line is set up correctly after exit and continue.
  12451. ;PS:<TIMREK>KERMIT.MAC.379, 25-Nov-83 17:13:16, Frank
  12452. ;[84] Add SET option to convert file names to "normal form".
  12453. ; SET FILE-BYTE-SIZE changed to SET FILE BYTESIZE to allow other file
  12454. ; options, like this new one (SET FILE NAMING).
  12455. ; Still allow "SET FILE 8", etc, for compatibility with the old way.
  12456. ;PS:<TIMREK>KERMIT.MAC.361, 25-Nov-83 11:34:54, Frank
  12457. ;[83] Return properly from SHOW ALL command.
  12458. ; Allow init file to be taken even when there is a command line argument.
  12459. ; Init file is always taken before looking at any other commands.
  12460. ;PS:<TIMREK>KERMIT.MAC.355, 11-Nov-83 19:14:43, Frank
  12461. ;[82] Clear/refuse links, system messages during file transfer.
  12462. ; Also, make sure we print the contents of any incoming error packet if
  12463. ; in local mode.  Also, don't echo back DEFINEs any more.
  12464. ;PS:<TIMREK>KERMIT.MAC.354,  9-Nov-83 18:35:53, Frank
  12465. ;[81] More miscellaneous fixes:
  12466. ; . Since CCOFF is called whenever RESLIN is called, have RESLIN call CCOFF.
  12467. ; . Don't turn ^C trap off between transactions if running in server mode.
  12468. ; . Fix broken autobyte code (skipn/skipe, sigh...)
  12469. ; . Fix broken "bit35" code in PUTCH for SOS & PDP-10 binary files.
  12470. ; . Remove debugging output for DEFINE & SET macro stuff.
  12471. ;PS:<TIMREK>KERMIT.MAC.338,  8-Nov-83 11:39:11, Frank
  12472. ;[80] Fix miscellaneous bugs:
  12473. ; . Communication line JFNs improperly juggled in $SETLN.
  12474. ; . Control-C trap was leaving an extra entry on the stack.
  12475. ; . Turn off Control-C trap after ^C out of send, receive, or server mode.
  12476. ; . Close file we're sending if other side sends an error packet.
  12477. ; . Time transfer started not always properly initialized.
  12478. ; . Remove garbage at end of set-macro body string.
  12479. ; . Clean up code at $SEND and $RECV for server entry.
  12480. ;PS:<TIMREK>KERMIT.MAC.331, 28-Oct-83 20:35:46, Frank
  12481. ;[79] Do an implicit TAKE of KERMIT.INI upon initial startup.
  12482. ;PS:<TIMREK>KERMIT.MAC.309, 28-Oct-83 15:29:45, Frank
  12483. ;[78] Add TAKE command to allow (nested) command files.
  12484. ;PS:<TIMREK>KERMIT.MAC.288, 27-Oct-83 18:55:44, Frank
  12485. ;[77] Add DEFINE command for SET macros.  Remove hardwired SET IBM.
  12486. ;PS:<TIMREK>KERMIT.MAC.268, 26-Oct-83 14:15:23, Frank
  12487. ;[76] Add SET HANDSHAKE.
  12488. ;PS:<TIMREK>KERMIT.MAC.251, 12-Oct-83 10:51:56, Frank
  12489. ;[75] Add ITS binary format file handling, as specified in KRFC #3.
  12490. ;PS:<TIMREK>KERMIT.MAC.243, 10-Oct-83 13:33:53, Frank
  12491. ;[74] Fix bug that truncated JSYS error messages in error packet text.
  12492. ;PS:<TIMREK>KERMIT.MAC.241, 10-Oct-83 13:07:33, Frank
  12493. ;[73] Make sure old JFN's on assigned TTYs are released properly.
  12494. ;PS:<TIMREK>KERMIT.MAC.240, 10-Oct-83 11:44:47, Frank
  12495. ;[72] Fix bug that made any file sent after a null file also null.
  12496. ; Fix bug in which last send from server sets byte size for next receive.
  12497. ;PS:<TIMREK>KERMIT.MAC.237,  7-Oct-83 16:47:24, Frank
  12498. ;[71] Fix SHOW DEBUG not to foul up if log JFN is .PRIOU.
  12499. ;PS:<TIMREK>KERMIT.MAC.230,  7-Oct-83 14:02:35, Frank
  12500. ;[70] Catch illegal memory references when mapping in a nonexistent page.
  12501. ; If i/o error sending a file, don't cancel, tell other side to discard.
  12502. ; This allows wildcard sends to proceed after a memory access error.
  12503. ; Also, allow ^C's to interrupt a nonworking FINISH or BYE command gracefully.
  12504. ;PS:<TIMREK>KERMIT.MAC.224,  6-Oct-83 18:56:09, Frank
  12505. ;[69] Fix bug that prevented interrupts from working after EXIT & continue.
  12506. ;PS:<TIMREK>KERMIT.MAC.219,  6-Oct-83 15:13:33, Frank
  12507. ;[68] Separate local and remote mode top-level command tables.
  12508. ; Make remote commands invisible in local mode & vice versa.
  12509. ; Move command keyword tables to where they are used.
  12510. ;PS:<TIMREK>KERMIT.MAC.212,  6-Oct-83 10:18:30, Frank
  12511. ;[67] Remove REMOTE & LOCAL commands for now -- these will be added later.
  12512. ; Update help text to reflect changes since last release, mainly ^A,^X,^Z.
  12513. ; Rename SET ABORTED-FILE to SET INCOMPLETE to avoid emotionally toned word.
  12514. ; Rename SET IBM-FLAG to SET IBM (flags are for programmers).
  12515. ; Break up help text for SET command.
  12516. ; Move help text for each command to same area as command itself.
  12517. ;PS:<TIMREK>KERMIT.MAC.202,  4-Oct-83 19:16:37, Frank
  12518. ;[66] Same deal as [63], but for file output routines.
  12519. ; Old PTCHR replaced by PUTBUF, DECODE, and PUTCH.
  12520. ; Also, include Nick Bush's CRC routine, but don't use it yet.
  12521. ;PS:<TIMREK>KERMIT.MAC.199, 30-Sep-83 19:48:52, Frank
  12522. ;[65] Clean up SEND command parsing, don't parse for initial filespec if no
  12523. ; wildcards given.
  12524. ;PS:<TIMREK>KERMIT.MAC.196, 29-Sep-83 19:13:45, Frank
  12525. ;[64] Debug the previous edit for basic service.
  12526. ;PS:<TIMREK>KERMIT.MAC.184, 28-Sep-83 18:53:21, Frank
  12527. ;[63] Rewrite file input routines to separate i/o from packet formation.
  12528. ; New routines are GETBUF to fill a packet buffer,
  12529. ; GETCH to get an input character,
  12530. ; ENCODE to process the character, performing control quoting, prefix quoting,
  12531. ;  and, if selected, 8th-bit quoting and repeat count processing.
  12532. ; GTCHR is still present, but not used at all.
  12533. ;PS:<TIMREK>KERMIT.MAC.169, 19-Sep-83 17:56:27, Frank
  12534. ;[62] Add ^X and ^Z to interrupt receiving a file or a batch, respectively.
  12535. ; Required insertion of data ("D") in ACK for data packet.
  12536. ;PS:<TIMREK>KERMIT.MAC.163, 16-Sep-83 19:19:13, Frank
  12537. ;[61] Put brief status report on ^A, like NFT has.
  12538. ;PS:<TIMREK>KERMIT.MAC.156, 16-Sep-83 15:45:56, Frank
  12539. ;[60] Add return code to SPACK to distinguish different kinds of failures.
  12540. ;PS:<TIMREK>KERMIT.MAC.151, 15-Sep-83 19:32:57, Frank
  12541. ;[59] Add ^X and ^Z to interrupt sending a file or a batch, respectively.
  12542. ; Required addition of data ("X" or "Z") to Z packet.
  12543. ;PS:<TIMREK>KERMIT.MAC.146, 15-Sep-83 16:18:26, Frank
  12544. ;[58] Add sending of "I" packets before server commands.
  12545. ;PS:<TIMREK>KERMIT.MAC.137,  8-Sep-83 20:20:28, Frank
  12546. ;[57] Add debugging log capability to server commands as well as file xfer.
  12547. ;PS:<TIMREK>KERMIT.MAC.130,  8-Sep-83 18:55:05, Frank
  12548. ;[56] Begin adding new server commands.  First, add LOCAL and REMOTE
  12549. ; top level commands, with operands like DELETE, TYPE, DISK, etc.
  12550. ; Implement DISK first, that's the easiest test of sending back info in
  12551. ; the data field of an ACK.  Also, catch a couple places where the nonskip
  12552. ; return from SPACK was not being accounted for (oops!).
  12553. ;**************** Version 3B *******************************
  12554. ;PS:<TIMREK>KERMIT.MAC.126,  8-Sep-83 15:14:37, Frank
  12555. ;[55] Add CFIBFs in BYE and FINISH; all commands to servers should do this.
  12556. ;PS:<TIMREK>KERMIT.MAC.123,  8-Sep-83 14:02:38, Frank
  12557. ;[54] Report number of NAKs and timeouts in STATISTICS command.
  12558. ;PS:<SY.FDC>KERMIT.MAC.7,  2-Sep-83 17:56:19, Frank
  12559. ;[53] When receiving a file, NAK a trashed packet immediately, don't just wait
  12560. ; for it to come again and only NAK after timeout.  This should result in a
  12561. ; major speed improvement over noisy lines.  The book has always said to do it
  12562. ; this way.  Fix is in RINIT, RFILE, RDATA.  Other KERMITs may need this too.
  12563. ;PS:<SY.FDC>KERMIT.MAC.4,  2-Sep-83 16:43:22, Frank
  12564. ;[52] Combine some common code in the send routines, and improve comments.
  12565. ;PS:<KERMIT>20KERMIT.MAC.40, 25-Aug-83 15:28:36, Frank
  12566. ;[51] Fix packet number compares for mod 64 in SFILE, SDATA, SEOF, SEOT.
  12567. ; This eliminates canceling whenever a retransmission of packet 0 occurs.
  12568. ;CU20D::PS:[SY.FDC]KERMIT.MAC.32, 29 June 1983, 5:39PM, Frank
  12569. ;[50] Change and document the calling conventions of RPAR & SPAR to eliminate
  12570. ; the mess from the last few edits.  Do even more validation in SPAR.
  12571. ;PS:<TIMREK>KERMIT.MAC.118, 29-Jun-83 14:31:52, Frank
  12572. ;[49] Fix another bug in SPAR, change method of incrementing packet numbers.
  12573. ;PS:<TIMREK>KERMIT.MAC.114, 28-Jun-83 16:43:09, Frank
  12574. ;[48] Point to data buffer correctly in SPAR & RPAR. This was lost in some
  12575. ; previous edit.
  12576. ;PS:<TIMREK>KERMIT.MAC.110, 28-Jun-83 15:10:26, Frank
  12577. ;[47] Fix bad checksum reporting, again.  Print most recent JSYS err in STAT.
  12578. ; Don't let other side's Send-Init parameters override any local SET commands.
  12579. ;PS:<TIMREK>KERMIT.MAC.104, 27-Jun-83 17:37:54, Frank
  12580. ;[46] CFIBF after timeout in RPACK.  Be more consistent about how errors
  12581. ; are handled in receive routines.  Clean up server command loop a little.
  12582. ;[PS:<TIMREK>KERMIT.MAC.101, 24-Jun-83 20:18:42, Frank
  12583. ;[45] Fix SHOW command for timing info.
  12584. ;[PS:<TIMREK>KERMIT.MAC.99, 24-Jun-83 17:54:07, Frank
  12585. ;[44] In SFILE, don't give up if OPENF failed because file already open.
  12586. ;PS:<TIMREK>KERMIT.MAC.92, 24-Jun-83 16:55:38, Frank
  12587. ;[43] Don't do timeouts if STIMOU is 0, as protocol says.  Kermit-65 was
  12588. ; sending a space (which translates to 0) in this field of the send-init by
  12589. ; mistake, and Kermit-20 was doing rapid-fire timeouts.
  12590. ;CU20D::PS:[SY.FDC]KERMIT.MAC.19, 22 Jun 83 17:12:33, Frank
  12591. ;[42] Release any piled up log jfns.  Issue KERMSGs any time we cancel.
  12592. ; Add SET ABORTED-FILE (DISPOSITION) DISCARD | KEEP
  12593. ;PS:<TIMREK>KERMIT.MAC.89, 17-Jun-83 11:48:26, Frank
  12594. ;[3A(41)] Clean up listing & help messages, declare minor version "A".
  12595. ;************************ Version 3A ******************************
  12596. ;PS:<TIMREK>KERMIT.MAC.83, 16-Jun-83 16:10:47, Frank
  12597. ;[41] Add bytesize selection option for debugging log file (7 or 8 bit),
  12598. ; for use when debugging binary file transfers.  Force debugging on
  12599. ; when log file requested.
  12600. ;PS:<TIMREK>KERMIT.MAC.75, 16-Jun-83 12:32:34, Frank
  12601. ;[40] Remove the last remaining long lines.  Get rid of hairy %CLEAR macro.
  12602. ; Don't send an error packet longer than the other side's maximum packet size.
  12603. ; Always blank out the error message packet buffer before filling.
  12604. ;PS:<TIMREK>KERMIT.MAC.71, 16-Jun-83 11:36:51, Frank
  12605. ;[39] Change STATUS to STATISTICS, give optional arguments to SHOW command.
  12606. ; Print program version upon startup.
  12607. ;CU20D::PS:<SY.FDC>KERMIT.MAC.13, 15-Jun-83 18:12:37, Frank
  12608. ;[38] Allow debugging output to go to a file.  Thus can even get debugging
  12609. ; information when running remotely.  Suggested by Dave King at CMU.
  12610. ;CU20D::PS:<SY.FDC>KERMIT.MAC.6, 15-Jun-83 14:34:19, Frank
  12611. ;[37] Add SET RETRY, fix FLDDB's so none are more than 80 chars wide.
  12612. ;PS:<TIMREK>KERMIT.MAC.68, 15-Jun-83 11:47:19, Frank
  12613. ;[36] Add SET SEND PAUSE, and include pause info in SHOW & STATUS commands.
  12614. ;PS:<TIMREK>KERMIT.MAC.64, 14-Jun-83 19:25:45, Frank
  12615. ;[35] Add SET RECEIVE PAUSE, suggested by Dave King at CMU.
  12616. ;PS:<TIMREK>KERMIT.MAC.61, 14-Jun-83 18:40:48, Frank
  12617. ;[34] In SPACK, send padding if requested.
  12618. ;PS:<KERMIT>20KERMIT.MAC.34, 10-Jun-83 12:55:42, Frank
  12619. ;[33] Cancel correctly if the output file can't be opened.
  12620. ; Enclose checksum characters in quotes in debugging messages.
  12621. ;*********** Version 3(40) Shipped to over 100 sites May 5 ************
  12622. ;PS:<TIMREK>KERMIT.MAC.56,  4-May-83 09:01:16, Frank
  12623. ;[32] Report bad checksums correctly when debugging.
  12624. ; Report error message from server & cancel if it can't get a file.
  12625. ;PS:<TIMREK>KERMIT.MAC.54, 26-Apr-83 19:08:00, Frank
  12626. ;[31] Beep when done with a transfer, if local.
  12627. ;PS:<KERMIT>20KERMIT.MAC.8, 15-Apr-83 14:45:36, Frank
  12628. ;[30] A NAK for the next packet is *not* the same as an ACK for the current
  12629. ; packet if the current packet is Send-Init.
  12630. ;PS:<TIMREK>KERMIT.MAC.42, 15-Apr-83 11:39:08, Frank
  12631. ;[29] When debugging packets, print checksum of incoming packets, and
  12632. ; print bad packets.
  12633. ;PS:<TIMREK>KERMIT.MAC.41,  8-Apr-83 19:31:28, Frank
  12634. ;[28] Add FINISH command.
  12635. ;PS:<TIMREK>KERMIT.MAC.29,  8-Apr-83 12:43:02, Frank
  12636. ;[27] Fix ^C trap to DEBRK to the right place in all cases.
  12637. ;PS:<TIMREK>KERMIT.MAC.28,  8-Apr-83 09:38:49, Frank
  12638. ;[26] Save and restore normal send timeout when going in & out of server
  12639. ; command-wait.
  12640. ;PS:<TIMREK>KERMIT.MAC.27,  7-Apr-83 20:20:15, Bill C.
  12641. ;[25] Neaten up SERVER mode time out changes.
  12642. ;PS:<TIMREK>KERMIT.MAC.20,  5-Apr-83 18:14:14, Frank
  12643. ;[24] Fix SPAR to account for the actual length of an incoming SEND-INIT.
  12644. ;PS:<TIMREK>KERMIT.MAC.19,  5-Apr-83 17:46:23, Frank
  12645. ;[23] Include both send and receieve parameters in SHOW command.
  12646. ;PS:<TIMREK>KERMIT.MAC.4, 3:20pm  Tuesday, 5 April 1983, Frank
  12647. ;[22] Add debugging options.  Remove i/o to DIAJFN and just test LOCAL and
  12648. ; DEBUG flag values.  Make DEBUG an AC, move RTOT & STOT to memory.
  12649. ;PS:<TIMREK>KERMIT.MAC.81,  1-Apr-83 15:59:19, Frank
  12650. ;[21] Change SET SEND/RECEIVE QUOTE to parse an octal number.  The hairy
  12651. ; .CMUQS/breakmask/.CMTOK parsing tended to hang the program...
  12652. ;PS:<TIMREK>KERMIT.MAC.75,  1-Apr-83 15:13:43, Bill C.
  12653. ;[20] Make packet time outs longer if in server mode awaiting commands.
  12654. ;PS:<TIMREK>KERMIT.MAC.72,  1-Apr-83 12:55:40, Frank
  12655. ;[19] Print "[OK]" for each file successfully sent or received, if local.
  12656. ;PS:<TIMREK>KERMIT.MAC.65, 31-Mar-83 16:43:20, Frank
  12657. ;[18] Expanded help text, with individual help for each command.
  12658. ; Added SET DUPLEX, SET SEND/RECEIVE START-OF-PACKET.
  12659. ;PS:<TIMREK>KERMIT.MAC.58, 31-Mar-83 13:35:57, Bill C.
  12660. ;[17] Restore CFIBFs of yore.  Clears up packet echoing and stacking.
  12661. ;PS:<TIMREK>KERMIT.MAC.52, 31-Mar-83 10:58:12, Frank
  12662. ;[16] Add SET ESCAPE (for CONNECT), try to print remote message after BYE.
  12663. ;PS:<TIMREK>KERMIT.MAC.48, 30-Mar-83 19:54:32, Frank
  12664. ;[15] Don't bomb if we can't open a file to be sent, just print nice msg.
  12665. ;PS:<TIMREK>KERMIT.MAC.47, 30-Mar-83 18:16:53, Frank
  12666. ;[14] Add code for ^B interrupts, but don't use it for anything yet.
  12667. ;PS:<TIMREK>KERMIT.MAC.45, 30-Mar-83 15:06:42, Frank
  12668. ;[13] Don't delay before send if local.
  12669. ;PS:<TIMREK>KERMIT.MAC.41, 30-Mar-83 13:52:57, Frank
  12670. ;[12] When local, print name of file being sent or received.
  12671. ;PS:<TIMREK>KERMIT.MAC.33, 29-Mar-83 17:59:47, Frank
  12672. ;[11] Talk to Kermit server.  Added BYE and GET commands.
  12673. ;************* Version 3 ****************
  12674. ;PS:<TIMREK>KERMIT.MAC.22, 28-Mar-83 14:56:39, Frank
  12675. ;[10] Enable ^C capability if not on already (reported by Willis Dair, SCU).
  12676. ; If we can't enable it, don't go on unless we're running under batch.
  12677. ;PS:<TIMREK>KERMIT.MAC.21, 20-Mar-83 17:55:27, Bill C.
  12678. ;[9] Fixed SHOW command to print number of blips correctly.
  12679. ;PS:<TIMREK>KERMIT.MAC.17, 18-Mar-83 20:31:00, Frank
  12680. ;[8] Added some help to the help text.
  12681. ;PS:<TIMREK>KERMIT.MAC.15, 18-Mar-83 19:03:51, Frank
  12682. ;[7] Assign & deassign line if not already assigned.  This prevents
  12683. ; "?Line is not active" and similar errors if Kermit is run on top of TTLINK
  12684. ; rather than vice versa, and not under DIAL (both TTLINK and DIAL will do
  12685. ; their own assigning, if necessary).  Thanks to Willis Dair, Santa Clara
  12686. ; University, for pointing out the bug.
  12687. ;PS:<TIMREK>KERMIT.MAC.14, 18-Mar-83 18:44:39, Frank
  12688. ;[6] Differentiate between remote & local timeouts in SHOW command.
  12689. ; Add version #, date/time, etc, to SHOW.
  12690. ; Replace a zillion NOUTs with NUMOUT macro.
  12691. ;PS:<TIMREK>KERMIT.MAC.12, 17-Mar-83 18:47:21, Frank
  12692. ;[5] Give error message when initial connection can't be made, if local.
  12693. ;PS:<TIMREK>KERMIT.MAC.7, 17-Mar-83 15:54:33, Frank
  12694. ;[4] When acting as local Kermit, show packet traffic by typing blips.
  12695. ;PS:<TIMREK>KERMIT.MAC.6, 17-Mar-83 15:31:30, Frank
  12696. ;[3] When comparing packet numbers, allow for wraparound.
  12697. ;PS:<TIMREK>KERMIT.MAC.3, 17-Mar-83 10:53:03, Frank
  12698. ;[2] Cont'd... Show range of timeouts in SHOW command.
  12699. ;PS:<TIMREK>KERMIT.MAC.2, 15-Mar-83 12:51:12, Frank da Cruz
  12700. ;[2] Make timeouts load-dependent.  Fix spelling of "interrupt" everywhere.
  12701. ;PS:<KERMIT>20KERMIT.MAC.22, 20-Feb-83 14:13:19, Bill C.
  12702. ;[1] Put in a CFIBF% in the INILIN code to clear the line at the beginning
  12703. ; of each send or receive of backed up NAKs.  This may not be just right.  This
  12704. ; can lose a Send Init packet some times.  This will work til the problem can
  12705. ; be looked at more closely.
  12706. ;*************************** Major Version 2 ********************************
  12707. ;PS:<SY.WBC3>KERMIT.MAC.20,  8-Feb-83 14:43:48, Bill C.
  12708. ; Put in (FINALLY!) the SHOW command.
  12709. ;PS:<SY.WBC3>KERMIT.MAC.11,  8-Feb-83 10:04:10, Bill C.
  12710. ; Add SET PARITY command.  Eliminate IGNORE-PARITY as its functionality is
  12711. ; replaced by SET PARITY SPACE.
  12712. ;PS:<KERMIT>20KERMIT.MAC.3,  4-Feb-83 11:04:08, Bill C.
  12713. ; Change TELNET to TTLINK (by FdC) and remove TELNET command.
  12714. ;PS:<SY.WBC3>KERMIT.MAC.38, 26-Jan-83 15:35:37, Bill C.
  12715. ; Make Kermit able to act as a SERVER.
  12716. ;PS:<KERMIT>20-KERMIT.MAC.29, 18-Jan-83 14:08:45, Bill C.
  12717. ; Take care of the case where user set terminal pause char to ^A.
  12718. ;PS:<KERMIT>20-KERMIT.MAC.27, 11-Jan-83 13:19:06, Bill C.
  12719. ; Fix ^C trap bug that caused illegal instruction.
  12720. ;PS:<KERMIT>20-KERMIT.MAC.22, 11-Jan-83 11:40:01, Bill C.
  12721. ; Fix bug in SET IGNORE-PARITY COMMAND.
  12722. ;PS:<KERMIT>20-KERMIT.MAC.11, 10-Jan-83 16:52:03, Bill C.
  12723. ; Add turn around char for the IBM running VM/CMS.
  12724. ;PS:<KERMIT>20-KERMIT.MAC.8,  7-Jan-83 17:59:01, Bill C.
  12725. ; Fix numerous mispellings of received.
  12726. ;PS:<KERMIT>20-KERMIT.MAC.3,  7-Jan-83 16:06:04, Bill C.
  12727. ; Clean up the diagnostic and error message code.
  12728. ;PS:<KERMIT>20-KERMIT.MAC.2,  7-Jan-83 15:06:02, Bill C.
  12729. ; Add the TELNET command (thanks to Bill Schilit.)  Change EXIT/CONT
  12730. ;    sequence to not throw away JFN.
  12731. ;PS:<KERMIT>KERMIT-20.MAC.2, 14-Dec-82 15:25:40, Bill C.
  12732. ; Be scrupulous in PMAP use after errors.  Don't make files with holes.
  12733. ;PS:<KERMIT>KERMIT.MAC.44, 28-Sep-82 09:47:32, Bill C.
  12734. ; Add ignore parity option for some UNIX systems.
  12735. ;PS:<KERMIT>KERMIT.MAC.19, 28-Apr-82 16:00:31, Bill C.
  12736. ; Big clean up.  Consolidate duplicate sections of code.  Also,
  12737. ;    no longer die on bad packet type, just NAK or retransmit.
  12738. ;    Removed empty show command.
  12739. ;PS:<KERMIT>KERMIT.MAC.18, 21-Apr-82 16:31:04, Bill C.
  12740. ; Clean up line on ^C from transfer.
  12741. ;PS:<KERMIT>KERMIT.MAC.17, 17-Feb-82 16:16:10, Bill C.
  12742. ; Add eight bit file mode.
  12743. ;PS:<KERMIT>KERMIT.MAC.16, 28-Jan-82 12:31:09, Bill C.
  12744. ; Clean up better on some error conditions.
  12745. ;PS:<KERMIT>KERMIT.MAC.15,  6-Jan-82 12:18:06, Bill C.
  12746. ; Fill out some of the SET command options.
  12747.  
  12748. ;[181]
  12749.  
  12750. ; Local Modes:
  12751. ; Mode:MACRO
  12752. ; Comment Column:32
  12753. ; Comment Start:;[182] 
  12754. ; Auto Fill Mode: 1
  12755. ; End:
  12756.