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

  1. $verno==^d5            ; Major version number.
  2. $mnver==^d1            ; Minor version number (minimum: 1).
  3. $edno==^d186             ; [185] Edit# increases independent of version.
  4. $who==^d0            ; [186] Who edited, 0=Columbia.
  5.                 ; [184] 2=ex-Columbia employees ...
  6. verdate: asciz/6-Jan-2006/    ; [186] Version datea
  7. ;
  8. ; Copyright (C) 1981, 2006,
  9. ; The Trustees of Columbia University in the City of New York.
  10. ;
  11. ; RECENT EDIT HISTORY (more at end):
  12. ;
  13. ;[TOMMYT]<FDC>K20MIT.MAC.368, Fri Jan  6 17:11:42 2006, Edit by FDC
  14. ;[186] Minor reformatting, add version date for 25th Anniversary Edition.
  15. ;[TOMMYT]STAR:<KERMIT>K20MIT.MAC.366,  4-Jan-2006 17:27:09, Edit by SLOGIN
  16. ;[185] Properly restore terminal length and width for large dimensions
  17. ;[TOMMYT]STAR:<KERMIT>K20MIT.MAC.355, 16-Mar-2005 14:47:16, Edit by SLOGIN
  18. ;[184] Set program version number to be decimal as typed by the EXEC.
  19. ; . Fix internal type out routines to support decimal.
  20. ; . Make 183 work when we quit, detach and continue
  21. ;[TOMMYT]STAR:<KERMIT>K20MIT.MAC.334,  5-Mar-2005 08:21:36, Edit by SLOGIN
  22. ;[183] A small amount of contingency logic.  Set the terminal JFN to
  23. ;    be restricted so that it can't be clobbered.
  24. ; . Check to see if a DTACH% happpened during the time we pushed so we
  25. ;   can punt the terminal JFN.  Otherwise we'll gronk on the attach
  26. ;   and continue.
  27. ;[TOMMYT]STAR:<KERMIT>K20MIT.MAC.327,  3-Aug-2003 16:50:33, Edit by SLOGIN
  28. ;[182] TVT-Binary automatic mode to check if we are on a TVT
  29. ; . Change ARPAnet references in typeout to Internet since there
  30. ;   may be some children who do know what the ARPAnet was...
  31. ;[TOMMYT]STAR:<KERMIT>KERMIT.MAC.259, 30-Jul-2003 12:48:04, Edit by SLOGIN
  32. ;[181] Merge PANDA network binary mode
  33. ; . Fix reslin and subroutines to always load the terminal jfn,
  34. ;   we were trying to clear the output buffer of .FHSLF!
  35. ; . put in default EMACS editing modes
  36. ;/w/fdc/timrek/kermit.mac, Mon Aug  6 14:28:27 2001, Frank (fdc@columbia.edu)
  37. ;[180] Buffered packet input instead per-character BIN% + better statistics.
  38. ;/w/fdc/timrek/kermit.mac, Sun Jan 28 17:33:20 2001, Frank (fdc@columbia.edu)
  39. ;[179] Added Long packets:
  40. ; . Added new symbol MAXBUF (10KB)
  41. ; . Increased packet buffer sizes to MAXBUF
  42. ; . Changed .setpk to allow sizes up to 9000 (near theoretical max)
  43. ; . Added CAPAS, WINDO, MAXLX1, MAXLX2 field support to rpar and spar.
  44. ; . Added long-packet sending/reading to spack/rpack.
  45. ; . Removed hardwired ^d94 packet-length references.
  46. ; . Speed improvements by up to a factor of 20.
  47. ; Changed default delay to 1 sec.
  48. ; Increased version number from 4.2 to 5.1.
  49. ; All long-packet related lines are marked "[179]".
  50. ;
  51. ;******************** Version 5.1 ************************
  52. ;PK:<TIMREK>KERMIT.MAC.259, 26-Jan-88 10:28:51, Frank (SY.FDC@CU20B)
  53. ;[178] Allow passwords to come from TAKE files.
  54. ;PK:<TIMREK>KERMIT.MAC.259, 25-Jan-88 18:38:14, Frank (SY.FDC@CU20B)
  55. ;[177] Fix [176].  It wasn't conditioning the line correctly.
  56. ;PK:<TIMREK>KERMIT.MAC.258, 11-Dec-87 14:16:09, Frank (SY.FDC@CU20B)
  57. ;[176] Allow commands to servers to be issued from TAKE file.
  58. ; Also, pass capabilities down to inferior process correctly.
  59. ;PS:<TIMREK>KERMIT.MAC.6,  6-May-85 17:39:44, Frank (SY.FDC@CU20B)
  60. ;[175] Delete any dot at the end of outbound file names (like 'makefile.').
  61. ;PS:<KERMIT>20KERMIT.MAC.256,  2-May-85 12:21:34, Frank (SY.FDC@CU20B)
  62. ;[174] Several things:
  63. ;. Don't ACK a Z packet if the file can't be closed.
  64. ;. Fix server interpretation of remote directory command with no args.
  65. ;. Fix "push" command message to not assume connected to remote.
  66. ;. Give appropriate messages for local/remote mode server entry.
  67. ;. Recover from i/o errors in debug log writing.
  68. ;. Recover from incoming filenames that start with dot.
  69. ;PS:<TIMREK>KERMIT.MAC.1028, 11-Dec-84 19:00:29, Frank (SY.FDC@CU20B)
  70. ;[173] Display contents of any incoming X packet.
  71. ;PS:<TIMREK>KERMIT.MAC.1028, 11-Dec-84 18:37:05, Frank (SY.FDC@CU20B)
  72. ;[172] Don't use "*" for default file type in SEND command.
  73. ;PS:<TIMREK>KERMIT.MAC.1021, 15-Nov-84 15:28:26, Frank (SY.FDC@CU20B)
  74. ;[171] Fix LOCAL CWD not to ask for password unless it has to.
  75. ;PS:<TIMREK>KERMIT.MAC.1018, 15-Nov-84 11:39:00, Frank (SY.FDC@CU20B)
  76. ;[170] Don't send 4 null bytes at end of ITS binary file.
  77. ;PS:<TIMREK>KERMIT.MAC.1012, 18-Oct-84 13:20:42, Frank (SY.FDC@CU20B)
  78. ;[169] Misc small fixes:
  79. ;. Make $XHOST allow ^C interrupt to work during SINFO.
  80. ;. Allow ^C interrupt in LOCAL TYPE.
  81. ;. REMOTE CWD Password: input was erroneously saying "?Too long"
  82. ;. In RUN command, don't let inferior log out.
  83. ;PS:<TIMREK>KERMIT.MAC.1012, 18-Oct-84 13:20:42, Frank (SY.FDC@CU20B)
  84. ;[168] Fix SPAR not to overrule SET commands when entering server mode.
  85. ;PS:<TIMREK>KERMIT.MAC.1004,  3-Oct-84 15:30:24, Frank (SY.FDC@CU20B)
  86. ;[167] Add ECHO command.
  87. ;PS:<TIMREK>KERMIT.MAC.1000,  3-Oct-84 12:13:10, Frank (SY.FDC@CU20B)
  88. ;[166] Add ^M and ^P interrupts for getting unstuck from TRANSMIT
  89. ;PS:<TIMREK>KERMIT.MAC.980,  2-Oct-84 19:36:41, Frank (SY.FDC@CU20B)
  90. ;[165] Add TRANSMIT command.
  91. ;PS:<TIMREK>KERMIT.MAC.972,  1-Oct-84 22:00:43, Frank (SY.FDC@CU20B)
  92. ;[164] Make session logging work during script execution.
  93. ;PS:<TIMREK>KERMIT.MAC.966, 30-Sep-84 13:27:04, Frank (SY.FDC@CU20B)
  94. ;[163] Add PC typeout to %JSERR
  95. ;PS:<TIMREK>KERMIT.MAC.962, 28-Sep-84 16:37:25, Frank (SY.FDC@CU20B)
  96. ;[162] Add CLEAR command.
  97. ;PS:<TIMREK>KERMIT.MAC.961, 28-Sep-84 08:37:26, Frank (SY.FDC@CU20B)
  98. ;[161] If SET SPEED done, remember it!
  99. ;PS:<TIMREK>KERMIT.MAC.946, 27-Sep-84 15:15:23, Frank (SY.FDC@CU20B)
  100. ;[160] Refinements of previous edit, add SET/SHOW INPUT.
  101. ;PS:<TIMREK>KERMIT.MAC.924, 26-Sep-84 16:35:53, Frank (SY.FDC@CU20B)
  102. ;[159] INPUT, OUTPUT, and PAUSE commands to provide a simple script facility.
  103. ;******************** Version 4.2 ************************
  104. ;
  105. ;PS:<TIMREK>KERMIT.MAC.918, 18-Jul-84 13:50:17, Frank
  106. ;[158] Clear up any XOFF condition when leaving protocol mode.
  107. ;PS:<TIMREK>KERMIT.MAC.916, 13-Jul-84 17:57:24, Frank
  108. ;[157] Don't get stuck if XOFF'd while typing out server message (thanks Jeff).
  109. ;PS:<TIMREK>KERMIT.MAC.914, 11-Jul-84 19:51:24, Frank
  110. ;[156] Debug previous edits.
  111. ;PS:<TIMREK>KERMIT.MAC.899, 10-Jul-84 18:52:39, Frank
  112. ;[155] Fix recently introduced bug in INILIN that broke handshake code.
  113. ;PS:<TIMREK>KERMIT.MAC.896, 10-Jul-84 17:12:04, Frank
  114. ;[154] Fix up session logging - avoid loss of nonopen JFN.  Add CLOSE command.
  115. ;PS:<TIMREK>KERMIT.MAC.893,  9-Jul-84 18:48:42, Frank
  116. ;[153] Always convert lc letters in incoming filenames to uc (for Bernie).
  117. ;PS:<TIMREK>KERMIT.MAC.888,  6-Jul-84 16:41:26, Frank
  118. ;[152] Add PUSH, SET SPEED, and SET BREAK.
  119. ;PS:<TIMREK>KERMIT.MAC.879,  5-Jul-84 12:53:06, Frank
  120. ;[151] Integrate connect code into this program, rather than running TTLINK
  121. ; in a lower fork.  Use TELNET-style separate input & output forks with no
  122. ; interrupts.  This was done for several reasons:
  123. ; . Release 6.0 of TOPS-20 doesn't allow multiple JFNs on a single TTY.
  124. ; . TTLINK did interrupt-driven i/o in a single fork, so would not work under
  125. ;   batch, where BATCON feeds i/o depending on whether "pty hungry".
  126. ; . Fewer source files to keep track of.
  127. ;******************** Version 4.1 ************************
  128. ;
  129. ;PS:<TIMREK>KERMIT.MAC.871,  3-Jul-84 10:50:55, Frank
  130. ;[150] Add dispatch tables for server and generic commands, to force us
  131. ; to think about every case -- e.g. server shouldn't complain about NAKs.
  132. ;PS:<TIMREK>KERMIT.MAC.870, 29-Jun-84 13:28:08, Frank
  133. ;[149] Fix bug in SET SEND/RECEIVE PADCHAR parsing (thanks, Daphne)
  134. ;PS:<TIMREK>KERMIT.MAC.859, 26-Jun-84 14:26:37, Frank
  135. ;[148] Allow source & destination filespecs for GET to be given separately.
  136. ;
  137. ;PS:<TIMREK>KERMIT.MAC.855, 26-Jun-84 12:38:18, Frank
  138. ;[147] Fix various problems reported by Ken Harrenstien (KLH@SRI-NIC):
  139. ; . Allow user to include !,?,@,;, etc in GET filespec with ^V quote.
  140. ; . Refuse links on file-transfer tty, not controlling tty!
  141. ; . Restore advice and links to tty after file transfer.
  142. ;
  143. ;PS:<TIMREK>KERMIT.MAC.840, 28-May-84 17:33:56, Frank
  144. ;[146] Get monitor version number at startup.  Under V6 or later, we can tell
  145. ; the real speed of the communication line (after all these years!). Also, we
  146. ; know speed of a local line.  Account for all this in CHKLIN, and report the
  147. ; percent efficiency in STATISTICS command when baud rate is known.
  148. ;
  149. ;PS:<TIMREK>KERMIT.MAC.820, 28-May-84 14:23:45, Frank
  150. ;[145] Allow LOCAL commands to be issued without the "LOCAL" prefix.
  151. ; Change LOCAL/REMOTE "DISK" to "SPACE".  Fill in local TYPE and RUN commands.
  152. ;
  153. ;PS:<TIMREK>KERMIT.MAC.810, 28-May-84 10:06:30, Frank
  154. ;[144] Misc bugs fixed:
  155. ; . In ENCODE, fix problem when exactly two consecutive repeat prefix
  156. ;    characters appear in data.
  157. ; . In SRVCMD, decode contents of ACK (it was being displayed "bare").
  158. ; . Remove test for remote at $SERVE, let server work over asg'd tty line.
  159. ; . In DOSRV, don't allow an I packet to cause a state transition.
  160. ; . Don't create empty debugging log files.
  161. ; . Fix bytesize in OPENF in RFIL3K (cosmetic)
  162. ; . Allow SET HANDSHAKE to also accept an octal number.
  163. ;
  164. ;PS:<TIMREK>KERMIT.MAC.804, 28-May-84 09:55:50, Frank
  165. ;[143] Add SET FLOW-CONTROL, SET EXPUNGE.
  166. ; Change SET DEBUGGING LOG to LOG DEBUGGING (like other Kermits).
  167. ;PS:<TIMREK>KERMIT.MAC.803, 19-Apr-84 12:16:59, Frank
  168. ;[142] Fix broken FILCNV for normal-form (from George Boyce, Cornell).
  169. ;PS:<TIMREK>KERMIT.MAC.799, 12-Apr-84 16:29:05, Frank
  170. ;[141] Decode filename in R packet instead of taking it literally.
  171. ; Also, allow ERMSG and KERMSG macros to take addresses, like %JSERR and
  172. ; %JSKER, and make their message formats nicer and more consistent.
  173. ;PS:<TIMREK>KERMIT.MAC.792,  5-Apr-84 13:23:38, Frank
  174. ;[140] Make ^X = ^Z if we're sending a directory (or deleted file) listing.
  175. ;PS:<TIMREK>KERMIT.MAC.791,  3-Apr-84 16:40:01, Frank
  176. ;[139] Fix "help receive" (table out of order).  Fix problem where server was
  177. ; sending a directory listing, interrupted, then asked to delete files, and
  178. ; sent rest of directory listing before deleting files.
  179. ;PS:<TIMREK>KERMIT.MAC.788, 26-Mar-84 13:11:11, Frank
  180. ;[138] Make sure any logs are closed after server FIN command.
  181. ;
  182. ;PS:<TIMREK>KERMIT.MAC.783, 23-Mar-84 11:00:06, Frank
  183. ;[137] When server gets a FINISH command, exit from program rather than
  184. ; going back to KERMIT command level, as we used to before.  Also:
  185. ; . Add SET PROMPT
  186. ; . Add SET RECEIVE SERVER-TIMEOUT (for Bernie)
  187. ; . Fix password delimitation in server CWD command.
  188. ; . Fill in LOCAL CWD command.
  189. ;
  190. ;PS:<TIMREK>KERMIT.MAC.778, 19-Mar-84 19:27:57, Frank
  191. ;[136] Fix mistake in CRC calculation when parity being used.
  192. ;
  193. ;PS:<TIMREK>KERMIT.MAC.767, 15-Mar-84 16:31:22, Frank
  194. ;[135] Move handshake code from beginning of SPACK to end of RPACK.
  195. ; This allows IBM communication to work again.
  196. ; Also, handle carrier drop a little better in SPACK.
  197. ; Also, make sure we close any open file after ^C out of file transfer.
  198. ;
  199. ;PS:<TIMREK>KERMIT.MAC.752, 14-Mar-84 11:50:47, Frank
  200. ;[134] Make SHOW LINE really test carrier, rather than possibly old flag.
  201. ; Put modem/carrier checking stuff in CHKLIN routine.  Also:
  202. ; . Be more defensive about terminal modes after running TTLINK.
  203. ; . Make sure file gets closed if in cAncel state.
  204. ; . Don't assign device if own controlling TTY (even if it is a TVT).
  205. ; . In GIVEUP, obey setting of INCOMPLETE FILE DISPOSITION for incoming
  206. ;   files that ask to be discarded.
  207. ;
  208. ;PS:<SY.FDC>KERMIT.MAC.736, 13-Mar-84 16:27:08, Frank
  209. ;[133] When sending an I packet, keep trying till retry limit exceeded.
  210. ; Also, include byte count and byte size in directory listing.
  211. ;
  212. ;PS:<TIMREK>KERMIT.MAC.735,  9-Mar-84 09:49:03, Frank
  213. ;[132] In STATISTICS, only show last JSYS error if debugging.  Also:
  214. ; . QCTL field in S/I packets and their ACKs was backwards!  Fix in SPAR, RPAR.
  215. ; . Fix a couple details with timers, clear all pending before setting.
  216. ; . In the unlikely event that an incoming filename can't be dealt with, store
  217. ;   the file as -UNTRANSLATABLE-FILENAME-.KERMIT.-1 to avoid sending an error
  218. ;   packet & terminating the transfer.
  219. ;
  220. ;PS:<TIMREK>KERMIT.MAC.726,  7-Mar-84 11:52:31, Frank
  221. ;[131] Add time stamps to debugging-packets log (suggested by BillW).  Also:
  222. ; . When logging incoming data, include current load-adjusted timeout interval.
  223. ; . Try to use different timeouts for sending & receiving.
  224. ; . Double outgoing IAC bytes in SPACK if TVT-BINARY is set.
  225. ;
  226. ;PS:<TIMREK>KERMIT.MAC.716,  5-Mar-84 12:15:09, Frank
  227. ;[130] Rename SET TAC to SET TVT, because it really applies to all ARPANET
  228. ; TVTs.  If TVT, must still OPENF line in 8 bit mode.  Also:
  229. ; . In INCHAR, detect carrier loss and close, deassign line when it happens.
  230. ; . Take class scheduler into account when getting load averages.
  231. ;
  232. ;PS:<TIMREK>KERMIT.MAC.705,  2-Mar-84 10:31:44, Frank
  233. ;[129] Install ARPANET TAC support changes from Dale Chase, ISI.
  234. ; Code mostly adapted from the TOPS-20 MODEM program (Bill Westfield, SRI).
  235. ; Dale's code modified at Columbia to operate through SET TAC rather than by
  236. ; determining TVT status through a site-dependent JSYS (DEC vs BBN vs...).
  237. ;
  238. ; Important installation note from Dale:
  239. ;
  240. ; Some TOPS-20s may need a patch or two to allow user programs to send the
  241. ; necessary telnet protocol negotiations.  The monitor cell NVTDOD must contain
  242. ; "400000,,RSKP" so that TOPS-20 will accept the negotiation.  And some sites
  243. ; may have code that "doubles" any IAC (octal 377) characters sent from a
  244. ; network terminal.  We turned that off here by putting a "RET" in CHKIAC.  If
  245. ; TOPS-20 doubles IACs, this program will not be able to negotiate telnet
  246. ; binary mode.
  247. ;
  248. ;PS:<TIMREK>KERMIT.MAC.691, 29-Feb-84 17:00:05, Frank
  249. ;[128] Several final things before field-test:
  250. ; . Accept null data field in server commands.
  251. ; . In RPAR, ask other side to time us out based on our 15-min ldav rather
  252. ;   than hardwired constant, DRTIM.  New routine ADJTIM does this.
  253. ;   Also, raise DRTIM from 8 to 15 seconds, since we're probably in better
  254. ;   control of the timeouts than the KERMIT on the other side.
  255. ; . In local mode, don't mix up blips with debugging output.
  256. ; . When starting to send, check for incoming NAKs to cut short any delay.
  257. ; . Add support for LOG SESSION command.
  258. ; . Fix mistake in setting file size by clearing RCHR before entering RD state.
  259. ; . Ditto for SCHR when entering SD state.
  260. ; . Exchange parameters before sending file related commands to a server.
  261. ; . Don't send garbage in X headers after a timeout.
  262. ; . Allow RECEIVE when local, for talking to a remote non-server (undo [94]).
  263. ;PS:<TIMREK>KERMIT.MAC.659, 24-Feb-84 18:53:47, Frank
  264. ;[127] Don't assign or open comm line if it's the controlling terminal, don't
  265. ; reset line between transactions if a server.  This prevents a server that got
  266. ; detached (e.g. when carrier dropped) from making the line unavailable for
  267. ; further use.
  268. ;PS:<TIMREK>KERMIT.MAC.653, 24-Feb-84 17:14:45, Frank
  269. ;[126] Put in all the transaction logging code, show status of it in SHOW.
  270. ;PS:<TIMREK>KERMIT.MAC.641, 23-Feb-84 19:01:24, Frank
  271. ;[125] LOG command, parsing only.
  272. ;PS:<TIMREK>KERMIT.MAC.638, 23-Feb-84 17:36:40, Frank
  273. ;[124] When sending a multipacket response to a server command, start with
  274. ; an S packet unless using type 1 block check, in which case start with X.
  275. ;PS:<TIMREK>KERMIT.MAC.636, 23-Feb-84 17:10:52, Frank
  276. ;[123] Add S and N packet heuristics to RPACK to help resync when fancy
  277. ; block check types are being used, but the two sides lose track.
  278. ;PS:<TIMREK>KERMIT.MAC.631, 23-Feb-84 14:38:50, Frank
  279. ;[122] Make directory listing neater.
  280. ;PS:<TIMREK>KERMIT.MAC.629, 23-Feb-84 10:41:34, Frank
  281. ;[121] Fix turning off ^C trap after FINISH, again.
  282. ; Don't try to CLOSF or GNJFN if sending generated text rather than files.
  283. ; Restore normal i/o after sending server help message.
  284. ; Fix SRVCMD to actually do what it says it does.
  285. ; Fix problem with spurious repeat counts appearing in file headers.
  286. ;PS:<TIMREK>KERMIT.MAC.627, 24-Jan-84 18:45:56, Frank
  287. ;[120] Add REMOTE HELP and server support for it.
  288. ;PS:<TIMREK>KERMIT.MAC.617, 24-Jan-84 13:11:20, Frank
  289. ;[119] Decode incoming filenames and validate them more completely.
  290. ;PS:<TIMREK>KERMIT.MAC.613, 23-Jan-84 19:28:23, Frank
  291. ;[118] Server does file deletions.
  292. ;PS:<TIMREK>KERMIT.MAC.612, 23-Jan-84 18:01:33, Frank
  293. ;[117] Fix bugs: SEND x (INITIAL) was broken, and check for receive-packet
  294. ; buffer overflow, to prevent writing over other data (thanks to Greg Small
  295. ; of Berkeley for uncovering that one).
  296. ;PS:<TIMREK>KERMIT.MAC.603, 19-Jan-84 17:08:00, Frank
  297. ;[116] Server sends directory listings.
  298. ;PS:<TIMREK>KERMIT.MAC.570, 18-Jan-84 10:30:07, Frank
  299. ;[115] Rewrite directory listing code to allow for i/o redirection.
  300. ;PS:<TIMREK>KERMIT.MAC.566, 17-Jan-84 11:03:38, Frank
  301. ;[114] Rewrite DIAMSG to give more informative message.
  302. ; When logging packets, precede received packets by "R:", sent by "S:".
  303. ;PS:<SY.FDC>KERMIT.MAC.31, 16-Jan-84 16:31:57, Frank
  304. ;[113] Add LOCAL DELETE command.
  305. ;PS:<SY.FDC>KERMIT.MAC.30, 16-Jan-84 16:15:25, Frank
  306. ;[112] Fix server command business of ACK vs Text Header; get/send one or the
  307. ; other, but not both.
  308. ;PS:<SY.FDC>KERMIT.MAC.18, 16-Jan-84 12:15:04, Frank
  309. ;[111] Make file stepping mechanism do 1-file lookahead.  Add LOCAL DIRECTORY.
  310. ;PS:<TIMREK>KERMIT.MAC.551, 13-Jan-84 19:16:44, Frank
  311. ;[110] Release TTY JFN when ^C'd out of server mode.
  312. ; Thanks to Kimmo Laaksonen (Helsinki), Norm Kincl (HP Labs) for reporting
  313. ; this bug, which surfaced when user detached after ^C out of server mode,
  314. ; leaving TTY assigned and unavailable for new jobs.
  315. ;PS:<TIMREK>KERMIT.MAC.550, 13-Jan-84 17:36:32, Frank
  316. ;[109] Fix bad bug in 8th-bit prefixing.  Also bug in SET PARITY command that
  317. ; prevented SET PARITY NONE from ever working.
  318. ;PS:<TIMREK>KERMIT.MAC.542, 11-Jan-84 09:28:05, Frank
  319. ;[108] Add REMOTE DELETE, REMOTE DIRECTORY.  Misc cleanups, minor fixes.
  320. ; Merge SDEBUG and DIAMSG.  Better recovery from SPACK failures.
  321. ;PS:<TIMREK>KERMIT.MAC.540, 10-Jan-84 17:40:57, Frank
  322. ;[107] Added server support for remote CWD command.
  323. ;PS:<TIMREK>KERMIT.MAC.521,  9-Jan-84 18:26:43, Frank
  324. ;[106] Added REMOTE CWD command.
  325. ;PS:<TIMREK>KERMIT.MAC.512,  9-Jan-84 12:44:11, Frank
  326. ;[105] Debug [104], add REMOTE HOST command.
  327. ;PS:<TIMREK>KERMIT.MAC.500,  6-Jan-84 19:40:33, Frank
  328. ;[104] Add server and user TYPE command.
  329. ; Collapse a lot of redundant code into routines like SRVCMD and DOSRV.
  330. ;PS:<TIMREK>KERMIT.MAC.499,  6-Jan-84 11:50:51, Frank
  331. ;[103] Provide disk quota query service in server mode.
  332. ;*************** Major Version 4.0 ****************
  333. ;
  334. ;(Old Edit History moved to end of file, after END statement)
  335.  
  336. ; THINGS TO DO...
  337. ;
  338. ; * Internal cleanup -- do state transition, packet input & ACK/NAK, etc
  339. ;   globally like C-Kermit, instead of replicating the same code all over.
  340. ;
  341. ; * Check/fix bugs:
  342. ;   . Page mode on/off on assigned line (got some complaints, not verified).
  343. ;   . ^A in local mode sometimes gets lost.
  344. ;   . ^A sometimes not turned off (e.g. after ^C out of f.t., then connect)
  345. ;
  346. ; * Move receive-file opening code to RDATA (& REOF); don't open file until
  347. ;   first data packet (or EOF if null file) arrives, to prepare for attributes.
  348. ;
  349. ; * Finish adding server functions: COPY, RENAME, WHO, MESSAGE, STATUS, RUN,
  350. ;   KERMIT (e.g. "remote kermit set file bytesize 8").
  351. ;
  352. ; * Do something with the REMOTE ERROR command (like think of a better name,
  353. ;   make it visible, and document it, maybe put it on ^E).
  354. ;
  355. ; * When local and receiving a file, if ^Z has no effect, send an error packet
  356. ;   to shut down the transaction.
  357. ;
  358. ; * Add host commands.  Fork an Exec, pass commands to it in rescan, somehow
  359. ;   pipe the Exec's typeout back, packetized.  Too bad TOPS-20 isn't UNIX...
  360. ;   Maybe use LOTS's new pipe device?
  361. ;
  362. ; * Add some support for file attribute packets.
  363. ;
  364. ; * Integrate %JSERR etc with the debugging log mechanism?
  365. ;
  366. ; * When receiving a file, put the name I open the file under in the data field
  367. ;   of the ACK to the File Header.  When receiving File Headers in local mode,
  368. ;   print the contents of the data field instead of doing a JFNS if the data
  369. ;   field is not empty.
  370. ;
  371. ; * In local mode, allow running as a background fork. Or use ^P as an
  372. ;   interrupt character during file transfer to Push to an inferior exec while
  373. ;   the transfer continues above.  ^A should still give progress report.
  374. ;
  375. ; * Separate out the routines according to ISO levels.  In particular, make the
  376. ;   transport-level routines available to any other application (like mail,
  377. ;   e.g. SMTP) that may want to use them.
  378. ;
  379. ; * For various reasons, it might be nice to allow KERMIT-20 to send its
  380. ;   packets to a file, without another KERMIT to talk to.  This will translate
  381. ;   a file into all printable characters (with data compaction, etc) suitable
  382. ;   for transmission over an RJE link or other picky communication media.
  383. ;
  384. ; * Parse single characters in nicer ways, like CONTROL X, or "^X", as well
  385. ;   as octal numbers (in all the SET commands).
  386.  
  387.     Title Kermit -- That's Celtic for "free".
  388.  
  389. ; Needs only standard DEC-distributed external files MONSYM, MACSYM, CMD.
  390.  
  391.     search monsym,macsym,cmd
  392.     .require sys:macrel,sys:cmd
  393.  
  394. ; Originally written by Bill Catchings, Columbia University, April 1981.
  395. ; Taken over by Frank da Cruz, Columbia University, March 1983.
  396. ;
  397. ; This program is the DEC-20 implementation of Columbia University's KERMIT
  398. ; file transfer protocol for use over serial asynchronous communication lines.
  399. ; See the KERMIT user and protocol manuals for the specifications.
  400. ;
  401. ; Version 1,  1981-82:  Basic service (Bill)
  402. ;
  403. ; Version 2,   Feb 83:  Basic server service (Bill)
  404. ;
  405. ; Version 3,   Mar 83:  Local mode, TTLINK, talk to server (Frank)
  406. ;
  407. ; Version 3B,  Oct 83:  I packets, ^X,^Z interrupts, TAKE, DEFINE, etc (Frank)
  408. ;         3C,  Nov 83:  8th-bit prefixing, repeat counts.
  409. ;         3.4, Dec 83:  2- and 3-character block checks.
  410. ;
  411. ; Version 4,   Jan 84:  Advanced server functions, LOG, ARPAnet support (Frank)
  412. ;
  413. ; Version 4.1, Jul 84:  Integrated CONNECT code, no more TTLINK (Frank)
  414. ;
  415. ; Version 4.2, Oct 84:  Non-Protocol upload/download, login scripts (Frank)
  416.  
  417.     subttl Help Text.    ;[18] Lengthy help messages added in edit [18].
  418.  
  419. ; Overall summary, more detailed help text is with each command.
  420. ;
  421. hkermi:    asciz |
  422. KERMIT is a file transfer protocol for use over an asynchronous serial
  423. telecommunication line.  Files are broken up into "packets" with checksums and
  424. other control information to promote error-free and complete transmission.
  425.  
  426. KERMIT-20 is the KERMIT implementation for the DECSYSTEM-20.  KERMIT-20 can be
  427. run "remotely" from another computer (e.g. a microcomputer), or "locally" with
  428. a remote Kermit on the other end of an assigned TTY line (e.g. over an
  429. autodialer connection)
  430.  
  431. You can run Kermit interactively by typing repeated commands in response to
  432. its "Kermit-20>" prompt, or you can invoke it from the TOPS-20 Exec with a
  433. single command line argument (e.g. "kermit receive"), or you can run it as a
  434. remote server.
  435.  
  436. KERMIT-20 command summary -- optional parts are in [brackets]:
  437.  
  438. * For exchanging files using KERMIT protocol:
  439.     SEND file(s) [(INITIAL) file]
  440.     RECEIVE [file]
  441.     GET remote-file(s)
  442.     SERVER
  443.  
  444. * For acting as local Kermit:
  445.     CONNECT [line], INPUT, OUTPUT, CLEAR
  446.     SET: LINE, FLOW, PARITY, DUPLEX, HANDSHAKE, ESCAPE, BREAK, SPEED
  447.  
  448. * For talking to a server:
  449.     BYE, FINISH, GET remote-file(s), SEND file(s);
  450.     REMOTE: DISK-USAGE, TYPE, CWD, DIRECTORY, DELETE, HELP, HOST
  451.  
  452. * Setting nonstandard transmission and file parameters:
  453.     SET: DEBUG, DELAY, FILE, INCOMPLETE, INPUT, ITS, PROMPT, RETRY, TVT;
  454.     SET SEND (or RECEIVE): END-OF-LINE, START-OF-PACKET, PACKET-LENGTH,
  455.         PAUSE, PADDING, TIMEOUT, SERVER-TIMEOUT
  456.     DEFINE a macro for a combination of SET commands.
  457.  
  458. * For non-protocol data transfer:
  459.     INPUT, OUTPUT, PAUSE, CLEAR, TRANSMIT, LOG SESSION
  460.  
  461. * For interrupting transmission: Control-X (^X), ^Z, ^C
  462.  
  463. * Getting information:        HELP [topic], STATISTICS, SHOW, ^A
  464. * Recording information:    LOG or CLOSE TRANSACTIONS, SESSION, DEBUGGING
  465. * Executing command files:      TAKE
  466. * Leaving the program:        EXIT, QUIT, BYE, PUSH
  467.  
  468. If you have a file called KERMIT.INI in your login directory, KERMIT-20 will
  469. execute an implicit TAKE command on it upon initial startup.  KERMIT.INI may
  470. contain any KERMIT-20 commands; DEFINE and SET commands are the most useful.
  471.  
  472. For further information, type "help" for any of the above, e.g. "help set",
  473. or see the "Kermit Users Guide" and the "Kermit Protocol Manual" for complete
  474. details.
  475. |
  476.  
  477.     subttl Definitions
  478.  
  479. pdlsiz==^d200            ; Stack size, be generous.
  480. takel==^d20            ;[78] TAKE command JFN stack size.
  481.  
  482. f=0                ; AC definitions:  flag AC (not used),
  483. t4=<t3=<t2=<t1=1>+1>+1>+1    ;  temporary AC's,
  484. q4=<q3=<q2=<q1=t4+1>+1>+1>+1    ;  and preserved AC's.
  485. state=q4+1            ; State of the automaton.
  486. rchr=state+1            ; Total file characters received.
  487. schr=rchr+1            ; Total file characters sent.
  488. debug=schr+1            ;[22] Debugging (0=none, 1=states, 2=packets)
  489.  
  490. mappag==200            ; Single page window for mapping files.
  491.  
  492. SOH==^o001            ; ASCII Start of header character.
  493. XON==^o021            ; XON is defined to be Control-Q (ASCII DC1).
  494. MAXBUF==^d10240            ; Packet buffer size [179]
  495. MAXPKT==^d94            ; Packet buffer size [179]
  496. IOBUF==^d1024            ; Communications i/o buffer [180]
  497.  
  498. maxpkt=="~"-" "+2        ; Maximum size of a packet.
  499. dmxtry==5            ; Default number of retries on a packet.
  500. dimxtr==20            ; Default number of retries send initiate.
  501. drpsiz==^d80            ; Default receive packet size.
  502. dspsiz==^d80            ; Default send packet size.
  503. spmin==^d10            ;[47] Minimum size packet we want to send.
  504. spmax==^d9000            ;[47] Maximum ...
  505. dstim==^d8            ; Default send time out interval.
  506. drtim==^d13            ;[128] Default receive time out interval.
  507. dsrvtm==^d30            ;[20] Def timout when awaiting server commands.
  508. drpaus==0.0            ;[35] Default pause before ACKing packets.
  509. dspaus==0.0            ;[36] Default pause before sending packets.
  510. dspad==^o0            ; Default send padding char.
  511. drpad==^d0            ; Default receive padding char.
  512. dspadn==^d0            ; Default number of send padding chars.
  513. drpadn==^d0            ; Default number of receive padding chars.
  514. dseol==.chcrt            ; Default send EOL char.
  515. dreol==.chcrt            ; Default receive EOL char.
  516. dsquot=="#"            ; Default outbound control prefix.
  517. drquot=="#"            ; Default incoming control prefix.
  518. dqbin=="&"            ; Default 8th-bit prefix.
  519. drept=="~"            ; Default repeat count prefix.
  520. ddelay==^d1            ; Default delay before the first packet, secs.
  521. dxfull==0            ;[18] Full duplex.
  522. dxhalf==1            ;[18] Half duplex.
  523. defesc==34            ; Default CONNECT escape character is ^\.
  524. defpar==none            ; Default parity.
  525. defits==-1            ;[75] Handle ITS binary files by default.
  526. defics==0            ;[160] Default case search for INPUT commands.
  527. defita==0            ;[160] Default timeout action for INPUTs.
  528. defito==5            ;[160] Default timeout interval for INPUTs.
  529. maxtim=^d94            ;[2] Maximum timeout interval to set, secs.
  530. minlod=4.0            ;[2] Minimum ldav to consider for timeout.
  531. maxlod=50.0            ;[2] Maximum ldav to consider for timeout.
  532. blip=^d5            ;[4] Every this many packets, print a blip.
  533.  
  534. mnblen==^d200            ;[77] Macro name buffer length (words).
  535. mtblen==^d1000            ;[77] Macro text buffer length (words).
  536. macmax==^d100            ;[77] Maximum number of macros.
  537.  
  538. ;[129] ARPA definitions
  539.  
  540. ifndef STAT%,<opdef STAT% [JSYS 745]> ; So this will assemble
  541. ifndef TCP%NT,<TCP%NT==40000000> ; without symbols from BBN TCP monitor.
  542.  
  543. iac==377            ; arpanet telnet IAC
  544. will==373            ; telnet will <option>
  545. wont==374            ; telnet wont <option>
  546. do==375                ; telnet do <option>
  547. dont==376            ; telnet don't <option>
  548. trnbin==0            ; transmit binary
  549. ifdef  .MORLT,<PANDASW==1>    ;[181] Assemble if we have monitor support
  550. ifndef .MORLT,<PANDASW==0>    ;[181]   Or not...
  551. define panda <ifn PANDASW , >    ;[181]     and a handy abbreviation!
  552. ;[182] Wouldn't it be REAL nice if these fields were defined in MONSYM?
  553. ntflag==MASKB(0,8)        ;[182] Terminal flags
  554. nttype==MASKB(9,17)        ;[182] Network type
  555. ntline==MASKB(18,35)        ;[182] Line type
  556. ntblen==<.NWNU1+2>        ;[182] Minimum length
  557.  
  558.     subttl Macros
  559.  
  560.  
  561. ; ERMSG -- Type error message on local terminal, and save a pointer to the
  562. ;  error string, that can be used when querying most recent error.
  563.  
  564. define ermsg (msg,label) <
  565.      jrst [    tmsg <
  566. >
  567.         hrroi t1, [asciz/?KERMIT-20: 'msg/]
  568.         movem t1, errptr ;; Save pointer to error msg for stats.
  569.         PSOUT%
  570.         tmsg <
  571. >
  572. ifb <label>,<    jrst .+1>
  573. ifnb <label>,<    jrst label>
  574.         ]
  575. >;ermsg
  576.  
  577.  
  578. ; KERMSG -- Like ERMSG, but also send the message to the other KERMIT in
  579. ;  an error packet, which cancels the current transfer.
  580.  
  581. define kermsg (msg,label) <
  582.     $count=0
  583.     irpc msg, <$count=$count+1>
  584.      jrst [    movei t1, "E"    ;; Send an error packet to the other side.
  585.         move t2, pktnum    ;; Packet number.
  586.         movei t3, $count+^d11 ;; The count.
  587.         move t4, [point 7, [asciz/KERMIT-20: 'msg/]] ;; The msg.
  588.         movem t4, errptr ;; Save pointer to error msg for status.
  589.         call spack    ;; Send the error packet.
  590.          nop
  591.         tmsg <
  592. ?KERMIT-20: 'msg
  593. >
  594. ifb <label>,<    jrst .+1>
  595. ifnb <label>,<    jrst label>
  596.         ]
  597. >
  598.  
  599. ; Error handling macros, cont'd
  600.  
  601.  
  602. ; %JSERR -- Invoked by ERJMP after a JSYS call.  Prints the given message,
  603. ;  if any, then the JSYS error message, and then jumps to the address given
  604. ;  or else halts (continuably) if no jump address given.
  605. ;[163] Make it include the address of the failing JSYS at end of message.
  606.  
  607. define %jserr (msg, label) <    ;; Use this immediately following a JSYS.
  608.     ercal [ ttcrlf        ;; Output a crlf if necessary
  609.         tmsg <?KERMIT-20: 'msg> ;; Type given msg with our prefix,
  610. ifnb <msg>,<    call jserr0>    ;;  if given, put JSYS error after dash,
  611. ifb <msg>,<    call jsmsg0>    ;;  else right after "?KERMIT-20:  "
  612.         tmsg < at PC >    ;; Say where it happened.
  613.         pop p, t2    ;; Pop the return address off the stack.
  614.         hrrzs t2    ;; Clear out junk from left half.
  615.         subi t2, 2    ;; Adjust to point at offending JSYS.
  616.         numout t2, ^d8    ;; Type JSYS PC in octal.
  617.         tmsg <
  618. >                ;; And a trailing CR.
  619. ifb <label>,<    HALTF%        ;; Then, if no label was specified, halt
  620.         jrst .+1    ;; continuably,
  621. >;ifb
  622. ifnb <label>,<    jrst label>    ;; or if there was, go there.
  623.           ]
  624. >;%jserr
  625.  
  626.  
  627. define %ermsg (msg, label) <    ;; Use this in any skipping context.
  628.     jrst [    ttcrlf
  629.         tmsg <?KERMIT-20: 'msg> ;; Otherwise, just like %JSERR.
  630. ifnb <msg>,<    call jserr0>    ;; Except no PC typeout.
  631. ifb <msg>,<    call jsmsg0>
  632.         tmsg <
  633. >
  634. ifb <label>,<    HALTF%
  635.         jrst .+1
  636. >;ifb
  637. ifnb <label>,<    jrst label>
  638.           ]
  639. >;%ermsg
  640.  
  641. ; %JSKER -- Like %JSERR, but also sends message to other KERMIT in an error
  642. ; packet, as KERMSG does.
  643.  
  644. define %jsker (msg, label) <    ;; Use this immediately following a JSYS.
  645.     erjmp [
  646. ifb <msg>,<    move t1, [point 7, [asciz/KERMIT-20: /]] >
  647. ifnb <msg>,<    move t1, [point 7, [asciz/KERMIT-20: 'msg - /]] >
  648.         movem t1, errptr ;; Save pointer to error msg for status.
  649.         call %%krms
  650.         ttcrlf
  651.         tmsg <?KERMIT-20: 'msg> ;; Type given msg with our prefix,
  652. ifnb <msg>,<    call jserr0>    ;;  if given, put JSYS error after dash,
  653. ifb <msg>,<    call jsmsg0>    ;;  else right after "?Kermit:  "
  654.         tmsg <
  655. >                ;; And a trailing CR.
  656. ifb <label>,<    HALTF%        ;; then if no label was specified, halt,
  657.         jrst .+1    ;; continuably,
  658. >;ifb
  659. ifnb <label>,<    jrst label>    ;; or if there was, go there.
  660.           ]
  661. >;%jsker
  662.  
  663. ; Support routines for error handling macros.
  664.  
  665.  
  666. ; JSERR0 synchronizes with terminal i/o in progress before typing the
  667. ;  JSYS error message.
  668. ;
  669. ; JSMSG0 just types the JSYS error message.
  670. ;
  671. jserr0:    movei t1,.priin
  672.     CFIBF%            ; Clear typeahead.
  673.     movei t1,.priou
  674.     DOBE%            ; Wait for previous output to finish.
  675.     tmsg < - >        ; Type a dash.
  676. jsmsg0:    movei t1,.priou
  677.     hrloi t2,.fhslf        ; This fork ,, last error.
  678.     setz t3,
  679.     ERSTR%
  680.      jfcl
  681.      jfcl
  682.     ret
  683.  
  684.  
  685. ; KERMSG -- Send an error message to the KERMIT on the other side in an
  686. ;  error packet.  Invoked from %JSKER, with T1 pointing at the user-provided
  687. ;  prefix (if any), to which the JSYS error message is appended.
  688.  
  689. blanks:    repeat <maxpkt/4>,<ascii/     />
  690.  
  691. %%krms: move t3, [blanks,,%%krbf] ;[40] Fill up the msg buffer with blanks.
  692.     blt t3, <%%krbf+<maxpkt/4>-1> ;[40]
  693.     move t3, [point 7, %%krbf] ; Get a pointer to the buffer.
  694.     setz t4,        ; Zero the counter.
  695. %%krm1:    ildb t2, t1        ; Get the byte.
  696.     jumpe t2, %%krm2    ; Is it a null?
  697.     idpb t2, t3        ; Deposit the byte.
  698.     aoja t4, %%krm1
  699. %%krm2:    move t1, t3        ; Put the information into the buffer.
  700.     hrloi t2, .fhslf    ; Say:  this fork ,, last error.
  701.     movn t3, spsiz        ; Specify the maximum to send as a negative
  702.     add t3, t4        ;  number
  703.     hrlzs t3        ;[74] (ERSTR wants -n,,0)
  704.     skipge t3        ;[50] (don't bother if not negative).
  705.      ERSTR%
  706.      trn
  707.      trn
  708.     move t2, t1        ; Set up to get the new length.
  709.     move t1, [point 7, %%krbf] ; ...
  710.     call subbp        ; Subtract byte pointers.
  711.      skipa            ;[40] If there is an error assume this count.
  712.     camle t3, spsiz        ;[40] Longer than we're supposed to send?
  713.      move t3, spsiz        ;[40] If so, truncate it.
  714.     movei t1, "E"        ; An error packet.
  715.     move t2, pktnum        ; Packet number.
  716.     move t4, [point 7, %%krbf] ; Pointer to string.
  717.     call spack        ; Send the error packet.
  718.      nop
  719.     ret
  720.  
  721. ; Misc macros
  722.  
  723.  
  724. ; NUMOUT - Type a number in the desired base (decimal by default), free format.
  725.  
  726. define numout(num,base<^d10>) <
  727.     call [    saveac <t1,t2,t3>
  728.         move t2, num
  729.         movei t1, .PRIOU
  730.         movei t3, base
  731.         NOUT%
  732.          nop
  733.         ret ]    
  734. >;numout
  735.  
  736.  
  737. ; OUTCHR - Type a character at the terminal without disturbing any registers.
  738.  
  739. define    OUTCHR(char) <
  740.     jrst [    exch t1, char
  741.         PBOUT
  742.         exch t1, char
  743.         jrst .+1 ]
  744. >;OUTCHR
  745.  
  746.  
  747. ;[126] Write time-stamped file message to the transaction log file.
  748. ;
  749. ; Macro arguments are a message string and the address of a JFN
  750. ; of the filename to write, e.g.
  751. ;
  752. ;    wtlog (<Sending >,filjfn)
  753. ;
  754. define wtlog(..msg,..file) <
  755.     call [ skipn t1, tlgjfn ;; Transaction log open?
  756.          ret          ;; No, skip this.
  757.         saveac <t2,t3,t4> ;; Yes, save these AC's
  758.         seto t2,    ;; Start with time stamp, current date/time.
  759.         movx t3, ot%nda    ;; No date.
  760.         ODTIM
  761.         hrroi t2, [asciz/: /] ;; Punctuation.
  762.         setzb t3, t4
  763.         SOUT
  764.         hrroi t2, [asciz/..msg/] ;; The given message.
  765.         SOUT
  766. ifnb <..file>,<
  767.         move t3, [111110,,js%paf]
  768.         skiple t2, ..file ; File name.
  769.          JFNS
  770. >;ifnb
  771.         setz t3,
  772.         hrroi t2, crlf
  773.         SOUT
  774.         ret ]
  775. >;wtlog
  776.  
  777. ; %TABLE - Beginning of COMND/TBLUK keyword table.
  778. ;
  779. define %table <
  780.     %%tbst== .        ;; Plant start of table
  781.     exp 0            ;;  and leave a hole for %tbend to fill
  782. >
  783.  
  784. ; %TBEND - End of COMND/TBLUK keyword table.
  785. ;
  786. define %tbend <
  787.     %%tbnd==.-1        ;; Get address of last entry in table
  788.     .org %%tbst        ;; Move back to start
  789.     xwd %%tbnd-%%tbst, %%tbnd-%%tbst;;  and build table header
  790.     .org            ;; Finally, get back to the way we were
  791. >
  792.  
  793. ; %KEY - COMND or TBLUK keyword definition
  794. ;
  795. ; This macro takes three arguments: an (alphanumerics only!) keyword, the
  796. ; data to be associated with the keyword, and an (optional) flag value.  It
  797. ; creates either a flagless keyword (the normal case), or, if any flags are
  798. ; given, a keyword with flags in the first word and CM%FW set.  Thus,
  799. ; the result is a TBLUK table entry, suitable for use by the .CMKEY COMND
  800. ; JSYS function.  Note that all %KEY words in a table must be bracketed
  801. ; by %TABLE and %TBEND macros (see above).
  802. ;
  803. define %key (name, data, flags) < ;; Flags are optional
  804.    ifb <flags>, <
  805.     xwd [asciz\name\],data    ;; No-flags case
  806.    >
  807.    ifnb<flags>, <
  808.     xwd [<flags>!cm%fw    ;; Flags: first word holds them,
  809.          asciz\name\], data    ;;  second is start of name
  810.    >
  811. >
  812.  
  813. define ttcrlf <             ;; Output a CRLF if not at left margin.
  814.     call [    saveac <t1,t2>
  815.         movei t1, .priou
  816.         RFPOS%    
  817.         hrroi t1, crlf
  818.         trne t2, -1
  819.          PSOUT
  820.         ret ]
  821. >;;ttcrlf
  822.  
  823.  
  824.     subttl Command Line Processing
  825.  
  826. ;  RESCAN - Routine to check for command line arguments.
  827. ;
  828. ;[85] Returns +1 always, with F$EXIT = 0 if no args, nonzero if some args.
  829. ;
  830. rescan:    setzm f$exit        ;[85] Assume no rescan arguments.
  831.     movx t1, .rsini        ; Now check.
  832.     RSCAN%            ;  ...
  833.      erjmp r        ;[85]  If none return.
  834.  
  835.     movx t1, .rscnt        ; Get the size of the rescan.
  836.     RSCAN%            ;  ...
  837.      erjmp r        ;[85]  Return if unsucessful.
  838.     jumpe t1, r        ;[85] If the size is zero return.
  839.     
  840.     prompt <>        ; Null prompt.
  841.     movei t1, r+1        ; Get the address we want to go to on reparse.
  842.     movem t1, repara    ; Fudge it.  This is to prevent looping back
  843.                 ;  to prompt <> for ever on an error on the
  844.                 ;  rescan line.
  845.     movei t1, [flddb. (.cmkey,,<[exp <1,,1>,<[asciz/Kermit/],,0>]>)]
  846.     call rflde        ; Parse it.
  847.      ret            ;[85]  If we don't find it return.
  848.     setom f$exit        ;[85] Assume we have command line arguments.
  849.     movei t1, [flddb. (.cmcfm,cm%sdh)] ; See if we can parse a confirm.
  850.     call rflde        ;  ...
  851.      ret            ;  If not, we have a rescan argument.
  852.     setzm f$exit        ;[85] Parsed confirmation, so no arguments.
  853.     ret            ;[85] Done.
  854.  
  855.     subttl KERMIT Program entry, initialization, and exit.
  856.  
  857. kermit:    jrst start        ; Start entry.
  858.     jrst reen        ; Re-entry.
  859. versio:    FLD($who,VI%WHO)!FLD($verno,VI%MAJ)!FLD($mnver,VI%MIN)!
  860.     FLD($edno,VI%EDN)!VI%DEC ;;[184] Want decimal version numbers
  861. evlen==.-kermit
  862.  
  863. reen:    jrst start        ; Nothing special for now...
  864.  
  865. start:    RESET%            ; Normal startup: reset everything
  866.     setzm monv        ; See what monitor version.
  867.     move t1, [sixbit/MONVER/] ; This only works in V6 or later.
  868.     SYSGT
  869.      erjmp .+1
  870.     skipe t2        ; Got anything?
  871.      movem t1, monv        ; Yes, save it.
  872.  
  873.     move p, [iowd pdlsiz,pdl] ;  and set up a stack.
  874.     setzm ttfork        ; Clear connect receive fork handle
  875.     setzm netjfn        ; and communication line JFN
  876.     setzm f$exit        ; and exit flag, so we re-init if restarted.
  877.  
  878. ;[78] Set up a JFN stack for 'take' commands.
  879.  
  880.     move t2, [iowd takel, takpdl] ;[78] Construct TAKE jfn stack pointer.
  881.     movem t2, takep        ;[78]
  882.     setzm takdep        ;[78] Start 'take depth' out at 0.
  883.     setzm takjfn        ;[78] And no TAKE file jfn.
  884.  
  885. ; Run KERMIT...
  886.  
  887.     call main        ; The actual program.
  888. halt:    HALTF%            ; Upon return, just halt.
  889.  
  890. ; If continued, fall thru to here...
  891.  
  892. cont:    setzm f$exit        ; Turn off the exit flag.
  893.     GJINF%            ;[184] Load current job line in t4
  894.     movem t4, ttynum    ;[184] stomp in a possible new line
  895.     move t1, ttynum        ;[87] Reassign the line we were using.
  896.     movem t1, pars3        ;[87] (this is the calling convention...)
  897.     call $setln        ;[85]
  898.  
  899.     call prsint        ; Go to command level.
  900.     jrst halt
  901.  
  902.     subttl  KERMIT main program
  903.  
  904. main:    setzm local        ; Start off running remotely.
  905.     call pinit        ; Initialize interrupt system.
  906.     movei t1, .fhslf    ;[176] Read current process capabilities.
  907.     RPCAP%            ;[176]
  908.     movem t2, capas        ;[176]
  909.     seto t1,        ; Get job info for this job.
  910.     move t2, [-20,,jobtab]    ; Into this job table.
  911.     setzb t3, t4
  912.     GETJI
  913.      %jserr (,.+1)
  914.     dmove t3, jobtab    ; Get job & terminal numbers.
  915.     movem t3, myjob        ; Job number of my job.
  916.     movem t4, mytty        ; Remember this is my controlling terminal.
  917.     movem t4, pars3        ; Make believe we parsed terminal number
  918.     setz debug,        ; And no debugging
  919.     call $setln        ; Set the line to our own.
  920. panda <    call chknbm >        ;[181] Determine if we have network binary mode
  921.     call cmdini        ; Initialize the command package.
  922.     call inifil        ;[79] Execute commands from KERMIT.INI, if any.
  923. ccl:     call rescan        ;[85] If no .INI file, look for rescan now.
  924.     skipe f$exit        ;[85] If there was a rescan argument,
  925.      jrst parse        ;[85] go do that.
  926.     jrst @dfstrt        ; No rescan go to default: PROMPT or SERVER.
  927.  
  928. server:    jrst getcom        ; Here if starting as server by default.
  929.  
  930. ; Here if starting in command mode by default.
  931.  
  932. promp:    skipe iniflg        ;[83] Doing init file?
  933.      jrst prsint        ;[83]  Yes, don't print herald yet.
  934.     move q1, [ret]        ;[39] Hokey calling convention for routine
  935.     call $shver        ;[39]  to print current program version.
  936.  
  937. prsint:    setzm rcving        ; Indicate neither receiving nor sending.
  938.     skipe f$exit        ; Exit flag set by EXIT command or CCL entry?
  939.      jrst clenup        ;  If so, go clean up and return.
  940.     hrroi t1, prompx    ;[137] Otherwise, point to prompt text.
  941.     call dpromp        ;[137] Issue prompt.
  942.  
  943. parse:    setzm pars1        ;[40] Clean out old parse values.
  944.     move t1, [pars1,,pars2] ;[40]
  945.     blt t1, parsx        ;[40]
  946.     setzm cjfnbk+.gjgen    ; Clear the JFN bits.
  947.     movei t1, [flddb. .cmkey,,cmdtab] ; Point to command keyword table.
  948.     skipe local        ;[68] Running in local mode?
  949.      movei t1, [flddb. .cmkey,,cmdtb2] ;[68] Yes, use that table instead.
  950.     call rflde        ;[78] Parse a keyword.
  951.      jrst eoftst        ;[78] If error, test for EOF on command file.
  952.     hrrz t2, (t2)        ; Get the command routine addresses.
  953.     movem t2, pars1        ; Save into pars1.
  954.     hlrz t1, (t2)        ; Get the next level routine.
  955.     call (t1)        ; Call it.
  956.  
  957. eval:    move t2, pars1        ; Get back data value.
  958.     hrrz t1, (t2)        ; Get evaluation routine.
  959.     call (t1)        ; Call it.
  960.     jrst prsint        ; Go round again.
  961.  
  962. ;[78] EOFTST:  Command file EOF handler.
  963. ;
  964. eoftst:    push p, t2        ; Save this in case we can resume.
  965.     movei t1, .fhslf    ; Get last process error.
  966.     GETER%            ; Test for eof on COMND input file.
  967.     move t1, t2        ; Move error code from t2 to t1
  968.     pop p, t2        ;  and restore t2.
  969.     hrrzs t1        ; Erase fork handle from this.
  970.     caie t1, iox4        ; Was error EOF?
  971.      cain t1, comnx9    ; Or this kind of EOF?
  972.      jrst eofts2        ;[85] Yes, some kind of EOF.
  973.  
  974.     skipe f$exit        ;[85] Parsing rescan line?
  975.      jrst [    tmsg <?Not a KERMIT command - > ;[85] Yes, print message
  976.         hrroi t1, atmbuf ;[85]
  977.         PSOUT        ;[85]
  978.         ret ]        ;[85] And quit.
  979.  
  980. ; Not EOF, and not parsing rescan line, just enter normal parse error handler.
  981.  
  982.     jrst cmderr        ; Complain, then resume parsing.
  983.  
  984. ; EOF on command file.
  985.  
  986. eofts2:    call popjfn        ; It was EOF.  Pop the command file JFN.
  987.      jrst [    movei t1, .priin ; On any error, revert parsing to TTY.    
  988.         call setcsb    ;  ...
  989.         jrst .+1 ]
  990.     skipn iniflg        ;[83] Just closed init file?
  991.      jrst prsint        ;[83]  No, don't bother with rescan stuff.
  992.  
  993. ;[83] Just closed init file, check for command line (rescan) arguments.
  994.  
  995.     setzm iniflg        ;[83] Flag that we're done with init file.
  996.     jrst ccl        ;[85] And go check for rescan arguments.
  997.  
  998. ; Top-Level command tables.
  999.  
  1000. ; Commands available to remote KERMIT.
  1001.  
  1002. cmdtab:    %table
  1003.     %key <bye>, [xwd .bye,$bye], cm%inv ;[11]
  1004.     %key <c>, %conn, cm%inv+cm%abr
  1005.     %key <clear>, [xwd .clear,$clear], cm%inv ;[162]
  1006.     %key <close>, [xwd .close,$close]
  1007. %conn:    %key <connect>, [xwd .conne,$conne]
  1008.     %key <cwd>, [xwd .ycwd,$ycwd] ;[145]
  1009.     %key <define>, [xwd .defin,$defin] ;[77]
  1010.     %key <delete>, [xwd .ydele,$ydele] ;[145]
  1011.     %key <directory>, [xwd .ydire,$ydire] ;[145]
  1012.     %key <e>, %exit, cm%inv+cm%abr
  1013.     %key <echo>, [xwd .echo,$echo]
  1014. %exit:    %key <exit>, [xwd .exit,$exit]
  1015.     %key <finish>, [xwd .finis,$finis], cm%inv ;[28]
  1016.     %key <get>,  [xwd .get,$get], cm%inv ;[11]
  1017.     %key <help>, [xwd .help,$help]
  1018.     %key <input>, [xwd .input,$input], cm%inv ;[159]
  1019.     %key <local>, [xwd .local,$local] ;[56]
  1020.     %key <log>, [xwd .log,$log] ;[125]
  1021.     %key <output>, [xwd .outpu,$outpu], cm%inv ;[159]
  1022.     %key <pause>, [xwd .pause,$pause], cm%inv ;[159]
  1023.     %key <prompt>, [xwd .promp,$promp], cm%inv
  1024.     %key <push>, [xwd .push,$push] ;[152]
  1025.     %key <quit>, [xwd .exit,$exit]
  1026.     %key <r>, %recv, cm%inv+cm%abr ;[56]
  1027. %recv:    %key <receive>, [xwd .recv,$recv]
  1028.     %key <remote>, [xwd .remot,$remot], cm%inv ;[56]
  1029.     %key <run>, [xwd .yrun,$yrun] ;[145]
  1030.     %key <s>, %send, cm%inv+cm%abr
  1031. %send:    %key <send>, [xwd .send,$send]
  1032.     %key <server>, [xwd .serve,$serve]
  1033.     %key <set>, [xwd .set,$set]
  1034.     %key <show>, [xwd .show,$show]
  1035.     %key <space>, [xwd .ydisk,$ydisk] ;[145]
  1036.     %key <statistics>, [xwd .stat,$stat]
  1037.     %key <take>, [xwd .take,$take] ;[78]
  1038.     %key <transmit>, [xwd .trans,$trans],cm%inv ;[165]
  1039.     %key <type>, [xwd .ytype,$ytype] ;[145]
  1040.     %tbend
  1041.  
  1042. ; Commands available to local KERMIT.
  1043.  
  1044. cmdtb2:    %table
  1045.     %key <bye>, [xwd .bye,$bye] ;[11]
  1046.     %key <c>, %conn2, cm%inv+cm%abr
  1047.     %key <clear>, [xwd .clear,$clear] ;[162]
  1048.     %key <close>, [xwd .close,$close]
  1049. %conn2:    %key <connect>, [xwd .conne,$conne]
  1050.     %key <cwd>, [xwd .ycwd,$ycwd] ;[145]
  1051.     %key <define>, [xwd .defin,$defin] ;[77]
  1052.     %key <delete>, [xwd .ydele,$ydele] ;[145]
  1053.     %key <directory>, [xwd .ydire,$ydire] ;[145]
  1054.     %key <e>, %exit2, cm%inv+cm%abr
  1055.     %key <echo>, [xwd .echo,$echo]
  1056. %exit2:    %key <exit>, [xwd .exit,$exit]
  1057.     %key <finish>, [xwd .finis,$finis] ;[28]
  1058.     %key <get>,  [xwd .get,$get]    ;[11]
  1059.     %key <help>, [xwd .help,$help]
  1060.     %key <input>, [xwd .input,$input] ;[159]
  1061.     %key <local>, [xwd .local,$local] ;[56]
  1062.     %key <log>, [xwd .log,$log] ;[125]
  1063.     %key <output>, [xwd .outpu,$outpu] ;[159]
  1064.     %key <pause>, [xwd .pause,$pause] ;[159]
  1065.     %key <prompt>, [xwd .promp,$promp], cm%inv
  1066.     %key <push>, [xwd .push,$push] ;[152]
  1067.     %key <quit>, [xwd .exit,$exit]
  1068.     %key <r>, %recv2, cm%inv+cm%abr ;[56]
  1069. %recv2:    %key <receive>, [xwd .recv,$recv]
  1070.     %key <remote>, [xwd .remot,$remot] ;[56]
  1071.     %key <run>, [xwd .yrun,$yrun] ;[145]
  1072.     %key <s>, %send2, cm%inv+cm%abr
  1073. %send2:    %key <send>, [xwd .send,$send]
  1074.     %key <server>, [xwd .serve,$serve], cm%inv
  1075.     %key <set>, [xwd .set,$set]
  1076.     %key <show>, [xwd .show,$show]
  1077.     %key <space>, [xwd .ydisk,$ydisk] ;[145]
  1078.     %key <statistics>, [xwd .stat,$stat]
  1079.     %key <take>, [xwd .take,$take] ;[78]
  1080.     %key <transmit>, [xwd .trans,$trans] ;[165]
  1081.     %key <type>, [xwd .ytype,$ytype] ;[145]
  1082.     %tbend
  1083.  
  1084.     subttl    ECHO command [167]
  1085.  
  1086. ; Help text for ECHO
  1087.  
  1088. hecho:    asciz |
  1089. ECHO text-string
  1090.  
  1091. Echoes the given text string at your terminal.  Useful in TAKE command files
  1092. and with login scripts for reporting progress or telling you what to do.
  1093. |
  1094. .echo:    noise <text at terminal> ; Issue noise words
  1095.     movei t1, [flddb. .cmtxt] ; Get the string into the atom buffer.
  1096.     call cfield
  1097.     ret
  1098.  
  1099. $echo:    hrroi t1, atmbuf    ; Point at the atom buffer.
  1100.     PSOUT            ; Type the string.
  1101.     hrroi t1, crlf        ; And a CRLF.
  1102.     PSOUT    
  1103.     ret
  1104.  
  1105.     subttl    EXIT and QUIT commands (which are the same)
  1106.  
  1107. ; Help text for QUIT.
  1108.  
  1109. hquit:    asciz |
  1110. QUIT
  1111.  
  1112. Synonym for EXIT.
  1113. |
  1114.  
  1115. ; Help text for EXIT...
  1116.  
  1117. hexit:    asciz |
  1118. EXIT
  1119.  
  1120. Exit from KERMIT-20.  You can CONTINUE the program from the TOPS-20 Exec,
  1121. provided you haven't run another program on top of it.  You can also exit from
  1122. KERMIT-20 by typing one or more control-C's, even if it's in the middle of
  1123. transferring a file.  KERMIT-20 will always restore your terminal to its
  1124. original condition, and you will be able to CONTINUE the program to get back
  1125. to KERMIT-20> command level.  When you EXIT from KERMIT-20, any open files,
  1126. including logs, will be closed.
  1127. |
  1128.  
  1129. ; Parse the rest of the EXIT or QUIT command.
  1130.  
  1131. .exit:    noise <from Kermit>
  1132.     confrm            ; Confirm.
  1133.     ret
  1134.  
  1135. ; Execute the EXIT or QUIT command.
  1136.  
  1137. $exit:    setom f$exit        ; Set exit flag.
  1138.     ret            ; (that's all)
  1139.  
  1140. ; Routine to clean up any open files or devices.
  1141.  
  1142. clenup:    move t1, netjfn        ;[127] Get communication line JFN.
  1143.     setzm netjfn
  1144.     setzm local
  1145.     caie t1, .cttrm        ;[127] Previous one was controlling terminal?
  1146.      skipn t1        ;[127] Close any assigned TTY.
  1147.      jrst clenu2
  1148.     CLOSF
  1149.      erjmp .+1        ; Ignore any error (silently).
  1150. clenu2:    skipn asgflg        ; Did I also assign the TTY?
  1151.      jrst clenu3        ; No.
  1152.     move t1, ttynum        ; Yes, so I should deassign it.
  1153.     movei t1, .ttdes(t1)
  1154.     RELD%
  1155.      erjmp .+1
  1156.     setzm asgflg
  1157.  
  1158. clenu3:    skipn t1, logjfn    ; Do we have a debugging log?
  1159.      jrst clenu4        ;  No.
  1160.     setz t2,        ;[144] Yes, any bytes written?
  1161.     RFPTR            ;[144]
  1162.      nop            ;[144]
  1163.     skipg t2        ;[144]
  1164.      txo t1, cz%abt        ;[144] None, don't bother keeping the log.
  1165.     setzm logjfn        ; Yes, forget about it,
  1166.     CLOSF            ; Close it.
  1167.      erjmp .+1
  1168.  
  1169. clenu4:    skipn t1, tlgjfn    ;[126] Transaction log was open?
  1170.      jrst clenu5
  1171.     wtlog <Closed Transaction Log>
  1172.      setzm tlgjfn
  1173.     CLOSF
  1174.      erjmp .+1
  1175.  
  1176. clenu5:    skipn t1, filjfn    ; Any file transfer JFNs hanging around?
  1177.      jrst clenu6
  1178.     setzm filjfn
  1179.     CLOSF
  1180.      erjmp .+1
  1181.  
  1182. clenu6:    skipn t1, sesjfn    ; How about a session log?
  1183.      jrst clenuz
  1184.     setzm sesjfn
  1185.     CLOSF
  1186.      erjmp .+1
  1187.  
  1188. clenuz:    ret            ; Note, we DON'T turn off interrupt system.
  1189.  
  1190.     subttl    HELP command
  1191.  
  1192. hsfdb1: flddb. .cmkey,,mactab,<SET macro,>,<summary>,hsfdb2
  1193. hsfdb2:    flddb. .cmkey,,sethlp,<SET option,>,<summary>
  1194.  
  1195. .help:    noise <about>        ;[18] HELP
  1196.     movei t1, [flddb. .cmkey,,hlptab,,<kermit>]
  1197.     call rfield        ;[67]
  1198.     move t2, (t2)        ; Get help text address.
  1199.     movem t2, pars3
  1200.     hrrzs t2        ;[67]
  1201.     caie t2, hset        ;[67] They want help for SET?
  1202.      jrst .helpx        ;[67]  No.
  1203.     noise <parameter>    ;[67] Yes, give guide word.
  1204.     movei t1, hsfdb1    ;[77] Parse from macro or SET keyword table.
  1205.     call rfield        ;[67] Get SET option they want help for.
  1206.     hrrzs t3        ;[77] Which function descriptor block was used?
  1207.     caie t3, hsfdb1        ;[77] The macro table?
  1208.      move t2, (t2)        ;[67]  Yes, don't do indirection
  1209.     movem t2, pars3        ;[67] SET...
  1210. .helpx:    confrm            ;[67]
  1211.     ret
  1212.  
  1213. hlptab:    %table            ;[18] Table of help commands.
  1214.     %key <bye>,hbye
  1215.     %key <clear>,hclear    ;[162]
  1216.     %key <close>,hclose
  1217.     %key <connect>,hconne
  1218.     %key <CWD>,hcwd
  1219.     %key <define>,hdefin    ;[77]
  1220.     %key <delete>,hdele
  1221.     %key <directory>,hdire
  1222.     %key <echo>,hecho
  1223.     %key <exit>,hexit
  1224.     %key <finish>,hfinis
  1225.     %key <get>,hget
  1226.     %key <help>,hhelp
  1227.     %key <input>,hinput    ;[159]
  1228.     %key <kermit>,hkermi
  1229.     %key <local>,hlocal
  1230.     %key <log>,hlog
  1231.     %key <output>,houtpu    ;[159]
  1232.     %key <pause>,hpause    ;[159]
  1233.     %key <prompt>,hpromp
  1234.     %key <push>,hpush
  1235.     %key <quit>,hquit
  1236.     %key <receive>,hrecei
  1237.     %key <remote>,hremot
  1238.     %key <run>,hrun
  1239.     %key <send>,hsend
  1240.     %key <server>,hserve
  1241.     %key <set>,hset
  1242.     %key <show>,hshow
  1243.     %key <space>,hspace
  1244.     %key <statistics>,hstatu
  1245.     %key <take>,htake
  1246.     %key <transmit>,htrans
  1247.     %key <type>,htype
  1248.     %tbend
  1249.  
  1250. sethlp:    %table            ;[67] Table of HELP SET commands.
  1251.     %key <break>, hsbrea
  1252.     %key <block-check>, hsbc
  1253.     %key <debugging>, hsdeb
  1254.     %key <delay>, hsdel
  1255.     %key <duplex>, hsdup
  1256.     %key <escape>, hsesc
  1257.     %key <file>, hsfil
  1258.     %key <flow-control>, hsflo ;[143]
  1259.     %key <handshake>, hshan    ;[76]
  1260.     %key <incomplete>, hsabf
  1261.     %key <input>, hsetin    ;[160]
  1262.     %key <ITS-binary>, hsits ;[75]
  1263.     %key <line>, hslin
  1264.     %key <parity>, hspar
  1265.     %key <prompt>, hsprom    ;[137]
  1266.     %key <receive>, hsrcv
  1267.     %key <retry>, hsrty
  1268.     %key <send>, hssnd
  1269.     %key <speed>, hspeed
  1270.     %key <summary>, hset
  1271.     %key <TVT-Binary>, hstac ;[129]
  1272.     %tbend
  1273.     
  1274.     ;...
  1275.  
  1276. ;...HELP command, cont'd
  1277.  
  1278.  
  1279. ; Help text for HELP command...
  1280.  
  1281. hhelp:    asciz |
  1282. HELP [topic]
  1283.  
  1284. Typing HELP alone prints a brief summary of KERMIT-20 and its commands.
  1285. You can also type
  1286.  
  1287.    HELP command
  1288.  
  1289. for any Kermit-20 command, e.g. "help send", to get more detailed information
  1290. about a specific command.  To see a list of all the available help commands,
  1291. type
  1292.  
  1293.    HELP ?
  1294.  
  1295. or consult the Kermit User Guide.
  1296. |
  1297.  
  1298. ; Execute the help command.
  1299.  
  1300. $help:    hrrz t3, pars3        ;[77] Special case for help about macro.
  1301.     cail t3, mactab+1
  1302.      caile t3, mactbx
  1303.      jrst $help2    
  1304.     tmsg <
  1305. ">
  1306.     hlro t1, (t3)
  1307.     PSOUT
  1308.     tmsg <" is a SET macro defined to be:
  1309.    >
  1310.     hrro t1, (t3)
  1311.     PSOUT
  1312.     tmsg <
  1313. >
  1314.     ret
  1315.  
  1316. $help2:    hrro t1, pars3        ;[18] Normal help text.
  1317.     PSOUT
  1318.     hrroi t1, crlf
  1319.     PSOUT
  1320.     ret
  1321.  
  1322.     subttl    INPUT, OUTPUT, and PAUSE added as edit [159].
  1323.  
  1324. hinput:    asciz |
  1325. INPUT interval string
  1326.  
  1327. INPUT is useful with OUTPUT and PAUSE for sending connect and login
  1328. sequences to a remote host, e.g. over a dialout connection.
  1329.  
  1330. On the currently selected communication line, look for the given string
  1331. for the specified time interval.  If no interval is specified, then wait
  1332. for the default interval, which is 2 seconds unless changed by SET INPUT
  1333. DEFAULT-TIMEOUT.  An interval of 0 or less means no timeout (wait
  1334. forever).
  1335.  
  1336. Characters coming in from the line will be scanned for the search string,
  1337. and when a match is found, the command will terminate successfully; if
  1338. the string is not found within the given interval, the command will
  1339. terminate unsuccessfully.  While the INPUT command is active, all
  1340. incoming characters will appear on your screen.
  1341.  
  1342. The search string may contain any printable characters.  Control or other
  1343. special characters may be included by preceding their octal ASCII value
  1344. with a backslash, for instance foo\15 is "foo" followed by a carriage
  1345. return, \100 is an atsign (@).  Alphabetic case is ignored ("a" = "A")
  1346. unless you have SET INPUT CASE OBSERVE.  If no search string is given,
  1347. then the INPUT command will keep operating until it times out.
  1348.  
  1349. If the INPUT command fails to find the requested string within the given
  1350. interval, it will "fail"; if the INPUT command was issued from a command
  1351. file (see TAKE), then the next command will be executed, unless you have
  1352. SET INPUT TIMEOUT-ACTION to QUIT, in which case the command file will be
  1353. terminated.  An INPUT command can by interrupted by typing two ^C's.
  1354.  
  1355. Type HELP SET INPUT for further information.
  1356. |
  1357. .input:    noise <interval>
  1358.     setzm buffer        ; Make dynamic default string.
  1359.     setzm buffer+1
  1360.     move t1, [point 7, buffer]
  1361.     move t2, indeft
  1362.     movei t3, ^d10
  1363.     NOUT
  1364.      erjmp .+1
  1365.     movei t1, [flddb. .cmnum,,^d10,<Number of seconds to wait,>,<5>]
  1366.     move t2, [point 7, buffer] ; The above default will be overridden
  1367.     skipe buffer        ; if there's anything in this buffer.
  1368.      movem t2, .cmdef(t1)    ; Stuff the pointer into the fdb.
  1369.     call rfield
  1370.     setzm buffer
  1371.     setzm buffer+1
  1372.     movem t2, pars2
  1373.     movei t1, [flddb. .cmtxt,cm%sdh,,<Text string to look for,
  1374. use \ooo (backslash followed by octal digits) to include control characters,
  1375. \\ to include a single backslash>]
  1376.     call cfield
  1377.     ret
  1378.  
  1379. ; INPUT command.
  1380.  
  1381. $input:    call getss        ; Get & decode search string from atom buffer.
  1382.     skipg pars2
  1383.      jrst $inpu5        ; Skip timer if interval 0 or negative.
  1384.  
  1385. ; Set the desired timeout.
  1386.  
  1387.     movei t1, .fhslf
  1388.     movx t2, 1b0        ; Turn on channel 0.
  1389.     AIC
  1390.      %jserr <Can't turn on timer channel>, <.+1>
  1391.  
  1392.     move t1, [.fhslf,,.timal] ; Remove all pending timer requests.
  1393.     setzb t2, t3
  1394.     TIMER
  1395.      %jserr <Can't clear pending timers>, <.+1>
  1396.  
  1397.     movem p, intstk        ; The timer interrupt routine needs this.
  1398.     movei t1, $inpu9    ; Where to go upon timeout
  1399.     movem t1, intpc        ;  ...
  1400.  
  1401.     move t1, [.fhslf,,.timel] ; Our process and time from now.
  1402.     move t2, pars2        ; The interval we parsed.
  1403.     imuli t2, ^d1000    ; Make time into milliseconds.
  1404.     setz t3,        ; Channel zero.
  1405.     TIMER
  1406.      %jserr <Can't set timer>, <.+1>
  1407.  
  1408. ; Try to get string from the communication line.
  1409.  
  1410. $inp4a:    call dobits        ; Condition the line for i/o.
  1411.      ret            ;  Pass along any failure.
  1412.     call ttyob        ; Put TTY in binary mode for output only.
  1413.     call ccon        ; Turn on ^C trap.
  1414.      jrst $inpuy        ; If ^C typed, go to this place.
  1415.  
  1416. $inpu5:    move t4, [point 7, strbuf] ; Point to the search string.
  1417.  
  1418. $inpu6:    skipn strc        ; Is there a search string?
  1419.      jrst $inpu7        ;  No, just go forever.
  1420.     ildb t3, t4        ; Get a character from search string.
  1421.     jumpe t3, $inpux    ; If no more, then success.
  1422.     ;...
  1423.     
  1424. ;...$INPUT, cont'd
  1425.  
  1426.  
  1427. ; Get & echo a character, compare with current position in search string.
  1428.  
  1429. $inpu7:    move t1, netjfn        ; Now get a character from the line.
  1430.     setz t2,
  1431.     BIN
  1432.      %jserr (,$inpux)
  1433.     andi t2, ^o177        ; Strip any parity.
  1434.     move t1, t2        ; Echo the character.
  1435.     PBOUT
  1436.     skiple t1, sesjfn    ; Session logging?
  1437.      jrst [    BOUT        ; Yes, record the character in the log.
  1438.          erjmp .+1
  1439.         jrst .+1 ]        
  1440.     skipn incase        ; Case-sensitive compare?
  1441.      jrst [    cail t2, "a"    ; No, is this a lower case letter?
  1442.          caile t2, "z"
  1443.          skipa        ; No.
  1444.          txz t2, 40    ; Yes, convert to upper.
  1445.         jrst .+1 ]
  1446.  
  1447.     camn t2, t3        ; Compare OK?
  1448.      jrst $inpu6        ;  Yes, get next from string and comm line.
  1449.     jrst $inpu5        ; No, rewind search string, get next from line.
  1450.  
  1451. ; Come here upon input timeout.
  1452.  
  1453. $inpu9:    hrroi t1, [asciz/
  1454. %/]                ; % message if proceeding
  1455.     skipe intima
  1456.      hrroi t1, [asciz/
  1457. ?/]                ; ? message if quitting (for batch)
  1458.     PSOUT
  1459.     hrroi t1, [asciz/KERMIT-20: INPUT timed out looking for "/]
  1460.     PSOUT
  1461.     hrroi t1, strbuf    ; Tell what string we couldn't find.
  1462.     PSOUT
  1463.     hrroi t1, [asciz/", proceeding...
  1464. /]                ; Say what we're doing, proceeding
  1465.     skipe intima
  1466.      hrroi t1, [asciz/", quitting /] ; ...or quitting.
  1467.     PSOUT
  1468.     skipn intima
  1469.      jrst $inpux        ; Proceeding, just exit from the INPUT command.
  1470.     movei t1, .priou    ; Quitting, tell which file we're quitting from
  1471.     move t2, takjfn        ;  (if any).
  1472.     setz t3,
  1473.     JFNS            ; If no TAKJFN, this will print nothing.
  1474.      erjmp .+1
  1475.     tmsg <
  1476. >
  1477.  
  1478. $inpuy:    call popjfn        ; Pop the TAKE file JFN from the TAKE stack.
  1479.     ;...
  1480.  
  1481. ;...$INPUT, cont'd
  1482.  
  1483.  
  1484. ; Exit thru here, turning off timer, restore line to previous condition.
  1485.  
  1486. $inpux:    call ccoff2        ; Turn off ^C trap.
  1487.     call unbits        ; Restore the line
  1488.     call ttyou        ; Restore controlling tty output.
  1489.     skipg pars2        ; Skip timer stuff if interval 0 or negative.
  1490.      ret
  1491.     move t1, [.fhslf,,.timbf] ; Turn off timer interrupts for this fork.
  1492.     hrloi t2, 377777    ; For all times before this (far in future).
  1493.     TIMER            ;
  1494.      erjmp .+1
  1495.     movx t1, .fhslf        ; Deactivate the channel.
  1496.     movx t2, 1b0
  1497.     DIC
  1498.      %jserr <Can't DIC>,<.+1>
  1499.     setzm strbuf        ; Leave the string buffer cleanup up
  1500.     setzm strbuf+1        ;  a bit...
  1501.     setzm strptr
  1502.     ret    
  1503.  
  1504. ; GETSS - Get & Decode a backslash-decoded search string from the atom buffer.
  1505. ; Returns +1 with 7-bit ASCIZ string in STRBUF, STRC 0 if null, else nonzero.
  1506. ;
  1507. getss:    move t1, [point 7, atmbuf] ; Copy search string from here
  1508.     move t2, [point 7, strbuf] ; ... to here
  1509.     movem t2, strptr    ; Use this pointer
  1510.     setzm strc        ;  and this counter.
  1511.  
  1512. getss2:    ildb t4, t1        ; Get a character.
  1513.  
  1514. getss3:    jumpe t4, getssx    ; If null, then done.
  1515.     aos strc        ; Got one, count it.
  1516.     cain t4, "\"        ; Backslash?
  1517.      jrst [    movei t3, ^d8    ; Yes, try to read a number.
  1518.         NIN
  1519.          nop        ; If error, just keep the backslash.
  1520.         idpb t2, strptr    ; OK, deposit ascii value of number.
  1521.         ldb t4, t1    ; Account for how NIN overshoots the pointer.
  1522.         jrst getss3 ]
  1523. getss4:    skipn incase        ; Case-sensitive compare?
  1524.      jrst [    cail t4, "a"    ; No, is this a lower case letter?
  1525.          caile t4, "z"
  1526.          skipa        ; No.
  1527.          txz t4, 40    ; Yes, convert to upper.
  1528.         jrst .+1 ]
  1529. getss5:    idpb t4, strptr        ; Deposit the result of all this.
  1530.     jrst getss2
  1531.  
  1532. getssx:    idpb t4, strptr        ; Deposit a null at the end.
  1533.     ret
  1534.  
  1535. houtpu:    asciz |
  1536. OUTPUT string
  1537.  
  1538. The given string is sent out the currently selected communication line.
  1539. Control characters may be included in \ooo format (backslash followed by
  1540. octal representation of ASCII value).  Currently selected settings for
  1541. DUPLEX, PARITY, and FLOW are used.
  1542.  
  1543. Type HELP INPUT for further information.
  1544. |
  1545. .outpu:    noise (string)        ; Parse OUTPUT command.
  1546.     movei t1, [flddb. .cmtxt,cm%sdh,,<Text string to send,
  1547. use \ooo (backslash followed by octal digits) to include control characters,
  1548. \\ to include a single backslash>]
  1549.     call cfield
  1550.     ret
  1551.  
  1552. $outpu:    move t1, [point 7, atmbuf] ; Do OUTPUT; move chars from here...
  1553.     move t2, [point 8, strbuf] ;  to here.
  1554.     movem t2, strptr
  1555.  
  1556. $outp3:    ildb t4, t1        ; Copy them
  1557. $out3x:    jumpe t4, $outp4    ;  up to a null.
  1558.     cain t4, "\"        ; Backslash?
  1559.      jrst [    movei t3, ^d8    ; Yes, read a number
  1560.         NIN
  1561.          movei t2, "\"    ; If error, keep the backslash.
  1562.         move t4, t2    ; Get ascii value into t4.
  1563.         seto t2,    ; Decrement the source byte pointer.
  1564.         adjbp t2, t1
  1565.         move t1, t2
  1566.         jrst .+1 ]
  1567.  
  1568. out3a:    exch t1, t4        ; Put character in t1, preserve source pointer.
  1569.     call @parity        ; Tack on desired parity.
  1570.     idpb t1, strptr        ; Deposit the result in the output buffer.
  1571.     move t1, t4        ; Restore the source pointer.
  1572.     jrst $outp3        ; Go back for next.
  1573.  
  1574. $outp4:    idpb t4, strptr        ; Done, deposit a null.
  1575.     move t1, netjfn        ; Comm line designator.
  1576.     move t2, [point 8, strbuf] ; Point to string.
  1577.     setzb t3, t4        ; It's null-terminated.
  1578.     SOUT            ; Send it.
  1579.      %jserr (<Can't send the string>,<.+1>)
  1580.     skipn duplex        ; Half duplex connection?
  1581.      ret            ;  No, host will echo.
  1582.     movei t1, .priou    ; Yes, do it ourselves.
  1583.     move t2, [point 8, strbuf] ; Point to string again.
  1584.     setzb t3, t4
  1585.     SOUT
  1586.      erjmp .+1
  1587.     skipn t1, sesjfn    ; Session logging?
  1588.      jrst $outpx        ; No.
  1589.     move t2, [point 8, strbuf] ; Yes, point again.
  1590.     setzb t3, t4
  1591.     SOUT
  1592.      erjmp .+1
  1593. $outpx:    ret            ; Done.
  1594.  
  1595. ; PAUSE command.
  1596.  
  1597. hpause:    asciz |
  1598. PAUSE interval
  1599.  
  1600. Pause for the given number of seconds.  Useful with INPUT and OUTPUT.
  1601. |
  1602. .pause:    noise (seconds)
  1603.     movei t1, [flddb. .cmnum,,^d10,<Number of seconds to pause>,<1>]
  1604.     call cfield
  1605.     movem t2, pars2
  1606.     ret
  1607.  
  1608. $pause:    move t1, pars2        ; Get the number that was parsed.
  1609.     imuli t1, ^d1000    ; Convert to millisecs.
  1610.     DISMS            ; Sleep.
  1611.      erjmp .+1
  1612.     ret
  1613.  
  1614.     subttl    TAKE command, added as edit 78.
  1615.  
  1616. htake:    asciz |
  1617. TAKE filespec
  1618.  
  1619. Execute KERMIT-20 commands from the specified file.  The file may contain
  1620. contain TAKE commands.  Command files may be nested up to a depth of 20.
  1621. |
  1622.  
  1623. ; Parse the rest of the TAKE command.
  1624.  
  1625. .take:    movx t1, cz%ncl!.fhslf    ; Release non-open jfn's.
  1626.     CLZFF
  1627.     noise <commands from file>
  1628.     move t1, [defbk,,cjfnbk] ; Insert our file parsing defaults.    
  1629.     blt t1, cjfnbk+defbkl
  1630.     movei t1, [flddb. .cmfil]
  1631.     call cfield
  1632.     movem t2, pars2        ; Here's the JFN just parsed.
  1633.     ret
  1634.  
  1635. ; Execute the TAKE command.
  1636.  
  1637. $take:    move t1, takdep        ; How deep are we?
  1638.     caile t1, takel        ; Too deep?
  1639.      jrst [    tmsg <?TAKE command file stack overflow> ; Yes, don't do it.
  1640.         ret ]
  1641.     move t1, takjfn        ; There's room, get current TAKE file jfn.
  1642.     move t2, takep        ; Push it on the stack
  1643.     push t2, t1        ; ...
  1644.     movem t2, takep        ; ...
  1645.     aos takdep        ; Remember what level we're on.
  1646.  
  1647.     move t1, pars2        ; Get JFN that was parsed
  1648.     movem t1, takjfn    ;  ...
  1649.     movx t2, fld(7,of%bsz)!of%rd ; 7-bit i/o, read access.
  1650.     OPENF
  1651.      %jserr (,$takex)
  1652.     callret setcsb        ; Opened OK, go set up command state block.
  1653.  
  1654. ; Error opening command file.
  1655.  
  1656. $takex: call popjfn        ; Remove offending JFN from TAKE stack.
  1657.      jrst [ tmsg <?TAKE file stack underflow>
  1658.         ret ]
  1659.  
  1660.     movx t1, cz%ncl!.fhslf    ; Release extraneous JFNs.
  1661.     CLZFF
  1662.      erjmp .+1
  1663.     ret
  1664.  
  1665. ; Default command filespec fields for .CMFIL:
  1666.  
  1667. defbk:    gj%old            ; Must be existing file.
  1668.     repeat 4,<0>        ; Normal defaults for dev:<dir>name.
  1669.     point 7, [asciz/CMD/]    ; Default extension is .CMD.
  1670.     0            ; Default protection,
  1671.     0            ;  and account.
  1672. defbkl==<.-defbk>        ; Length of this GTJFN argument block.
  1673.     
  1674. ; SETCSB - Set up Command State Block to parse from JFN in t1.
  1675. ;
  1676. setcsb:    skipg t1        ; Make sure there's a real JFN.
  1677.      movei t1, .priin    ; If not, revert.
  1678.     hrlm t1, sbk+.cmioj    ; Put the input JFN into the CSB.
  1679.     movei t2, .priou    ; Assume JFN is primary input.
  1680.     caie t1, .priin        ; Is it?
  1681.      movx t2, .nulio    ; No, it's a file, so nullify COMND output.
  1682.     hrrm t2, sbk+.cmioj    ; Put output JFN in CSB.
  1683.     ret
  1684.  
  1685.  
  1686. ; POPJFN
  1687. ; Routine to pop a command file JFN off the JFN stack.
  1688. ;
  1689. ; Enter with current command file jfn in TAKJFN.
  1690. ;
  1691. ; Returns:
  1692. ;  +1 if stack empty,
  1693. ;  +2 otherwise, with popped jfn in TAKJFN.
  1694. ;
  1695. popjfn:    skipg takdep        ; Back at top level?
  1696.      ret            ;  Yes, return silently.
  1697.  
  1698. ; Close current command file.
  1699.  
  1700.     hrrz t1, takjfn        ; No, close the current file
  1701.     CLOSF            ;  ...
  1702.      %jserr (,.+1)        ; Just print message on error.
  1703.  
  1704. ; Return to previous one.
  1705.  
  1706.     move t2, takep        ; Get the TAKE stack pointer
  1707.     pop t2, t1        ;  and the previous TAKE file JFN,
  1708.     movem t2, takep        ;  restore them,
  1709.     movem t1, takjfn    ;  ...
  1710.     call setcsb        ;  and also restore the command state block.
  1711.     sos takdep        ; Decrement the depth indicator
  1712.     retskp            ; Return successfully.
  1713.  
  1714. ;[79] INIFIL -- Process initialization file.
  1715. ;
  1716. ;[85] Returns +1 if there was no init file, +2 if there was.
  1717. ;
  1718. inifil:    move t2, jobtab+.jiuno
  1719.     move t1, [point 7, dirbuf, 27] ; Put string here.
  1720.     DIRST    
  1721.      erjmp r
  1722.     movei t3, 76        ; Right angle bracket.
  1723.     idpb t3, t1
  1724.     move t2, [point 7, [asciz/KERMIT.INI/]]    ; File name.
  1725.  
  1726. inif2:    ildb t3, t2        ; Copy file name.
  1727.     idpb t3, t1
  1728.     jumpn t3, inif2
  1729.  
  1730. inif3:    movx t1, gj%old+gj%sht    ; Get JFN on it.
  1731.     hrroi t2, dirbuf
  1732.     GTJFN
  1733.      erjmp r        ; If we can't, return silently.
  1734.     hrrzm t1, pars2        ; Got one, pretend we parsed it.
  1735.     setom iniflg        ;[83] Flag that we're doing init file.
  1736.     call $take        ; Go TAKE the file.
  1737.     retskp            ;[85]
  1738.  
  1739.     subttl    LOCAL and REMOTE commands.
  1740.  
  1741. ;[56] LOCAL and REMOTE commands added as edit 56
  1742.  
  1743. .local:    setom lcflg        ; -1 = local
  1744.     movei t1, [flddb. .cmkey,,loctab] ; LOCAL what?
  1745.     jrst .remo2        ; Go parse the rest.
  1746.  
  1747. loctab:    %table
  1748.     %key <cwd>, [xwd .ycwd,$ycwd]
  1749.     %key <delete>, [xwd .ydele,$ydele]
  1750.     %key <directory>, [xwd .ydire,$ydire]
  1751.     %key <run>, [xwd .yrun,$yrun]
  1752.     %key <space>, [xwd .ydisk,$ydisk]
  1753.     %key <type>, [xwd .ytype,$ytype]
  1754.     %tbend
  1755.  
  1756. .remot:    setzm lcflg        ; 0 = remote
  1757.     movei t1, [flddb. .cmkey,,remtab] ; REMOTE what?
  1758. .remo2:    call rfield        ; Parse a keyword.
  1759.     hrrz t2, (t2)        ; Get the command routine addresses.
  1760.     movem t2, pars2        ; Save into pars2.
  1761.     hlrz t1, (t2)        ; Get the next level routine.
  1762.     call (t1)        ; Call it.
  1763.     ret
  1764.  
  1765. remtab:    %table
  1766.     %key <cwd>, [xwd .xcwd,$xcwd]
  1767.     %key <delete>, [xwd .rmfil,$xdele]
  1768.     %key <directory>, [xwd .rmfil,$xdire]
  1769.     %key <error>, [xwd .xerr,$xerr], cm%inv
  1770.     %key <help>, [xwd .xhelp,$xhelp] ;[120]
  1771.     %key <host>, [xwd .xhost,$xhost] ;[105]
  1772. ;;;*    %key <run>, [xwd .???, $???]
  1773.     %key <space>, [xwd .xdisk,$xdisk]
  1774.     %key <type>, [xwd .rmfil,$xtype]
  1775.     %tbend
  1776.  
  1777. ; LOCAL command help text.
  1778.  
  1779. hlocal:    asciz |
  1780. LOCAL option
  1781.  
  1782. Execute a command locally.  Options include:
  1783.  
  1784.  CWD            Change Working Directory (connect to directory).
  1785.  DELETE filespec    Delete a file or file group.
  1786.  DIRECTORY filespec    Print a directory listing.
  1787.  HOST command        A command to be executed by the TOPS-20 Exec.
  1788.  RUN program            Run the specified program.
  1789.  SPACE area        Disk usage query.
  1790.  TYPE filesec        Type a local file or file group at the terminal.
  1791.  
  1792. For further information, type HELP CWD, HELP DELETE, etc.
  1793. |
  1794.  
  1795. ;[137] LOCAL CWD command parsing.
  1796. ;
  1797. hcwd:    asciz |
  1798. CWD means CHANGE WORKING DIRECTORY.  It is the same as LOCAL CWD, i.e. it is
  1799. executed on the local system.  The operation is the same as the DEC-20
  1800. CONNECT command.
  1801. |
  1802. .ycwd:    setzm pasbuf        ; Zero this out.
  1803.     setzm pasbuf+1        ;  ...
  1804.     noise <to directory>    ; Issue guide words.
  1805.     movei t1, [
  1806.         flddb. .cmdir,cm%sdh,,<directory name or logical name,
  1807.  or carriage return to connect back to your login directory>,,[
  1808.         flddb. .cmcfm,cm%sdh ]]
  1809.     call rfield        ; Parse a directory specification.
  1810.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  1811.     cain t3, .cmcfm        ; Confirmation?
  1812.      jrst [    move t2, jobtab+.jilno ; Yes, then use own logged in dir no.
  1813.         movem t2, pars3
  1814.         ret ]
  1815.  
  1816.     movem t2, pars3        ; No, directory number, save it.
  1817.     confrm            ; Get confirmation.
  1818.     ret
  1819.  
  1820. ; Execute the LOCAL CWD command.
  1821. ;
  1822. ;[171] Rewritten to only prompt for the password when necessary, as
  1823. ; the Exec CONNECT command does, and to print the name of the directory
  1824. ; connected to.
  1825. ;
  1826. ; First try to connect with no password.  This returns immediately on error.
  1827. ;
  1828. $ycwd:    move t1, [ac%con!<3>]    ; Ask for connect function, arg block length 3.
  1829.     movei t2, pars3        ; Point to argument block.
  1830.     setom pars5        ; Specify "this job".
  1831.     ACCES            ; Try to connect.
  1832.      erjmp $ycwdx        ;  If error, go prompt for password.
  1833.     jrst $ycwdz        ; Connected OK, exit.
  1834.  
  1835. ; Handle error by prompting for password and then trying to connect again.
  1836.  
  1837. $ycwdx:    setzm pars4        ; Assume no password will be given.
  1838.     call getpas        ; Ask for password.
  1839.     movem t1, pars4        ; Save pointer to (possibly null) string.
  1840.     move t1, [ac%con!<3>]    ; Try to connect again.
  1841.     movei t2, pars3        ; If this fails, monitor won't return
  1842.     ACCES            ;  for about 3 seconds.
  1843.      %jserr (,.+1)        ; On failure, give message and exit.
  1844.  
  1845. ; Done either way, exit.
  1846.  
  1847. $ycwdz:    setzm pasbuf        ; Connected, clear this out for security.
  1848.     setzm pasbuf+1
  1849.  
  1850.     tmsg <[Connected to >    ; Print what we're connected to.
  1851.     seto t1,        ; Get this job's connected directory number.
  1852.     hrroi t2, t3
  1853.     movei t3, .jidno
  1854.     GETJI
  1855.      erjmp r
  1856.     move t2, t3        ; Convert to string.
  1857.     movem t2, jobtab+.jidno    ; Remember for future reference.
  1858.     movei t1, .priou
  1859.     DIRST
  1860.      erjmp r
  1861.     movei t1, "]"
  1862.     PBOUT
  1863.     ret
  1864.  
  1865. ; GETPAS -- Get a password from the terminal
  1866. ;
  1867. ; Prompts for password, turns off echoing during typein, leaves result in
  1868. ; PASBUF, with t1 pointing to it.
  1869. ;
  1870. ; Uses t1-t4.
  1871. ;
  1872. getpas:    skipn takdep        ;[178] Do specially for TAKE files
  1873.      jrst getpa2        ;[178]  (here thru ret)
  1874.     setzm pasbuf
  1875.     move t1, takjfn        ; Read line from the TAKE file
  1876.     hrroi t2, pasbuf    ; Into here
  1877.     movei t3, pasbfl    ; This many chars, max
  1878.     movei t4, .CHLFD    ; terminate on linefeed.
  1879.     SIN
  1880.      erjmp getpax
  1881.     seto t3,        ; Decrement the returned byte pointer.
  1882.     adjbp t3, t2
  1883.     setz t4,        ; Write a zero over the terminating CR.
  1884.     dpb t4, t3
  1885.     idpb t4, t3        ; And linefeed.
  1886. getpax:    move t1, [point 7, pasbuf] ; Return pointer to password.
  1887.     ret            ;[178]
  1888.  
  1889. getpa2:    hrroi t1, [asciz/ Password: /] ; Issue first prompt.
  1890.     PSOUT    
  1891.     movei t1, .priin    ; Get TTY mode word
  1892.     setz t2,
  1893.     RFMOD
  1894.      erjmp .+1
  1895.     call [    saveac <t1,t2>    ; Save TTY info.
  1896.         txz t2, tt%eco    ; Turn off echoing.
  1897.         SFMOD
  1898.          erjmp r
  1899.         hrroi t1, pasbuf ; Ask for password.
  1900.         move t2, [rd%crf+rd%bel+pasbfl]
  1901.         hrroi t3, [asciz/ Password: /]
  1902.         RDTTY
  1903.          %jserr (,r)
  1904.         move t4, t2    ;[169] Remember flag bits that were returned.
  1905.         setz t2,    ; Write a zero over the terminating linefeed.
  1906.         dpb t2, t1
  1907.         ret ]        ; Restore TTY info.
  1908.     SFMOD            ; Restore TTY to normal echoing.
  1909.      erjmp .+1    
  1910.     tmsg <
  1911. >                ; Echo the crlf that wasn't echoed.
  1912.     txnn t4, rd%btm        ; Too long?
  1913.      jrst [    tmsg <
  1914. ?Password too long>        ;* This doesn't help, must do something better
  1915.         jrst .+1 ]    ;* later on...
  1916.     move t1, [point 7, pasbuf] ; Return pointer to result.
  1917.     ret
  1918.  
  1919. ;[111] LOCAL DIRECTORY
  1920.  
  1921. hdire:    asciz |
  1922. DIRECTORY is the same as LOCAL directory.  It produces a directory listing of
  1923. the specified files at your terminal.
  1924. |
  1925.  
  1926. ; Default wildcard filespec fields for .CMFIL:
  1927.  
  1928. dirbk:    gj%old!gj%ifg!gj%flg!.gjall ; Flag bits,,generation number.
  1929.     .priin,,.priou        ; COMND i/o.
  1930.     repeat 2,<0>        ; Normal defaults for dev:<dir> and gen.
  1931.     repeat    2,<point 7, [asciz/*/]>    ; *.* for name and type.
  1932.     0            ; Default protection,
  1933.     0            ;  and account.
  1934. dirbkl==<.-dirbk>        ; Length of this GTJFN argument block.
  1935.  
  1936. .ydire:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  1937.     CLZFF
  1938.     noise <of files>    ; Issue guide words.
  1939.     move t1, [dirbk,,cjfnbk] ; Insert our file parsing defaults.    
  1940.     blt t1, cjfnbk+dirbkl
  1941.     movei t1, [flddb. .cmfil]
  1942.     call cfield
  1943.     movem t2, pars3        ; Here's the JFN just parsed.
  1944.     ret
  1945.  
  1946. ; LOCAL DIRECTORY command execution.
  1947.  
  1948.  
  1949. ; Set up.
  1950.  
  1951. $ydire:    setzm ffunc        ; Function is "directory".
  1952. $ydir1:    move t2, pars3        ; Here's the JFN.
  1953.     setzm filjfn        ; Make sure no one thinks this is in use.
  1954.     call dirhdr        ; Do the header first.
  1955.  
  1956. ; File-listing loop
  1957.  
  1958. $ydir2:    call dmpbuf        ; Get some directory listing.
  1959.     call dirlst        ; Print it.
  1960.      jumpn t1, $ydir2    ; Go back for more.
  1961.  
  1962.     ret            ; Till done.
  1963.  
  1964. ; DIRHDR
  1965. ;
  1966. ; Put directory listing header in string buffer.
  1967. ; Initializes buffer pointers, counters, etc.
  1968. ; Call with t2/ JFN of files to list.
  1969. ; Returns +1 always.
  1970. ;
  1971. dirhdr:    movem t2, ndxjfn    ; Save wildcard bits.
  1972.     hrrzm t2, nxtjfn    ; Initialize lookahead
  1973.     setzm filcnt        ; File counter
  1974.     setom dirfin        ; Initialize directory finished flag.
  1975.  
  1976.     move t1, [point 7, srvbuf] ; Put the listing in the srving buffer.
  1977.     skipe ffunc        ; Directory listing?
  1978.      jrst dirhdx        ;  No, skip printing the heading.
  1979.  
  1980.     setom dirfin        ; Assume some error.
  1981.     move t3, [111110,,js%paf] ; dev:<dir>name.typ.gen
  1982.     JFNS
  1983.      erjmp r
  1984.     
  1985.     hrroi t2, [asciz/
  1986. Name                Pages Bytes(Size)        Creation Date
  1987. /]
  1988.     setzb t3, t4        ; Print heading.
  1989.     SOUT
  1990.  
  1991. dirhdx:    setzm dirfin        ; No error, so not finished.
  1992.     movem t1, srvptr    ; Preserve string buffer pointer.
  1993.     ret
  1994.     
  1995. ; DIRLST
  1996. ;
  1997. ; Builds a directory listing in a chunk of memory starting at
  1998. ; SRVBUF and ending at (or slightly after) SRVBZ, with pointer in SRVPTR.
  1999. ;
  2000. ; Returns +1 always, with t1/ -1 if we got some data, t1/ 0 if done.
  2001. ;
  2002. ; Keeps global file counter in FILCNT.
  2003. ;
  2004. dirlst:    setz t1,
  2005.     skipe dirfin        ; Finished?
  2006.      ret            ;  Yes.
  2007.     move t1, srvptr        ; No, there's more to do.
  2008.     hrroi t2, crlf        ; Issue a line break.
  2009.     setzb t3, t4
  2010.     SOUT
  2011.     movem t1, srvptr    ; Save the buffer pointer.
  2012.     call gtnfil        ; Get next file.
  2013.      jrst dirlsz        ;  If none, done.
  2014.     aos filcnt        ; Got one, count it.
  2015.  
  2016. ;[133] Get detailed size info from FDB.
  2017.  
  2018.     hrrzs t1, t1        ; Get rid of any flags.
  2019.     move t2, [3,,.fbbyv]    ; Get size info from FDB.
  2020.     movei t3, pagcnt    ; Put info in PAGCNT,BYTCNT,CRDATE
  2021.     GTFDB            ; which are adjacent in the data area.
  2022.      erjmp dirlsz
  2023.     move t2, t1        ; Put JFN in t2 for JFNS below.
  2024.  
  2025. ;[122] The rest of this routine rewritten to provide nice columnar listing.
  2026.  
  2027.     move t1, [ascii/     /]    ; Fill the filename buffer with blanks.
  2028.     movem t1, filbuf
  2029.     move t1, [filbuf,,filbuf+1]
  2030.     blt t1, filbfz-1
  2031.  
  2032.     move t1, [point 7, filbuf] ; Now start filling in the fields.
  2033.     move t3, [001110,,<js%tmp!js%paf>] ; First the filename.
  2034.     JFNS
  2035.      erjmp dirlsz
  2036.     skipe ffunc        ; What was the file function?
  2037.      jrst dirls2        ;  Not directory, so skip the rest.
  2038.     ;...
  2039.  
  2040. ;...DIRLST, cont'd
  2041.  
  2042.  
  2043. ; For real directory listing, include file size and creation date.
  2044.  
  2045. dirlsm:    move t4, t2        ; Save file JFN in t4 for a while...
  2046.     movei t3, 40        ; Put a blank over the null left by JFNS.
  2047.     idpb t3, t1
  2048.     hrrz t2, t1        ; Get address from updated pointer.
  2049.     caige t2, filbuf+4    ; Name stayed within its field?
  2050.      jrst [    move t1, [point 7, filbuf+4] ; Yes, advance to next field.
  2051.         movx t3, <no%lfl!no%ast!fld(5,no%col)!fld(^d10,no%rdx)>
  2052.         jrst dirlsa ]    ;  Use right-adjusted number format.
  2053.     movei t2, 40        ; No, do free format.
  2054.     idpb t2, t1        ; Deposit a blank, advance pointer.
  2055.     movei t3, ^d10        ; No fixed-field stuff on page count.
  2056.  
  2057. ;[133] More detailed info about size: pages, byte count, byte size.
  2058.  
  2059. dirlsa:    hrrz t2, pagcnt        ; Number of pages in file.
  2060.     NOUT
  2061.      erjmp dirlsz
  2062.     movei t3, 40        ; A blank
  2063.     idpb t3, t1
  2064.     move t2, bytcnt        ; Byte count, free format.
  2065.     movei t3, ^d10
  2066.     NOUT
  2067.      erjmp dirlsz
  2068.     movei t3, "("        ; Byte size, in parens.
  2069.     idpb t3, t1
  2070.     ldb t2, [pointr (pagcnt,fb%bsz)]
  2071.     movei t3, ^d10
  2072.     NOUT
  2073.      erjmp dirlsz
  2074.     movei t3, ")"
  2075.     idpb t3, t1        ;[133](end) Closing parens.
  2076.  
  2077.     hrrz t3, t1        ; Same deal to advance to date field.
  2078.     caige t3, filbuf+11
  2079.      jrst [    move t1, [point 7, filbuf+11]
  2080.         jrst dirlsb ]
  2081.     movei t2, 40        ; Put in a blank to separate.
  2082.     idpb t2, t1
  2083.  
  2084. dirlsb:    move t2, t4        ; File JFN again.
  2085.     movei t3, js%cdr    ; Get the creation date.
  2086.     JFNS
  2087.      erjmp dirlsz
  2088.  
  2089. dirls2:    setz t3,        ; Done with this line, make it asciz.
  2090.     idpb t3, t1    
  2091.     ;...
  2092.  
  2093. ; DIRLST, cont'd
  2094.  
  2095.  
  2096. ; Copy the result into the server sending buffer.
  2097.  
  2098.     move t4, [point 7, filbuf] ; Source pointer
  2099.  
  2100. dirlsc:    ildb t3, t4        ; Copy loop
  2101.     jumpe t3, dirlsx
  2102.     idpb t3, srvptr
  2103.     jrst dirlsc
  2104.  
  2105. ; Still expect to have file jfn in t2 when we get here.
  2106.  
  2107. dirlsx:    skipe t1, ffunc        ; What is the function?
  2108.      call (t1)        ;  Not directory, so go do selected function.
  2109.     move t1, srvptr
  2110.     hrrz t2, t1        ; See if buffer full.
  2111.     cail t2, srvbz
  2112.      jrst [ seto t1,    ; Return indicating we have data.
  2113.         ret ]
  2114.     jrst dirlst        ; Loop
  2115.  
  2116. ; Done, print summary.
  2117.  
  2118. dirlsz:    move t1, srvptr        ; Get the buffer pointer.
  2119.     movei t2, " "        ; Summary.  First a space.
  2120.     BOUT
  2121.     move t2, filcnt        ; Then the number of files.
  2122.     movei t3, ^d10
  2123.     NOUT
  2124.      erjmp .+1
  2125.     setzb t3, t4
  2126.     hrroi t2, [asciz/ files
  2127. /]
  2128.     sosn filcnt        ; Do singular or plural right.
  2129.      hrroi t2, [asciz/ file
  2130. /]
  2131.     SOUT
  2132.     movem t1, srvptr    ; Save pointer.
  2133.     seto t1,        ; Say we're returning data.
  2134.     setom dirfin        ; Set finished flag for next time through.
  2135.     ret
  2136.  
  2137. ;[115] DMPBUF
  2138. ;
  2139. ; Dump the buffer.
  2140. ;
  2141. ; Call with SRVPTR/ current pointer (to end of string to be dumped)
  2142. ; Returns +1 with t1/ new pointer.  Uses t2.
  2143. ;
  2144. ; Dumps the buffer starting from SRVBUF thru present position,
  2145. ; resets pointer SRVPTR to beginning of SRVBUF.
  2146. ;
  2147. dmpbuf:    move t1, srvptr        ; Get current pointer.
  2148.     setz t2,
  2149.     idpb t2, t1        ; Make sure string is asciz.
  2150.     move t1, [point 7, srvbuf] ; Point to buffer
  2151.     movem t1, srvptr    ; Save new pointer.
  2152.     skipn srvflg        ; Am I a server?
  2153.      PSOUT            ;  If not, print it.
  2154.     setzm srvbuf        ; Clear it.
  2155.     move t1, [srvbuf,,srvbuf+1]
  2156.     blt t1, srvbzz
  2157.     move t1, srvptr        ; Return pointer in t1.
  2158.     ret
  2159.  
  2160. ;[113] LOCAL DELETE
  2161. ;
  2162. ; LOCAL DELETE
  2163. ;
  2164. hdele:    asciz |
  2165. DELETE filespec
  2166.  
  2167.   DELETE is the same as LOCAL DELETE.  It works like the DEC-20 DELETE command,
  2168.   except that if you SET EXPUNGE ON, then all files that you delete with
  2169.   KERMIT, whether with interactive DELETE commands, or via REMOTE DELETE
  2170.   commands when KERMIT-20 is running as a server, will also be automatically
  2171.   expunged.
  2172. |
  2173. ; Default filespec fields for .CMFIL:
  2174.  
  2175. delbk:    gj%old!gj%ifg!gj%flg!.gjall ; Flag bits,,generation number.
  2176.     .priin,,.priou        ; COMND i/o.
  2177.     repeat 6,<0>        ; No defaults, except all generations.
  2178. delbkl==<.-delbk>        ; Length of this GTJFN argument block.
  2179.  
  2180. .ydele:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  2181.     CLZFF
  2182.     noise <files>        ; Issue guide words.
  2183.     move t1, [delbk,,cjfnbk] ; Insert our file parsing defaults.    
  2184.     blt t1, cjfnbk+delbkl
  2185.     movei t1, [flddb. .cmfil]
  2186.     call cfield
  2187.     movem t2, pars3        ; Here's the JFN just parsed.
  2188.     ret
  2189.  
  2190. ;[118] LOCAL DELETE command execution.
  2191.  
  2192. $ydele:    movei t2, delfil    ; Address of delete-file code.
  2193.     movem t2, ffunc        ; Make it the file function.
  2194.     callret $ydir1        ; Go do it like a directory.
  2195.  
  2196. ;[118] DELFIL - Routine to delete a file.
  2197.  
  2198. delfil:    move t1, t2        ; Put the JFN in the right place.
  2199.     skipe expung        ;[143] Expunging automatically?
  2200.      txo t1, df%exp        ;[143] Yes, set the bit.
  2201.     DELF            ; Try to delete it.
  2202.      jrst [    move t1, srvptr ; Error, record the message
  2203.         hrroi t2, [asciz/: /]
  2204.         setzb t3, t4
  2205.         SOUT
  2206.          erjmp .+1
  2207.         hrloi t2,.fhslf    ; This fork ,, last error.
  2208.         setz t3,
  2209.         ERSTR
  2210.          nop
  2211.          nop
  2212.         sos filcnt    ; "Uncount" this file, it wasn't deleted.
  2213.         jrst delf2 ]
  2214.     
  2215.     move t1, srvptr        ; Confirmation message.
  2216.     hrroi t2, [asciz/ [OK]/]
  2217. delf2:    setzb t3, t4
  2218.     SOUT
  2219.      erjmp r
  2220.     movem t1, srvptr    ; Update the string pointer.
  2221.     ret            ; Done
  2222.  
  2223. ; LOCAL SPACE
  2224. hspace:    asciz |
  2225. SPACE is the same as LOCAL SPACE.  It tells the number of disk pages allowed
  2226. and used in the current local directory.
  2227. |
  2228.  
  2229. .ydisk:    noise <usage query>
  2230.     confrm
  2231.     ret
  2232.  
  2233. $ydisk:    seto t1,        ; local disk usage query.
  2234.     GTDAL%
  2235.      %jserr (,r)
  2236.     dmove q1, t1
  2237.     cail t1, [^d100000000]
  2238.      jrst [    tmsg <
  2239.  Quota: +Inf>
  2240.         jrst $ydsk3 ]
  2241.  
  2242. $ydsk2:    tmsg <
  2243.  Quota: >
  2244.     numout q1
  2245.  
  2246. $ydsk3:    tmsg <, used: >
  2247.     numout q2
  2248.     tmsg < (pages)>
  2249.     ret
  2250.  
  2251. ; LOCAL RUN
  2252.  
  2253. hrun:    asciz |
  2254. RUN [filespec]
  2255.  
  2256.   RUN is the same as LOCAL RUN.  It runs the specified file as a program in a
  2257.   fork underneath KERMIT-20.  The default file type is .EXE.  When the program
  2258.   terminates, you will be back at KERMIT-20 prompt level.  If you want to issue
  2259.   Exec commands without leaving KERMIT-20, you can RUN SYSTEM:EXEC.EXE, and
  2260.   then type POP to get back to KERMIT.  If you have already RUN a program once,
  2261.   you can run it again without the overhead of fork creation by typing the RUN
  2262.   command without an argument.
  2263. |
  2264.  
  2265. ; JFN block for RUN command.
  2266.  
  2267. runbk:    gj%old!gj%ifg!gj%flg    ; Flag bits,,most recent generation.
  2268.     .priin,,.priou        ; COMND i/o.
  2269.     repeat 3,<0>        ; No defaults, except
  2270.     -1,,[asciz/EXE/]    ;  file type.
  2271.     repeat 2,<0>        ; No defaults, except
  2272. runbkl==<.-runbk>        ; Length of this GTJFN argument block.
  2273.  
  2274. ; Parse local RUN command.
  2275.  
  2276. .yrun:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  2277.     CLZFF
  2278.     noise <file>        ; Issue guide word.
  2279.     move t1, [runbk,,cjfnbk] ; Insert our file parsing defaults.    
  2280.     blt t1, cjfnbk+runbkl    ; Same as for DELETE.
  2281.     movei t1, [flddb. .cmfil]
  2282.     skipe rufork        ; Already have a fork?
  2283.      movei t1, [        ;  Yes, let them rerun it.
  2284.         flddb. .cmfil,cm%sdh,,<name of program to run,
  2285.  or carriage return to re-run the program you ran last time>,,[
  2286.         flddb. .cmcfm,cm%sdh ]]
  2287.     call rfield        ; Parse a directory specification.
  2288.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  2289.     cain t3, .cmcfm        ; Confirmation?
  2290.      jrst [    setom pars3    ; Yes, set "jfn" to -1.
  2291.         ret ]
  2292.  
  2293.     hrrzm t2, pars3        ; No, real JFN, save it.
  2294.     confrm            ; Get confirmation.
  2295.     ret
  2296.  
  2297. ; Execute local RUN command.
  2298.  
  2299. $yrun:    skipg pars3        ; Re-run current fork?
  2300.      jrst $yrun2        ;  Yes, do do that.
  2301.     skiple t1, rufork    ; No, do we have a current fork to kill?
  2302.      KFORK            ;  Yes, try to kill it.
  2303.      erjmp .+1
  2304.     setz t1,        ; Take care of capabilities below.
  2305.     setzm t2
  2306.     CFORK            ; Make a fork.
  2307.      %jserr <Can't create run fork>,r
  2308.     movem t1, rufork    ; Remember the fork handle.
  2309.     move t2, capas        ;[169] Get our capabilities.
  2310.     txz t2, sc%log        ;[169] Inferior has same ones,
  2311.     txo t2, sc%gtb        ;[169] but with GETAB capability (for Exec),
  2312.     move t3, t2        ;[169] and no logout!
  2313.     EPCAP            ;[169]  ...
  2314.      erjmp .+1        ;[169]  ...
  2315.     hrlzs t1        ; Move handle into left half.
  2316.     hrr t1, pars3        ; JFN in right half.
  2317.     setzm t2        ; Nothing special.
  2318.     GET            ; Get the file to run.
  2319.      %jserr <Can't GET program to run>,r
  2320.     move t1, pars3        ; Got the file, now can release its JFN.
  2321.     RLJFN
  2322.      erjmp .+1
  2323.  
  2324. ; Can come straight here to re-run current fork.
  2325.  
  2326. $yrun2:    skipg t1, rufork    ; Get fork handle.
  2327.      ermsg <No fork to run>,r ; Make sure it's ok.
  2328.     setz t2,        ; Primary start address.
  2329.     SFRKV            ;  Start it up.
  2330.      %jserr <Can't start run fork>,r
  2331.     WFORK            ; wait for the fork to halt.
  2332.      %jserr <Can't wait for run fork>,r
  2333.  
  2334.     ret
  2335.  
  2336. ;[165] TRANSMIT
  2337. htrans:    asciz |
  2338.  
  2339. TRANSMIT filespec [prompt]
  2340.  
  2341.   For use in local mode only.  Sends the specified text file a line at a time
  2342.   to the remote system, waiting for the specified prompt for each line.  Kermit
  2343.   protocol is not used; the file is sent "raw".  The prompt is any string, for
  2344.   instance the prompt of a line editor in text insertion mode.  The prompt
  2345.   string may include special characters by preceding their octal ASCII values
  2346.   with a backslash, e.g. \15 for carriage return.  Only a single file may be
  2347.   sent, no wildcards allowed in the filespec.
  2348.  
  2349.   If a prompt string is supplied, alphabetic case will be ignored in searching
  2350.   for it unless you SET INPUT CASE OBSERVE.  If a prompt string is not
  2351.   supplied, then linefeed will be used by default, unless you have performed
  2352.   a SET HANDSHAKE command, in which case the handshake character will be used.
  2353.   If you really want to send the entire file without looking for any prompts,
  2354.   specify a prompt of "\0" (ASCII zero, null) (not recommended).
  2355.  
  2356.   The file will be sent using the current settings for duplex, parity, and flow
  2357.   control.  There are no timeouts on input, as there are with the INPUT
  2358.   command.  The TRANSMIT command waits forever for each prompt to appear.  You
  2359.   may use the following controls during TRANSMIT:
  2360.  
  2361.   Carriage Return - Send the next line immediately, even if the prompt hasn't
  2362.             appeared.
  2363.   Control-P       - Resend the previous line.
  2364.   Control-C       - Typed two or three times will cancel the TRANSMIT command
  2365.                      and return you to the Kermit-20> prompt.
  2366. |
  2367. .trans:    noise <file>        ; Prompt for file name.
  2368.     movei t1, [flddb. .cmifi]
  2369.     call rfield
  2370.     movem t2, pars2        ; Save the JFN
  2371.     noise <using prompt>    ; Prompt for prompt...
  2372.     movei t1, [flddb. .cmtxt,cm%sdh,,<Remote system's line input prompt,
  2373. use \ooo (backslash followed by octal digits) to include control characters,
  2374. \\ to include a single backslash>] ; No default, supplied in action routine.
  2375.     call cfield        ; Get prompt string into atom buffer.
  2376.     ret
  2377.  
  2378. ; TRANSMIT command execution.
  2379.  
  2380.  
  2381. $trans:    move t1, pars2        ; First make sure we can open the file.
  2382.     movem t1, filjfn
  2383.     movx t2, fld(7,of%bsz)!of%rd ; 7-bit read access.
  2384.     OPENF
  2385.      %jserr (,r)
  2386.     call getss        ; Get & decode prompt (search) string.
  2387.     skipe strc        ; Was there one?
  2388.      jrst $tran2        ;  Yes, use it.
  2389.     setzm strbuf        ; No, then supply an appropriate default.
  2390.     move t2, [point 7, strbuf]
  2391.     skipn t1, handsh    ; Handshaking?
  2392.      movei t1, .chlfd    ;  No, then use linefeed.
  2393.     idpb t1, t2        ; Deposit what we have
  2394.  
  2395. $tran2:    call dobits        ; Condition the line.
  2396.      jrst $tranx
  2397.     call ccon        ; Turn on ^C trap
  2398.      jrst $tranx        ; Where to go upon ^C.
  2399.     call ttyob        ; Let controlling tty output binary.
  2400.     movei t1, $tran3    ; Where to go if ^M typed (send next)
  2401.     movem t1, cmloc        ;  ...
  2402.     movei t1, $tran4    ; Where to go if ^P typed (resend previous)
  2403.     movem t1, cploc        ;  ...
  2404.     call cmpon        ; Enable interrupts on ^M, ^P.
  2405.     tmsg <
  2406. [KERMIT-20: Transmitting >    ; Tell user we're starting.
  2407.     movei t1, .priou
  2408.     move t2, filjfn
  2409.     setz t3,
  2410.     JFNS
  2411.      erjmp .+1
  2412.     tmsg <
  2413.  If stuck, type:
  2414.  Carriage Return to send next line,
  2415.  ^P to resend current line,
  2416.  ^C^C to cancel.  Here goes...]
  2417. >
  2418.     ;...
  2419.  
  2420. ; Get a line from the file.
  2421.  
  2422. $tran3:    skipe cmseen        ; ^M typed?
  2423.      jrst [    tmsg < Sending next...]
  2424. >                ; Yes, type msg
  2425.         setzm cmseen    ; and unset flag.
  2426.         jrst .+1 ]
  2427.  
  2428.     move t1, filjfn        ; Input file pointer
  2429.     move t2, [point 8, strbf2] ; Where to put the line
  2430.     movei t3, ^d512        ; Maximum characters to read
  2431.     movei t4, .chlfd    ; but preferably terminate on linefeed.
  2432.     SIN
  2433.      erjmp [movei t1, .fhslf ; Get last process error.
  2434.         GETER        ; Test for eof.
  2435.         hrrzs t2    ; Erase fork handle from left half.
  2436.         caie t2, iox4    ; Was error EOF?
  2437.          %ermsg (,$tranx) ; No, give message.
  2438.         tmsg <
  2439. [KERMIT-20: Transmit Complete.]
  2440. >                ; Yes, reassure.
  2441.         jrst $tranx ]
  2442.     ldb t4, t2        ; Was last char a LF?
  2443.     caie t4, .chlfd
  2444.      ibp t2            ; If not, don't overwrite it.
  2445.     setz t4,        ; Deposit a null, overwriting
  2446.     dpb t4, t2        ;  last char if it was a LF.
  2447.     ;...
  2448.  
  2449. ; TRANSMIT, cont'd...  Echo the string if necessary.
  2450.  
  2451. $tran4:    skipe cpseen        ; ^P typed?
  2452.      jrst [    tmsg < - Resending...
  2453. >                ; Yes, type msg
  2454.         setzm cpseen    ; and unset flag.
  2455.         jrst .+1 ]
  2456.  
  2457.     move t1, [point 8, strbf2] ; Point to the string.
  2458.     move t2, t1        ; Here too.
  2459.     skipn duplex        ; Half duplex?
  2460.      jrst $tran5        ;  No.
  2461.     PSOUT            ; Yes, display it at the tty.
  2462.     movei t1, .chlfd    ; Also need to add linefeed.
  2463.     PBOUT
  2464.  
  2465. ; Tack on desired parity, in place.
  2466.  
  2467.     move t2, [point 8, strbf2] ; Point to the string.
  2468.  
  2469. $tran5:    ildb t1, t2        ; Get a byte.
  2470.     jumpe t1, $tran6    ; If null, done.
  2471.     call @parity        ; Set parity bit.
  2472.     dpb t1, t2        ; Put it back.
  2473.     jrst $tran5        ; Back for more.
  2474.  
  2475. ; Send the string
  2476.  
  2477. $tran6:    move t1, netjfn        ; ... out the communication line.
  2478.     move t2, [point 8, strbf2]
  2479.     setzb t3, t4
  2480.     SOUT
  2481.      %jserr (,$tranx)
  2482.  
  2483. ; Now wait for prompt.
  2484.  
  2485. $tran7:    move t4, [point 7, strbuf] ; Point to string buffer.
  2486.  
  2487. $tran8:    ildb t3, t4        ; Get first character of search string.
  2488.     jumpe t3, $tran3    ; If no more then we have the prompt.
  2489.     move t1, netjfn        ; Get char from line.
  2490.     setz t2,
  2491.     BIN
  2492.      %jserr (,$tranx)
  2493.     andi t2, ^o177        ; Strip any parity.
  2494.     movei t1, .priou    ; Echo it.
  2495.     BOUT
  2496.     skipn incase        ; Case sensitive compare?
  2497.      jrst [    cail t2, "a"    ;  No, fold.
  2498.          caile t2, "z"
  2499.          skipa
  2500.          txz t2, 40
  2501.         jrst .+1 ]
  2502.     camn t2, t3        ; Match?
  2503.      jrst $tran8        ;  Yes, get next.
  2504.     jrst $tran7        ; No, rewind search string, then get next.
  2505.  
  2506. ; Done, call terminal restore routines in reverse order.
  2507.  
  2508. $tranx:    call cmpoff        ; ^M, ^P interrupts off.
  2509.     call ttyou        ; Restore controlling tty.
  2510.     call ccoff2        ; ^C trap off.
  2511.     call unbits        ; Put line back to previous state.
  2512.     movei t1, .priin    ; Flush any junk they may have typed
  2513.     CFIBF
  2514.      erjmp .+1
  2515.     move t1, filjfn        ; Close the file.
  2516.     CLOSF
  2517.      %jserr (,$tranz)
  2518.     skipa
  2519. $tranz:    RLJFN            ; Release the JFN.
  2520.      erjmp .+1
  2521.     setzm filjfn        ; Zero the JFN holder.
  2522.     ret
  2523.  
  2524. ;[143] LOCAL TYPE
  2525. htype:    asciz |
  2526. TYPE filespec
  2527.  
  2528.   TYPE is the same as LOCAL TYPE.  It types the specified file or files at your
  2529.   terminal.  Unlike the DEC-20 TYPE command, it will try to do input from each
  2530.   file based on its byte size.  Also, Control-O output suppression applies only
  2531.   on a per-file basis.
  2532. |
  2533. typbk:    gj%old!gj%ifg!gj%flg    ; Flag bits,,most recent generation.
  2534.     .priin,,.priou        ; COMND i/o.
  2535.     repeat 6,<0>        ; No defaults, except all generations.
  2536. typbkl==<.-typbk>        ; Length of this GTJFN argument block.
  2537.  
  2538. .ytype:    movx t1, cz%ncl!.fhslf    ; Close any nonopen JFNs.
  2539.     CLZFF
  2540.     noise <files>        ; Issue guide words.
  2541.     move t1, [typbk,,cjfnbk] ; Insert our file parsing defaults.    
  2542.     blt t1, cjfnbk+typbkl    ; Same as for DELETE.
  2543.     movei t1, [flddb. .cmfil]
  2544.     call cfield
  2545.     movem t2, pars3        ; Here's the JFN just parsed.
  2546.     ret
  2547.  
  2548. ; LOCAL TYPE command execution.
  2549.  
  2550.  
  2551. $ytype:    move t1, pars3        ; Get the JFN.
  2552.     setzm filjfn        ; Set up for file stepping.
  2553.     movem t1, ndxjfn
  2554.     hrrzm t1, nxtjfn
  2555.     call ccon        ;[169] Allow ^C out of this.
  2556.      jrst [    move t1, filjfn ;[169] Upon ^C, close the file.
  2557.         CLOSF        ;[169]
  2558.          erjmp $ytypz    ;[169]
  2559.         jrst $ytypz ]    ;[169] And quit
  2560. $ytyp2:    call gtnfil        ; Any more?
  2561.      jrst $ytypz        ;  No, done.
  2562.     push p, t1        ; Yes, save the JFN for a sec.
  2563.     tmsg <
  2564. >
  2565.     movei t1, .priou    ; Turn off any Control-O
  2566.     RFMOD
  2567.     txz t2, tt%osp
  2568.     SFMOD
  2569.     move t2, (p)        ; Say the name.
  2570.  
  2571.     setz t3,    
  2572.     JFNS
  2573.      erjmp .+1
  2574.     tmsg <
  2575.  
  2576. >
  2577.     pop p, t1        ; Restore the JFN.
  2578.     move t2, [1,,.fbbyv]    ; Get bytesize.
  2579.     movei t3, t4
  2580.     setz t4,
  2581.     GTFDB
  2582.      erjmp .+1
  2583.     movx t2, of%rd+fld(7,of%bsz) ; Assume 7-bit mode.
  2584.     ldb t3, [pointr (t4,fb%bsz)] ; Extract the bytesize.
  2585.     cain t3, ^d8        ; 8 bit?
  2586.      movx t2, of%rd+fld(^d8,of%bsz) ; Yes, 8-bit.
  2587.     OPENF            ; Open the file in appropriate mode.
  2588.      %jserr (,$ytyp2)    ; Report any errors.
  2589.     call typfil        ; Type the file
  2590.     move t1, filjfn        ; Close the file.
  2591.     CLOSF
  2592.      nop
  2593.     jrst $ytyp2        ; Go back back for another.
  2594.  
  2595. $ytypz:    tmsg <
  2596. >
  2597.     call ccoff
  2598.     ret            ; No more, done.
  2599.  
  2600. ; Routine to type a file at the local terminal.
  2601. ;
  2602. ; Type the file whose JFN is in FILJFN.  Return +1 always.
  2603. ;
  2604. typfil:    saveac<t1,t2,t3>
  2605.  
  2606.     setz t4,        ; EOF flag.
  2607.  
  2608. typfi2:    jumpl t4, r        ; EOF yet?
  2609.     move t1, filjfn        ; No, get JFN of the file.
  2610.     hrroi t2, strbuf    ; Get a bufferfull.
  2611.     movni t3, <strbln-1>    ; This many characters, leave room for null.
  2612.     setz t4,
  2613.     SIN
  2614.      erjmp [ setom t4
  2615.          jrst .+1 ]
  2616.     movei t1, .priou    ; Type what we got.
  2617.     hrroi t2, strbuf
  2618.     addi t3, <strbln-1>
  2619.     movns t3        ; Exactly this many.
  2620.     SOUT
  2621.     jrst typfi2        ; Go back for more.
  2622.  
  2623. ; REMOTE command help text.
  2624.  
  2625.  
  2626. hremot:    asciz |
  2627. REMOTE option
  2628.  
  2629. Ask the KERMIT server on the other end of the connection to execute a command
  2630. on its own system.  This command won't work unless you are running in local
  2631. mode (you have SET LINE n) and the KERMIT on the other end is running as a
  2632. server.
  2633.  
  2634. Options include:
  2635.  
  2636.  CWD            Change Working Directory (connect).
  2637.  DELETE filespec    Delete a file or file group.
  2638.  DIRECTORY filespec    Send a directory listing.
  2639.  HOST command        To be executed by remote system's command processor.
  2640.  SPACE             Disk usage query.
  2641.  TYPE filesec        Type a file or file group at the terminal.
  2642. |
  2643.  
  2644. $remot:    ; REMOTE and LOCAL command dispatcher...
  2645.  
  2646.     skipe takdep        ;[177] OK from TAKE file
  2647.      jrst $local        ;[177]
  2648.     skipn local
  2649.      jrst [    tmsg <?Must SET LINE before issuing a REMOTE command>
  2650.         ret ]
  2651.  
  2652. $local:    move t2, pars2        ; Get back data value.
  2653.     hrrz t1, (t2)        ; Get evaluation routine.
  2654.     call (t1)        ; Call it.
  2655.     ret
  2656.  
  2657. ; REMOTE CWD Parsing
  2658.  
  2659.  
  2660. .xcwd:    setzm pasbuf        ; Zero this out.
  2661.     setzm pasbuf+1        ;  ...
  2662.     noise <to directory>    ; Issue guide words.
  2663.     movei t1, [
  2664.      flddb. .cmtxt,cm%sdh,,<directory or area on server file system,
  2665.  or carriage return for default area>]
  2666.     call cfield        ; Parse a string.
  2667.     setzm pars3        ; Assume they didn't give an area.
  2668.     move t2, [point 7, atmbuf] ; Did they give one?
  2669.     ildb t1, t2
  2670.     jumpe t1, r        ; No, done.
  2671.  
  2672.     call getpas        ; They did, ask for password.
  2673.     movem t1, pars3        ; Save pointer to it.
  2674.     ret            ; Done.
  2675.  
  2676. ;[106] REMOTE CWD Execution
  2677.  
  2678.  
  2679. $xcwd:
  2680. $xcwd2:    setzm strbuf        ; Zero out old stuff
  2681.     setzm strbuf+1
  2682.     move t1, [point 7, atmbuf] ;  Copy directory name from here
  2683.     move t2, [point 7, strbuf] ;  to here.
  2684.  
  2685.     movei t4, "C"        ; CWD generic command.
  2686.     idpb t4, t2
  2687.     ibp t2            ; Leave room for length.
  2688.  
  2689.     setz t3,        ; Counter.
  2690. $xcwd3:    ildb t4, t1        ; Copy the directory string.
  2691.     jumpe t4, $xcwd4
  2692.     idpb t4, t2
  2693.     aoja t3, $xcwd3
  2694.  
  2695. ; Note that lengths here apply to UNPREFIXED values.  If a length turns out to
  2696. ; be the same as a prefix character, it will be quoted itself.
  2697.  
  2698. $xcwd4:    move t4, [point 7, strbuf, 13] ; Deposit count at head of field.
  2699.     addi t3, 40        ; Make it printable.
  2700.     dpb t3, t4
  2701.     skipn pars3        ; Got a password too?
  2702.      jrst $xcwdz        ;  No.
  2703.  
  2704. $xcwd5:    movem t2, strptr    ; Yes.  Save current pointer.
  2705.     ibp t2            ; Save a place for length of this field.
  2706.     setz t3,        ; Reset counter for new field.
  2707.     move t1, pars3
  2708.  
  2709. $xcwd6:    ildb t4, t1        ; Get a character.
  2710.     jumpe t4, $xcwd7    ; If zero, done.
  2711.     idpb t4, t2        ; Deposit it.
  2712.     aoja t3, $xcwd6        ; Count it & loop.
  2713.  
  2714. $xcwd7:    idpb t4, t2        ; Make it asciz.
  2715.     addi t3, 40        ; Make count printable.
  2716.     idpb t3, strptr        ; Deposit it at head of field.
  2717.  
  2718. $xcwdz:    move t1, [point 7, strbuf] ; Point to it.
  2719.     movei t2, "G"        ; Packet type is H.
  2720.     jrst dosrv        ; Go send it and handle the reply.
  2721.  
  2722. ; REMOTE DELETE, DIRECTORY, TYPE parsing -- Parse a remote filespec.
  2723.  
  2724. .rmfil:    noise <remote files>    ; Parse the rest of the command.
  2725.     movei t1, [flddb. .cmtxt,cm%sdh,,<remote file specification>]
  2726.     call cfield
  2727.     ret
  2728.  
  2729. ; REMOTE DELETE (Erase) execution
  2730.  
  2731. $xdele: movei t4, "E"        ; Generic command is E.
  2732.     jrst srvfil
  2733.  
  2734.  
  2735. ; REMOTE DIRECTORY execution
  2736.  
  2737. $xdire:    movei t4, "D"        ; Generic command is D.
  2738.     jrst srvfil
  2739.  
  2740.  
  2741. ; REMOTE TYPE command execution.
  2742.  
  2743. $xtype:    movei t4, "T"        ; Generic command is T.
  2744.     jrst srvfil
  2745.  
  2746.  
  2747. ; SRVFIL
  2748. ;
  2749. ; Common code to construct a generic one-field command.
  2750. ; Generic command is single character in t4.  Argument is in ATMBUF.
  2751. ; Puts a 1-character length field at the beginning.
  2752. ;
  2753. srvfil:    call sinfo        ;[128] Exchange parameters with I packet.
  2754.      ret            ;[133]  Failed, give up.
  2755.     setzm strbuf        ; Zero out old stuff
  2756.     setzm strbuf+1
  2757.     move t1, [point 7, atmbuf] ;  Copy directory name from here
  2758.     move t2, [point 7, strbuf] ;  to here.
  2759.  
  2760.     idpb t4, t2        ; Deposit generic command.
  2761.     ibp t2            ; Leave a space
  2762.  
  2763.     setz t3,        ; Initialize counter
  2764.  
  2765. srvfi2:    ildb t4, t1        ; Get next one.
  2766.     idpb t4, t2        ; Deposit this one.
  2767.      skipe t4        ; If null, done.
  2768.     aoja t3, srvfi2        ; Count it & loop.
  2769.  
  2770. ;*    jumpe t3, [        ; Make sure there was at least one character.
  2771. ;*        tmsg <?No file specified>
  2772. ;*        ret ]
  2773.  
  2774. srvfi3:    move t1, t3        ; Length
  2775.     addi t1, 40        ; CHAR of that.
  2776.     move t2, [point 7, strbuf, 13] ; Deposit count at head of field.
  2777.     dpb t1, t2
  2778.     move t1, [point 7, strbuf] ; Point to generic command.
  2779.     movei t2, "G"        ; Packet type is G.
  2780.     jrst dosrv        ; Go do it.
  2781.  
  2782. ; REMOTE SPACE parsing
  2783.  
  2784. .xdisk:    noise <usage query>
  2785.     confrm
  2786.     ret
  2787.  
  2788.  
  2789. ; REMOTE SPACE execution
  2790.  
  2791. $xdisk:    move t1, [point 7, [asciz/U/]] ; U command for data field.
  2792.     movei t2, "G"        ; Packet type is G.
  2793.     jrst dosrv
  2794.  
  2795.  
  2796. ; REMOTE HELP parsing
  2797.  
  2798. .xhelp:    noise <from KERMIT server>
  2799.     confrm
  2800.     ret
  2801.  
  2802. ; REMOTE HELP execution
  2803.  
  2804. $xhelp:    call sinfo        ; Exchange parameters.
  2805.      ret            ;[133] Failed, give up.
  2806.     move t1, [point 7, [asciz/H/]] ; H command for data field.
  2807.     movei t2, "G"        ; Packet type is G.
  2808.     jrst dosrv
  2809.  
  2810.  
  2811. ;[105] REMOTE HOST command.
  2812.  
  2813. .xhost:    noise <command>    ; Parse the rest of the REMOTE HOST command.
  2814.     movei t1, [
  2815.      flddb. .cmtxt,cm%sdh,,<command for server's host command processor>]
  2816.     call cfield
  2817.     ret
  2818.  
  2819. $xhost: skipe takdep        ;[176] Allow commands to servers from TAKE file
  2820.      jrst $xhos2
  2821.     skipe local        ; This only works if local Kermit.
  2822.      jrst $xhos2
  2823.     ermsg <Can't use REMOTE commands without prior SET LINE>,r
  2824.  
  2825. $xhos2:    move t1, [point 7, atmbuf] ; And move them from here
  2826.     move t2, [point 7, strbuf] ;  to here.
  2827.  
  2828. $xhos3:    ildb t4, t1        ; Copy the string.
  2829.     jumpe t4, $xhos4
  2830.     idpb t4, t2
  2831.     jrst $xhos3
  2832.  
  2833. $xhos4:    move t3, seolch        ; Terminate it with the host's eol character.
  2834.     idpb t3, t2
  2835.     idpb t4, t2        ; And a null.
  2836.  
  2837.     call ccon        ;[169] Enable ^C during this bit.
  2838.      jrst ccoff        ;[169]  Where to go if ^C happens.
  2839.     call sinfo        ; Exchange params.
  2840.      jrst ccoff        ;[169] Failed, give up, turn off ^C trap.
  2841.     call ccoff        ;[169]
  2842.     move t1, [point 7, strbuf] ; Point to command.
  2843.     movei t2, "C"        ; Packet type is C.
  2844.     jrst dosrv           ; Go send it and handle the reply.
  2845.  
  2846.  ; REMOTE ERROR -- a secret command to send a null error packet.
  2847.  
  2848. .xerr:    confrm
  2849.     ret
  2850.  
  2851. $xerr:    movei t1, "E"        ; Send an error packet.
  2852.     move t2, pktnum
  2853.     setzb t3, t4
  2854.     call spack
  2855.      nop
  2856.     ret
  2857.  
  2858.  
  2859.  
  2860.  
  2861. ; DOSRV
  2862. ;
  2863. ; Call this exactly like SRVCMD.
  2864. ;
  2865. ; Send a command to a server and dispatch appropriately depending on the reply.
  2866. ;
  2867. dosrv:    setzm gotx        ; Clear flags: "got X packet",
  2868.     setzm gots        ;  "got S packet".
  2869.     call srvcmd        ; Send a generic command.
  2870.      ret            ;  Didn't get good response.
  2871.     cain t1, "Y"        ; Was it an ACK?
  2872.      ret            ;  Yes, so we're done.
  2873.         
  2874. ; Come here if we're about to receive a multipacket reply.
  2875.  
  2876.     caie t1, "X"        ; Text header?
  2877.      jrst dosrv3        ;  No
  2878.     setom gotx        ; Yup, flag that we already got it.
  2879.     movei state, "F"    ; State state to file receive.
  2880.     skipn t3        ;[173](begin) Any contents?
  2881.      jrst $recvb        ; No.
  2882.     push p, t1        ; Yes, print them.
  2883.     hrroi t1, crlf
  2884.     PSOUT
  2885.     move t1, pktacs+3
  2886.     PSOUT
  2887.      erjmp $recvb
  2888.     hrroi t1, crlf
  2889.     PSOUT
  2890. dosrv2:    pop p, t1        ;[173](end)
  2891.     jrst $recvb        ; Go receive whatever is coming.
  2892.  
  2893. dosrv3:    cain t1, "S"        ; Or Send-Init?
  2894.      jrst [    setom gots    ; Yes, flag that we already got it.
  2895.         movei state, "R" ; Set state to receive init.
  2896.         jrst $recvb ]    ; Go receive what's coming.
  2897.  
  2898.     ermsg <Unexpected packet type returned by SRVCMD>,r
  2899.  
  2900. ; SRVCMD
  2901. ;
  2902. ; Routine to send a command to a server.
  2903. ; Call with:
  2904. ;  t1/ Byte pointer to string.
  2905. ;        First character is Generic Command, subsequent chars are arguments.
  2906. ;  t2/ Packet type, e.g. "G" for Generic, "C" for Host Command.
  2907. ;
  2908. ; Returns:
  2909. ;  +1 if reply was not received successfully.
  2910. ;  +2 If we got a good response, with
  2911. ;     t1/ packet type of response, "Y", "X", or "S".
  2912. ;     PKTACS/ Block of 4 words containing the data returned by RPACK.
  2913. ;
  2914. ;     If packet was ACK containing data, this routine prints it.
  2915. ;
  2916. srvcmd: skipe takdep        ;[176] Allow commands to servers from TAKE file
  2917.      jrst srvxx
  2918. srvxx:    saveac <q1,q2>        ; Preserve these work registers.
  2919.     dmove q1, t1        ; Copy arguments into them.
  2920.     skipn local        ;[177] Local Kermit?
  2921.      call inilin        ;[177] No, set TTY: up for packets.
  2922.     setzm numtry        ; Reset retry counter.
  2923.     setzm nnak        ; Init some statistics counters
  2924.     setzm ntimou        ;  ...
  2925.     setom bctone        ; Force 1-char checksum.
  2926.     move t1, netjfn        ; Clear out any stacked-up NAKs
  2927.     CFIBF%            ;
  2928.      %jserr (,.+1)        ; Give warning in case there's a problem.
  2929.     call ccon        ; Let them ^C out gracefully
  2930.      jrst srvcmx        ;  and go here if they do.
  2931.  
  2932.     call setlog        ; Set up any debugging log.
  2933.      nop
  2934.  
  2935. ; Put the command into the data field of the packet, using the normal
  2936. ; packet-filling technique, prefixing, etc.
  2937.  
  2938.     setzm data        ; Zero the buffer.
  2939.  
  2940. srvcma:    movei t1, gtsch        ; Indicate routine to be used for getting
  2941.     movem t1, source    ;  characters.
  2942.     movem q1, strptr    ; And where it should get them from.
  2943.     setom next        ; Set initial condition.
  2944.     move t1, maxdat        ; Get a buffer full of data.
  2945.     call getbuf        ; ...
  2946.      jumpn t1, srvcmx    ;  Clean up if this fails.
  2947.     setzm source        ; Got it, so put GETCH back to normal.
  2948.  
  2949.     movem t1, gclen        ; Save length.
  2950.     jumpn t1, srvcm2    ; Proceed if we got any.
  2951.  
  2952.     ermsg <No data for generic command>, srvcmx ; Do this otherwise.
  2953.     ;...
  2954.  
  2955. ;...SRVCMD, cont'd
  2956.  
  2957.  
  2958. ; Top of try-again loop.
  2959.  
  2960. srvcm2:    move q1, numtry        ; Too many tries?
  2961.     caml q1, maxtry
  2962.      ermsg <Can't send generic command, max tries exceeded>,srvcmx
  2963.     aos numtry        ; Not too many, count this try.
  2964.     move t1, q2        ; Packet type.
  2965.     setz t2,        ; Make the packet number zero.
  2966.     move t3, gclen        ; Length of data.
  2967.     move t4, [point 8, data] ; Point to data block.
  2968.     call spack        ; Send it off.
  2969.      jrst @[exp srvcm2, srvcmx](t1)    ; Handle nonfatal & fatal failures.
  2970.     setzm gotx        ; Assume it'll be an ACK.
  2971.     call rpack        ; Look for response.
  2972.      ermsg <RPACK failed>,srvcm2
  2973.  
  2974.     caie t1, "X"        ; X or Y?
  2975.      cain t1, "Y"
  2976.      jrst srvcmz        ; Good.
  2977.  
  2978.     caie t1, "S"        ; S or I?
  2979.      cain t1, "I"
  2980.      jrst srvcmz        ; That's ok too.
  2981.  
  2982.     cain t1, "E"        ; Error packet?
  2983.      jrst [    hrroi t1, [asciz/?Remote error -- /] ; Yes, print it.
  2984.         PSOUT%
  2985.         move t1, t4    ; Get pointer to it,
  2986.         PSOUT%        ; and print it.
  2987.          jrst srvcmx ]    ;[70]
  2988.     caie t1, "N"        ; NAK?
  2989.      cain t1, "T"        ; Or Timeout?
  2990.      jrst srvcm2        ;  One of those, go try again.
  2991.  
  2992.     ermsg <Invalid response from server>
  2993.  
  2994. ; Exit point for any kind of error, failure, or interruption
  2995.  
  2996. srvcmx:    call ccoff        ; Turn off ^C trap.
  2997.     call caxzof        ; Turn these interrupts off too.
  2998.     skiple filjfn        ;[135] Any file left open?
  2999.      jrst [    hrrz t1, filjfn    ;  Apparently, try to close it.
  3000.         setzm filjfn
  3001.         CLOSF
  3002.          erjmp .+1
  3003.         jrst .+1 ]    ;[135](end)
  3004.     skipn local        ;[177] Put controlling TTY back to normal
  3005.      call rrsl2        ;[177] ... (entry point to reslin)
  3006.     setzm source        ; Put things back to normal.
  3007.     seto t1,        ; Indicate no good response was received.
  3008.     ret            ; Return +1.
  3009.  
  3010.     ;...
  3011.  
  3012. ;...SRVCMD, cont'd
  3013.  
  3014.  
  3015. ; Exit here when response received successfully.
  3016.  
  3017. srvcmz:    dmovem t1, pktacs    ;[112] Save the ACs returned in RPACK
  3018.     dmovem t3, pktacs+2    ;[112]  ...
  3019.     movem t2, pktnum    ; Synchronize packet numbers.
  3020.     cain t1, "Y"        ;[121] Was the reply an ACK?
  3021.      jrst [    skipg t2, t3    ;[144] Yes, any characters?
  3022.          jrst .+1    ;[144] No.
  3023.         movei t1, puttch ;[144] Routine to display decoded characters.
  3024.         movem t1, dest    ;[144] ...
  3025.         move t1, t4    ;[144] Pointer to data buffer.
  3026.         call putbuf    ;[144] Go decode it.
  3027.          nop        ;[144]
  3028.         setzm dest    ;[144]
  3029.         jrst .+1 ]
  3030.     move t1, pktacs        ;[112] Get packet type back.
  3031.     call ccoff        ; Turn off ^C trap.
  3032.     skipn local        ;[177] Put controlling TTY back to normal
  3033.      call rrsl2        ;[177] ... (entry point to reslin)
  3034.     retskp            ; Done.
  3035.  
  3036. ;[58] SINFO added as part of edit 58.
  3037. ;
  3038. ; Call this routine before sending any server command which has a nontrivial
  3039. ; response.  For instance, it should be called before requesting a remote
  3040. ; directory listing, but need not be called before sending a CWD command,
  3041. ; which normally responds with a simple ACK.
  3042. ;
  3043. ; Action: Sends an info packet with our own parameters, waits for ACK with
  3044. ; other side's.  Uses packet number 0, does not increment the packet number.
  3045. ; If other side doesn't know about I packets, this routine returns as if a
  3046. ; an ACK was received containing all default values.
  3047. ;
  3048. ; Returns:
  3049. ;  +1 on failure, maximum tries exceeded.
  3050. ;  +2 on "success" getting a reply, even if it was an error packet,
  3051. ;     with other sides parameters set.
  3052. ;
  3053. sinfo:    saveac<t3,t4>        ;[128] Save these.
  3054.     setzm numtry        ; Give it a try,
  3055.     setzm pktnum        ;  starting out with a clean slate.
  3056.     setom bctone        ;[98] Use 1-char checksum.
  3057.  
  3058.     move t1, netjfn        ; Clear out any piled up NAKs.
  3059.     CFIBF%
  3060.      %jserr (,.+1)
  3061.     
  3062.     call setlog        ; Set up any debugging log.
  3063.      nop
  3064.     movei state, "S"    ;[133] This will be a little state switcher.
  3065.  
  3066. sinfo2:    movei t1, "I"        ;[100][133] Packet type.
  3067.     setom iflg        ;[100] Say we're doing I, not S.
  3068.     call sinit        ;[100] Let SINIT send it & get reply.
  3069.     cain t1, "E"        ; Other side doesn't know I packet?
  3070.      jrst [    setzb t3, t4    ;[133] Then set defaults this way.
  3071.         call spar    ;[133]
  3072.         jrst sinfoz ]    ;[133] And return successfully.
  3073.  
  3074. ;[133] Keep going if it doesn't get thru the first time.
  3075.  
  3076.     cain state, "F"        ; Switched into F state?
  3077.      jrst sinfoz        ;  Yes, so I was ACK'd, done.
  3078.     cain state, "S"        ; Still in S state?
  3079.      jrst sinfo2        ;  So go round again.
  3080.     
  3081. sinfox:    setzm iflg        ; Must have exceeded retry limit.
  3082.     ret            ; Fail.
  3083.  
  3084. sinfoz:    setzm iflg        ;[100] Done with sending I packet.
  3085.     retskp
  3086.  
  3087.     subttl    SET command
  3088.  
  3089.  
  3090. ; SET command help text.
  3091.  
  3092. hset:    asciz |
  3093. SET parameter [option] [value]
  3094.  
  3095.   Establish or modify various parameters for file transfer or terminal
  3096.   connection.  You can examine their values with the SHOW command.  The
  3097.   following parameters may be SET:
  3098.  
  3099.   BLOCK-CHECK error detection method
  3100.   BREAK       number of nulls at 50 baud for BREAK simulation
  3101.   DEBUGGING   mode or log file
  3102.   DELAY       how long to wait before starting to send
  3103.   DUPLEX      for terminal connection, full (remote echo) or half (local echo)
  3104.   ESCAPE      character for terminal connection
  3105.   FILE        for setting file parameters like name conversion and byte size
  3106.   FLOW-CONTROL for enabling and disabling XON/XOFF flow control
  3107.   HANDSHAKE   for turning around half duplex communication line
  3108.   INCOMPLETE  what to do with an incomplete file
  3109.   INPUT       desired behavior for INPUT command
  3110.   ITS-BINARY  special format for 8-bit binary files
  3111.   LINE        TTY line to use for terminal connection or file transfer
  3112.   PARITY      character parity to use
  3113.   PROMPT      for changing the KERMIT-20 program prompt
  3114.   RECEIVE     various parameters for receiving files
  3115.   RETRY       how many times to retry a packet before giving up
  3116.   SEND        various parameters for sending files
  3117.   SPEED       set speed (baud rate) of currently selected line
  3118.   TVT-BINARY  binary mode negotiation for Internet virtual terminals
  3119.  
  3120. For further information, type "help set" followed by one of these keywords.
  3121. Also, type "help define" to see how to define "macros" for SET commands.
  3122. |
  3123.  
  3124. ;[77] Parse SET command.  (This routine rewritten for edit 77.)
  3125.  
  3126. sfdb1:    flddb. .cmkey,,mactab,<SET macro,>,,sfdb2
  3127. sfdb2:    flddb. .cmkey,,settab
  3128.  
  3129. .set:    movei t1, sfdb2        ; Normal SET command table.
  3130.     hlrz t2, mactab        ; Anything in macro table?
  3131.     skipe t2        ; If so, include them too.
  3132.      skipe definf        ; Unless we're defining a macro.
  3133.      skipa            ; Don't allow recursive definitions!
  3134.      movei t1, sfdb1    ; Macro table is searched first.
  3135.     call rfield        ; Parse a keyword.
  3136.     ;...
  3137.  
  3138. ;...SET, cont'd
  3139.  
  3140.  
  3141. .set2:    setzm macrof        ; Assume regular SET keyword was parsed.
  3142.     hrrzs t3        ; See which function descriptor block was used.
  3143.     cain t3, sfdb1        ; The macro table?
  3144.      jrst [    hrrz t1, (t2)    ; Yes, get the data.
  3145.         hrli t1, (point 7,) ; This will be a pointer to the macro text.
  3146.         movem t1, pars2    ; Save it.
  3147.         confrm        ; Get confirmation.
  3148.         setom macrof    ; Set the macro flag.
  3149.         ret ]        ; No more to do.
  3150.  
  3151.     hrrz t2, (t2)        ; Get the command routine addresses.
  3152.     movem t2, pars2        ; Save into pars2.
  3153.     hlrz t1, (t2)    ; Get the next level routine.
  3154.     call (t1)        ; Call it.
  3155.  
  3156. ; If doing a DEFINE, loop through SET commands until CR typed.
  3157.  
  3158.     skipn definf        ; Doing DEFINE?  If so, allow comma here.
  3159.      ret
  3160.     movei t1, [flddb. .cmcma,cm%sdh,,<Comma for another SET parameter>,,[
  3161.             flddb. .cmcfm]
  3162.            ]
  3163.     call rfield
  3164.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  3165.     cain t3, .cmcma        ; Comma?
  3166.       jrst .set         ;  Yes, go back & get another SET parameter.
  3167.     ret            ; Confirmation, done.
  3168.  
  3169. ; SET keyword table.
  3170.  
  3171. settab:    %table
  3172.     %key <block-check>, [xwd .setbc,$setbc] ;[98]
  3173.     %key <break>, [xwd .setbr,$setbr]
  3174.     %key <debugging>, [xwd .setdb,$setdb]
  3175.     %key <delay>, [xwd .setdl,$setdl]
  3176.     %key <duplex>, [xwd .setdu,$setdu]
  3177.     %key <escape>, [xwd .setes,$setes]
  3178.     %key <expunge>, [xwd .setex,$setex] ;[143]
  3179.     %key <file>, [xwd .setfi,$setfi]
  3180.     %key <flow-control>, [xwd .setfl,$setfl] ;[143]
  3181.     %key <handshake>, [xwd .setha,$setha] ;[76]
  3182.     %key <incomplete>, [xwd .setab,$setab]
  3183.     %key <input>, [xwd .setin,$setrs] ;[160]
  3184.     %key <ITS-binary>, [xwd .setit,$setit]
  3185.     %key <line>, [xwd .setln,$setln]
  3186.     %key <parity>, [xwd .setpa,$setpa]
  3187.     %key <prompt>, [xwd .setpr,$setpr]
  3188.     %key <receive>, [xwd .setrc,$setrs]
  3189.     %key <retry>, [xwd .setre,$setre]
  3190.     %key <send>, [xwd .setsn,$setrs]
  3191.     %key <speed>, [xwd .setxp,$setsp]
  3192.     %key <TVT-Binary>, [xwd .setta,$setta] ;[129]
  3193.     %tbend
  3194.  
  3195. ; SET command, cont'd
  3196.  
  3197. ;[98] SET BLOCK-CHECK (This command added as part of edit 98)
  3198.  
  3199. hsbc:    asciz |
  3200.  SET BLOCK-CHECK option
  3201.  
  3202.    A block check is a quantity formed by arithmetically combining all the
  3203.    characters in a packet.  The sender of the packet appends the block check
  3204.    to it, the receiver recomputes the block check and compares it with the
  3205.    one that was received.  If they don't agree, the packet is retransmitted.
  3206.    The SET BLOCK-CHECK command is used to request one of three block check
  3207.    techniques:
  3208.  
  3209.      1-CHARACTER-CHECKSUM
  3210.         The standard KERMIT 6-bit checksum, the most efficient of the three
  3211.     options, sufficient in almost every case.  This is the default.
  3212.      2-CHARACTER-CHECKSUM
  3213.         A 12-bit checksum.  Adds transmission overhead, but catches more
  3214.     errors.
  3215.      3-CHARACTER-CRC
  3216.         A 16-bit cyclic redundancy check.  Adds even more overhead, catches
  3217.     even more errors.  Only use this for very noisy connections.
  3218.  
  3219.    KERMIT-20 will request the type of block check set by this command be used
  3220.    for a transfer.  If the other KERMIT agrees (not all KERMITs know how to
  3221.    compute the 2- and 3-character block checks), then the desired block check
  3222.    type will be used.  If not, the single character checksum will be used.
  3223. |
  3224.  
  3225. .setbc:    noise <type to>        ; Issue guide words
  3226.     movei t1, [flddb. .cmkey,,bctab,,<1>] ; Parse keyword, default is "1".
  3227.     call rfield
  3228.     hrrz t2, (t2)        ; Save the value we parsed.
  3229.     movem t2, pars3
  3230.     skipn definf        ; In a DEFINE command?
  3231.      confrm            ;  No, make them type a carriage return.
  3232.     ret
  3233.  
  3234. bctab:    %table
  3235.     %key <1-character-checksum>, "1"
  3236.     %key <2-character-checksum>, "2"
  3237.     %key <3-character-crc>, "3"
  3238.     %tbend
  3239.  
  3240. ; SET BLOCK-CHECK command execution.
  3241.  
  3242. $setbc:    move t1, pars3        ; Get what was parsed.
  3243.     movem t1, bctr        ; Save it as "block check type requested".
  3244.     ret
  3245.  
  3246. ; SET command, cont'd
  3247.  
  3248. ; SET INCOMPLETE
  3249.  
  3250. hsabf:    asciz |
  3251.  SET INCOMPLETE options
  3252.    Specify what to do when a file transfer fails before it is completed.
  3253.    The options are DISCARD (the default) and KEEP.  If you choose KEEP, then if
  3254.    a transfer fails to complete successfully, you will be able to keep the
  3255.    incomplete part that was received.
  3256. |
  3257.  
  3258. .setab:    noise <file disposition> ;[42] SET INCOMPLETE (file disposition)
  3259.     movei t1, [flddb. .cmkey,,[<2,,2>
  3260.         <[asciz/discard/],,0>
  3261.         <[asciz/keep/],,1>
  3262.         ],,<discard>]
  3263.     call rfield        ; Parse & confirm.
  3264.     hrrz t2, (t2)
  3265.     movem t2, pars3
  3266.     skipn definf        ;[77] In DEFINE?
  3267.      confrm            ;[77]  No, get confirmation.
  3268.     ret
  3269.  
  3270. ; SET command, cont'd
  3271.  
  3272.  
  3273. ; SET BREAK
  3274.  
  3275. hsbrea:    asciz |
  3276.  SET BREAK n
  3277.   Specify the number of nulls to be sent at 50 baud to simulate a BREAK
  3278.   signal when connected to a remote host via SET LINE and CONNECT.
  3279. |
  3280. .setbr:    noise (nulls)
  3281.     movei t1, [
  3282.      flddb. .cmnum,,^d10,<Number of nulls at 50 baud to simulate BREAK,>]
  3283.     call rfield
  3284.     skipge t2
  3285.      jrst [ tmsg <?Number must be positive>
  3286.         jrst cmder1 ]
  3287.     caile t2, maxnul
  3288.      jrst [    tmsg <?Too many nulls, maximum is >
  3289.         numout [maxnul]
  3290.         jrst cmder1 ]
  3291.     movem t2, pars3
  3292.     skipn definf        ;[77] In DEFINE?
  3293.      confrm            ;[77]  No, get confirmation.
  3294.     ret
  3295.  
  3296. $setbr:    move t2, pars3        ; Execute SET BREAK.
  3297.     movem t2, brk
  3298.     ret
  3299.  
  3300. ; SET DEBUG
  3301.  
  3302. hsdeb:    asciz |
  3303.  SET DEBUG options
  3304.    Show packet traffic explicitly on your terminal (if local) or in a file.
  3305.    Options are:
  3306.      STATES   Show Kermit state transitions and packet numbers (brief).
  3307.  
  3308.      PACKETS  Display each incoming and outgoing packet (lengthy).
  3309.  
  3310.      OFF      Don't display debugging information (this is the default).  If
  3311.               debugging was in effect, turn it off and close any log file.
  3312.  
  3313.    To record debugging information in a file, use LOG DEBUGGING.
  3314. |
  3315.  
  3316. .setdb:    noise <option>        ; SET DEBUGGING
  3317.     movei t1, [flddb. .cmkey,,dbgtab,,states]
  3318.     call rfield        ; Parse a keyword.
  3319.     hrrz t2, (t2)        ; Get the value for the keyword.
  3320.     movem t2, pars3        ; Save into pars3.
  3321.  
  3322. .stdbx:    skipn definf        ;[77] In DEFINE?
  3323.      confrm            ;[77]  No, get confirmation.
  3324.     ret
  3325.  
  3326. dbgtab:    %table
  3327.     %key <off>, 0
  3328.     %key <packets>, 2    ;[22]
  3329.     %key <states>, 1    ;[22]
  3330.     %tbend
  3331.  
  3332. dbstab:    %table            ;[41] (this table)
  3333.     %key <7>,7
  3334.     %key <8>,8
  3335.     %tbend
  3336.  
  3337. ;...SET command, cont'd
  3338.  
  3339.  
  3340. ; SET FILE
  3341.  
  3342. ; Help text...
  3343.  
  3344. hsfil:    asciz |
  3345.  SET FILE paramater keyword
  3346.    Establish file-related parameters:
  3347.  
  3348.    BYTESIZE keyword or number
  3349.      Byte size for DEC-20 file input/output.  The choices are SEVEN, EIGHT, and
  3350.      AUTO.  If SEVEN, do normal ASCII character i/o.  EIGHT is necessary for
  3351.      transmission of non-DEC-20 binary files, like .COM files from
  3352.      microcomputers.  AUTO is equivalent to SEVEN for incoming files, and for
  3353.      outgoing files means to use EIGHT if the DEC-20 file bytesize (as shown by
  3354.      the Exec VDIR command) is 8, otherwise use SEVEN.  The default is AUTO.
  3355.  
  3356.      SEVEN or AUTO can be used to send and receive DEC-20 binary files, such as
  3357.      .EXE or .REL files.  EIGHT is only for "foreign" 8-bit binary files.
  3358.  
  3359.    NAMING UNTRANSLATED or NORMAL-FORM
  3360.      If NORMAL-FORM the names of incoming or outgoing files will be converted
  3361.      to contain only uppercase letters, digits, and periods.  If UNTRANSLATED,
  3362.      filenames will be left alone.  If conversion is being done, all control
  3363.      and punctuation characters (other than ".") in filenames will be
  3364.      translated to "X", and lower case letters will be capitalized.
  3365.      UNTRANSLATED is the default.
  3366. |
  3367.  
  3368. ; Parse rest of SET FILE
  3369.  
  3370. sfitab:    %table            ; Table of file parameters to SET.
  3371.     %key <bytesize>,0
  3372.     %key <naming>,1
  3373.     %tbend
  3374.  
  3375. ; The following ruse using chained FDB's allows the old-style command to
  3376. ; be parsed most of the time, like "SET FILE 8".
  3377.  
  3378. sfifd1: flddb. .cmkey,,sfitab,,<bytesize>,sfifd2
  3379. sfifd2:    flddb. .cmkey,,sfbtab,<DEC-20 file byte size,>,<auto>
  3380.  
  3381. .setfi:    noise <parameter>    ;[84] SET FILE
  3382.     movei t1, sfifd1
  3383.     call rfield
  3384.     hrrz t2, (t2)
  3385.     hrrzs t3        ;[84] Which function descriptor block was used?
  3386.     setzm pars3        ;[84] Assume they specified a bytesize.
  3387.     cain t3, sfifd2        ;[84] They specified a bytesize?
  3388.      jrst .setfz        ;[84]  Yes, so don't parse it again.
  3389.     movem t2, pars3
  3390.     noise <to>
  3391.     movei t1, [flddb. .cmkey,,sfbtab,<DEC-20 file byte size,>,<auto>]
  3392.     skipe pars3        ;[84]
  3393.      movei t1, [flddb. .cmkey,,fntab,,<untranslated>] ;[84]
  3394.     call rfield        ; Parse a keyword.
  3395.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3396. .setfz:    movem t2, pars4        ;[84] Save here.
  3397.     skipn definf        ;[77] In DEFINE?
  3398.      confrm            ;[77]  No, get confirmation.
  3399.     ret
  3400.  
  3401. ; file name translation keywords.
  3402.  
  3403. fntab:    2,,2
  3404.     [asciz/normal-form/],,1
  3405.     [asciz/untranslated/],,0
  3406.  
  3407. ; file bytesize keyword table.
  3408.  
  3409. sfbtab:    %table
  3410.     %key <7-bit>, 0
  3411.     %key <8-bit>, 1
  3412.     %key <auto>, 2
  3413.     %key <eight-bit>, 1
  3414.     %key <seven-bit>, 0
  3415.     %tbend
  3416.  
  3417. ;...SET command, cont'd
  3418.  
  3419.  
  3420. ; SET PARITY
  3421.  
  3422. hspar:    asciz |
  3423.  SET PARITY keyword
  3424.    If parity is being used on the communication line, you must
  3425.    inform KERMIT-20, so it can send the desired parity on outgoing characters,
  3426.    and strip it from incoming ones.  The DEC-20 does not use parity on
  3427.    communication lines.  The choices are NONE (the default), ODD, EVEN, MARK,
  3428.    and SPACE.  NONE means no parity processing is done, and the 8th bit of
  3429.    each character can be used for data when transmitting binary files.
  3430.  
  3431.    If ODD, EVEN, MARK, or SPACE are selected, binary files will be transferred
  3432.    using 8th-bit-prefixing if the other side agrees, otherwise they cannot be
  3433.    be successfully transferred.  If NONE is specified, 8th-bit-prefixing will
  3434.    not be requested.
  3435.  
  3436.    SET PARITY should be used for communicating with hosts that require
  3437.    character parity, or through devices or networks (like TELENET) that add
  3438.    parity to characters that pass through them.  Both KERMITs should be set to
  3439.    the same parity.
  3440.  
  3441.    The specified parity is used both for terminal connection (CONNECT) and
  3442.    file transfer (SEND, RECEIVE, GET).
  3443. |
  3444.  
  3445. .setpa:    noise <to>        ; SET PARITY
  3446.     movei t1, [flddb. .cmkey,,partab,,none,]
  3447.     call rfield        ; Parse a keyword.
  3448.     hrrz t2, (t2)        ; Get the value for the keyword.
  3449.     movem t2, pars3        ; Save into pars3.
  3450.     skipn definf        ;[77] In DEFINE?
  3451.      confrm            ;[77]  No, get confirmation.
  3452.     ret
  3453.  
  3454. partab:    %table
  3455.     %key <even>, even
  3456.     %key <mark>, mark
  3457.     %key <none>, none
  3458.     %key <odd>, odd
  3459.     %key <space>, space
  3460.     %tbend
  3461.  
  3462. ;...SET command, cont'd
  3463.  
  3464.  
  3465. ;[137] SET PROMPT
  3466.  
  3467. hsprom:    asciz |
  3468.  SET PROMPT string
  3469.    Set the KERMIT-20 prompt to whatever character string you like.
  3470.    This is especially useful when connected to another DEC-20 through a
  3471.    dialer, using another KERMIT-20 on the remote system.  A unique prompt
  3472.    for each KERMIT-20 will clear up any confusion about which one you're
  3473.    talking to.
  3474. |
  3475.  
  3476. .setpr:    noise <to>        ; Parse the rest of the SET PROMPT command.
  3477.     movei t1, [
  3478.      flddb. .cmtxt,,,<KERMIT-20 command prompt>,<x>] ; Phony default.
  3479.     hrroi t2, [asciz/Kermit-20>/] ; Set up real default
  3480.     movem t2, .cmdef(t1)
  3481.     call cfield
  3482.     ret
  3483.  
  3484.  
  3485. ; Execute the SET PROMPT command.
  3486.  
  3487. $setpr:    move t1, [point 7, atmbuf] ; And move the characters from here
  3488.     move t2, [point 7, prompx] ;  to here.
  3489.  
  3490. $stpra:    ildb t4, t1        ; Copy the string.
  3491.     jumpe t4, $stprb
  3492.     idpb t4, t2
  3493.     jrst $stpra
  3494.  
  3495. $stprb:    idpb t4, t2        ; And a null.
  3496.     ret
  3497.  
  3498. ; SET command, cont'd
  3499.  
  3500. ; SET RETRY
  3501.  
  3502. hsrty:    asciz |
  3503.  SET RETRY option decimal-number
  3504.    Set the maximum number of retries allowed for:
  3505.      INITIAL CONNECTION -- How many times to try connecting before giving up.
  3506.      PACKETS -- How many times to try sending a particular packet.
  3507. |
  3508.  
  3509.  
  3510. .setre:    noise <maximum for>    ;[37] SET RETRY
  3511.     movei t1, [flddb. .cmkey,,[<2,,2>
  3512.         <[asciz/initial-connection/],,0>
  3513.         <[asciz/packets/],,1>
  3514.         ],,<packets>]
  3515.     call rfield
  3516.     hrrz t2, (t2)        ; Get the keyword index
  3517.     movem t2, pars3
  3518.     noise <to>        ; Prompt for the value
  3519.     movei t1, [flddb. .cmnum,,^d10,<times to retry before giving up,>,5]
  3520.     skipn pars3
  3521.      movei t1, [flddb. .cmnum,,^d10,<times to retry before giving up,>,16]
  3522.     call rfield
  3523.     movem t2, pars4
  3524.     skipn definf        ;[77] In DEFINE?
  3525.      confrm            ;[77]  No, get confirmation.
  3526.     ret
  3527.  
  3528. offon:    %table            ; Table for parsing ON or OFF.
  3529.     %key <off>, 0
  3530.     %key <on>, 1
  3531.     %tbend
  3532.  
  3533. ; SET command,  cont'd
  3534.  
  3535.  
  3536. ;[143] SET FLOW-CONTROL added as edit 143
  3537.  
  3538. hsflo:    asciz |
  3539.  SET FLOW-CONTROL option
  3540.    For communicating with full duplex systems.  The DEC-20 system is capable
  3541.    of regulating the flow of characters on the line using XON/XOFF flow
  3542.    control.  If characters are coming into the DEC-20 too fast, the DEC-20 will
  3543.    send an XOFF signal, Control-S, to tell the system on the other side to stop
  3544.    sending characters.  After it has finished processing the characters in its
  3545.    input buffer, it will send a Control-Q to tell the other side to resume
  3546.    sending.  The other system does the same thing when the DEC-20 is sending
  3547.    data characters.  KERMIT-20 will use XON/XOFF flow control on a full-duplex
  3548.    connection by default, and it will not use it on a half duplex connection.
  3549.    The options of the SET FLOW-CONTROL command are XON-XOFF and NONE.  If you
  3550.    SET FLOW-CONTROL to anything other than NONE, HANDSHAKE is set to NONE.
  3551. |
  3552. .setfl:    movei t1, [flddb. .cmkey,,flotab,,XON-XOFF] ; SET FLOW-CONTROL
  3553.     call rfield        ; Parse a keyword.
  3554.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3555.     movem t2, pars3        ; Save into pars3.
  3556.     skipn definf        ; In DEFINE?
  3557.      confrm            ;  No, get confirmation.
  3558.     ret
  3559.  
  3560. flotab:    %table            ; Flow-Control keywords
  3561.     %key <none>,0
  3562.     %key <XON-XOFF>,1
  3563.     %tbend
  3564.  
  3565. ;[76] SET HANDSHAKE added as edit 76.
  3566.  
  3567. hshan:    asciz |
  3568.  SET HANDSHAKE option
  3569.    For communicating with half duplex systems.  This lets you specify the line
  3570.    turnaround character sent by the half duplex host to indicate it has ended
  3571.    its transmission and is granting you permission to transmit.  When a
  3572.    handshake is set, KERMIT-20 will not send a packet until the half duplex
  3573.    host has sent the specified character.  The options are:
  3574.  
  3575.      NONE
  3576.      XOFF  (^S)
  3577.      XON   (^Q)
  3578.      BELL  (^G)
  3579.      CR    (^M, carriage return)
  3580.      LF    (^J, linefeed)
  3581.      ESC   (Escape)
  3582.      or an octal number specifying any ASCII control character.
  3583.  
  3584. If you SET HANDSHAKE to anything other than NONE, FLOW-CONTROL is set to NONE.
  3585. |
  3586.  
  3587.  
  3588. .setha:    movei t1, [flddb. .cmkey,,hshtab,,XOFF,[
  3589.      flddb. .cmnum,cm%sdh,^d8,<octal value of ASCII control character>]]
  3590.     call rfield        ; Parse a keyword.
  3591.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  3592.     caie t3, .cmnum        ; Number?
  3593.      hrrz t2, (t2)        ;  No, get the keyword's associated value.
  3594.     caile t2, 37        ; Control character?
  3595.      cain t2, 177
  3596.      skipa
  3597.      jrst [    tmsg <?Must be in ASCII control range, 0-37 or 177>
  3598.         jrst cmder1 ]
  3599.     movem t2, pars3        ; Save into pars3.
  3600.     skipn definf        ;[77] In DEFINE?
  3601.      confrm            ;[77]  No, get confirmation.
  3602.     ret
  3603.  
  3604. hshtab:    %table            ; Handshake keywords
  3605.     %key <bell>,7
  3606.     %key <CR>,15
  3607.     %key <ESC>,33
  3608.     %key <LF>,12
  3609.     %key <none>,0
  3610.     %key <XOFF>,23
  3611.     %key <XON>,21
  3612.     %tbend
  3613.  
  3614. ; SET command, cont'd
  3615.  
  3616. ;[160] SET INPUT
  3617.  
  3618. hsetin:    asciz |
  3619.  SET INPUT parameter value
  3620.    Specify how the INPUT command is to behave (see INPUT).
  3621.  
  3622.    SET INPUT DEFAULT-TIMEOUT n
  3623.       n is the number of seconds for an INPUT command to time out after
  3624.       not receiving the requested input, if no interval is explicitly
  3625.       given in the INPUT command.
  3626.  
  3627.    SET INPUT TIMEOUT-ACTION PROCEED or QUIT
  3628.       If the INPUT command comes from a command file (see TAKE command),
  3629.       then use this command to specify whether processing of the command
  3630.       file should proceed or quit after a timeout occurs.
  3631.  
  3632.    SET INPUT CASE IGNORE or OBSERVE
  3633.       Specify whether alphabetic case should be ignored ("a" matches "A")
  3634.       or observed ("a" does not match "A").
  3635. |
  3636.     ;...
  3637.  
  3638. ; SET INPUT parsing, like SET SEND/RECEIVE -- an extra level of parsing.
  3639.  
  3640.  
  3641. .setin:    movei t1, [flddb. .cmkey,,sintab] ; SET INPUT ...
  3642.     call rfield        ; Parse a keyword.
  3643.     hrrz t2, (t2)        ; Get the command routine addresses.
  3644.     movem t2, pars3        ; Save into pars3.
  3645.     hlrz t1, (t2)        ; Get the next level routine.
  3646.     call (t1)        ; Call it.
  3647.     ret
  3648.  
  3649. sintab:    %table
  3650.     %key <case>, [xwd .sinca,incase]
  3651.     %key <default-timeout>, [xwd .sindt,indeft]
  3652.     %key <timeout-action>, [xwd .sinta,intima]
  3653.     %tbend
  3654.  
  3655. .sinca:    noise <for matching>    ; SET INPUT CASE
  3656.     movei t1, [flddb. .cmkey,,castab,,<ignore>]
  3657.     jrst .sinkp        ; Go below & parse rest.
  3658.  
  3659. castab:    %table            ; Case table.
  3660.     %key <ignore>, 0
  3661.     %key <observe>, 1
  3662.     %tbend
  3663.  
  3664. .sindt:    noise <for INPUT commands> ; SET INPUT DEFAULT-TIMEOUT
  3665.     movei t1, [
  3666.      flddb. .cmnum,,^d10,<seconds,
  3667. when interval not specified in INPUT command,>]
  3668.     call rfield
  3669.     movem t2, pars4
  3670.     skipn definf        ; In DEFINE?
  3671.      confrm            ; No, get confirmation.
  3672.     ret
  3673.  
  3674. .sinta:    noise <for command file> ; SET INPUT TIMEOUT-ACTION
  3675.     movei t1, [flddb. .cmkey,,itatab,,<proceed>]
  3676.  
  3677. .sinkp:    call rfield        ; Parse keyword.
  3678.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3679.     movem t2, pars4        ; Save into pars4.
  3680.     skipn definf        ; In DEFINE?
  3681.      confrm            ; No, get confirmation.
  3682.     ret
  3683.  
  3684. itatab:    %table            ; INPUT timeout action table
  3685.     %key <proceed>, 0
  3686.     %key <quit>, 1
  3687.     %tbend
  3688.  
  3689. ; SET command, cont'd
  3690.  
  3691.  
  3692. ;[75] SET ITS-BINARY (format) ON or OFF
  3693.  
  3694. hsits:    asciz |
  3695.  SET ITS-BINARY (format) ON or OFF
  3696.    Specify whether ITS-Binary file headers are to be recognized or ignored.
  3697.    ITS binary format is a way (devised at MIT) of storing foreign 8-bit binary
  3698.    data on a 36-bit machine to allow automatic recognition of these files when
  3699.    sending them out again, so that you don't have to depend on the file byte
  3700.    size, or to issue explict SET FILE BYTESIZE commands to KERMIT.
  3701.  
  3702.    An ITS format binary file contains the sixbit characters "DSK8" left-
  3703.    adjusted in the first 36-bit word.  If ITS-BINARY is ON, then KERMIT-20 will
  3704.    send any file starting with this "header word" using 8-bit i/o, and will not
  3705.    send the header word itself, and it will store any incoming file that begins
  3706.    with that header word with 8-bit bytesize, again discarding the header word
  3707.    itself.  If ITS-BINARY is OFF, then the header word, if any, will be sent,
  3708.    and i/o will be according to the setting of FILE BYTESIZE.
  3709. |
  3710.  
  3711. .setit:    noise <format>        ; Issue guide word.
  3712.     movei t1, [flddb. .cmkey,,offon,,on] ; SET ITS-BINARY
  3713.     call rfield        ; Parse a keyword.
  3714.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3715.     movem t2, pars3        ; Save into pars3.
  3716.     skipn definf        ;[77] In DEFINE?
  3717.      confrm            ;[77]  No, get confirmation.
  3718.     ret
  3719.  
  3720. ; SET command, cont'd
  3721.  
  3722.  
  3723. ; SET LINE
  3724.  
  3725. hslin:    asciz |
  3726.  SET LINE octal-number
  3727.    Specify the octal TTY number to use for file transfer or CONNECT.
  3728.    If you issue this command, you will be running as a local Kermit, and you
  3729.    must log in to the remote system and run Kermit on that side in order to
  3730.    transfer a file.  If you don't issue this command, KERMIT-20 assumes it is
  3731.    running remotely, and does file transfer over its job's controlling
  3732.    terminal line.
  3733.  
  3734.    You can also select the line directly in the CONNECT command.
  3735. |
  3736.  
  3737. ; Parse rest of SET LINE command.
  3738.  
  3739. .setln:    noise <to tty>        ; SET LINE
  3740.     movei t1, [
  3741.      flddb. .cmnum,,^d8,<TTY to transfer files over,>,,[
  3742.      flddb. .cmcfm,cm%sdh,,<confirm to reset>]]
  3743.     call rfield        ; Parse a tty number.
  3744.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  3745.     caie t3, .cmnum        ; Is it a TTY number?
  3746.      jrst .setl1        ;  If not it must be a confirm.
  3747.     movem t2, pars3        ; Save the tty number.
  3748.     skipn definf        ;[77] In DEFINE?
  3749.      confrm            ;[77]  No, get confirmation.
  3750.     ret
  3751.  
  3752. .setl1:    move t4, mytty        ; Get the our terminal number.
  3753.     movem t4, pars3        ; Make believe we parsed it.
  3754.     ret
  3755.  
  3756. hsdel:    asciz |
  3757.  SET DELAY decimal-number
  3758.    How many seconds to wait before sending the first packet.  Use when remote
  3759.    and SENDing files back to your local Kermit.  This gives you time to
  3760.    "escape" back and issue a RECEIVE command before packets start arriving.
  3761.    The normal delay is 5 seconds.
  3762. |
  3763.  
  3764. .setdl:    noise <to>        ; SET DELAY
  3765.     movei t1, [flddb. .cmnum,,^d10,<seconds before sending first packet,>]
  3766.     call rfield        ; Parse a number.
  3767.     movem t2, pars3        ; Save the number.
  3768.     skipn definf        ;[77] In DEFINE?
  3769.      confrm            ;[77]  No, get confirmation.
  3770.     ret
  3771.  
  3772. ; SET command, cont'd
  3773.  
  3774.  
  3775. ; SET DUPLEX
  3776.  
  3777. hsdup:    asciz |
  3778.  SET DUPLEX keyword
  3779.    For use when CONNECTed to a remote system.  The choices are FULL and HALF.
  3780.    FULL means the remote system echoes the characters you type, HALF means
  3781.    the local system echoes them.  FULL is the default, and is used by most
  3782.    hosts.  HALF is necessary when connecting to IBM mainframes.
  3783. |
  3784.  
  3785. ; Parse SET DUPLEX
  3786.  
  3787. .setdu:    noise <to>        ;[18] SET DUPLEX
  3788.     movei t1, [flddb. .cmkey,,duptab,,<full>]
  3789.     call rfield
  3790.     hrrz t2, (t2)
  3791.     movem t2, pars3
  3792.     skipn definf        ;[77] In DEFINE?
  3793.      confrm            ;[77]  No, get confirmation.
  3794.     ret
  3795.  
  3796. duptab:    %table            ;[18] Table of legal duplexes
  3797.     %key <full>,dxfull
  3798.     %key <half>,dxhalf
  3799.     %tbend
  3800.  
  3801. ;[143] SET EXPUNGE
  3802. ;
  3803. hsexp:    asciz |
  3804.   SET EXPUNGE ON or OFF
  3805.     Tell whether you want a DELETE command (either the LOCAL DELETE command
  3806.     or a REMOTE DELETE command sent to a KERMIT-20 server) to expunge files as
  3807.     it deletes them.  On the DEC-20, a deleted file continues to take up space,
  3808.     and may be "undeleted" at a later time in the same session.  To expunge a
  3809.     deleted file means to remove it completely and irrevocably.  EXPUNGE is OFF
  3810.     (i.e. no automatic expunging of deleted files) by default.
  3811. |
  3812. .setex:    noise <deleted files automatically> ; SET EXPUNGE
  3813.     movei t1, [flddb. .cmkey,,offon,,on]
  3814.     call rfield        ; Parse a keyword.
  3815.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  3816.     movem t2, pars3        ; Save into pars3.
  3817.     skipn definf        ;[77] In DEFINE?
  3818.      confrm            ;[77]  No, get confirmation.
  3819.     ret    
  3820.  
  3821. ; SET ESCAPE
  3822.  
  3823. hsesc:    asciz |
  3824.  SET ESCAPE octal-number
  3825.    Tell what control character you want to use to "escape" from remote
  3826.    connections.  34 (Control-Backslash ^\) by default.  The number is the octal
  3827.    value of the ASCII control character, 1 to 37.  When you type the escape
  3828.    character, you must follow it by a single-character "argument":
  3829.  
  3830.    C  Close connection
  3831.    S  Status report
  3832.    P  Push to a new Exec on the local system
  3833.    Q  If you have given a LOG SESSION command, temporarily Quit logging
  3834.    R  Resume logging to session log
  3835.    B  Attempt to send a simulated BREAK signal.
  3836.    ?  List available options
  3837.    or second copy of the escape character to send the escape character itself.
  3838. |
  3839.  
  3840. ; Parse rest of SET ESCAPE command.
  3841.  
  3842. .setes:    noise <character for connect to> ;[16] SET ESCAPE
  3843.     movei t1, [
  3844.      flddb. .cmnum,,^d8,<Value of ASCII control character,>,<34>]
  3845.     call rfield
  3846.     caile t2, 37        ; Control character?
  3847.      cain t2, 177
  3848.      skipa
  3849.      jrst [    tmsg <?Must be in ASCII control range, 0-37 or 177>
  3850.         jrst cmder1 ]
  3851.     movem t2, pars3
  3852.     skipn definf        ;[77] In DEFINE?
  3853.      confrm            ;[77]  No, get confirmation.
  3854.     ret
  3855.  
  3856. ; SET command, cont'd
  3857.  
  3858. ; SET RECEIVE parameters
  3859.  
  3860. hsrcv:    asciz |
  3861.  SET RECEIVE parameter
  3862.    Parameters to request or expect for incoming packets, as follows:
  3863.  
  3864.    END-OF-LINE octal-number
  3865.      Carriage return (15) by default.  The DEC-20 does not actually need any
  3866.      line terminator for incoming packets.
  3867.  
  3868.    PACKET-LENGTH decimal-number
  3869.      Maximum length packet for the other side to send, decimal number,
  3870.      between 10 and 9000, 80 by default.
  3871.  
  3872.    PADDING octal-number, PADCHAR octal-number
  3873.      Should never be necessary; the DEC-20 needs no padding.
  3874.  
  3875.    PAUSE floating-point-number
  3876.      How many seconds to pause before acknowledging a packet.
  3877.      Setting this to a nonzero value will slow down the rate at which
  3878.      data packets come in to the DEC-20, which may be necessary for DEC-20's
  3879.      that have "sensitive" front ends and cannot accept input at a high rate.
  3880.  
  3881.    QUOTE octal-number
  3882.      What printable character to use for quoting of control characters.
  3883.      Specify the octal ASCII value.  "#" (43) by default.  There should be no
  3884.      reason to change this.
  3885.  
  3886.    SERVER-TIMEOUT decimal-numer
  3887.      When running as a server, how often to send periodic NAKs during server
  3888.      server command wait.  0 means don't send them at all.  94 seconds maximum.
  3889.  
  3890.    START-OF-PACKET octal-number
  3891.      The control character to mark the beginning of incoming packets.  Normally
  3892.      SOH (Control-A, ASCII 1).  There should be no reason to change this.
  3893.  
  3894.    TIMEOUT decimal-number
  3895.      How many seconds the other Kermit should wait for a packet before asking
  3896.      for retransmission.  If 0, then no timing out will be done.  94 seconds
  3897.      maximum.
  3898. |
  3899.  
  3900. ; Parse rest of SET RECEIVE...
  3901.  
  3902. .setrc:    movei t1, [flddb. (.cmkey,,srtabl,,)] ; SET RECEIVE ...
  3903.     call rfield        ; Parse a keyword.
  3904.     hrrz t2, (t2)        ; Get the command routine addresses.
  3905.     movem t2, pars3        ; Save into pars3.
  3906.     hlrz t1, (t2)        ; Get the next level routine.
  3907.     call (t1)        ; Call it.
  3908.     ret
  3909.  
  3910. srtabl:    %table
  3911.     %key <end-of-line>, [xwd .seteo,reolch]
  3912.     %key <packet-length>, [xwd .setpk,rpsiz]
  3913.     %key <padchar>, [xwd .setpc,rpadch]
  3914.     %key <padding>, [xwd .setpd,rpadn]
  3915.     %key <pause>, [xwd .srpau,rpause] ;[36]
  3916.     %key <quote>, [xwd .setqu,rquote]
  3917.     %key <server-timeout>, [xwd .setim,srvtim] ;[137]
  3918.     %key <start-of-packet>, [xwd .setsp,rsthdr] ;[18]
  3919.     %key <timeout>,[xwd .setim,rtimou]
  3920.     %tbend
  3921.  
  3922. ; SET SEND parameters
  3923.  
  3924. hssnd:    asciz |
  3925.  SET SEND parameter
  3926.    Parameters for outgoing packets, as follows:
  3927.  
  3928.    END-OF-LINE octal-number
  3929.      The octal value of the ASCII character to be used as a line terminator
  3930.      for packets, if one is required by the other system.  Carriage return
  3931.      (15) by default.  You will only have to use this command for systems
  3932.      that require a line terminator other than carriage return.
  3933.  
  3934.    PACKET-LENGTH decimal-number
  3935.      Maximum packet length to send, decimal number, between 10 and 9000, 80 by
  3936.      default.  Shortening the packets might allow more of them to get through
  3937.      through without error on noisy communication lines.
  3938.  
  3939.    PADDING octal-number, PADCHAR octal-number
  3940.      How much padding to send before a packet, if the other side needs padding,
  3941.      and what character to use for padding.  Defaults are no padding, and NUL
  3942.      (0) for the padding character.
  3943.  
  3944.    PAUSE floating-point-number
  3945.      How many seconds to pause before sending each data packet.  Setting this
  3946.      to a nonzero value may allow some slow systems enough time to process
  3947.      a data packet sent by the DEC-20 before the next one arrives.  Normally,
  3948.      no per-packet pausing is done.
  3949.  
  3950.    QUOTE octal-number
  3951.      What printable character to use for quoting of control characters.
  3952.      Specify an octal ASCII value.  "#" (43) by default.  There should be no
  3953.      reason to change this.
  3954.  
  3955.    START-OF-PACKET octal-number
  3956.      The control character that marks the beginning of a packet.  Normally
  3957.      SOH (Control-A, ASCII 1).  There should be no reason to change this.
  3958.  
  3959.    TIMEOUT decimal-number
  3960.      How many seconds to wait for a packet before trying again.
  3961. |
  3962.  
  3963. .setsn:    movei t1, [flddb. (.cmkey,,sstabl,,)] ; SET SEND ...
  3964.     call rfield        ; Parse a keyword.
  3965.     hrrz t2, (t2)        ; Get the command routine addresses.
  3966.     movem t2, pars3        ; Save into pars3.
  3967.     hlrz t1, (t2)        ; Get the next level routine.
  3968.     call (t1)        ; Call it.
  3969.     ret
  3970.  
  3971. sstabl:    %table
  3972.     %key <end-of-line>, [xwd .seteo,seolch]
  3973.     %key <packet-length>, [xwd .setpk,spsiz]
  3974.     %key <padchar>, [xwd .setpc,spadch]
  3975.     %key <padding>, [xwd .setpd,spadn]
  3976.     %key <pause>, [xwd .sspau,spause] ;[35]
  3977.     %key <quote>, [xwd .setqu,squote]
  3978.     %key <start-of-packet>, [xwd .setsp,ssthdr] ;[18]
  3979.     %key <timeout>,[xwd .setim,stimou]
  3980.     %tbend
  3981.  
  3982. ;...SET command, cont'd
  3983.  
  3984.  
  3985. ; SET PACKET-LENGTH
  3986.  
  3987. .setpk:    noise <to>        ; SET SEND/RECEIVE PACKET-LENGTH
  3988.     movei t1, [
  3989.      flddb. .cmnum,cm%sdh,^d10,<Decimal number between 10 and 94>]
  3990.     call rfield        ; Parse the packet size.
  3991.     movem t2, pars4        ; Save the packet size.
  3992.     cail t2, ^d10        ; Is the number in the right range?
  3993.      caile t2, ^d9000    ;[179] (was ^d94)
  3994.       jrst [tmsg <?Illegal packet size>
  3995.         jrst cmder1 ]
  3996.     skipn definf        ;[77] In DEFINE?
  3997.      confrm            ;[77]  No, get confirmation.
  3998.     ret
  3999.  
  4000.  
  4001. .srpau:    noise <between packets to> ;[36] SET RECEIVE PAUSE
  4002.     movei t1, [
  4003.      flddb. .cmflt,,,<seconds to pause after receiving a packet,>,<0>]
  4004.     jrst .sxpau        ; Join common code.
  4005.  
  4006.  
  4007. .sspau:    noise <between packets to> ;[35] SET SEND PAUSE
  4008.     movei t1, [
  4009.      flddb. .cmflt,,,<seconds to pause before sending a packet,>,<0>]
  4010.  
  4011.  
  4012. .sxpau:    call rfield        ;[36] Common code.
  4013.     movem t2, pars4
  4014.     noise <seconds>
  4015.     skipn definf        ;[77] In DEFINE?
  4016.      confrm            ;[77]  No, get confirmation.
  4017.     skipge pars4        ; Is the number in the right range?
  4018.      jrst [    tmsg <?Must be a positive number>
  4019.         jrst cmder1 ]
  4020.     ret
  4021.  
  4022. .setpd:    noise <to>        ; SET SEND/RECEIVE PADDING
  4023.     movei t1, [
  4024.      flddb. .cmnum,,^d10,<number of padding characters, positive>,<0>]
  4025.     call rfield        ; Parse the number of padding chars.
  4026.     movem t2, pars4        ; Save the number.
  4027.     skipn definf        ;[77] In DEFINE?
  4028.      confrm            ;[77]  No, get confirmation.
  4029.     move t2, pars4        ; Get the amount of padding we parsed.
  4030.     skipge t2        ; Is the number in the right range?
  4031.      jrst [    tmsg <?Must be a positive number>
  4032.         jrst cmder1 ]
  4033.     ret
  4034.  
  4035. ;...SET command, cont'd
  4036.  
  4037.  
  4038. .setpc:    noise <to>        ; SET SEND/RECEIVE PADCHAR
  4039.     movei t1, [
  4040.      flddb. .cmnum,,^d8,<Value of ASCII character, 0 to 37, or 177,>]
  4041.     call rfield        ; Parse the padding character.
  4042.     movem t2, pars4        ; Save the padding char.
  4043.     skipn definf        ;[77] In DEFINE?
  4044.      confrm            ;[77]  No, get confirmation.
  4045.     move t2, pars4        ; Get the padding char we parsed.
  4046.     cain t2, ^o177        ;[149] Is it a DEL?
  4047.      ret            ;[149] OK.
  4048.     skipl t2        ; Is it in the control range, 0 to...
  4049.      caile t2, ^o37        ; ...37 octal?
  4050.       jrst [tmsg <?Illegal padding character> ; No, give error message
  4051.         jrst cmder1 ]    ; and allow command retry.
  4052.     ret            ; Yes, OK.
  4053.  
  4054. .seteo:    noise <to>        ; END-OF-LINE
  4055.     movei t1, [
  4056.      flddb. .cmnum,,^d8,<Value of ASCII control character, 0-37,>,<15>]
  4057.     call rfield        ; Parse the EOL char.
  4058.     skipl t2        ; Is the number in the right range?
  4059.      caile t2, ^o37        ;  Fix to compare correctly.
  4060.       jrst [tmsg <?Illegal EOL character>
  4061.         jrst cmder1 ]
  4062.     movem t2, pars4        ; Get the EOL char we parsed.
  4063.     skipn definf        ;[77] In DEFINE?
  4064.      confrm            ;[77]  No, get confirmation.
  4065.     ret
  4066.  
  4067.  
  4068. .setsp:    noise <to>        ;[18] START-OF-PACKET
  4069.     movei t1, [
  4070.      flddb. .cmnum,cm%sdh,^d8,<Octal value of ASCII control character>,<1>]
  4071.     call rfield
  4072.     skipl t2        ; Is the number in the right range?
  4073.      caile t2, ^o37        ;  Fix to compare correctly.
  4074.       jrst [tmsg <?Illegal start-of-packet character>
  4075.         jrst cmder1 ]
  4076.     movem t2, pars4
  4077.     skipn definf        ;[77] In DEFINE?
  4078.      confrm            ;[77]  No, get confirmation.
  4079.     ret
  4080.  
  4081.     ;...
  4082.  
  4083. ; More SET commands...
  4084.  
  4085. .setqu:    noise <to>        ; SET SEND/RECEIVE QUOTE
  4086.     movei t1, [
  4087.      flddb. .cmnum,,^d8,<Value of printable ASCII character,>,<43>] ;[21]
  4088.     call rfield        ;[21]
  4089.     caile t2," "        ;[21] Printable?
  4090.      caile t2, "~"        ;[21]
  4091.      jrst [    tmsg <?Must be printable character, range 41-176>
  4092.         jrst cmder1 ]    ;[21]
  4093.     movem t2, pars4        ;[21] OK, stash it.
  4094.     skipn definf        ;[77] In DEFINE?
  4095.      confrm            ;[77]  No, get confirmation.
  4096.     ret
  4097.  
  4098. .setim:    noise <to>        ; SET SEND/RECEIVE TIMEOUT
  4099.     movei t1, [
  4100.      flddb. .cmnum,,^d10,<Number of seconds before timing out, 1 to 94,>]
  4101.     call rfield        ; Parse the number.
  4102.     movem t2, pars4        ; Save the number.
  4103.     skipn definf        ;[77] In DEFINE?
  4104.      confrm            ;[77]  No, get confirmation.
  4105.     move t2, pars4        ; Get the number we parsed.
  4106.     cail t2, 0        ;[94] Is the number in the right range?
  4107.      caile t2, ^d94        ;  Fix to compare correctly.
  4108.       jrst [tmsg <?Illegal number of seconds>
  4109.         jrst cmder1 ]
  4110.     ret
  4111.  
  4112.     subttl SET command action routines.
  4113.  
  4114. ; SET ... command dispatcher.
  4115.  
  4116. $set:    skipe macrof        ;[77] Was a macro used?
  4117.      jrst $set2        ;[77] If so, go handle that.
  4118.     move t2, pars2        ; Get back data value.
  4119.     hrrz t1, (t2)        ; Get evaluation routine.
  4120.     call (t1)        ; Call it.
  4121.     ret
  4122.  
  4123.     ;...
  4124.  
  4125. ;...$SET, cont'd
  4126.  
  4127.  
  4128. ;[77] SET macro was typed.
  4129.  
  4130. $set2:    move t1, pars2         ; Pointer to macro text (SET operands)
  4131.     movem t1, macxp
  4132. ;*    PSOUT            ; echo it for debugging...
  4133.     setzm mdone        ; Say macro not done yet.
  4134.  
  4135. ; Loop to copy one set command into the command buffer.
  4136.  
  4137. $set3:    move t1, [ascii/set  /]    ; Fake a SET command
  4138.     movem t1, cmdbuf
  4139.     move t2, [point 7, cmdbuf, 27] ; Copy them to after "set "
  4140.     movem t2, sbk+.cmptr
  4141.  
  4142. ; Loop for each character.
  4143.  
  4144. $set4:    ildb t1, macxp        ; Get a character from the macro text
  4145.     aos sbk+.cminc        ; Account for it in the CSB
  4146.     sos sbk+.cmcnt        ;  ...
  4147.     jumpe t1, $set5        ; If null, done.
  4148.     cain t1, ","        ; Comma?
  4149.      jrst [    movei t1, .chcrt ; Yes, substitute a carriage return.
  4150.         idpb t1, t2
  4151.         aos sbk+.cminc
  4152.         sos sbk+.cmcnt
  4153.         movei t1, .chlfd ; And a linefeed...
  4154.         idpb t1, t2
  4155.         aos sbk+.cminc
  4156.         sos sbk+.cmcnt
  4157.         setz t1,    ; And a null...
  4158.         idpb t1, t2
  4159.         jrst $set6 ]    ; Go execute this part.
  4160.  
  4161.     idpb t1, t2        ; Not a comma, copy the character.
  4162.     jrst $set4
  4163.  
  4164. ; Get here at end of null-terminated macro body.
  4165.  
  4166. $set5:    idpb t1, t2        ;[80] Deposit the null.
  4167.     setom mdone        ; Flag that we're done interpreting the macro.
  4168.  
  4169. $set6:    move t1, sbk        ; Zero the CSB flags.
  4170.     hrrzm t1, sbk        ;  ...
  4171. ;*    hrroi t1, cmdbuf    ; Echo the command.
  4172. ;*    PSOUT            ; ...
  4173.     call .set        ; Go parse the string.
  4174.     call $set        ; Go execute what was parsed.
  4175.     skipn mdone        ; Any more?
  4176.      jrst $set3        ; Yes, go do them.
  4177.     setzm mdone        ; No, all done.
  4178.     ret
  4179.  
  4180. ;[42] SET INCOMPLETE
  4181.  
  4182. $setab:    move t1, pars3        ; Just save what we parsed.
  4183.     movem t1, abtfil
  4184.     ret
  4185.  
  4186.  
  4187. ; SET DEBUGGING
  4188.  
  4189. $setdb:    skipn t1, pars3        ;[38] See what we got.
  4190.      jrst [    setz debug,    ;[38] Turning debugging off.
  4191.         skipn t1, logjfn ;[38] Did we have a log?
  4192.          ret        ;[38] No, done.
  4193.         setz t2,    ;[144] Yes, any bytes written?
  4194.         RFPTR        ;[144]
  4195.          nop        ;[144]
  4196.         skipg t2    ;[144]
  4197.          txo t1, cz%abt    ;[144] None, don't bother keeping the log.
  4198.         setzm logjfn    ;[38] Zero this so we know...
  4199.         CLOSF        ;[38] Close it.
  4200.          erjmp .+1    ;[144] Ignore errors, may already be closed
  4201.         ret ]        ;[38]  by previous EXIT command.
  4202.  
  4203.     skipl debug, pars3    ; DEBUG. Get the value we parsed.
  4204.      caile debug, 2        ;[22] Make sure it's 0, 1, or 2.
  4205.      movei debug, 1        ;[22] ...
  4206.     ret
  4207.  
  4208. ; SET SEND/RECEIVE command dispatcher.
  4209.  
  4210. $setrs:    move t1, @pars3        ; SEND/RECEIVE.  Address of variable to set.
  4211.     move t2, pars4        ; The value that was parsed.
  4212.     movem t2, (t1)        ; Save the value.
  4213.     ret
  4214.  
  4215. ; SET DELAY
  4216.  
  4217. $setdl:    move t1, pars3        ; DELAY. Get the number of seconds to delay.
  4218.     movem t1, delay        ; Save the delay time.
  4219.     movem t1, odelay    ;[27] Here too, for saving & restoring.
  4220.     ret
  4221.  
  4222. ; SET DUPLEX
  4223.  
  4224. $setdu:    move t1, pars3        ;[18] DUPLEX.  Get what was parsed.
  4225.     movem t1, duplex
  4226.     ret
  4227.  
  4228. ; SET ESCAPE
  4229.  
  4230. $setes:    move t1, pars3        ;[16] ESCAPE.  Get what we parsed.
  4231.     movem t1, escape
  4232.     ret
  4233.  
  4234. ; SET EXPUNGE
  4235.  
  4236. $setex:    move t1, pars3        ;[143] SET EXPUNGE
  4237.     movem t1, expung
  4238.     ret
  4239.  
  4240. ; SET FILE
  4241.  
  4242. $setfi:    skipn t1, pars3        ;[84] Which file parameter are we setting?
  4243.      jrst $setf8        ;[84] Bytesize, go do that.
  4244.  
  4245. ;  ... FILE NAMING
  4246.  
  4247. $setfn:    sojn t1, [        ;[84] We'll have to get a little fancier
  4248.         tmsg <?Impossible parse value> ;[84] if more file parameters
  4249.         ret ]        ;[84] are added...
  4250.     move t1, pars4        ;[84] OK, get the value.
  4251.     movem t1, xfnflg    ;[84] Save it.
  4252.     ret            ;[84] Done.
  4253.  
  4254. ;  ... FILE BYTESIZE
  4255.  
  4256. $setf8:    move t1, pars4        ; BYTESIZE... Get the value of the flag.
  4257.     cain t1, 2        ; Is it autobyte?
  4258.      jrst [ setom autbyt    ;  If so, say so,
  4259.         setzm ebtflg    ;  and say this not so.
  4260.         ret ]
  4261.     setzm autbyt        ; Say no auto-byte.
  4262.     movem t1, ebtflg    ; Set the flag.
  4263.     ret
  4264.  
  4265. ; SET PARITY
  4266.  
  4267. $setpa:    move t1, pars3        ;[109] What did they say?
  4268.     caie t1, none        ;[109] Was the parity NONE?
  4269.      jrst [    setom ebqr    ;[89] No, so request 8th-bit prefixing.
  4270.         movei t2, dqbin    ;[89] Use the default prefix.
  4271.         movem t2, ebq    ;[89]
  4272.         tmsg <%Will request 8th-bit prefixing.
  4273. %If the other KERMIT doesn't agree,
  4274. %binary files cannot be sent correctly.
  4275. >
  4276.         jrst .+2 ]    ;[89]
  4277.      jrst [    movei t1, "Y"    ;[95] If none, just say we will do 8th-bit
  4278.         movem t1, ebq    ;[95]  prefixing if requested.
  4279.         setzm ebqr    ;[95] But we won't request it ourselves.
  4280.         jrst .+1 ]    ;[95]
  4281.     move t1, pars3
  4282.     movem t1, parity
  4283.     ret
  4284.  
  4285. ; SET RETRY
  4286.  
  4287. $setre:    move t1, pars3        ;[37] SET RETRY
  4288.     move t2, pars4
  4289.     movem t2, @[exp imxtry, maxtry](t1)
  4290.     ret
  4291.  
  4292. ;[143] SET FLOW-CONTROL
  4293.  
  4294. $setfl:    skipe t1, pars3        ; Get flow control option.
  4295.      setzm handsh        ; If nonzero, turn off handshake.
  4296.     movem t1, flow
  4297.     ret
  4298.  
  4299. ;[76] SET HANDSHAKE
  4300.  
  4301. $setha:    skipe t1, pars3        ;[143] Get the handshake option.
  4302.      setzm flow        ;[143] If nonzero, turn off flow control.
  4303.     movem t1, handsh    ; Save it.
  4304.     ret            ; Done.
  4305.  
  4306. ;[75] SET ITS-BINARY
  4307.  
  4308. $setit:    move t1, pars3        ; Just save the value in the ITS flag.
  4309.     movem t1, itsflg
  4310.     ret
  4311.  
  4312. ; SET LINE
  4313. ;
  4314. ;[87] Call with PARS3/ number of line to assign.
  4315. ;
  4316. $setln:    move t1, ttynum        ; Previous line number, if any.
  4317.     movem t1, oldnum    ; Remember it.
  4318.     move t1, pars3
  4319.     movem t1, ttynum    ;
  4320.     move t1, asgflg        ; Remember in case we already had another...
  4321.     movem t1, oasflg    ;
  4322.     move t1, netjfn        ;[80]
  4323.     movem t1, oldjfn    ;[80]
  4324.         setzm local             ; Assume we're a remote Kermit.
  4325.         move t1, ttynum         ;[80]
  4326.         came t1, mytty          ; Lines the same?
  4327.          setom local            ; No, so we're local.
  4328.  
  4329.     call chktvt        ;[182] Possibly detect if we're a TVT
  4330.  
  4331. $stln1:    move t1, ttynum        ;[182] Load the line in question
  4332.     txo t1, .ttdes        ;[182] Form device designator.
  4333.     DVCHR            ;
  4334.      erjmp asser1        ;
  4335.     hlre t1, t3        ; Who has it?
  4336.     movem t1, job        ; Job number of who has it, or -1 (or -2).
  4337.     setzm asgflg        ; Assume I don't have to assign it.
  4338.     skipn local        ; Own controlling TTY?
  4339.      jrst [    skipe tvtflg    ;[130] Yes, but is it an ARPANET TVT?
  4340.          jrst $stln2    ;[130]  If so, still have to OPENF in 8b mode.
  4341.         movei t1, .cttrm ; No, so I don't have to assign it.
  4342.         movem t1, netjfn ; Just use controlling terminal designator.
  4343.         jrst $stln3 ]
  4344.     move t3, myjob        ; My job number.
  4345.     camn t3, job        ; If I had it assigned already,
  4346.      jrst $stln2
  4347.     move t1, ttynum        ; Form device designator again,
  4348.     movei t1, .ttdes(t1)    ;  and...
  4349.     ASND            ;  give it a try.
  4350.      erjmp asser1        ; Uh oh, can't assign it.
  4351.     setom asgflg        ; Assigned it.  Set this flag to remember.
  4352.  
  4353.     ;...
  4354.  
  4355. ; $SETLN (SET LINE), cont'd
  4356.  
  4357. $stln2:    move t1, [170700,,filbuf] ; Pointer to file name buffer.
  4358.     move t2, [ascii/TTY/]    ; Build TTYn: filename.
  4359.     movem t2, filbuf    ; Into filbuf.
  4360.     move t2, ttynum        ; TTY number.
  4361.     movei t3, ^d8        ; Octal.
  4362.     NOUT%
  4363.      %jserr <Can't NOUT TTY number>,asserz
  4364.     movei t2, ":"        ; Add a colon.
  4365.     idpb t2, t1
  4366.     setz t2,
  4367.     idpb t2, t1
  4368.     movx t1, gj%sht!gj%acc    ;[183] Now try to get a JFN on the TTY.
  4369.     hrroi t2, filbuf
  4370.     GTJFN%
  4371.      %jserr <Can't get JFN on TTY>,asserz ; Error, probably no such device.
  4372.     hrrzm t1, netjfn    ; Got JFN OK, save it as the "network" JFN.
  4373.     movx t2, fld(8,of%bsz)!of%wr!of%rd ; 8-bit bytes, read & write access.
  4374.     OPENF%            ; Open the device.
  4375.      erjmp asserr        ;  Can't, print informative error message.
  4376.     setzm setspd        ;[161] Flag that speed has not been SET.
  4377.  
  4378. $stln3:    move t1, oldjfn        ;[127] Get JFN of line previously used.
  4379.     skiple t1        ;[127] No previous one?
  4380.      cain t1, .cttrm    ;[127] Previous one was controlling terminal?
  4381.      jrst $stlnz        ;   One of those, nothing to do.
  4382.     CLOSF%            ; Close it.
  4383.       %jserr (,.+1)        ;
  4384.     setzm oldjfn        ; Remember that we did.
  4385.     skipe oasflg        ; Had I also assigned the old one?
  4386.      jrst [    skipg t1, oldnum ; Yes, did I remember the number?
  4387.          jrst .+1    ; No...    
  4388.         movei t1, .ttdes(t1) ; Yes, then deassign the old one.
  4389.         RELD%
  4390.          %jserr (,.+1)
  4391.         setzm oldnum    ; Set these to zero...
  4392.         setzm oasflg
  4393.         jrst .+1 ]
  4394.     ;...
  4395.  
  4396. ;...SET LINE, cont'd
  4397.  
  4398.  
  4399. ;[182] Move the TVT detection code to earlier so we side-effect the
  4400. ;[182] tvtflg variable before we check to see if we should open in 8
  4401. ;[182] bit mode
  4402.  
  4403. ;[130] See if line is remote, and if so, if carrier is up.
  4404.  
  4405.  
  4406. $stlnz:    move t1, netjfn        ; Get the line's JFN back.
  4407.     call chklin        ;[134] Check on remote & carrier status.
  4408.  
  4409. ;* Note, commented out because it seems to take some time for carrier to come
  4410. ;* up when dialing out.  Better not to scare users.
  4411. ;*
  4412. ;*    hrroi t1, [asciz/
  4413. ;*%Warning - No carrier on remote line/]
  4414. ;*    skipe mdmlin
  4415. ;*     skipe carier        ; Give warning if none.
  4416. ;*     skipa
  4417. ;*     PSOUT
  4418.  
  4419. $stlzz:    movei t2, .chcrt    ; Send a CR down the line to get things going.
  4420.     BOUT
  4421.      erjmp r
  4422.     ret            ; Done.
  4423.  
  4424.     ;...
  4425.  
  4426. ; $SETLN (SET LINE), cont'd
  4427.  
  4428.  
  4429. ;[7] (this whole section...) Get here if error assigning link tty.
  4430.  
  4431. asserr:    movei t1, .fhslf    ; Got error trying to open link tty.
  4432.     GETER%
  4433.     hrrzs t2
  4434.     caie t2, opnx7        ; Somebody else has it?
  4435.      %jserr <Can't assign or open TTY>,asserz ; No, something else.
  4436.  
  4437. ; In use by someone else.  Say who.
  4438.  
  4439. asser1:    tmsg <
  4440. ?Line >
  4441.     numout ttynum, 8    ; Line so-&-so...
  4442.     tmsg < in use by job >    ; ...in use by job
  4443.     numout job        ; ...job number
  4444.     tmsg <, user >        ; Tell who the user is.
  4445.     move t1, job
  4446.     hrroi t2, t3
  4447.     movei t3, .jiuno
  4448.     GETJI
  4449.       erjmp asserx
  4450.     movei t1, .priou
  4451.     move t2, t3        ; User name of who has the line.
  4452.     DIRST
  4453.       erjmp asserx
  4454.     tmsg <
  4455. >
  4456.     jrst asserz
  4457.  
  4458. asserx:    tmsg <???
  4459. >
  4460.  
  4461. asserz:    move t2, oldnum        ; Restore old line.
  4462.     movem t2, ttynum
  4463.     move t2, oldjfn        ; And line JFN.
  4464.     movem t2, netjfn
  4465.     move t2, oasflg        ; And the I-assigned-it flag.
  4466.     movem t2, asgflg
  4467.     ret
  4468.  
  4469. ; Check the line whose JFN is in t1.
  4470. ; Set flags MDMLIN if line is remote, CARIER if line has carrier up.
  4471. ; SPEED is set to a nonnegative number if known, -1 otherwise.
  4472. ;
  4473. ; Returns +1 always, with t1 unchanged, t2-t4 modified.
  4474. ;
  4475. chklin:    saveac<t1>        ; Save the argument
  4476.     movei t2, .morsp    ; "Read Speed"
  4477.     MTOPR            ; Flag bits are returned in LH(T2)
  4478.      %jserr (,.+1)        ;  ...
  4479.     hrres t3        ; No split speed.
  4480.     setzm carier        ; Assume no carrier.
  4481.     setzm mdmlin        ; Assume line not modem-controlled.
  4482.     txnn t2, mo%rmt        ; Is it?
  4483.      jrst [    movem t3, speed    ;  No, it's local, so speed is valid.
  4484.         ret ]        ;  Don't have to worry about carrier.
  4485.     setom mdmlin        ; Yes, flag for SHOW LINE, etc.
  4486.     skipe setspd        ;[161] Was speed explicitly SET for this line?
  4487.      jrst chkli2        ;[161]  Yes, so skip next part.
  4488.     skipe monv        ; TOPS-10 V6 or later?
  4489.      jrst [    movem t3, speed    ;  Yes, so we can believe the speed.
  4490.         jrst chkli2 ]    ;  Go check carrier.
  4491.     came t3, speed        ; Pre-V6.  Does this agree with what was set?
  4492.      seto t3,        ;  No, so we don't really know the speed.
  4493.     movem t3, speed        ; Save the speed or else -1 for don't know.
  4494.  
  4495. ; Entry point just to see if we have carrier (assume MDMLIN already -1).
  4496.  
  4497. chkli2:    setzb t2, carier    ; See if we have carrier.
  4498.     RFMOD            ; Get mode word.
  4499.      erjmp .+1    
  4500.     txne t2, tt%car        ; Carrier?
  4501.      setom carier        ;  Yes.
  4502.     ret
  4503.  
  4504. ;
  4505. hspeed:    asciz |
  4506.  
  4507.  SET SPEED n
  4508.    Set the speed of the currently selected line -- the controlling terminal
  4509.    by default, or else the line specified in the most recent SET LINE
  4510.    command -- to the baud rate indicated by n, for example 1200.  Under
  4511.    releases of TOPS-20 prior to 6.0, you must issue this command before you
  4512.    can send a simulated BREAK signal during CONNECT.
  4513. |
  4514. .setxp:    noise <to>
  4515.     movei t1, [flddb. .cmkey,,baudtb]
  4516.     call rfield
  4517.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  4518.     movem t2, pars3        ; Save into pars3.
  4519.     skipn definf        ;[77] In DEFINE?
  4520.      confrm            ;[77]  No, get confirmation.
  4521.     ret    
  4522.  
  4523. baudtb:    %table
  4524.     %key <110>,^d110
  4525.     %key <1200>,^d1200
  4526.     %key <150>,^d150
  4527.     %key <1800>,^d1800
  4528.     %key <2000>,^d2000
  4529.     %key <2400>,^d2400
  4530.     %key <300>,^d300
  4531.     %key <3600>,^d3600
  4532.     %key <4800>,^d4800
  4533.     %key <600>,^d600
  4534.     %key <7200>,^d7200
  4535.     %key <9600>,^d9600
  4536.     %tbend
  4537.  
  4538. $setsp:    move t3, pars3        ; Get the speed that was parsed.
  4539.     movem t3, speed        ; Record it.
  4540.     move t1, netjfn        ; Get the output terminal JFN.
  4541.     movx t2, .mospd        ; Speed to set.
  4542.     hrl t3, speed        ; Input and output speeds the same.
  4543.     MTOPR            ; Attempt to set it.
  4544.      %jserr (,r)
  4545.     setom setspd        ;[161] Flag that speed was explicitly set.
  4546.     ret
  4547.  
  4548. ; $SETTA (SET TVT-BINARY)
  4549. ;
  4550. ; Request binary-mode negotion with ARPAnet TAC.
  4551. ;
  4552. ;[129] This command added as part of edit 129.
  4553. ;[182] Help message updated for automatic mode
  4554. ;
  4555. hstac:    asciz |
  4556.  SET TVT-BINARY AUTOMATIC, ON or OFF
  4557.  
  4558.    Only for users running KERMIT-20 on an Internet DEC-20, signed on
  4559.    to a DEC-20 TVT (Internet virtual terminal), from either another
  4560.    Internet host or through a TAC.  Without TVT Binary mode, file
  4561.    transfer through a TVT would not work in most cases.
  4562.  
  4563.    SET TVT AUTOMATIC causes Kermit to determine your line type.  If
  4564.    you sign on from a TVT, then TVT-Binary mode will be enabled.  Any
  4565.    other type of line wil cause TVT-Binary mode to be disabled.
  4566.    SET TVT AUTOMATIC is the default.
  4567.  
  4568.    SET TVT ON overrides the automatic setting and forces KERMIT-20 to
  4569.    always negotiate TELNET binary mode during a file transfer.  This
  4570.    should ONLY be done on a line that you are sure is a TVT that
  4571.    KERMIT-20 is not recognizing as such.  This can happen on older
  4572.    pre-Release 7 monitors.
  4573.  
  4574.    If this happens and you normally use KERMIT-20 through a TVT, you
  4575.    can put the command SET TVT-BINARY ON into your KERMIT.INI file.
  4576.  
  4577.    SET TVT OFF overrides the automatic setting and forces KERMIT-20 to
  4578.    NEVER negotiate TELNET binary mode during a file transfer.  This
  4579.    should ONLY be done on a line that you are sure is NOT a TVT that
  4580.    KERMIT-20 is mistakenly identifying as a TVT.  While such a problem
  4581.    is indicative of a monitor problem, this will allow you to get
  4582.    around it until such time as the monitor is fixed.
  4583.  
  4584.    CAUTION: This facility requires certain facilities in the Release 5
  4585.    TOPS-20 Internet monitor: TELNET binary negotiations are accepted
  4586.    (bug fix), and the monitor does NOT double the TELNET attention
  4587.    character (IAC, octal 377).  This program will attempt to use
  4588.    monitor calls to enable TELNET binary mode.  If the calls fail, it
  4589.    will then send IAC escape sequences to negotiate TELNET binary
  4590.    mode, and doubles any IACs that appear in data during file
  4591.    transfer.
  4592.  
  4593.    Further caution: setting or unsetting binary mode may take up to 8
  4594.    seconds.
  4595. |
  4596.  
  4597. .setta:    noise <negotiation>     ; SET TVT-BINARY
  4598.     movei t1, [flddb. .cmkey,,tvtkey,,automatic] ;[182] 
  4599.     call rfield        ; Parse a keyword.
  4600.     hrrz t2, (t2)        ; Get the value for the keyword (0 or 1).
  4601.     movem t2, pars3        ; Save into pars3.
  4602.     skipn definf        ;[77] In DEFINE?
  4603.      confrm            ;[77]  No, get confirmation.
  4604.     ret    
  4605.  
  4606. tvtkey:    %table            ;[182] Table for parsing TVT keywords
  4607.     %key <automatic>,[0,,1]    ;[182] Figure it out for me
  4608.     %key <off>, [0,,0]    ;[182] Override to never negotiate
  4609.     %key <on>, [1,,0]    ;[182] Override to ALWAYS negotiate
  4610.     %tbend            ;[182] Which will break on LAT, CTERM, etc..
  4611.  
  4612.  
  4613. $setta:    move t1, pars3        ; Get the value that was parsed.
  4614.     move t2,(t1)        ;[182] De-reference to get values
  4615.     hrrz t3,t2        ;[182] Right halfword is automatic mode
  4616.     hlrz t2,t2        ;[182] Left halfword is the TVT-Binary mode
  4617.      jumpn t3,$sett1    ;[182]  Setting automatic mode?
  4618.     dmovem t2,tvtflg    ;[182] No, override both TVT line
  4619.     ret            ;[182] and turn off line discovery
  4620.  
  4621. $sett1:    exch t3, tvtchk        ;[182] Update TVT checking mode, get old mode
  4622.      jumpn t3,R        ;[182]  Wants automatic and it was already set?
  4623.     call chktvt        ;[182] Went from override to automatic, check
  4624.     ret            ; Done.
  4625.  
  4626.     subttl chktvt - check to see if we are using a TVT line
  4627.  
  4628. ;[182] Begin code addition
  4629. ;
  4630. ; NTINF%, which was introduced in 6.0 series Tops-20 and is now known
  4631. ; to work in 7.0 series PANDA monitor and XKL.  I believe there are
  4632. ; also standard patches to the DEC monitor to make it work.
  4633. ;
  4634. ; We use NTINF% when the user sets TVT-Binary mode to automatic which
  4635. ; is an additional keyword (used to be just on or off).  Automatic is
  4636. ; the default, but we still allow overide.
  4637. ;
  4638. ; If the NTINF% failes, then we recover by using STAT% to try to
  4639. ; indentify whether the line is in the range of TVT's. 
  4640. ;
  4641. ; PANDA monitor verified to have 400000,,RSKP in NVTDOD (see [129])
  4642. ;
  4643. ;passed:  nothing, but check to see whether we are in automatic
  4644. ;      mode and if so, we execute our code, otherwise we are
  4645. ;      in override mode and we skip any checks
  4646. ;
  4647. ;returns: +1, always, although may complain about Jsyi errors
  4648. ;
  4649. ;      Expects to be ablt to trash t1,t2 and t3
  4650. ;      tvtflg will be side-effect by our (possible lack of) discovery
  4651.  
  4652. chktvt:    skipn tvtchk        ;[182] Are we supposed to figure out if TVT?
  4653.      ret            ;[182]  No, so skip all this cruft
  4654.  
  4655.     hrrz t1,ttynum        ;[182] Load the current line
  4656.     txo t1,.ttdes        ;[182] Convert line to a device designator
  4657.     movem t1,ntiblk+.NWLIN    ;[182] Store requested terminal
  4658.     dmove t1,[exp ntblen,.NWRRH] ;[182] Requesting remote host information
  4659.     dmovem t1,ntiblk+.NWABC    ;[182] Store length and request type
  4660.     dmove t1,[exp .NULIO,.NWRRH] ;[182] Output the node name to NUL:
  4661.     dmovem t1,ntiblk+.NWNNP    ;[182] return remote host information
  4662.     setz t1,        ;[182] Everything else is zero
  4663.     movem t1,tvtflg        ;[182] Assume not on a TVT
  4664.     movem t1,ntiblk+.NWNNU    ;[182] Initialize returned node numbers and
  4665.     move t1,[ntiblk+.NWNNU,,ntiblk+.NWNU1] ;[182] clobber everything else
  4666.     blt t1,ntiblk+ntblen-1    ;[182] Clear whatever is left in the block
  4667.  
  4668.     movei t1,ntiblk        ;[182] Load the address of the argument block
  4669.     NTINF%            ;[182] finally try to see out what's going on
  4670.      %jserr <NTINF failed>,chktv0 ;[182] Phooey, try the olde fashioned way
  4671.                 ;[182] Load network type and line type
  4672.     ldb t1,[POINTR(<ntiblk+.NWTTF>,nttype)]
  4673.     ldb t2,[POINTR(<ntiblk+.NWTTF>,ntline)]
  4674.     cain t1,NW%TCP        ;[182] Is the network type NOT TCP?
  4675.      caie t2,NW%TV        ;[182]  or is this NOT a TVT?
  4676.       ret            ;[182]   Leave line set as not a TVT
  4677.     aos tvtflg        ;[182] Okay, set TVT-BInary to ON
  4678.     ret            ;[182] 
  4679.  
  4680. ;[182] Begin moved code from before $stlnz:, above
  4681.  
  4682. ;The following code is not used because a BBN TCP jsys is called.
  4683. ;Some ARPA sites don't have the BBN jsys's any more.  Those that have them
  4684. ;keep them in different places (MONSYM, TCPSYM, etc).  Rather than make the
  4685. ;program site-dependent, this has been replaced with a SET TVT command until
  4686. ;the DEC TCP jsys's become standard and widespread, assuming there will be a
  4687. ;GETAB or other jsys to tell whether a given TTY is a TVT.
  4688.  
  4689.  
  4690. chktv0:                ;[182] Here to try to grovel over STAT
  4691.  
  4692. ;[129] The next 10 or so lines of code adapted from MODEM.MAC
  4693.  
  4694.     movx t1,tcp%nt        ;[129] Want aobjn ptr for tvts
  4695.     STAT%            ;[129] Get it
  4696.      %jserr <STAT failed>,r ;[182]  Just give up
  4697.     hrrz t3,ttynum        ;[129] Tty line we're useing
  4698.     hrrz t1,t2        ;[129] Get first tvt
  4699.     camge t3,t1        ;[129] Are we less than the first?
  4700.      ret            ;[182] Yes
  4701.     hlres t2        ;[129] Calculate last tvt
  4702.     sub t1,t2        ;[129] ...
  4703.     subi t1,1        ;[129] ...
  4704.     camg t3,t1        ;[129] Are we .le. last tvt?
  4705.      aos tvtflg        ;[182] Yes, flag for later
  4706.     ret            ;[182]
  4707.  
  4708. ;[182] End moved code from before $stlnz:, above
  4709.  
  4710.  
  4711.  
  4712.     subttl    STATISTICS command
  4713.  
  4714. ; Help text for STATISTICS
  4715.  
  4716. hstatu:    asciz |
  4717. STATISTICS
  4718.  
  4719. Give statistics about the most recent file transfer.
  4720. |
  4721.  
  4722. ; Parse rest of STATISTICS command.
  4723.  
  4724. .stat:    noise <about last file transfer> ; STATISTICS
  4725.     confrm
  4726.     ret
  4727.  
  4728. ; Execute STATISTICS command.
  4729.  
  4730. $stat:    setzm otot        ;[180]
  4731.     tmsg <
  4732.  Maximum number of characters in packet:  >
  4733.     numout rpsiz
  4734.     tmsg < received; >
  4735.     numout  spsiz
  4736.     tmsg < sent
  4737. >
  4738.     skipn t2, stdat        ;[36] If no time was spent transferring,
  4739.      jrst $statx        ;[36]  skip the rest.
  4740.     tmsg < Number of characters transmitted in >
  4741.     idivi t2, ^d3        ; Convert thirds of seconds to seconds.
  4742.     movem t2, sec        ; Save the number of seconds.
  4743.     idivi t2, ^d60        ; Divide to get minutes.
  4744.     move t4, t3        ; Save the remainder.
  4745.     jumpe t2, $stat2    ; If no minutes then don't print them.
  4746.     numout t2
  4747.     tmsg < minutes and >
  4748. $stat2:    move t2, t4        ; Get the remainder.
  4749.     jumpe t2, $stat3    ; If no seconds then don't print them.
  4750.     numout t2
  4751.     tmsg < seconds>
  4752. $stat3:    tmsg <
  4753.     Sent:      >
  4754.     numout stot
  4755.     tmsg <        Overhead:    >
  4756.     movei t1, .priou    ; Output the number of chars in decimal.
  4757.     move t2, stot
  4758.     sub t2, stchr
  4759.     addm t2, otot        ;[180]
  4760.     numout t2
  4761.     tmsg <
  4762.     Received:  >
  4763.     numout rtot
  4764.     tmsg <        Overhead:    >
  4765.     movei t1, .priou    ; Output the number of chars in decimal.
  4766.     move t2, rtot
  4767.     sub t2, rtchr
  4768.     addm t2, otot        ;[180]
  4769.     numout t2
  4770.     ;...
  4771.  
  4772. ; STATISTICS command, cont'd
  4773.  
  4774.  
  4775.     tmsg <
  4776.     Total:     >
  4777.     movei t1, .priou    ; Output the number of chars in decimal.
  4778.     move t2, rtot
  4779.     add t2, stot
  4780.     move t4, t2        ; Save the total number of chars.
  4781.     numout t2
  4782.     tmsg <        Overhead:    >
  4783.     movei t1, .priou    ; Output the number of chars in decimal.
  4784.     move t2, otot        ;[180] Get total chars.
  4785.     numout t2
  4786.     tmsg <
  4787.  Total characters transmitted per second:    >
  4788.     move t2, t4        ; Total chars transmitted.
  4789.     idiv t2, sec        ; Divided by the number of seconds.
  4790.     numout t2
  4791.     tmsg <
  4792.  Effective data rate:    >
  4793.     skipn t2, stchr        ; Is the number of chars sent zero?
  4794.      move t2, rtchr        ;  If so we were receiving.
  4795.     idiv t2, sec        ; Divided by the number of seconds.
  4796.     imuli t2, ^d10        ; Multiply chars/sec by 10 to get bits/sec.
  4797.     numout t2
  4798.     tmsg < bps>
  4799.  
  4800. ;[180]...
  4801.     tmsg <
  4802.  ILDB: >
  4803.     numout ttildb
  4804.     tmsg <  SIN:  >
  4805.     numout ttisin
  4806.     tmsg <  SIN Max:  >
  4807.     numout ttimax
  4808.     tmsg <  BIN:  >
  4809.     numout ttibin    
  4810. ;...[180]
  4811.  
  4812.     skipge speed        ;[146] Do we know the speed?
  4813.      jrst $stat4        ; No.
  4814.     fltr t2, t2        ; Yes, float the effective data rate.
  4815.     fltr t4, speed        ; And the line speed.
  4816.     fmp t2, [100.0]
  4817.     fdv t2, t4
  4818.     tmsg <
  4819.  Efficiency:            >
  4820.     movei t1, .priou    
  4821.     setz t3,
  4822.     FLOUT
  4823.      erjmp .+1    
  4824.     tmsg < per cent>
  4825. $stat4:    skipn errptr        ; Was there an error?
  4826.      jrst $statx        ;  If not, done.
  4827.     tmsg <
  4828.  Canceled by error:  >
  4829.     move t1, errptr
  4830.     PSOUT%            ; If so output it.
  4831.     hrroi t1, crlf        ;[50]
  4832.     PSOUT%
  4833.     ;...
  4834.  
  4835. ; STATISTICS command, cont'd
  4836.  
  4837.  
  4838. ;[36] Interpacket pause.
  4839.  
  4840. $statx:    tmsg <
  4841.  Interpacket pause in effect: >
  4842.     movei t1, .priou
  4843.     move t2, pause
  4844.     setz t3,
  4845.     FLOUT
  4846.      nop
  4847.     tmsg < sec
  4848.  
  4849.  Timeouts: >            ;[54] How many timeouts and NAKs.
  4850.     numout ntimou
  4851.     tmsg <
  4852.  NAKs:       >
  4853.     numout nnak
  4854.  
  4855. ;[47][132] If debugging, tell most recent JSYS error.
  4856.  
  4857.     jumpe debug, $statz    ;[132] Debugging?
  4858. $statj:    tmsg <
  4859.  Last JSYS error: >        ; Yes, tell about last error.
  4860.     movei t1, .priou
  4861.     hrloi t2, .fhslf
  4862.     setz t3,
  4863.     ERSTR
  4864.      nop
  4865.      nop
  4866.     tmsg <
  4867.  Timer errors:    >        ;[132] Also, give hints if anything is
  4868.     numout timerx        ;  going wrong with timers.
  4869.  
  4870. $statz:    tmsg <
  4871.  
  4872. >
  4873.     ret
  4874.  
  4875. ; SHOW command.
  4876.  
  4877. ; Help text...
  4878.  
  4879. hshow:    asciz |
  4880. SHOW
  4881.  
  4882. Display current SET parameters, version of KERMIT-20, or other info:
  4883.  
  4884.   DAYTIME           Current date, time, phase of moon.
  4885.   DEBUGGING         Debugging mode and log file in effect, if any.
  4886.   FILE-INFO         Byte size for DEC-20 file i/o, incomplete file disposition.
  4887.   INPUT             Parameters for INPUT command.
  4888.   LINE              TTY line, parity, duplex, handshake, escape character.
  4889.   MACROS            Definitions for SET macros.
  4890.   PACKET-INFO       For incoming and outbound packets.  Items under RECEIVE
  4891.                     column show parameters for packets KERMIT-20 expects
  4892.                     to receive, under SEND shows parameters for outgoing
  4893.                     packets.
  4894.   TIMING-INFO       Delays, retries, server NAK intervals.
  4895.   VERSION           Program version of KERMIT-20.
  4896.   ALL               (default) All of the above.
  4897. |
  4898.  
  4899. ; Parse rest of SHOW command...
  4900.  
  4901. .show:    noise <parameters>    ; SHOW command
  4902.     movei t1, [flddb. .cmkey,,shotab,,<all>] ;[39]
  4903.     call cfield        ;[39]
  4904.     hrrz t2, (t2)        ;[39]
  4905.     movem t2, pars2        ;[39]
  4906.     ret
  4907.  
  4908. shotab:    %table            ;[39] (this whole keyword table)
  4909.     %key <all>,0
  4910.     %key <daytime>,$shday
  4911.     %key <debugging>,$shdeb
  4912.     %key <file-info>,$shfil
  4913.     %key <input-info>,$shinp ;[160]
  4914.     %key <line>,$shlin
  4915.     %key <macros>,$shmac    ;[77]
  4916.     %key <packet-info>,$shpkt
  4917.     %key <timing-info>,$shtim
  4918.     %key <version>,$shver
  4919.     %tbend
  4920.     
  4921. $show:    move q1, [ret]        ;[39] Return after each piece
  4922.     skipn t2, pars2        ;[39] unless ALL was selected, in which case
  4923.      jrst [    move q1, [nop]    ;[39] fall thru from piece to piece,
  4924.         jrst $shtop ]    ;[39] starting from top.
  4925.     tmsg <
  4926. >                ;[39] Single SHOW item.  Emit blank line,
  4927.     jrst (t2)        ;[39] then go show the requested stuff.
  4928.  
  4929. $shtop: ;[39] Top of SHOW command.
  4930.  
  4931. ; SHOW VERSION
  4932.  
  4933. $shver:    tmsg <TOPS-20 Kermit version >
  4934. $shv2:    ldb t2, [pointr versio,VI%MAJ] ;[184] major version
  4935.     numout t2, ^d10        ;[184] 
  4936.     ldb t2, [pointr versio,VI%MIN] ;[184] 
  4937.     skipe t2        ;[95] minor version
  4938.      call [    movei t1, "."    ;[95] Use new decimal notation
  4939.         PBOUT        ;[95]
  4940.         numout t2, ^d10    ;[184] 
  4941.         ret ]
  4942.     ldb t3, [pointr versio,VI%EDN] ;[184] edit
  4943.     skipe t3
  4944.      call [    movei t1, "("
  4945.         PBOUT
  4946.         numout t3, ^d10    ;[184] 
  4947.         movei t1, ")"
  4948.         PBOUT
  4949.         ret ]
  4950.     ldb t4, [pointr versio,VI%WHO] ;[184] who
  4951.     skipe t4
  4952.      call [    movei t1, "-"
  4953.         PBOUT
  4954.         numout t4, ^d10    ;[184] 
  4955.         ret ]
  4956.      tmsg < >                ;[186] Show version date
  4957.     hrroi t1, verdate       ;[186] (defined at top)
  4958.     PSOUT                   ;[186]
  4959.         tmsg <
  4960. >
  4961.     xct q1            ;[39] return or proceed...
  4962.  
  4963. ; SHOW DAYTIME
  4964.  
  4965. $shday:    movx t1, .priou        ; Current date and time.
  4966.     seto t2,        ;
  4967.     movx t3, ot%day!ot%fdy!ot%fmn!ot%4yr!ot%dam!ot%spa!ot%scl
  4968.     ODTIM%
  4969.      erjmp .+1
  4970.     call moon        ; Phase of the moon.
  4971.  
  4972.     tmsg <
  4973. >
  4974.     xct q1            ;[39] return or proceed...
  4975.  
  4976. ; SHOW LINE
  4977.  
  4978. $shlin:    tmsg <TTY for file transfer:  >
  4979.     numout ttynum, 8
  4980.     move t4, mytty        ; See whether we're local or remote...
  4981.     hrroi t1, [asciz/
  4982.  (job's controlling terminal, KERMIT-20 is REMOTE)/]
  4983.     came t4, ttynum
  4984.      hrroi t1, [asciz/
  4985.  (assigned TTY line, KERMIT-20 is LOCAL)/]
  4986.     PSOUT%
  4987.  
  4988.     move t1, netjfn        ;[130] Tell about modem control & carrier.
  4989.     call chklin
  4990.     skipn mdmlin
  4991.      jrst $show3
  4992.     tmsg <
  4993.   Line has modem control
  4994.   Carrier:          >
  4995.     hrroi t1, [asciz/On/]    ; Say it's on.
  4996.     skipn carier        ; Is it?
  4997.      hrroi t1, [asciz/Off/]    ; No.
  4998.     PSOUT            ; Tell
  4999.  
  5000. $show3:    tmsg <
  5001.   Handshake:        >        ;[76] Handshake
  5002.     skipn t1, handsh    ; Any?
  5003.      jrst [    tmsg <None>
  5004.         jrst $shw3a ]
  5005.     call putc
  5006. $shw3a:    tmsg <
  5007.   Flow-Control:     >        ;[143]
  5008.     hrroi t1, [asciz/XON-XOFF/]
  5009.     skipn flow
  5010.      hrroi t1, [asciz/None/]
  5011.     PSOUT
  5012.  
  5013. $show4:    tmsg <
  5014.   Parity:           >
  5015.     move t2, parity
  5016.     hrroi t1, [asciz/None/]
  5017.     cain t2, space
  5018.      hrroi t1, [asciz/Space/]
  5019.     cain t2, mark
  5020.      hrroi t1, [asciz/Mark/]
  5021.     cain t2, odd
  5022.      hrroi t1, [asciz/Odd/]
  5023.     cain t2, even
  5024.      hrroi t1, [asciz/Even/]
  5025.     PSOUT%
  5026.  
  5027. $sho4a:    tmsg <
  5028.   Duplex:           >        ;[18]
  5029.     move t2, duplex
  5030.     hrroi t1, [asciz/Full/]
  5031.     caie t2, dxfull
  5032.      hrroi t1, [asciz/Half/]
  5033.     PSOUT
  5034.     ;...
  5035.  
  5036. ;...SHOW LINE, cont'd
  5037.  
  5038.     tmsg <
  5039.   Speed:            >            ; Line speed.
  5040.     skipl speed        ; If negative, we don't really know it.
  5041.      numout speed
  5042.     hrroi t1, [asciz/(Unknown)/]
  5043.     skipge speed        ; If not negative, we know it.
  5044.      PSOUT
  5045.  
  5046. $sho4b:    skipn local        ;[96] Don't confuse them with this
  5047.      jrst $sho4c        ;[96]  unless they're local.
  5048.     tmsg <
  5049.   Escape:           >
  5050.     move t1, escape
  5051.     call putc
  5052.  
  5053. $sho4c:    tmsg <
  5054.   Break Simulation: >
  5055.     hrroi t1, [asciz/Enabled/]
  5056.     skipg speed
  5057.      hrroi t1, [asciz/Disabled/]
  5058.     PSOUT
  5059.     skipg speed
  5060.      jrst $sho4d
  5061.     tmsg <, >
  5062.     numout brk
  5063.     tmsg < NULs at 50 baud>
  5064.  
  5065. $sho4d: tmsg <
  5066.   TVT Binary:       >         ;[129] ARPAnet TVT binary mode.
  5067.     hrroi t1, [asciz/Off/]
  5068.     skipe tvtflg
  5069.      hrroi t1, [asciz/On/]
  5070.     PSOUT
  5071.     tmsg <
  5072.   TVT Negotiate:    >         ;[182] ARPAnet TVT discovery
  5073.     hrroi t1, [asciz/Override/]
  5074.     skipe tvtchk
  5075.      hrroi t1, [asciz/Automatic/]
  5076.     PSOUT
  5077.  
  5078. $sho4e:    tmsg <
  5079.   Log:              >
  5080.     skipg t2, sesjfn    ; are we logging?
  5081.      skipl t2, savjfn    ; or toggled off?
  5082.      skipa
  5083.      jrst [    tmsg <(none)>
  5084.         jrst $sho4f ]
  5085.     movei t1, .priou    ; so print the Log file
  5086.     setzb t3, t4        ; default format, no prefix
  5087.     JFNS            ; output it
  5088.      erjmp [tmsg <(none)>
  5089.         jrst $sho4f ]
  5090.     hrroi t1, [asciz/ (on)/] ; assume toggled on
  5091.     skipg sesjfn        ; is that correct?
  5092.      hrroi t1, [asciz/ (off)/] ; no, use other message
  5093.     PSOUT            ; output it
  5094.  
  5095. $sho4f:    ;put next one here...
  5096.  
  5097. $sho4x:    tmsg <
  5098.  
  5099. >
  5100.     xct q1            ;[39] return or proceed...
  5101.  
  5102. ; SHOW FILE-INFO
  5103.  
  5104. $shfil:    tmsg <Byte size for file I/O:  >
  5105.     hrroi t1, [ASCIZ/"Auto"/]
  5106.     skipn autbyt
  5107.      jrst [    hrroi t1, [asciz/Seven-Bit/]
  5108.         skipe ebtflg
  5109.          hrroi t1, [asciz/Eight-Bit/]
  5110.         jrst .+1 ]
  5111.     PSOUT%
  5112.     tmsg <
  5113.   File name conversion: >    ;[84]
  5114.     hrroi t1, [asciz/Off/]    ;[84]
  5115.     skipe xfnflg        ;[84]
  5116.      hrroi t1, [asciz/On/]    ;[84]
  5117.     PSOUT            ;[84]
  5118.     tmsg <
  5119.   ITS-binary-format file recognition >    ;[75]
  5120.     hrroi t1, [asciz/enabled/]    ;[75]
  5121.     skipn itsflg            ;[75]
  5122.      hrroi t1, [asciz/disabled/]    ;[75]
  5123.     PSOUT                ;[75]
  5124.     tmsg <
  5125.   Disposition for incomplete incoming files: > ;[42]
  5126.     hrroi t1, [asciz/Discard/]
  5127.     skipe abtfil        ;[42]
  5128.      hrroi t1, [asciz/Keep (whatever was received)/]
  5129.     PSOUT%            ;[42]
  5130.     tmsg <
  5131.   Deleted files are >        ;[143]
  5132.     hrroi t1, [asciz/NOT /]
  5133.     skipn expung
  5134.      PSOUT
  5135.     tmsg <expunged automatically
  5136.   Transaction log file: >    ;[126]
  5137.     skipn t2, tlgjfn    ; Any?
  5138.      jrst [    hrroi t1, [asciz/ (none)/] ; No.
  5139.         PSOUT
  5140.         jrst $shflx ]
  5141.     movei t1, .priou    ; Yes, a real file,
  5142.     setz t3,        ; Say what it is.
  5143.     JFNS
  5144.      %jserr (,.+1)
  5145. $shflx:    tmsg <
  5146.  
  5147. >
  5148.     xct q1            ;[39] return or proceed...
  5149.  
  5150. ; SHOW DEBUG
  5151.  
  5152. $shdeb:    tmsg <Debugging: >
  5153.     hrro t1, [
  5154.         [asciz/Off/]
  5155.         [asciz/States/]
  5156.         [asciz/Packets/]
  5157.         ](debug)
  5158.     PSOUT%
  5159.     jumpe debug, $shdbx    ;[38]
  5160.     tmsg <
  5161.   Debugging log file: >        ;[38]
  5162.     move t2, logjfn        ;[38] Any log file?
  5163.     cail t2, 1        ;[71] 0 or -1 means none.
  5164.      caile t2, 100        ;[71] 100 or above is .priou or whatever...
  5165.      jrst [    hrroi t1, [asciz/ (none)/] ;[38] None.
  5166.         PSOUT        ;[38]
  5167.         jrst $shdbx ]    ;[38]
  5168.     movei t1, .priou    ;[38] Yes, a real file,
  5169.     setz t3,        ;[38] Say what it is.
  5170.     JFNS            ;[38]
  5171.      %jserr (,.+1)        ;[38]
  5172.     tmsg <, bytesize >    ;[41]
  5173.     numout logbsz        ;[41]
  5174. $shdbx:    tmsg <
  5175.  
  5176. >                ;[39]
  5177.     xct q1            ;[39] return or proceed...
  5178.  
  5179. ; SHOW PACKET-INFO
  5180.  
  5181. ;[100] New headings, less confusing.
  5182. ;
  5183. $shpkt:    tmsg <Packet parameters:
  5184.  
  5185.               Inbound         Outbound
  5186.   Size:            >
  5187.     numout rpsiz,^d10
  5188.     tmsg <        >
  5189.     numout spsiz,^d10
  5190.     tmsg < characters
  5191.   Padding:         >
  5192.     numout rpadn
  5193.     tmsg <        >
  5194.     numout spadn
  5195.     tmsg <
  5196.   Pad Character:   >
  5197.     move t1, rpadch
  5198.     call putc
  5199.     tmsg <        >
  5200.     move t1, spadch
  5201.     call putc
  5202. $show8:    tmsg <
  5203.   End-Of-Line:     >
  5204.     move t1, reolch
  5205.     call putc
  5206.     tmsg <        >
  5207.     move t1, seolch
  5208.     call putc
  5209.     tmsg <
  5210.   Control Prefix:  >
  5211.     move t1, rquote
  5212.     call putc
  5213.     tmsg <        >
  5214.     move t1, squote
  5215.     call putc
  5216.     ;...
  5217.  
  5218. $showa: tmsg <
  5219.   Start-Of-Packet: >
  5220.     move t1, ssthdr        ;[18]
  5221.     call putc
  5222.     tmsg <        >
  5223.     move t1, rsthdr        ;[18]
  5224.     call putc
  5225.  
  5226. ;[100] New headings for this stuff.
  5227. $shpk2:    tmsg <
  5228.  
  5229.               Requested       Used
  5230.   8th-bit Prefix:  >        ;[88] Begin addition
  5231.     skipe ebqr        ; Did our user request 8th bit prefix?
  5232.      jrst [    move t1, ebq    ; Yes.
  5233.         call putc    ; Say what it is.
  5234.         tmsg <            >
  5235.         jrst .+1 ]
  5236.     skipn ebqr
  5237.      jrst [    tmsg <(none)       > ; No, just say we'll do it if asked.
  5238.         jrst .+1 ]
  5239.     skipe ebqflg        ; Was it used during last transfer?
  5240.      jrst [    move t1, ebq    ; Looks like it, say what prefix.
  5241.         call putc
  5242.         jrst .+1 ]    ;[88] End addition
  5243.     skipn ebqflg
  5244.      jrst [    tmsg <(none)>    ; No, just say we'll do it if asked.
  5245.         jrst .+1 ]
  5246.     tmsg <
  5247.   Repeat Prefix:   >        ;[92] Begin addition
  5248.     move t1, rptq        ; What we use to flag repeat counts.
  5249.     call putc
  5250.     tmsg <        >
  5251.     skipe rptflg        ; Was it actually used?
  5252.      jrst [    move t1, rptq
  5253.         call putc
  5254.         jrst .+1 ]    ;[92] End addition
  5255.     skipn rptflg
  5256.      jrst [    tmsg <(none)    > ; No, just say we'll do it if asked.
  5257.         jrst .+1 ]
  5258.     tmsg <
  5259.   Block Check:     >        ;[98] Block check type.
  5260.     move t1, bctr
  5261.     call putc
  5262.     tmsg <        >
  5263.     numout bctu        ;[98]
  5264.  
  5265.     tmsg <
  5266.  
  5267. >
  5268.     xct q1            ;[39] return or proceed...
  5269.  
  5270. ; SHOW TIME-INFO
  5271.  
  5272. $shtim:    tmsg <Timing parameters:
  5273.  
  5274.               Receive         Send
  5275.   Timeout:         >        ;[45]
  5276.     numout rrtimo        ;[128]
  5277.     tmsg <        >
  5278.     skipg stimou        ;[45]
  5279.      jrst [    tmsg <(none)>    ;[45]
  5280.         jrst $shpau ]    ;[45]
  5281.     numout stimou
  5282.     movei t1, "-"        ;[6]
  5283.     PBOUT%            ;[6]
  5284.     numout [maxtim]        ;[6]
  5285.     tmsg < sec>
  5286. $shpau:    tmsg <
  5287.   Pause:           >        ;[36]
  5288.     movei t1, .priou    ;[36]
  5289.     move t2, rpause        ;[36]
  5290.     setz t3,        ;[36]
  5291.     FLOUT            ;[36]
  5292.      nop            ;[36]
  5293.     tmsg <        >    ;[36]
  5294.     movei t1, .priou    ;[36]
  5295.     move t2, spause        ;[36]
  5296.     FLOUT            ;[36]
  5297.      nop            ;[36]
  5298.     tmsg < sec
  5299.  
  5300. Delay before sending first packet:  >
  5301.     move t1, delay        ;[100]
  5302.     skipe local        ;[100]
  5303.      setz t1,        ;[100]
  5304.     numout t1        ;[100]
  5305.     tmsg < sec
  5306. Packet retries before timeout:      >
  5307.     numout maxtry
  5308. $showc:    tmsg <
  5309. Number of retries for init packet:  >
  5310.     numout imxtry
  5311.     skipn srvtim
  5312.      jrst $shwc2
  5313.     tmsg <
  5314. Server sends NAKs every >
  5315.     numout srvtim
  5316.     tmsg < sec while waiting for command.>
  5317. $shwc2:    skipn debug        ; No blips if debugging.
  5318.      skipn local        ; Or if not local.
  5319.      jrst $showx        ;  ...
  5320. $showd:    tmsg <
  5321.  
  5322. "." for every >            ;[4]
  5323.     numout [blip]        ;[9]
  5324.     tmsg < packets, "%" for each NAK.>
  5325. $showx:    tmsg <
  5326.  
  5327. >                ;[4]
  5328.     xct q1
  5329.  
  5330. ;[160] Show INPUT parameters
  5331. ;
  5332. $shinp:    tmsg <Parameters for INPUT commands:>
  5333.     tmsg <
  5334.   Alphabetic Case: >
  5335.     hrroi t1, [asciz/Ignored in matching/]
  5336.     skipe incase
  5337.      hrroi t1, [asciz/Observed in matching/]
  5338.     PSOUT
  5339.     tmsg <
  5340.   Default Timeout: >
  5341.     skiple indeft
  5342.      numout indeft
  5343.     hrroi t1, [asciz/ sec/]
  5344.     skiple indeft
  5345.      PSOUT    
  5346.     hrroi t1, [asciz/Infinite/]
  5347.     skipg indeft
  5348.      PSOUT
  5349.     tmsg <
  5350.   Timeout Action:  >
  5351.     hrroi t1, [asciz/Proceed with command file
  5352.  
  5353. /]
  5354.     skipe intima
  5355.      hrroi t1, [asciz/Quit from command file
  5356.  
  5357. /]
  5358.     PSOUT    
  5359.     xct q1        
  5360.  
  5361.  
  5362. ;[77] SHOW MACRO DEFINITIONS
  5363. ;
  5364. $shmac:    tmsg <Macro definitions:>
  5365.     hlrz t4, mactab        ; Anything in macro table?
  5366.     skipg t4        ; Yes, tell what.
  5367.      jrst [    tmsg < (none)
  5368. >
  5369.         jrst $shmax ]    ; No, say so.
  5370.     tmsg <
  5371. >                ; Yes, list it/them.
  5372.     movei t3, 1
  5373.  
  5374. $shma2:    movei t1, 40        ; Space
  5375.     PBOUT
  5376.     hlro t1, mactab(t3)    ; Point to macro name.
  5377.     PSOUT            ; Print it.
  5378.     tmsg < = >
  5379.     hrro t1, mactab(t3)    ; Same deal for macro body.
  5380.     PSOUT
  5381.     aos t3            ; Bump index.
  5382.     sojg t4, $shma2        ; Do for all macros in table.
  5383.     tmsg <
  5384. >
  5385. $shmax:    ret            ;[83] Last one, always want to return.
  5386.  
  5387. ; PUTC - Routine to print a single character, using ^X notation, DEL, etc.
  5388. ;
  5389. ; Call with t1/ character to print.
  5390. ;
  5391. putc:    caile t1, "~"        ; Rubout?
  5392.      jrst [ tmsg <DEL>    ;  Yes, type this?
  5393.         ret ]
  5394.     caige t1, " "        ; Is it a control char?
  5395.      jrst [ push p, t1    ;  Save the char.
  5396.         movei t1, "^"    ;  Get the control quote.
  5397.         PBOUT%
  5398.         pop p, t1
  5399.         ori t1, ^o100    ;  Turn on the non-control bit.
  5400.         jrst .+1 ]
  5401.     PBOUT%
  5402.     ret
  5403.  
  5404.     subttl    BYE command
  5405.  
  5406. hbye:    asciz |
  5407. BYE    
  5408.  
  5409. When running as a local Kermit, talking to a KERMIT server over a TTY line
  5410. specified in a SET LINE command, use the BYE command to shut down and log out
  5411. the server.  This will also close any local debugging log file and exit from
  5412. the local KERMIT.
  5413. |
  5414.  
  5415. ; Parse rest of BYE command.
  5416.  
  5417. .bye:    noise (to remote server) ; Parse rest of BYE command.
  5418.     confrm
  5419.     ret
  5420.  
  5421. ; Execute the BYE command.
  5422.  
  5423. $bye:    move t1, [point 7, [asciz/L/]]    ; An "L" for the data field.
  5424.     movei t2, "G"        ; Packet type is G.
  5425.     call srvcmd        ;[121] Send the command.
  5426.      jrst $byez        ;  Some error, don't exit.
  5427.  
  5428. ;[16] From here to end is part of edit 16.
  5429.  
  5430. $byex:    movei q1, 5        ; Try this 5 times
  5431.     movei t1, ^d750        ; Sleep a second.
  5432.     DISMS%
  5433. $byex2:    movei t1, ^d250        ; Sleep a little bit
  5434.     DISMS%
  5435.     move t1, netjfn        ; Any messages?
  5436.     SIBE%
  5437.      skipa t3, t2        ; Yes, this many characters.
  5438.      jrst $byexx        ;  No, try again.
  5439.     hrroi t2, buffer    ; Get whatever is there.
  5440.     movei t4, .chlfd
  5441.     SIN%
  5442.     setz t3,
  5443.     idpb t3, t2
  5444.     hrroi t1, buffer    ; And print it.
  5445.     PSOUT%
  5446. $byexx: sojg q1, $byex2        ; See if we want to type some more.
  5447.  
  5448.     setzm buffer        ; Zero this out, just in case.
  5449.     tmsg <...>        ; Maybe there's more, but...
  5450.     move t1, netjfn        ;  can't wait forever for it,
  5451.     CFIBF%            ;  throw the rest away.
  5452.      erjmp .+1
  5453.     setom f$exit        ;[38] Set exit flag.
  5454.  
  5455. ; Error exit
  5456.  
  5457. $byez:    setzm f$exit        ;[70] Don't exit.
  5458.     ret            ;[70]
  5459.  
  5460.     subttl    FINISH command
  5461.  
  5462.  ;[28] The FINISH command is edit 28.
  5463.  
  5464. ; Help text for FINISH command.
  5465.  
  5466. hfinis:    asciz |
  5467. FINISH
  5468.  
  5469. When running as a local Kermit, talking to a KERMIT server over a TTY line
  5470. specified in a SET LINE command, use the FINISH command to shut down the
  5471. server without logging out the remote job, so that you can CONNECT back to it.
  5472. Also, close any local debugging log file.
  5473. |
  5474.  
  5475. ; Parse rest of FINISH command.
  5476.  
  5477. .finis:    noise (remote server operation) ; Parse rest of FINISH command.
  5478.     confrm
  5479.     ret
  5480.  
  5481.  
  5482. ; Execute FINISH command.
  5483.  
  5484. $finis:    move t1, [point 7, [asciz/F/]] ; An "F" for the data field.
  5485.     movei t2, "G"        ; Packet type is G.
  5486.     call srvcmd        ; Go send the command.
  5487.      nop            ;  Ignore any failure.
  5488.     ret            ; Done.
  5489.  
  5490. hclear:    asciz |
  5491. CLEAR
  5492.  
  5493. Clear the input and output buffers of the currently selected line;
  5494. attempt to clear any XOFF condition.  Useful in local mode, when the
  5495. connection to the remote system appears to be stuck.
  5496. |
  5497. .clear:    noise <line>
  5498.     confrm
  5499.     ret
  5500.  
  5501. $clear:    call ttxon        ; Clear output buffer, send XON, etc.
  5502.     CFIBF            ; Also clear input buffer.
  5503.      erjmp r
  5504.     ret
  5505.  
  5506. hclose:    asciz |
  5507. CLOSE keyword
  5508.  
  5509. Close the specified log file, TRANSACTION, DEBUGGING, or SESSION,
  5510. and stop recording to that file.
  5511. |
  5512. ; Parse CLOSE command.
  5513.  
  5514. .close:    noise (logging of)
  5515.     movei t1, [flddb. .cmkey,,logtab] ; Parse what kind of log.
  5516.     call cfield
  5517.     hrrz t2, (t2)
  5518.     movem t2, pars2
  5519.     ret
  5520.  
  5521. ; Execute CLOSE command.
  5522.  
  5523. $close:    move t4, pars2        ; Get dispatch table offset.
  5524.     setz t1,        ; Make a zero.
  5525.     jrst @[exp $clost, $closs, $closd](t4) ; Dispatch.
  5526.  
  5527. $clost:    exch t1, tlgjfn        ; Load transaction log JFN and zero it.
  5528.     jrst $closx
  5529.  
  5530. $closs:    exch t1, sesjfn        ; Load session log JFN and zero it.
  5531.     skipg t1        ; Were we using the saved JFN?
  5532.      move t1, savjfn    ; Try that.
  5533.     setzm savjfn        ; Also zero any saved copy.
  5534.     jrst $closx
  5535.  
  5536. $closd:    exch t1, logjfn
  5537.  
  5538. $closx:    skipg t2, t1        ; Move JFN to t2 for JFNS, check for validity.
  5539.      jrst [    tmsg <
  5540. ?Logging was not being done>
  5541.         ret ]        ;  If no valid JFN, give this message.
  5542.     movei t1, "["        ; JFN looks OK - opening bracket for message.
  5543.     PBOUT
  5544.     movei t1, .priou    ; Type the filename.
  5545.     setz t3,
  5546.     JFNS
  5547.      %jserr (,r)
  5548.     move t1, t2        ; JFN back to t1 for other JSYS's.
  5549.     move t3, t2        ; Save the JFN here, too.
  5550.     RFPTR            ; Get file position.
  5551.      seto t2,        ;  On error, substitute -1.
  5552.     CLOSF            ; Close the file.
  5553.      erjmp [hrrzs t1    ; If error, check what it was.
  5554.         caie t1, clsx1    ; Already closed?
  5555.          %ermsg (,r)    ;  No, give message.
  5556.         move t1, t3    ; Yes, get the JFN back.
  5557.         RLJFN        ; Release it.
  5558.          nop        ; Ignore any errors.
  5559.         jrst .+1 ]
  5560.     tmsg < Closed, >    ; Finish the message,
  5561.     numout t2        ; including count of bytes written.
  5562.     tmsg < Byte(s) Written]>
  5563.     ret
  5564.  
  5565.     subttl    CONNECT command
  5566.  
  5567. ; Help text for CONNECT...
  5568.  
  5569.  
  5570. hconne:    asciz |
  5571. CONNECT [number]
  5572.  
  5573. Establish a terminal connection to the system connected to the octal TTY number
  5574. specified here or in the most recent SET LINE command, using full duplex
  5575. echoing and no parity unless otherwise specified in previous SET commands, and
  5576. logging the session to the file specified in the most recent LOG SESSION
  5577. command, if any.  Get back to KERMIT-20 by typing the escape character followed
  5578. by the letter C.  The escape character is Control-Backslash (^\) by default.
  5579. When you type the escape character, several single-character commands are
  5580. possible:
  5581.  
  5582. C -- Close the connection and return to KERMIT-20.
  5583. B -- Transmit a BREAK signal.
  5584. S -- Show status of the connection.
  5585. Q -- Temporarily quit logging.
  5586. R -- Resume logging.
  5587. P -- Push to a new Exec.  POP from the Exec to get back to the connection.
  5588. ^\ (or whatever you have set the escape character to be) -- Typing the escape
  5589.  character twice sends one copy of it to the connected host.
  5590.  
  5591. You can use the SET ESCAPE command to define a different escape character.
  5592. |
  5593.     ;...
  5594.  
  5595. ;...CONNECT command, cont'd
  5596.  
  5597.  
  5598. ; Parse rest of CONNECT command...
  5599.  
  5600. .conne:    noise <to tty>
  5601.     movei t1, [
  5602.      flddb. .cmnum,cm%sdh,^d8,<octal tty number to connect to>,,[
  5603.      flddb. .cmcfm,cm%sdh,,<confirm to connect to selected line>]]
  5604.     call rfield        ; Parse a tty number.
  5605.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  5606.     caie t3, .cmnum        ; Is it a number?
  5607.      ret            ;  If not it must be a confirm.
  5608.     movem t2, pars3        ; Save the tty number.
  5609.     confrm
  5610.     ret
  5611.  
  5612. ;[151] CONNECT code totally rewritten as Edit 151.  Formerly, CONNECT was
  5613. ; accomplished by running a program TTLINK in a lower fork.  Now, the code is
  5614. ; integrated into this program.  This was done for two reasons:
  5615. ;
  5616. ; 1. V6 of TOPS-20 doesn't allow multiple JFNs on the same TTY device.
  5617. ; 2. TTLINK was interrupt-driven and therefore did not work under batch.
  5618. ;
  5619. ; This method, similar to that used in Mark Crispin's TELNET program, uses
  5620. ; separate input and output forks.  It works under batch because the "pty"
  5621. ; is always "hungry".
  5622. ;
  5623. $conne:    skipe pars3        ; Did we parse a TTY number?
  5624.      call $setln        ;  If so, use that one.
  5625.     move t4, mytty        ; Find our terminal number.
  5626.     camn t4, ttynum        ; Is this number the same as requested one?
  5627.      jrst [    tmsg <
  5628. ?You can't CONNECT to your own line.
  5629.  Please use the SET LINE n command to select another line.>
  5630.         ret ]
  5631.  
  5632. ; Set up controlling TTY for talk mode, issue connect message.
  5633.  
  5634.     call ttyini        ; Init controlling TTY.
  5635.     tmsg <[KERMIT-20: Connecting to remote host over TTY> ; Type message.
  5636.     numout ttynum,^d8
  5637.     tmsg <:, type >
  5638.     movei t1, 74        ; Left pointy bracket...
  5639.     PBOUT
  5640.     tmsg <CTRL->
  5641.     move t1, escape        ; (tell escape character)
  5642.     addi t1, "A"-1
  5643.     PBOUT
  5644.     movei t1, 76        ; ...Right pointy bracket
  5645.     PBOUT
  5646.     tmsg <C to return.]
  5647. >
  5648. ; Tell about session log, if any.
  5649.  
  5650.     skipg t2, sesjfn    ; Logging?
  5651.      jrst ttsfrk        ; No.
  5652.     tmsg <[KERMIT-20: Logging to File > ; Yes, tell them now.
  5653.     movei t1, .priou    ; Type the filename.
  5654.     setz t3,
  5655.     JFNS    
  5656.      %jserr (,.+1)
  5657.     tmsg <]
  5658. >                ; End of message.
  5659.  
  5660. ; Create and start a fork to get and display input from the remote end.
  5661.  
  5662. ttsfrk:    movx t1, <cr%map!cr%cap!cr%st!netin> ; Share our map, start at NETIN.
  5663.     CFORK
  5664.      %jserr (,r)
  5665.     movem t1, ttfork    ; It's running, save fork handle.
  5666.  
  5667. ;[151] Keyboard input loop.
  5668.  
  5669. ttinch:    skipn ttfork        ; Have a fork?
  5670.      jrst $connx        ;  No, it's gone, so disconnect.
  5671.     move t1, ttyjfn        ; Get a byte from the controlling TTY.
  5672.     BIN
  5673.      %jserr (<Can't input from tty>,<.+1>) ; What could happen?
  5674.     ldb t3, [point 7, t2, 35] ; Make copy without parity.
  5675.     camn t3, escape        ; Is it the escape character?
  5676.      jrst doesc        ; Yes, go process single-char command.
  5677.     skipe duplex        ; Have to echo locally?
  5678.      call echo        ;  Yes, do.
  5679.     move t1, t2        ; Tack on desired parity.
  5680.     call @parity        ; The parity routine wants the character in t1.
  5681.     move t2, t1
  5682.     move t1, netjfn        ; Output the character to the connected TTY.
  5683.     BOUT
  5684.      %jserr (<Can't output to line>,tterr) ; If error, go check.
  5685.     jrst ttinch        ; Go back and do it again.
  5686.  
  5687. ; Error handler for connected TTY.
  5688.  
  5689. tterr:    skipn mdmlin        ; Modem controlled line?
  5690.      jrst ttinch        ;  No, go back.
  5691.     call chkli2        ; Go check for carrier.
  5692.     skipn carier        ; Still have it?
  5693.      skipa            ;  No, close the connection.
  5694.     jrst ttinch        ; Yes, keep plugging away till they disconnect.
  5695.  
  5696. ; Lost carrier, shut down the connection.
  5697.  
  5698.     tmsg <
  5699. [KERMIT-20: Lost Carrier On Remote Connection -- Returning to DEC-20]
  5700.  
  5701. >
  5702.     jrst $connx
  5703.  
  5704. ;[151] Code for receive fork.  Runs forever, asynchronously, till killed.
  5705.  
  5706. netin:     move t1, netjfn        ; Wait for input
  5707.     BIN
  5708.      %jserr (<Can't input from line>,neterr) ; Handle any errors.
  5709.     txz t2, 200        ; Strip parity.
  5710.     move t1, ttyjfn        ; Display incoming character on screen.
  5711.     BOUT            
  5712.      %jserr (<Can't output to tty>,<.+1>)
  5713.     skipg t1, sesjfn    ; Logging?
  5714.      jrst netin        ;  No, go back for more.
  5715.     BOUT            ; Yes, do that.
  5716.      %jserr (<Can't write log>,netlgx)
  5717.     jrst netin        ; Loop forever.
  5718.  
  5719. ; Error handler for session log output.
  5720.  
  5721. netlgx:    setz t1,        ; Go shut down the session log.
  5722.     call $closs    
  5723.     jrst netin    
  5724.  
  5725. ; Error handler for network TTY.
  5726.  
  5727. neterr:    skipn mdmlin        ; Modem controlled line?
  5728.      jrst netin        ;  No, go back.
  5729.     call chkli2        ; Go check for carrier.
  5730.     skipn carier        ; Still have it?
  5731.      skipa            ;  No, close the connection.
  5732.     jrst netin        ; Yes, keep plugging away till they disconnect.
  5733.  
  5734. ; Lost carrier, shut down the connection.
  5735.  
  5736. neterx:    tmsg <
  5737. [KERMIT-20: Lost Carrier On Remote Connection -- Returning to DEC-20]
  5738.  
  5739. >
  5740.     setzm ttfork        ; Zero the fork handle/flag.
  5741.     HALTF            ; Halt this fork.
  5742.     0            ; Should never get here...
  5743.  
  5744. ;[151] Escape character was typed -- Get argument.
  5745.  
  5746. doesc:    move t1, ttyjfn
  5747.     BIN            ; Escape char was typed, get argument.
  5748.     trz t2, 200        ; Strip any parity bit.
  5749.     cail t2, "a"        ; Uppercase any letter.
  5750.      caile t2, "z"
  5751.      skipa    
  5752.      subi t2, 40
  5753.     cain t2, " "        ; The null command.
  5754.      jrst ttinch        ;  ...
  5755.     cain t2, "S"        ; Status query
  5756.      jrst [    move q1, [ret]    ; Calling convention for show line.
  5757.         call $shlin    ; Go show line parameters.
  5758.         jrst ttinch ]    ; Go back for more input.
  5759.     cain t2, "C"        ; Close connection.
  5760.      jrst $connx
  5761.     cain t2,"B"        ; is it a break?
  5762.      jrst [ call brkin0    ; yes, handle it
  5763.         jrst ttinch ]    ; then continue
  5764.     cain t2, "Q"        ; Quit logging
  5765.      jrst [    call qlog
  5766.         jrst ttinch ]
  5767.     cain t2, "R"        ; Resume logging
  5768.      jrst [ call rlog
  5769.         jrst ttinch ]
  5770.     cain t2, "?"        ; Help
  5771.      jrst [    hrroi t1, [asciz\
  5772. KERMIT-20 Single-Character CONNECT-Mode Commands:
  5773.  B - Send BREAK signal
  5774.  C - Close connection
  5775.  S - Status
  5776.  P - Push to Exec
  5777.  Q - Quit logging
  5778.  R - Resume logging
  5779.  ? - This message
  5780. Type the escape character twice to send one copy of it to the remote host.
  5781.  
  5782. Escape character is "\]
  5783.         PSOUT
  5784.         move t2, escape    ; Type the escape character.
  5785.         call echo
  5786.         tmsg <".
  5787. >
  5788.         jrst ttinch ]
  5789.     ;...
  5790.  
  5791. ;[151]...DOESC, cont'd
  5792.  
  5793.  
  5794.     camn t2, escape        ; Send escape character
  5795.      jrst [    skipe duplex    ; If local echo
  5796.          call echo    ;  take care of that.
  5797.         move t1, t2
  5798.         call @parity     ; Add desired parity to it.
  5799.         move t2, t1
  5800.         move t1, netjfn    ; Send it out the link.
  5801.         BOUT        ;
  5802.          %jserr (,tterr)
  5803.         jrst ttinch ]
  5804.     cain t2, "P"        ; PUSH to Exec
  5805.      jrst [    call fixtty    ; Put TTY in normal mode.
  5806.         call push    ; Do the pushing.
  5807.         call ttyini    ; Put back in talk mode.
  5808.         tmsg <
  5809. [KERMIT-20: Back at remote host]
  5810. >
  5811.         jrst ttinch ]
  5812.     movei t1, 7        ; Anything else, just beep
  5813.     PBOUT
  5814.     jrst ttinch
  5815.  
  5816. ; Come here to restore things.
  5817. ;
  5818. ; Take care of any session log file.  We want to close it, but leave the JFN
  5819. ; around in case the logging is resumed, the program continued, etc.
  5820. ;
  5821. $connx:    skipg t2, sesjfn    ; Is a log file open?
  5822.      jrst $conx2        ;  No, go do the rest.
  5823.     tmsg <
  5824. [KERMIT-20: Closing Log File >
  5825.     movei t1, .priou    
  5826.     setz t3,    
  5827.     JFNS
  5828.      %jserr (,.+1)
  5829.     tmsg <]
  5830. >
  5831.     move t1, t2        ; Get the JFN back into t1.
  5832.     hrli t1, (co%nrj)    ; Close, but don't release JFN.
  5833.     CLOSF%            ;  ...
  5834.      erjmp [hrrzs t1    ; If error, check what it was.
  5835.         cain t1, clsx1    ; Already closed?
  5836.          jrst .+1    ;  Yes, ignore.
  5837.         setzm sesjfn    ; Some other error, so JFNs are probably
  5838.         setzm savjfn    ; unusable, zero them out,
  5839.         %ermsg (,$conx2) ] ; complain, and return.
  5840.     movei t1, (t1)        ; Closed OK, open it again to prevent CLZFF
  5841.     movx t2, <fld(7,of%bsz)+of%app>    ; from stomping on the JFN.
  5842.     OPENF
  5843.      erjmp .+1
  5844.  
  5845. $conx2:    call fixtty        ; Put controlling tty back in data mode.
  5846.     movx t1, .priin        ; Flush any pending tty input.
  5847.     CFIBF
  5848.      erjmp .+1
  5849.     skipe t1, ttfork    ; Kill receive fork.
  5850.      KFORK%
  5851.      erjmp .+1
  5852.     setzm ttfork        ; Remember it's gone.
  5853.     movei t1, .priou    ; Output a CRLF if not at left margin.
  5854.     RFPOS%    
  5855.     hrroi t1, crlf
  5856.     trne t2, -1
  5857.      PSOUT%    
  5858.     tmsg <[KERMIT-20: Connection Closed]> ; Closed message.
  5859.     ret
  5860.  
  5861. ;[151] Character echoing routine.
  5862. ;
  5863. ; Need to do this because having tty open in binary mode overrides ccoc
  5864. ; settings.  t2 contains character to echo.
  5865. ;
  5866. echo:    saveac<t1,t2,t3>    ; Must save all ACs.
  5867.  
  5868.     trz t2, 200        ; Strip any parity.
  5869.     move t3, t2        ; Make a copy of the character.
  5870.  
  5871.     cail t3, 40        ;[18] Check most common case first,
  5872.      caile t3, 126        ;[18] namely, whether it's a printable
  5873.      skipa            ;[18] character.
  5874.      jrst echo2        ;[18] If so, just go print it.
  5875.  
  5876.     caig t3, 6        ; Check for control char, null thru ^F.
  5877.      jrst echo1
  5878.     cain t3, 13        ; ^K
  5879.      jrst echo1
  5880.     cail t3, 16        ; ^N-^Z
  5881.      caile t3, 32
  5882.      skipa
  5883.      jrst echo1
  5884.     cail t3, 34        ; ^\-^_
  5885.      caile t3, 37
  5886.      skipa
  5887.      jrst echo1
  5888.     cain t3, 33        ; ESC
  5889.      jrst [    movei t2, "$"    ; Echo as dollar sign
  5890.         jrst echo2 ]
  5891.     cain t3, 177        ; DEL
  5892.      jrst [    seto t3,     ; So it echoes as ^? (100-1=77="?")
  5893.         jrst echo1 ]
  5894.     move t2, t3        ; Anything else, just type it.
  5895.     jrst echo2
  5896.  
  5897. echo1:    skipg t1, ttyjfn    ; Echo it on the tty.
  5898.      movei t1, .priou
  5899.     movei t2, "^"        ; Print an uparrow
  5900.     BOUT
  5901.       %jserr (,.+1)
  5902.     skiple t1, sesjfn    ; Logging?
  5903.      call [    BOUT        ; Yes, do that.
  5904.          %jserr (,qlog)    ;  Error, print msg, close log, rtn from there.
  5905.         ret ]        ; No error.
  5906.     movei t2, 100(t3)    ; Convert to char to uncontrollified version.
  5907. echo2:    skipg t1, ttyjfn    ; Back to TTY.
  5908.      movei t1, .priou
  5909.     BOUT            ; Print the character itself.
  5910.      %jserr (,.+1)
  5911.     skiple t1, sesjfn    ; Logging?
  5912.      call [    BOUT        ; Yes, do that.
  5913.          %jserr (,qlog)    ;  Error, print msg, close log, rtn from there.
  5914.         ret ]        ; No error.
  5915.     ret
  5916.  
  5917. ;[151] BREAK-sending routine.  Simulate by sending some nulls at
  5918. ; a low baud rate.  Originally by Bill Schilit, Columbia.
  5919. ;
  5920. brkin0:    saveac <t1,t2,t3,t4>    ; save all used registers
  5921.     skipg speed        ; do we know about a speed?
  5922.      jrst brkin2        ; no, give a message
  5923.     move t1, netjfn        ; get the output terminal jfn
  5924.     movx t2, .mospd        ; set the speed
  5925.     hrlz t3, speed        ; same input speed
  5926.     hrri t3, ^d50        ; but output is lower (input,,output speeds)
  5927.     MTOPR
  5928.      %jserr (,r)
  5929.     skipg t3, brk        ; get count of nulls to send
  5930.      movei t3, defbrk    ; use the default
  5931.     caile t3, maxnul    ; greater than we support?
  5932.      movei t3, maxnul    ; yes, use that
  5933.     movns t3        ; make negative
  5934.     move t2, [point 7,nulls] ; point to them
  5935.     setzm t4        ; no stop char
  5936.     SOUT
  5937.      %jserr (,.+1)
  5938.     movx t2, .mospd        ; now reset speed
  5939.     move t3, speed
  5940.     hrls t3            ; make input same as output
  5941.     MTOPR
  5942.      %jserr (,r)
  5943.     ret
  5944.  
  5945. brkin2:    tmsg <
  5946. [KERMIT-20: Can't send BREAK, line speed unknown -- use SET SPEED command.]
  5947. >
  5948.     ret
  5949.  
  5950. defbrk==3            ; Default number of breaks.
  5951. maxnul==100            ; Maximum number of nulls.
  5952. nulls:    repeat <maxnul/5>+1,<0>    ; A string of nulls.
  5953.  
  5954. ;[151] Quit logging session during CONNECT.
  5955.  
  5956.  
  5957. qlog:    skipg t1, sesjfn    ; Do we have a session log?
  5958.      jrst [    tmsg <
  5959. %KERMIT-20 wasn't logging this session...
  5960. >
  5961.          ret ]
  5962.     movem t1, savjfn    ; Yes, save the JFN elsewhere.
  5963.     hrli t1, (co%nrj)    ; Close the log, but don't release JFN.
  5964.     CLOSF
  5965.      erjmp .+1
  5966.     setom sesjfn        ; Signal that we're not logging.
  5967.  
  5968. ; Open the log file again, to keep the JFN from getting flushed by CLZFF.
  5969.  
  5970.     movei t1, (t1)        ; Clear out bits from left half.
  5971.     movx t2, <fld(7,of%bsz)+of%app> ; Open for appending.
  5972.     OPENF
  5973.      %jserr (, [
  5974.         setom sesjfn
  5975.         jrst .+1 ])
  5976.     tmsg <
  5977. [KERMIT-20: Quit logging]
  5978. >
  5979.     ret
  5980.  
  5981.  
  5982. ;[151] Resume logging session after a hiatus.
  5983.  
  5984. rlog:    skiple sesjfn        ; Check for this...
  5985.      jrst [ tmsg <
  5986. %KERMIT-20 already logging...
  5987. >
  5988.         ret ]
  5989.     skipg t1, savjfn    ; Get the saved log JFN back.
  5990.      jrst [    tmsg <
  5991. %KERMIT-20 wasn't logging...
  5992. >
  5993.         ret ]
  5994.  
  5995. ; A log was selected, but not active.  Just juggle the JFNs.
  5996.  
  5997.     movem t1, sesjfn    ; Put saved JFN back as the log JFN.
  5998.     setom savjfn        ; Flag that there's no saved JFN.
  5999.     tmsg <
  6000. [KERMIT-20: Resume logging]
  6001. >
  6002.     ret
  6003.  
  6004.     subttl PUSH Command
  6005.  
  6006. ;[151] Push to Exec
  6007.  
  6008. push:    seto t1,        ; Save subsystem & program names...
  6009.     move t2, [-2,,pname]
  6010.     movei t3, .jisnm
  6011.     GETJI
  6012.      erjmp .+1
  6013.     tmsg <
  6014. [KERMIT-20: PUSHing to new EXEC.]
  6015. [POP from Exec to return.]
  6016. >
  6017.     skipe t1, execf        ; Have one already?
  6018.      jrst [    txo t1, sf%con    ;  Yes, just continue it.
  6019.         SFORK
  6020.          erjmp .+1    ;  Unless it disappeared...
  6021.         jrst push3 ]
  6022.     movx t1, cr%cap        ; No, create a fork.
  6023.     CFORK
  6024.      %jserr (,r)
  6025.     movem t1, execf        ; Save its handle.
  6026.        move t2, capas        ; Mask capas with this fork's enabled ones.
  6027.     txz t2, sc%log        ; Turn off logout capability.
  6028.     txo t2, sc%gtb        ; Turn on GETAB capability (must have it...)
  6029.     skipe jobtab+.jibat    ; Under batch?
  6030.      txz t2, sc%ctc        ;  If so, don't try to enable ^C capability.
  6031.     move t3,  t2        ; Enable capabilities.
  6032.     EPCAP
  6033.      %jserr (,r)        ;  Fail if can't, since Exec must have them.
  6034.     movx t1, gj%old+gj%sht    ; Get JFN on the Exec.
  6035.     hrroi t2, [asciz/SYSTEM:EXEC.EXE.0/]
  6036.     GTJFN
  6037.      %jserr (,r)
  6038.     move t4, t1        ; Save the JFN for a sec.
  6039.  
  6040.     hrl t1, execf        ; Get the Exec into the fork.
  6041.     GET
  6042.      %jserr (,r)
  6043.     move t1, t4        ; Release the Exec's JFN, don't need it.
  6044.     RLJFN
  6045.      nop
  6046.     move t1, execf        ; Exec fork handle.
  6047.     setz t2,        ; Start up the fork.
  6048.     SFRKV
  6049.      %jserr (,r)
  6050. push3:    WFORK            ; Wait for it to halt.
  6051.     dmove t1, pname        ; Restore program/subsys name.
  6052.     SETSN
  6053.      nop
  6054.  
  6055.     REMARK Maybe release terminal during push?  Keeps TCB locked
  6056.  
  6057. push4:    GJINF%            ;[183] Load current job line in t4
  6058.     skipn t1, netjfn    ;[183] Load terminal JFN
  6059.      ret            ;[183]  Nothing there, so don't bother
  6060.     DVCHR%            ;[183] and find out about it
  6061.      erjmp r        ;[183]  make this somebody else's problem
  6062.     load t1, DV%TYP,t2    ;[183] Pick up the device type byte
  6063.     caie t1, .DVTTY        ;[183] and is this a terminal?
  6064.      ret            ;[183]  Nope, nothing to check, then
  6065.     hrrz t1, t3        ;[183] Load the current TTY line number
  6066.     came t1, mytty        ;[183] Was this different from me?
  6067.      ret            ;[183]  Yes, so seperate line was being used
  6068.     camn t1, t4        ;[183] Otherwise, any change?
  6069.      ret            ;[183]  Nope, nothing to do, then
  6070.                  ;[183] lifted from cleanup
  6071. push5:     move t1, netjfn        ;[183] Get communication line JFN.
  6072.     setzm netjfn
  6073.     setzm local
  6074.     caie t1, .cttrm        ;[183] Previous one was controlling terminal?
  6075.      skipn t1        ;[183] Close any assigned TTY.
  6076.       jrst push6
  6077.     CLOSF            ;[183] Also releases a held TCB.
  6078.      erjmp .+1        ;[183] Ignore any error (silently).
  6079. push6:    skipn asgflg        ;[183] Did I also assign the TTY?
  6080.      jrst push7        ;[183] No.
  6081.     move t1, ttynum        ;[183] Yes, so I should deassign it.
  6082.     movei t1, .ttdes(t1)
  6083.     RELD%
  6084.      erjmp .+1
  6085. push7:    setzm asgflg
  6086.     movem t4, ttynum    ;[183] stomp in the new terminal
  6087.     movem t4, mytty        ;[183] stomp in the new terminal
  6088.     movem t4, pars3        ;[183] fake up a parse
  6089.     callret $setln        ;[183] Go set the line again
  6090.  
  6091.  
  6092. ; Put TTY in binary mode for output only.  Still allows normal input,
  6093. ; ^C trapping, etc.
  6094. ;
  6095. ttyob:    movei t1, .priou    ; Get CCOC words
  6096.     RFCOC
  6097.     dmovem t2, myccoc    ; Save em.
  6098.     move t2, [525252525252]    ; Make all characters output
  6099.     move t3, [525252525000]    ;  with no translation.
  6100.     SFCOC
  6101.     movei t2, .morxo    ; Get tty pause-end-of-page status.
  6102.     MTOPR%
  6103.      %jserr (,.+1)
  6104.     movem t3, ttpau        ; Save it.
  6105.     movei t2, .moxof    ; Set the terminal pause end...
  6106.     movei t3, .mooff    ; to no pause on end.
  6107.     MTOPR%
  6108.      %jserr (,.+1)
  6109.     ret
  6110.  
  6111. ; Restore TTY output to condition before TTYOB was called.
  6112.  
  6113. ttyou:    movei t1, .priou    ; Restore normal tty output.
  6114.     dmove t2, myccoc
  6115.     SFCOC
  6116.      %jserr (,.+1)
  6117.     movei t2, .moxof    ; Set terminal pause end-of-page...
  6118.     move t3, ttpau        ;  to what it used to be.
  6119.     MTOPR%
  6120.      %jserr (,.+1)
  6121.     ret
  6122.  
  6123. ;[151] Set up TTY for linking, and open any logging file.
  6124.  
  6125. ttyini:    movei t1, .fhslf    ; Read current process capabilities.
  6126.     RPCAP%
  6127.     movem t3, capas
  6128.     movei t1, .priin    ; Turn off terminal page mode and data mode.
  6129.     movem t1, ttyjfn
  6130.     movei t2, ttydim    ;[185] Point to controlling terminal block
  6131.     call savlnw        ;[185] Save the terminal length and width
  6132.     RFMOD            ; Get tty mode word.
  6133.     movem t2, ttymod    ; Save it, to be restored later.
  6134. ; No echo, no data mode, full duplex.
  6135.      txz t2, <tt%eco!tt%dam!tt%dum!tt%lic> ;[129] Add TT$DUM
  6136. ; No wakeup stuff, infinite width & length.
  6137.     txz t2, <tt%wkf!tt%wkn!tt%wkp!tt%wka!tt%wid!tt%len!tt%uoc>
  6138. ; No formfeed/tab/case interpretation, use XON/XOFF.
  6139.     txo t2, <tt%mff!tt%tab!tt%lca!tt%pgm>
  6140.     skipn handsh        ;[155] Doing handshake?
  6141.      skipn flow        ;[155] Doing flow control?
  6142.      txz t2, tt%pgm        ; Handshake, or no flow - don't do XON/XOFF.
  6143.     SFMOD            ; Set the bits
  6144.      %jserr (,r)
  6145.     STPAR            ; ...and the other bits...
  6146.      %jserr (,r)
  6147.     movx t1, .fhjob        ; Turn off ^C, ^O, ^T interrupts for whole job.
  6148.     RTIW
  6149.     movem t2, tiword
  6150.     tdz t2, [1b<.ticcc>+1b<.ticco>+1b<.ticct>]
  6151.     move t3, capas        ; Do we have  ^C capability?
  6152.     txne t3, sc%ctc        ; Can't do STIW if we don't...
  6153.      STIW
  6154.      %jserr (,.+1)
  6155.     call seslog        ; Open the session log file.
  6156.     ret
  6157.  
  6158. ; Open the session log file.
  6159.  
  6160. seslog:    skipg t1, sesjfn    ; Logging?
  6161.      ret            ;  No.
  6162.     movx t2, <fld(7,of%bsz)+of%app> ; Yes, open for appending.
  6163.     OPENF
  6164.      erjmp [hrrzs t1    ; Got an error, get code.
  6165.         cain t1, opnx1    ; Already open?
  6166.          ret        ;  Ignore the error.
  6167.         setzm sesjfn    ; Real error, disable logging.
  6168.         %ermsg (,r) ]
  6169.     ret
  6170.  
  6171.  
  6172. ;[151] Restore TTY parameters, turn off interrupts, and close any log file.
  6173.  
  6174. fixtty:    move t1, ttyjfn        ; Restore mode word.
  6175.     move t2, ttymod
  6176.     SFMOD            ; Do both of these...
  6177.     STPAR
  6178.     movei t2, ttydim    ;[185] Point to controlling terminal dimensions
  6179.     call rstlnw        ;[185] Restore length and width
  6180.     movx t1, .fhjob        ; Put tty back the way it was.
  6181.     move t2, tiword        ; put the terminal interrupt word
  6182.     move t3, capas        ; Mask capas with this fork's enabled ones.
  6183.     txne t3, sc%ctc        ; Can't do this if no ^C capability.
  6184.      STIW            ;
  6185.      %jserr (,r)
  6186.     ret
  6187.  
  6188.  
  6189. ;[185] Save and restore terminal lengths (a.k.a., heights) and widths.
  6190. ;[185] This is necessary because linear dimensions in excess of seven
  6191. ;[185] bits (127) can not be stored in the JFN mode word as saved by
  6192. ;[185] SFMOD% and restored by STPAR%
  6193. ;[185] 
  6194. ;[185] As these are stored in halfwords, this allows for a maximum of
  6195. ;[185] 262,143 for either a width or a length.  As this is two decimal
  6196. ;[185] orders of magnitude larger than the highest resolution graphics
  6197. ;[185] cards (4096 in 2006), we probably don't have to worry about
  6198. ;[185] overflowing the field for the next decade or so.  None the
  6199. ;[185] less, the MTOPR% does return a FULL 36 bit word; so if we ever
  6200. ;[185] overflow 18 bits, then we should change this code.
  6201. ;[185] 
  6202. ;[185] Assumes:
  6203. ;[185] 
  6204. ;[185] t1/ Valid terminal JFN (possibly .PRIOU)
  6205. ;[185] t2/ Pointer to block to save length and width
  6206. ;[185] 
  6207. ;[185] Preserves the register file and is completely silent about errors.
  6208.  
  6209. savlnw:    saveac <t1,t2,t3,t4,q1>    ;[185] Do not side-effect the register file!
  6210.     dmove t4, t1        ;[185] Preserve JFN, dimension block address
  6211.                 ;[185] 
  6212.     DVCHR%            ;[185] What kind of device is this?
  6213.      erjmpr r        ;[185] it's a bogus device!
  6214.     load t3, dv%typ, t2    ;[185] Get device type field
  6215.     caie t3, .dvtty        ;[185] Is this a terminal?
  6216.      ret            ;[185] No, better leave it alone
  6217.     move t1, t4        ;[185] Restore the JFN
  6218.                 ;[185] Assume infinite (and therefore useless)
  6219.     setzb t3, (q1)        ;[185] defaults for width and length
  6220.     movx t2, .morll        ;[185] Return the terminal page length
  6221.     MTOPR%            ;[185] Which may be over 127 ...
  6222.      erjmps .+2        ;[185]  Must be a bogus JFN
  6223.       hrlm t3, (q1)        ;[185]   Save length
  6224.     dmove t2,[exp .morlw,0]    ;[185] Return the terminal page width.
  6225.     MTOPR%            ;[185] Which may be over 127 ...
  6226.      erjmps .+2        ;[185]  Must be a bogus JFN
  6227.       hrrm t3, (q1)        ;[185]   Save length
  6228.     ret            ;[185] Done, restore register file
  6229.  
  6230. rstlnw: saveac <t1,t2,t3,t4,q1>    ;[185] Do not side-effect the register file!
  6231.     dmove t4, t1        ;[185] Preserve JFN, dimension block address
  6232.                 ;[185] 
  6233.     DVCHR%            ;[185] What kind of device is this?
  6234.      erjmpr r        ;[185] it's a bogus device!
  6235.     load t3, dv%typ, t2    ;[185] Get device type field
  6236.     caie t3, .dvtty        ;[185] Is this a terminal?
  6237.      ret            ;[185] No, better leave it alone
  6238.     move t1, t4        ;[185] Restore the JFN
  6239.                 ;[185] 
  6240.     movx t2, .mosll        ;[185] Set the terminal page length.
  6241.     hlrz t3, (q1)        ;[185] Load old width
  6242.     caie t3, 0        ;[185] Ever get anything?  If not, leave
  6243.      MTOPR%            ;[185]  it alone; otherwise restore it
  6244.       erjmps .+1        ;[185]   Ignore errors, preserve JFN
  6245.     movx t2, .moslw        ;[185] Set the terminal page width.
  6246.     hrrz t3, (q1)        ;[185] Load old width
  6247.     caie t3, 0        ;[185] Ever get anything?  If not, leave
  6248.      MTOPR%            ;[185]  it alone; otherwise restore it
  6249.       erjmps .+1        ;[185]   Ignore errors, preserve JFN
  6250.     ret            ;[185] Done, restore register file
  6251.  
  6252. ;[185] End code insertion
  6253.  
  6254.  
  6255. ;[77] DEFINE command, added as edit 77.
  6256. ;
  6257. hdefin:    asciz |
  6258. DEFINE macroname set-parameters
  6259.  
  6260. Define a "SET macro" to allow convenient association of one or more SET
  6261. parameters with a mnemonic keyword of your choice.  The set-parameters are
  6262. a list of one or more SET options, separated by commas.  If you use KERMIT-20
  6263. to communicate with several different kinds of systems, you may set up a macro
  6264. for each, for instance:
  6265.  
  6266.   DEFINE IBM PARITY MARK, DUPLEX HALF, HANDSHAKE XON, SEND PACKET-LENGTH 80
  6267.   DEFINE UNIX PARITY NONE, DUPLEX FULL, HANDSHAKE NONE
  6268.   DEFINE TELENET PARITY MARK
  6269.  
  6270. You may then type SET IBM, SET UNIX, and so forth to set all the desired
  6271. parameters with a single command.  It is convenient to include these
  6272. definitions in your KERMIT.INI file.
  6273.  
  6274. You may redefine an existing macro in the same manner as you defined it.
  6275. You can undefine an existing macro by typing an empty DEFINE command for it,
  6276. for instance:
  6277.  
  6278.   DEFINE IBM
  6279.  
  6280. Macro definitions may not include macro names.
  6281. |
  6282.  
  6283. ;...DEFIN, cont'd
  6284.  
  6285.  
  6286. .defin:    noise <SET macro named>    ; Macro definition
  6287.     movei t1, [
  6288.      flddb. .cmfld,cm%sdh,,<new macro name for combining SET options>,,[
  6289.      flddb. .cmkey,,mactab,<old macro name to delete or redefine,>]
  6290.      ]
  6291.     call rfield        ; Get the macro name
  6292.  
  6293. ; Check on space for name string.
  6294.  
  6295. .defi2:    move t2, namp        ; Get current name buffer pointer.
  6296.     movei t3, namx        ; Is it at the end of the buffer?
  6297.     caig t3, (t2)
  6298.      jrst [    tmsg <?Macro name buffer full>
  6299.         jrst cmder1 ]
  6300.  
  6301. ; Have room, align pointer to word boundary.
  6302.  
  6303. .defi3:    hlrz t4, t2        ; Is it on a word boundary?
  6304.     caie t4, 440700    
  6305.      jrst [    aos t2        ; No, put it on one.
  6306.         hrli t2, (point 7,)
  6307.         movem t2, namp
  6308.         jrst .+1 ]
  6309.     movem t2, onamp        ; Remember pointer to beginning of string.
  6310.  
  6311. ; Copy the macro name into the macro name buffer.
  6312.  
  6313.     move t1, [point 7, atmbuf] ; Copy the string out of the atom buffer.
  6314.  
  6315. .defi4:    ildb t4, t1        ; Get a character.
  6316.     idpb t4, namp        ; Copy it.
  6317.     jumpn t4, .defi4    ; Everything up to & including the first null.
  6318.  
  6319. ; Let them type CR here to undefine the macro, or else jump into the SET
  6320. ; command parser to let them define a new macro, or redefine an old one.
  6321. ;
  6322. .defi5:    noise <to SET>        ; Prompt with guide words.
  6323.     move t1, sbk+.cmptr    ; Get current pointer from comnd state block.
  6324.     movem t1, macptr    ; Save it as pointer to macro body.
  6325.  
  6326. .defi6:    setom definf        ; Flag that we're doing a DEFINE.
  6327.     movei t1, [flddb. .cmkey,,settab,,,[
  6328.      flddb. .cmcfm,cm%sdh,,<Carriage return to undefine this macro>]
  6329.      ]
  6330.     call rfield        ; Parse a keyword or a CR.
  6331.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  6332.     setom undeff        ; Assume we're undefining?
  6333.     cain t3, .cmcfm        ; Parsed a CR?
  6334.      ret            ;  Yes, so done.
  6335.     setzm undeff        ; No, we're defining after all.
  6336.     callret .set2        ; Go parse SET commands.
  6337.  
  6338. ; DEFINE command execution.
  6339.  
  6340. ; Echo back what was typed...
  6341.  
  6342. $defin:    skipe undeff        ; Define or Undefine?
  6343.      jrst $defi7        ;  Undefine, go do that.
  6344. ;[82]    move t1, onamp        ; Name
  6345. ;[82]    PSOUT
  6346. ;[82]    tmsg < = >
  6347.     move t1, macptr        ; Text
  6348. ;[82]    PSOUT
  6349.  
  6350. ; Check for room left in macro text buffer.
  6351.  
  6352.     move t3, macbp        ; Get current macro text buffer pointer.
  6353.     movei t2, macx        ; Is it at the end of the buffer?
  6354.     caig t2, (t3)
  6355.      jrst [    tmsg <?Macro text buffer full>
  6356.         ret ]
  6357.  
  6358. ; Adjust to word boundary.
  6359.  
  6360. $defi2:    hlrz t4, t3        ; Is it on a word boundary?
  6361.     caie t4, 440700    
  6362.      jrst [    aos t3        ; No, put it on one.
  6363.         hrli t3, (point 7,)
  6364.         jrst .+1 ]
  6365.     movem t3, macbp        ; This copy is to be used.
  6366.     movem t3, omacbp    ; This points to the beginning of the result.
  6367.  
  6368. ; Copy the text out of the command buffer.
  6369.  
  6370. $defi3:    ildb t4, macptr        ; Get a character.
  6371.     idpb t4, macbp        ; Copy it.
  6372.     jumpn t4, $defi3    ; Everything up to & including the first null.
  6373.     
  6374. ; Add <address of macro name,,address of body> to macro keyword table.
  6375.  
  6376. $defi4:    movei t1, mactab    ; Stick it in the macro table.
  6377.     hrlz t2, onamp        ; Address of keyword,,
  6378.     hrr t2, omacbp        ;  argument (address of body)
  6379.     TBADD            ; ...
  6380.      erjmp $defi5        ; Handle any errors below.
  6381.     ret            ; OK, done.
  6382.  
  6383.     ;...
  6384.  
  6385. ; DEFINE command, cont'd
  6386.  
  6387.  
  6388. ; TBADD got an error.
  6389.  
  6390. $defi5:    movei t1, .fhslf    ; What was it?
  6391.     GETER
  6392.     hrrzs t2
  6393.     cain t2, taddx1        ; Table full?
  6394.      jrst [    tmsg <?Macro table is full> ; Yes, give message.
  6395.         ret ]
  6396.  
  6397. ; Duplicate entry?
  6398.  
  6399. $defi6:    caie t2, taddx2        ; Duplicate?
  6400.      callret jserr0        ; No, something unforseen.  Give message.
  6401.  
  6402. ; Come here directly to undefine an existing macro.
  6403. ; First look it up.
  6404. ;
  6405. $defi7:    movei t1, mactab    ; Yes, look up its address in the kwd table.
  6406.     move t2, onamp        ; Pointer to macro name.
  6407.     TBLUK
  6408.      %jserr (,r)
  6409.     skipn undeff        ; Were we undefining?
  6410.      jrst $defi8        ;  No, don't be beastly then...
  6411.     txnn t2, tl%exm        ; Yes, found an exact match?
  6412.      jrst [    tmsg <%">    ; No, warn.
  6413.         move t1, onamp
  6414.         PSOUT
  6415.         tmsg <" not found in SET macro table>
  6416.         ret ]
  6417.  
  6418. ; Using the table index just obtained, delete the entry.
  6419.  
  6420. $defi8:    move t2, t1        ; The address we just got.
  6421.     movei t1, mactab
  6422.     TBDEL            ; Delete the old entry.
  6423.      %jserr (,r)
  6424.     skipe undeff        ; Were we undefining, or replacing?
  6425.      ret            ; Undefining, so done.
  6426.  
  6427. ; Try to add the new definition again.
  6428.  
  6429. $defi9:    hrlz t2, onamp        ; Address of keyword,,
  6430.     hrr t2, omacbp        ;  argument (address of body)
  6431.     movei t1, mactab    ; Stick it in the macro table.
  6432.     TBADD
  6433.      %jserr (,r)        ; This time really give up on error.
  6434.     ret
  6435.  
  6436. ;[125] LOG command
  6437. ;
  6438. ; LOG help text..
  6439.  
  6440. hlog:    asciz |
  6441. LOG TRANSACTIONS or SESSION or DEBUGGING (to) filespec
  6442.  
  6443. Log files are closed upon exit from KERMIT-20, or explicitly by the CLOSE
  6444. command.
  6445.  
  6446. TRANSACTIONS:
  6447.  
  6448. Direct KERMIT-20 to log transactions, such as files successfully sent or
  6449. received, files that could not be successfully sent or received, and so forth,
  6450. to the specified file.
  6451.  
  6452. SESSION:
  6453.  
  6454. Create a transcript of a CONNECT session, when running KERMIT-20 in local
  6455. mode and connected to a remote system, in the specified file.  Log is closed
  6456. when connection is closed.  Logging can be toggled by typing the connect
  6457. escape character followed by Q (Quit logging) or R (Resume logging).
  6458.  
  6459. DEBUGGING:
  6460.  
  6461. Log the selected information (STATES or PACKETS, type HELP SET DEBUG for
  6462. further information) to the specified file.  If log file not specified, then
  6463. use TTY if local, DEBUGGING.LOG if remote.  If specified, then log STATES by
  6464. default.  Also allow specification of bytesize for log file, 7 (normal,
  6465. default), or 8 (for debugging binary transfers, use FILDDT to inspect the log).
  6466. |
  6467. logtab:    %table
  6468.     %key <debugging>,2    ;[143]
  6469.     %key <session>,1
  6470.     %key <transactions>,0
  6471.     %tbend
  6472.  
  6473. .log:    noise <what>        ; Give guide word
  6474.     movei t1, [flddb. .cmkey,,logtab,,<session>] ; Parse what kind of log.
  6475.     call rfield
  6476.     hrrz t2, (t2)
  6477.     movem t2, pars2
  6478.  
  6479.     skipe t1, pars3        ; Release any piled up JFNs from reparsing
  6480.      RLJFN
  6481.      nop
  6482.  
  6483.     noise <to file>        ; Noise
  6484.     move t2, pars2
  6485.     move t1, [
  6486.         [flddb. .cmofi,,,,<TRANSACTION.LOG.-1>] ; transaction log.
  6487.         [flddb. .cmofi,,,,<SESSION.LOG.-1>] ; Default session log,
  6488.         [flddb. .cmofi,,,,<DEBUGGING.LOG.-1>] ; & debugging log.
  6489.         ](t2)        ; Note index!
  6490.  
  6491.     call rfield        ; Parse log filespec.
  6492.     movem t2, pars3        ; Stash JFN here.
  6493.     move t2, pars2        ;[143] Debugging log?
  6494.     caie t2, 2        ;[143]
  6495.      jrst [    confrm        ;[143] No, get confirmation    
  6496.         ret ]        ;[143] and return.
  6497.     noise <with file byte size> ;[41] Yes, parse the file byte size.
  6498.     movei t1, [flddb. .cmkey,,dbstab,<log-file bits per byte,>,7] ;[41]
  6499.     call rfield        ;[41] Parse it.  Defaults to 7.
  6500.     hrrz t2, (t2)        ;[41] Get result.
  6501.     movem t2, pars4     ;[41] Save it.
  6502.     noise <bits>        ;[41] Comforting noise...
  6503.     confrm
  6504.     ret
  6505.  
  6506. ; Open the desired log.
  6507.  
  6508. $log:    move t1, pars2        ; What kind of log?
  6509.     jrst @[exp $logt, $logs, $logd](t1) ; Dispatch
  6510.  
  6511.  
  6512. ;[126] Transaction log.
  6513.  
  6514. $logt:    skipe t1, tlgjfn    ; Already had one open?
  6515.      CLOSF            ;  Close it
  6516.      nop
  6517.     setzm tlgjfn        ; In case of failure.
  6518.     move t1, pars3        ; Open the log
  6519.     movx t2, of%wr!fld(7,of%bsz) ; Write access, 7-bit bytes.
  6520.     OPENF
  6521.      %jserr (,r)
  6522.     movem t1, tlgjfn    ; Save the jfn.
  6523.     hrroi t2, [asciz/KERMIT-20 Transaction Log File, /]
  6524.     setzb t3, t4
  6525.     SOUT
  6526.     seto t2,        ; Write header in log file.
  6527.     move t3, [ot%ntm!ot%day!ot%fdy!ot%fmn!ot%4yr]
  6528.     ODTIM
  6529.     hrroi t2, crlf
  6530.     setzb t3, t4
  6531.     SOUT
  6532.     hrroi t2, crlf
  6533.     setzb t3, t4
  6534.     SOUT    
  6535.     wtlog (<Opened Log: >, tlgjfn)
  6536.     ret
  6537.  
  6538. ;[126] end of addition.
  6539.  
  6540. ; Session log.
  6541.  
  6542. $logs:    move t1, pars3        ; Get JFN we parsed.
  6543.     setzm savjfn        ; Where to put this JFN when not logging.
  6544.     movx t2, <fld(7,of%bsz)!of%wr> ;[154] 7-bit bytesize, new file.
  6545.     OPENF            ; Open now, avoid being stomped by CLZFFs.
  6546.      erjmp [movei t1, (t1)    ; Got an error, get code.
  6547.         cain t1, opnx1    ; Already open?
  6548.          ret        ;  Ignore the error.
  6549.         setzm sesjfn    ; Real error, disable logging.
  6550.         %ermsg (,r) ]    ;[154](end)
  6551.     movem t1, sesjfn    ; Save the open JFN.
  6552.     ret
  6553.  
  6554. ; Debugging log.
  6555.  
  6556. $logd:    setzm logjfn        ;[38] Zero this out.
  6557.     move t1, pars3        ;[38] Get the JFN we parsed.
  6558.     move t4, pars4        ;[41] And bytesize we want.
  6559.     movem t4, logbsz     ;[41] Save bytesize for SHOW command.
  6560.     movx t2, <fld(7,of%bsz)!of%wr> ;[41] Write access, assume 7-bit.
  6561.     cain t4, 8        ;[41] 8-bit requested?
  6562.      movx t2, <fld(8,of%bsz)!of%wr> ;[41] Yes, use 8-bit bytes.
  6563.     OPENF%            ;[38]
  6564.      %jserr <Can't open log file>,r
  6565.     movem t1, logjfn     ;[38] Opened OK, save it.
  6566.     skipn debug        ;[41] Was debugging asked for?
  6567.      movei debug, 1        ;[41] Not yet, so set default debugging.
  6568.     ret
  6569.  
  6570. ; PROMPT command
  6571.  
  6572. ; PROMPT help text...
  6573.  
  6574. hpromp:    asciz |
  6575. PROMPT
  6576.  
  6577. If KERMIT-20 runs in server mode by default, typing the following command
  6578. to the TOPS-20 Exec
  6579.  
  6580.    kermit prompt
  6581.  
  6582. will start it up in interactive mode, and leave you at the "Kermit-20>" prompt.
  6583. |
  6584.  
  6585. ; Parse the rest of the PROMPT command.
  6586.  
  6587. .promp:    confrm            ; Confirm.
  6588.     ret
  6589.  
  6590. ; PROMPT command execution.
  6591.  
  6592. $promp:    setzm f$exit        ; Reset exit flag.
  6593.     ret
  6594.  
  6595.  
  6596. hpush:    asciz |
  6597. PUSH
  6598.  
  6599. Push to a DEC-20 command processor.  Get back to KERMIT with all current
  6600. settings intact by typing the Exec POP command.
  6601. |
  6602. ; Parse & execute PUSH command.
  6603.  
  6604. .push:    confrm
  6605.     ret
  6606.  
  6607. $push:    jrst push
  6608.  
  6609. ; SERVER command
  6610.  
  6611. ; Help text.
  6612.  
  6613. hserve:    asciz |
  6614. SERVER
  6615.  
  6616. Act as a server for another Kermit.  Take all further commands only from the
  6617. other Kermit.  Only works when running remotely.  After issuing this command,
  6618. escape back to your local system and issue SEND, RECEIVE or GET, REMOTE,
  6619. FINISH, BYE, or other server-oriented commands from there.  If your local
  6620. KERMIT does not have a BYE command, it does not have the full ability to
  6621. communicate with a KERMIT server in which case you shouldn't run KERMIT-20 as a
  6622. server.  If your local KERMIT does have a BYE command, use it to shut down and
  6623. log out the KERMIT server when you are done with it; otherwise, connect back to
  6624. the DEC-20, type several Control-C's to stop the server, and logout.
  6625.  
  6626. For doing nonstandard kinds of file transfer (for instance to send binary files
  6627. from a microcomputer), you must issue the appropriate SET commands before the
  6628. SERVER command.
  6629. |
  6630.  
  6631. ; Parse rest of SERVER command.
  6632.  
  6633. .serve:    confrm            ; Confirm.
  6634.     ret
  6635.  
  6636. ; Execute the SERVER command.
  6637.  
  6638. ;[144] Remove test for remote mode operation.  KERMIT-20 works fine as a
  6639. ; server over an assigned line, although the messages may look a bit strange.
  6640. ;
  6641. $serve:    call getcom        ; Go serve.
  6642. ;[137]    setzm f$exit        ;[110] Return to command mode if they ^C out.
  6643.     ret
  6644.  
  6645. ; GET remote files
  6646. ;
  6647. ;[11] This whole command is part of edit 11
  6648.  
  6649. ; GET command help text.
  6650.  
  6651. hget:    asciz |
  6652. GET [remote-filespec]
  6653.  
  6654. For use only when talking to a remote KERMIT server.
  6655.  
  6656. When running as a local KERMIT (i.e. when communicating with a remote KERMIT
  6657. over an assigned TTY line, which you have specified with the SET LINE
  6658. command), you may use the GET command to request the remote KERMIT server to
  6659. send you the specified files.  The filespec is any string that can be a legal
  6660. file specification for the remote system; it is not parsed or validated
  6661. locally.  As files arrive, their names will be displayed on your screen, along
  6662. with "." and "%" characters to indicate the packet traffic.  You may type
  6663. Control-A to get a brief status report, ^X to request that the current incoming
  6664. file be cancelled, ^Z to request that the entire incoming batch be cancelled.
  6665.  
  6666. If the remote KERMIT is not capable of server functions, then you will probably
  6667. get an error message back from it like "Illegal packet type".  In this case,
  6668. you must connect to the other Kermit, give a SEND command, escape back, and
  6669. give a RECEIVE command.
  6670.  
  6671. Syntax:  The GET command accepts an arbitrary string, terminated by a
  6672. carriage return.  The string specifies a file or files in the syntax of the
  6673. remote system.  The normal DEC-20 command characters for help (?), comment
  6674. delimitation (! and ;), and file indirection (@) are enabled at the beginning
  6675. of the field, you can only enter filenames starting with one of these
  6676. characters by "quoting" it with a Control-V, which is discarded before
  6677. sending the string to the remote system.
  6678.  
  6679. If you want to store the incoming file name with a different name than the
  6680. remote host sends it with, just type GET alone on a line; Kermit-20 will
  6681. prompt you separately for the source (remote) and destination (local)
  6682. file specification.  If more than one file arrives, only the first one will
  6683. be stored under the given name; the rest will be stored under the names
  6684. they are sent with.
  6685. |
  6686.  
  6687. ;...GET command, cont'd
  6688.  
  6689. ;[148] Rewritten to allow source & destination files specified separately.
  6690.  
  6691. .get:    noise <remote files>    ; Parse the rest of the GET command.
  6692.     setzm pars2        ; Make sure these are zero...
  6693.     setzm pars3
  6694.  
  6695.     movei t1, [flddb. .cmcfm,cm%sdh,,,,[
  6696.  flddb. .cmtxt,cm%sdh,,<Remote file specification in remote host's own syntax
  6697.  (Use CTRL-V to quote otherwise illegal characters like "!", "?", and "@"),
  6698.  or carriage return to enter source and destination names separately.>]]
  6699.  
  6700.     call rfield
  6701.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  6702.     cain t3, .cmcfm        ; Parsed a CR?
  6703.      jrst .get2        ;  Yes, go prompt.
  6704.  
  6705.     confrm            ; No, so go GET the specified file(s).
  6706.     move t1, [point 7, atmbuf] ; Let $GET know where to find the string.
  6707.     movem t1, pars2
  6708.     setzm filjfn
  6709.     ret
  6710.  
  6711. ; Prompt separately for source and destination filespecs.
  6712.  
  6713. .get2:    hrroi t1, [asciz/ Remote Source File: /] ; Prompt for remote filespec
  6714.     PSOUT
  6715.     move t1, [point 7, buffer]
  6716.     setzm buffer
  6717.     movem t1, pars2        ; Let $GET know where to find the string.
  6718.     move t2, [rd%crf+rd%bel+<MAXBUF>]
  6719.     hrroi t3, [asciz/ Remote Source File: /]
  6720.     RDTTY
  6721.      %jserr (,r)
  6722.     setz t2,        ; Write a zero over the terminating linefeed.
  6723.     dpb t2, t1
  6724.     skipn buffer        ; If they typed nothing, then skip next part.
  6725.      ret
  6726.  
  6727. ; Now get local filespec for storing the incoming file.
  6728.  
  6729. .get3:    hrroi t1, [asciz/ Local Destination File: /]
  6730.     call dpromp
  6731.     movei t1, [flddb. .cmofi]
  6732.     call cfield
  6733.     movem t2, pars3
  6734.     ret
  6735.  
  6736. ; GET command execution.
  6737.  
  6738. $get: skipe takdep        ;[176] Allow commands to servers from TAKE file
  6739.      jrst $get2
  6740.     skipe local        ; This only works if local Kermit.
  6741.      jrst $get2
  6742.     ermsg <Can't GET without prior SET LINE>, r
  6743.  
  6744. ;[148] Check for and validate local filespec.
  6745.  
  6746. $get2:    skipn local        ;[177] If we're in remote mode...
  6747.      call inilin    
  6748.     setzm filjfn        ; Assume no local file given.
  6749.     skipn t1, pars3        ; JFN of local file, if any...
  6750.      jrst $get3        ;  If none, skip this.
  6751.     DVCHR            ; Make sure it's on disk.
  6752.     txne t2, dv%typ        ; ...
  6753.      ermsg <Destination file must be on disk>, r
  6754.     move t1, pars3        ; Get this back.
  6755.     movem t1, filjfn    ; Save it here.
  6756.  
  6757. ; Handle the remote filespec.
  6758.  
  6759. $get3:    setz t3,        ; Count the characters...
  6760.     move t1, pars2        ; And move them from here
  6761.     move t2, [point 7, strbuf] ;  to here.
  6762.  
  6763. $get4:    ildb t4, t1        ; Now copy the rest.  Get a byte.
  6764.     cain t4, 26        ;[147] Control-V?
  6765.      ildb t4, t1        ;[147]  Yes, it's a quote, get next byte.
  6766.     idpb t4, t2        ; Deposit the byte.
  6767.     skipe t4        ; Null?
  6768.      aoja t3, $get4        ; No, then keep going.
  6769.     jumpe t3, [ermsg <No remote filespec given>,r] ; Yes, done, any chars?
  6770.  
  6771.     movem t3, temp2        ; Save this till after next part.
  6772.  
  6773. ; OK, they gave a remote filespec.  Send an info packet in case we want to
  6774. ; tell them to send with nonstandard parameters, like 8bq or fancy block check.
  6775.  
  6776.     setom bctone        ;[98] Force 1-char checksum.
  6777.     call sinfo        ;[100] Go send Info packet.
  6778.      ret            ;[133] Failed, give up.
  6779.     setom bctone        ;[100] In case sinfo or sinit clears this!
  6780.  
  6781. ; Parameters exchanged (perhaps), now send the R packet.
  6782.  
  6783. $get5:    move t3, temp2        ; Restore length.
  6784.     movei t1, "R"        ; Packet type is Receive-Init.
  6785.     setz t2,        ; Packet number is zero.
  6786.     move t4, [point 7, strbuf] ; Point to remote filespec.
  6787.     call spack        ; Send the packet.
  6788.      jrst $getx
  6789.     movei state, "R"    ; Sent it ok, go into receive state.
  6790.     callret $recvb
  6791.  
  6792. $getx:    ermsg <Can't send Receive-Init>,r
  6793.  
  6794.     subttl    RECEIVE command
  6795.  
  6796. ; Help text
  6797.  
  6798. hrecei:    asciz |
  6799. RECEIVE    [filespec]
  6800.  
  6801. Receive a file or file group from the other host.  If only one file is being
  6802. received, you may include the optional filespec as the name to store it under
  6803. when it arrives; otherwise, the name is taken from the incoming file header
  6804. packet.  Even if the name in the header packet is not a legal TOPS-20 file
  6805. name, KERMIT-20 will store it under that name, in which case you can refer to
  6806. it later only by quoting the illegal characters (spaces, lowercase letters,
  6807. control characters, etc) with ^V.  (You may also use SET FILE NAMING to have
  6808. KERMIT-20 pick out a more conventional name.)
  6809.  
  6810. If a file with the same name already exists, KERMIT-20 just creates a new
  6811. generation of the same name and type.
  6812.  
  6813. If running as a local Kermit, the names of the incoming files will be
  6814. displayed on your screen, along with "." and "%" characters to indicate the
  6815. packet traffic; you can type Control-A during the transfer for a brief status
  6816. report.
  6817.  
  6818. If you are asking KERMIT-20 to receive binary files from a microcomputer or
  6819. other 8-bit system, you must first type SET FILE BYTESIZE 8.  Otherwise, the
  6820. 8th bit of each byte will be lost.  For ordinary text files, no special action
  6821. is necessary.
  6822.  
  6823. If you have SET PARITY, then 8th-bit quoting will be requested.  If the other
  6824. side cannot do this, binary files cannot be transferred correctly.  In all
  6825. cases, KERMIT-20 will request the other KERMIT to compress repeated characters;
  6826. if the other side can do this (not all KERMITs know how) there may be a
  6827. significant improvement in transmission efficiency.
  6828.  
  6829. When running locally and receiving files, you can attempt to cancel the
  6830. current file by typing Control-X; this sends a cancellation request to the
  6831. remote KERMIT.  If the remote KERMIT understands this request, it will comply;
  6832. otherwise it will continue to send.  If a file group is being sent, you can
  6833. request the entire group be cancelled by typing Control-Z.
  6834.  
  6835. If running as a remote Kermit, you should escape back to your local Kermit and
  6836. give the SEND command.
  6837. |
  6838.  
  6839. ; RECEIVE command, cont'd
  6840.  
  6841.  
  6842. ; Parse a filespec or just confirmation.
  6843.  
  6844. .recv:    noise <into file>    ; First, issue noise word.
  6845.     movei t1, [
  6846.      flddb. .cmofi,cm%sdh,,<local output file specification>,,[
  6847.      flddb. .cmcfm,cm%sdh,,<confirm to use remote filespec>]]
  6848.     call rfield        ; Parse a file spec or a confirm.
  6849.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  6850.     caie t3, .cmofi        ; Is it an input file spec?
  6851.      ret            ;  If not it must be a confirm, so done.
  6852.  
  6853.     movem t2, filjfn    ; Filespec, so save the JFN,
  6854.     movei t1, [flddb. .cmcfm] ; and parse the confirmation.
  6855.     call rflde
  6856.      skipa            ; Error, handle it.
  6857.      ret
  6858.  
  6859. ; Parse error handler.
  6860.  
  6861.     skipg t1, filjfn    ; Release any JFN.
  6862.      RLJFN%
  6863.      erjmp .+1        ; Ignore any errors.
  6864.     setzm filjfn        ; Zero the JFN to indicate we don't have one.
  6865.     tmsg <?Not confirmed>    ; Issue our own parse message
  6866.     jrst cmder1        ;  and get back inside CMD to clean up.
  6867.  
  6868. ;[57] Resolve debugging status. (This made into a separate routine in edit 57).
  6869. ;
  6870. ; Call this routine at the beginning of any packet transaction (send, receive,
  6871. ; server command, etc).
  6872. ;
  6873. ; Returns +1 if there's no debugging going on
  6874. ;         +2 if there is, with the log jfn set up correctly.
  6875. ;
  6876. setlog:    jumpe debug, r        ; Return nonskip if not debugging.
  6877.     skipe t1, logjfn    ; Yes, has a log file been specified?
  6878.      jrst [    caie t1, .priou ; Yes, but is it the terminal?
  6879.          jrst rskp    ; No, it's a file, which is always OK.
  6880.         setzm logjfn    ; It's the TTY, so say no log file,
  6881.         jrst .+1 ]    ;  and do next bit.
  6882.     movei t1, .priou    ; No log file specified.
  6883.     skipe local        ; If running in local mode,
  6884.      movem t1, logjfn    ; use the terminal.
  6885.     retskp
  6886.  
  6887. ; RECEIVE, GET, REMOTE TYPE command execution.
  6888.  
  6889.  
  6890. ; Initialization -- First, stuff only for when not being a server.
  6891.  
  6892. $recv:    movei state, "R"    ; Start out in receive init state.
  6893.  
  6894. ; Entry point for server commands.
  6895.  
  6896. $recvb:    setom $recvf        ;[88] Executing RECEIVE command,
  6897.     setzm $sendf        ;[88] not SEND command.
  6898.     setzm ttildb        ;[180] (stats)
  6899.     setzm ttibin        ;[180] (stats)
  6900.     setzm ttisin        ;[180] (stats)
  6901.     setzm ttimax        ;[180] (stats)
  6902.     call caxzon        ;[62] Turn on keyboard interrupts.
  6903.     hrroi t1, [        ;[61] Tell about terminal interrupts,
  6904.      asciz/^A for status report, ^X to cancel file, ^Z to cancel batch.
  6905. /]
  6906.     skipe local        ;[62]  if local.
  6907.      PSOUT%            ;[62]
  6908.     call inilin        ; Initialize the line.
  6909.     call ccon        ; Turn on the ^C trap.
  6910.      jrst reslin         ;[27] On ^C go reset line & return from there.
  6911.     skipn gotx        ; If I don't already have an X packet,
  6912.      setzm pktnum        ;  inititialize the packet sequence number.
  6913.  
  6914. ; Entry point for server.
  6915.  
  6916. $recvs:    GTAD            ; Current date/time for start of transaction.
  6917.     movem t1, stdat
  6918.     setzm stot        ; Initialize statistics variables.
  6919.     setzm rtot
  6920.     setzb schr, stchr
  6921.     setzb rchr, rtchr
  6922.     setzm files        ;[61] File counter
  6923.     setom rptot        ;[4]  Init received-packet counter to -1.
  6924.     setom sptot
  6925.     setzm nnak        ;[54] Init the number of NAKs
  6926.     setzm ntimou        ;[54]  and the number of timeouts.
  6927.     setzm timerx        ;[132] Timer error counter.
  6928.     setzm errptr        ; Zero the error message pointer.
  6929.     setom bctone        ;[98] Force block check type to 1 initially.
  6930.  
  6931.     skipe autbyt        ;[72] Using autobyte?
  6932.      setzm ebtflg        ;[72]  If so reset eight-bit-mode flag.
  6933.     move t1, rpause        ;[36] Get the requested receive-pause interval
  6934.     movem t1, pause        ;[36]  and make it the current one.
  6935.     setzm numtry        ; Set the number of tries to zero.
  6936.  
  6937. $recva:    call setlog        ;[57] Set up any debugging log.
  6938.      nop
  6939.     ;...
  6940.  
  6941. ; RECEIVE command, cont'd
  6942.  
  6943. ; State Table Switcher
  6944.  
  6945. $recv2:    cain state, "D"        ; Are we in the data receive state?
  6946.      jrst [    call rdata    ; Yes, go read data packets.
  6947.         jrst $recv2 ]
  6948.     cain state, "F"        ; Are we in the file receive state?
  6949.      jrst [    move t1, filjfn    ;  Get the file's JFN.
  6950.         call rfile    ;  Call receive file.
  6951.         jrst $recv2 ]
  6952.     cain state, "R"        ; Are we in the receive initiate state?
  6953.      jrst [    call rinit    ;  Call receive initiate.
  6954.         jrst $recv2 ]
  6955.     cain state, "C"        ; Are we in the receive complete state?
  6956.      jrst [    movei t1, "C"
  6957.         move t2, pktnum
  6958.         call diamsg    ;[38]
  6959.         GTAD%        ;  Get the time we ended.
  6960.         subm t1, stdat    ;  Figure how long it all took.
  6961.         movei t1, .chbel ;[31] Give a beep
  6962.         skipe local    ;[31] if local
  6963.          PBOUT        ;[31]
  6964.         jrst $recvz ]    ;[88] Done.
  6965.  
  6966.     cain state, "A"        ; Are we in the receive cAncel state?
  6967.      jrst [    movei t1, "A"    ; Print diagnostic message if debugging.
  6968.         move t2, pktnum    ;  ...
  6969.         call diamsg    ;  ...
  6970.         GTAD%        ; Get the time we ended.
  6971.         subm t1, stdat    ; Figure how long it all took.
  6972.         call giveup    ; Clean up the file if necessary.
  6973.         jrst $recvz ]    ;[88] Done.
  6974.  
  6975.     movei t1, "U"        ; Undefined...
  6976.     move t2, pktnum
  6977.     call diamsg
  6978.  
  6979. $recvz:    call caxzof        ;[62] Turn off ^A,^X,^Z traps.
  6980.     call reslin        ;[88] Put the line back the way it was.
  6981.     setzm $recvf        ;[88] RECEIVE command finished.
  6982.     ret
  6983.  
  6984.     subttl receive routines
  6985.  
  6986. ; RINIT -- Receive Initiate; get other side's Send-Init packet.
  6987. ;
  6988. rinit:    saveac <q1>        ; Save this AC.
  6989.  
  6990.     skipe gots        ; Got the S packet already?
  6991.      jrst rinit3        ;  Yes, don't try to read it.
  6992.  
  6993. ; Give up if we've tried too many times, otherwise keep trying.
  6994.  
  6995.     aos q1, numtry        ; Increment the number of tries.
  6996.     caml q1, imxtry        ; Have we reached the maximum number of tries?
  6997.      jrst [    movei state, "A" ;  Change the state to cAncel.
  6998.         kermsg <Can't receive Send-Init>,r ] ;[46]
  6999.     call rpack        ; Try to get a packet.
  7000.      jrst [    move t2, pktnum    ;[53]  Failed, NAK the one we want.
  7001.         callret nak ]    ;[53]
  7002.         
  7003. ; Got a packet.  Check the type and take appropriate action.
  7004.  
  7005. rinit2:    cain t1, "E"        ;[32] Error packet?
  7006.      jrst pxerr        ;[82]  Yes, print it & cancel.
  7007.  
  7008. ; Should have the other side's Send-Init packet at this point, with T1-T4
  7009. ; containing the various pointers, counts, etc.
  7010.  
  7011. rinit3:    setzm gots        ; Clear this flag.
  7012.     move q1, t1        ; Save the packet type.
  7013.     GTAD%            ; Get the time we start.
  7014.     movem t1, stdat        ; Save it.
  7015.     caie q1, "S"        ; Got a send-init?
  7016.      jrst [    move t2, pktnum    ;  No, something else, or timed out.
  7017.         callret nak ]    ;  Just NAK the packet we wanted.
  7018.     movem t2, pktnum    ; Yes, synchronize packet numbers.
  7019.     call spar        ; Get what the other side wants us to do.
  7020.     move t4, [point 8, data] ; Tell the other side what we want
  7021. rinit4:    call rpar        ;  it to do, by returning our Send-Init
  7022.     movei t1, "Y"        ;  parameters in our ACK to its Send-Init.
  7023.     move t2, pktnum        ; Packet number.
  7024.     move t4, [point 8, data] ; The address of the data.
  7025.     call spack        ; Send our params in the acknowledgment.
  7026.      jrst rinitx
  7027.  
  7028. rinit5: call rrinit        ; Go set things up for receiving.
  7029.     
  7030. rinitz:    movei state, "F"    ; Set the state to file receive.
  7031.     ret
  7032.  
  7033. rinitx:    movei state, "A"     ; Failed, set state to cAncel.
  7034.     ret
  7035.  
  7036. ;[126] Set things up for receiving.
  7037. ;
  7038. ; This code is used by RINIT and by XSEND.
  7039. ;
  7040. rrinit:    move t2, numtry        ; Get the number of tries.
  7041.     movem t2, oldtry    ; Save it.
  7042.     setzm numtry        ; Reset the number of tries.
  7043.     aos t2, pktnum        ; Increment the packet number,
  7044.     andi t2, 77        ; modulo 100,
  7045.     movem t2, pktnum    ; and save it back.
  7046.     call ebqmsg        ; Maybe print message about 8 bit prefix.
  7047.     setzm bctone        ; Enable fancy block checks.
  7048.  
  7049. ;[126] Log the beginning of this transaction.
  7050.  
  7051.     skipe iflg        ;[134] Is this an I packet?
  7052.      ret            ;[134]  If so, skip logging.
  7053.  
  7054.     wtlog <-- Receive Begins -->
  7055.  
  7056. ; The following can be called to log ebq & bct for either send or receive.
  7057.  
  7058. rrlog: skipn t1, tlgjfn        ; Logging transactions?
  7059.      jrst rinitz        ;  No, skip ahead.
  7060.     hrroi t2, [asciz/   8th bit prefixing: /]
  7061.     setzb t3, t4
  7062.     SOUT
  7063.     hrroi t2, [asciz/Off/]
  7064.     skipe ebqflg
  7065.      hrroi t2, [asciz/On/]
  7066.     setzb t3, t4
  7067.     SOUT
  7068.     hrroi t2, [asciz/
  7069.    Block check type: /]
  7070.     SOUT
  7071.     move t2, bctu
  7072.     movei t3, ^d10
  7073.     NOUT
  7074.      nop
  7075.     hrroi t2, crlf
  7076.     setzb t3, t4
  7077.     SOUT
  7078.     ret
  7079.  
  7080. ;[89] EBQMSG
  7081. ;
  7082. ;Print warning message if 8th bit prefixing requested but won't be done.
  7083.  
  7084. ebqmsg:    skipe local        ; Local?
  7085.      jrst [    skipn ebqr    ; Yes, wanted 8th bit quoting?
  7086.          jrst .+1     ;  No, so no message will be needed.
  7087.         hrroi t1, [asciz/
  7088. %Warning: Other side won't do 8th-bit prefixing.
  7089. %Binary files will not be transmitted correctly.
  7090. /]                ; Yes,
  7091.         skipn ebqflg    ;  will other side do it?
  7092.          PSOUT        ; No, warn.
  7093.         jrst .+1 ]
  7094.     ret
  7095.  
  7096. ; RFILE - Receive File Header
  7097.  
  7098. rfile:    saveac<q1>
  7099.     setzm cxseen        ;[62] Zero ^X,^Z flags, since they apply
  7100.     setzm czseen        ;[62] on a per-file basis.
  7101.     setzm bctone        ;[99] Can't hurt... (but why do we need it????)
  7102.     move q1, numtry        ; Have we reached the maximum number of tries?
  7103.     caml q1, maxtry        ;  ...
  7104.      jrst [ movei state, "A" ; Yes, change the state to cAncel.
  7105.         kermsg <Can't receive File-Header>,r ]
  7106.     aos numtry        ; No, count this try.
  7107.     skipe gotx        ;[112] Already got an "X" packet?
  7108.      jrst rfil3t        ;[112]  Yes, so don't need to get one.
  7109.     call rpack        ; Try to get a packet.
  7110.      jrst [    move t2, pktnum    ;[53]  Failed, NAK the one we want.
  7111.         callret nak ]    ;[53]
  7112.  
  7113. rfile1:    caie t1, "S"        ; Got a packet.  What's the type?
  7114.      jrst rfile2        ;  Send-Init?  Missed our previous ACK?
  7115. rfil1a:    move q1, oldtry        ; Yes, Send-Init.  Get the number of tries.
  7116.     caml q1, imxtry        ; How many times have we tried to ACK this?
  7117.      jrst [    movei state, "A" ; Too many, change the state to cAncel.
  7118.         kermsg <Too many Send-Inits>,r ]
  7119.     aos oldtry        ; Save the updated number of tries.
  7120.     skipg q1, pktnum    ;[3] Get the present packet number.
  7121.      movei q1, 100        ;[3]  If it just wrapped around, do this.
  7122.     caie t2, -1(q1)        ; Is the packet's number one less than now?
  7123.      ret            ;  No, fail, stay in this state, keep trying.
  7124.     setzm numtry        ; OK, it's the Send-Init again.
  7125.     move t4, [point 8, data] ;[50] ...
  7126.     call rpar        ; Put our parameters in it.
  7127.     movei t1, "Y"        ; Send the ACK with our parameters again.
  7128.     move t2, pktnum        ;[47] Not for the current packet,
  7129.     sos t2            ;[47] but the previous one.
  7130.     call spack        ;  ...
  7131.      jrst @[exp rfil1a, rinitx](t1) ; Handle failures.
  7132.     ret
  7133.     ;...
  7134.  
  7135. ; RFILE, Cont'd
  7136.  
  7137.  
  7138. rfile2:    caie t1, "Z"        ; Is the packet an EOF packet?
  7139.      jrst rfile3        ;  No, try something else.
  7140. rfil2a:    move q1, oldtry        ; Yes, EOF.  How many ACKs have we sent?
  7141.     caml q1, maxtry        ; Too many?
  7142.      jrst [    movei state, "A" ; Yes, change the state to cAncel.
  7143.         kermsg <Can't ACK EOF in RFILE>,r ]
  7144.     aos oldtry        ; Save the updated number of tries.
  7145.     skipg q1, pktnum    ;[3] Get the present packet number.
  7146.      movei q1, 100        ;[3] If it just wrapped around, do this.
  7147.     caie t2, -1(q1)        ; Is the packet's number one less than now?
  7148.      ret            ;  No, then hold out for right one.
  7149.     setzm numtry        ; OK, it's the previous packet again.
  7150.     movei t1, "Y"        ; Restart count, and re-ACK it.
  7151.     setzb t3, t4        ; No data.
  7152.     call spack        ; Send the packet.
  7153.      jrst @[exp rfil2a, rfil2x](t1)
  7154.     ret
  7155.  
  7156. rfil2x: movei state, "A"    ; Set state to cAncel.
  7157.     ret
  7158.  
  7159. ; Process the remote file header
  7160.  
  7161. rfile3:    came t2, pktnum        ; Packet number OK?
  7162.      ret            ;  No, hold out for the right one.
  7163.  
  7164. ;[104] Begin change for receiving "X" packets.
  7165.  
  7166.     cain t1, "F"        ; Start of file?
  7167.      jrst rfil3k        ;  Yes.
  7168.     caie t1, "X"        ; Text header?
  7169.      jrst rfile4        ;  No.
  7170.  
  7171. rfil3t:    setzm gotx        ;[112] Reset this flag.
  7172.     setom filjfn        ; Yes, indicate this way.
  7173.     skipn local
  7174. ;[177]     jrst [    movei state, "A"
  7175. ;[177]        kermsg <Can't receive screen text in remote mode>, r ]
  7176.     jrst rfil3c        ;[177] Let it come, just don't print it.
  7177.  
  7178. ; Local, print the file name on the screen.
  7179.  
  7180.     hrroi t1, [asciz/
  7181.  /]
  7182.     PSOUT
  7183.     move t1, t4
  7184.     PSOUT
  7185.      erjmp .+1
  7186.     hrroi t1, crlf
  7187.     PSOUT
  7188.     jrst rfil3c        ; Skip past file opening stuff.
  7189.  
  7190. ;[104] End change.
  7191.  
  7192.     ;...
  7193.  
  7194. ; RFILE, Cont'd
  7195.  
  7196.  
  7197. ; Come here with normal file header.
  7198.  
  7199. rfil3k:    move t1, t4        ; Got the header we want, point to filename.
  7200.     move t2, t3        ; Get the length of the filename string.
  7201.     call makfil        ; Go get JFN on it.
  7202.      jrst [    movei state, "A" ;  Can't, set state to cAncel.
  7203.         ret ]        ; MAKFIL has already issued appropriate E pkt.
  7204.     movem t1, filjfn    ; All OK, save the JFN.
  7205.  
  7206. ; Open the file.
  7207.  
  7208.     setzm itsfil        ;[75] Assume not ITS binary file.
  7209.     setzm itscnt        ;[75] Init counter for header char matching.
  7210.     move t1, filjfn        ; Open the file.
  7211.     movx t2, fld(36,of%bsz)!of%wr ; 36-bit bytes, write access.
  7212.     OPENF%            ; Open the file (fix bytesize later).
  7213.      %jsker <Can't open file>, rfil3a ;[42] Send this + JSYS error msg.
  7214.     wtlog <Opened: >,filjfn ;[126]
  7215.     jrst rfil3b        ;[42] Opened OK, skip error handling.
  7216.  
  7217. ; Come here if the file can't be opened.
  7218.  
  7219. rfil3a:    skipe t1, tlgjfn    ;[126] Log this failure in transaction log.
  7220.      jrst [    wtlog <Can't Receive >,filjfn
  7221.         hrroi t2, [asciz/   Because: /]
  7222.         setzb t3, t4
  7223.         SOUT
  7224.         hrloi t2, .fhslf ; Tell why.
  7225.         setz t3,
  7226.         ERSTR
  7227.          nop
  7228.          nop
  7229.         hrroi t2, crlf
  7230.         setzb t3, t4
  7231.         SOUT
  7232.         jrst .+1 ]
  7233.  
  7234.     move t1, filjfn        ; Get the output JFN.
  7235.     RLJFN%            ; Release it.
  7236.      nop            ;[33] Ignore any error.
  7237.     setzm filjfn        ; Clear the JFN.
  7238.     movei state, "A"     ; Change state to cAncel.
  7239.     ret
  7240.     ;...
  7241.  
  7242. ; RFILE, Cont'd...
  7243.  
  7244. ;[66] If outputting to a file, set up the mapping page pointers.
  7245.  
  7246. rfil3b:    skiple filjfn        ;[66] JFN on a file?
  7247.      jrst [    move t1, [point 7, mappag*1000]    ;[66] Yes, point to page.
  7248.         skipe ebtflg        ;[66] Eight bit mode?
  7249.          hrli t1, (point 8,)    ;[66] Then use 8-bit bytes.
  7250.         movem t1, pagptr    ;[66] Save it here.
  7251.         setzm pagno        ;[66] Begin at file page zero.
  7252.         jrst .+1 ]
  7253.  
  7254. ; If running locally, echo filename to screen.
  7255.  
  7256.     movei t1, 7        ;[66] Remember file byte size for reporting.
  7257.     skipe ebtflg        ;[66] (this may be revised later because
  7258.      movei t1, 8        ;[66]  of ITS binary headers or similar...)
  7259.     movem t1, bytsiz    ;[66]
  7260.  
  7261.     setom rcving        ;[62] Indicate we're receiving a file.
  7262.     skipn local        ;[12] Local Kermit?
  7263.      jrst rfil3c        ;[12]  No, no terminal messages necessary.
  7264.     movei t1, .priou    ;[12] Yes, print the file name.
  7265.     RFPOS%            ;[12] First see if we need to start a new line.
  7266.     hrroi t1, crlf        ;[12]  ...
  7267.     trne t2, -1        ;[12]  ...
  7268.      PSOUT%            ;[12]
  7269.     movei t1, .priou     ;[12] Now print the file name.
  7270.     hrrz t2, filjfn        ;[12]
  7271.     setz t3,        ;[12]
  7272.     JFNS%            ;[12]
  7273.      nop            ;[12]
  7274.     movei t1, " "        ;[12]
  7275.     PBOUT%            ;[12]
  7276.  
  7277. ; ACK file header, initialize counters and go into Receive-Data state.
  7278.  
  7279. rfil3c:    movei t1, "Y"        ; Acknowledge the packet.
  7280.     move t2, pktnum        ; This packet number.
  7281.     setzb t3, t4        ; No data.
  7282.     call spack        ; Send the packet.
  7283.      jrst rfil3x
  7284.     setzm mapflg        ; Say no pages mapped in yet.
  7285.     move t2, numtry        ; Get the number of tries.
  7286.     movem t2, oldtry    ; Save it.
  7287.     setzm numtry        ; Reset the number of tries.
  7288.     aos t2, pktnum        ; Increment the packet number,
  7289.     andi t2, 77        ; modulo 100,
  7290.     movem t2, pktnum    ; and save it back.
  7291.     setz rchr,        ;[128] Initialize file character counter.
  7292.     movei state, "D"    ; Set the state to file send.
  7293.     ret
  7294.  
  7295. rfil3x:    movei state, "A"    ; On fatal errors, set the state to cAncel.
  7296.     ret
  7297.  
  7298. ;...RFILE, cont'd
  7299.  
  7300.  
  7301. ; It wasn't a File Header or EOF packet; check for other possibilities.
  7302.  
  7303. rfile4:    caie t1, "B"        ; End of transmission?
  7304.      jrst rfile5        ;  No.
  7305.     came t2, pktnum        ; Yes, but is it the right packet number?
  7306.      ret            ;  No, hold out for the right one.
  7307.     movei t1, "Y"        ; All OK, acknowledge the EOT packet.
  7308.     setzb t3, t4        ; No data.
  7309.     call spack        ; Send the packet.
  7310.      skipa state, "A"
  7311.      movei state, "C"    ; Sent ok, set state to Complete.
  7312.     move t1, netjfn        ;[158] Wait until the packet
  7313.     DOBE            ;[158]  gets all the way out.
  7314.      erjmp .+1        ;[158]
  7315.     skiple filjfn        ;[126] Were we writing to a file?
  7316.      wtlog <Receive Complete> ;[126] Yes, record in transaction log.
  7317.     ret
  7318.  
  7319. rfile5:    cain t1, "T"        ; Timer interrupt pseudo packet?
  7320.      jrst [    move t2, pktnum    ; Yes, NAK the expected packet.
  7321.         callret nak ]
  7322.     cain t1, "E"        ;[82] Error packet?
  7323.      jrst pxerr        ;[82]  Yes, print it & cancel.
  7324.  
  7325. rfilex:    ret            ;[46] Something else, just hold out...
  7326.  
  7327. ; RDATA -- Receive Data state.
  7328.  
  7329. rdata:    saveac <q1,q2>        ; Save these
  7330.     aos q1, numtry        ;[42] Too many tries for this packet?
  7331.     camle q1, maxtry    ;[42]
  7332.      kermsg <Retry count exhausted in RDATA>, rdterr
  7333.     call rpack        ; Get a packet.
  7334.      jrst [    move t2, pktnum    ;[53] Failed, NAK the one we want.
  7335.         callret nak ]    ;[53]
  7336.     caie t1, "D"        ; Got one.  Data packet?
  7337.      jrst rdata3        ;[42] No, go see what it is.
  7338.     came t2, pktnum        ; Yes, but is it the right data packet?
  7339.      jrst rdata2        ;  No.
  7340.  
  7341. ; Process a normal data packet.
  7342.  
  7343. rdok:    move t1, t4        ; Got the one we want, point to data.
  7344.     move t2, t3        ; Get the length of the data.
  7345.     call putbuf        ;[66] Write the buffer to the output file.
  7346.      kermsg <Can't write to file>,rdterr ; This error is always fatal.
  7347.     movei t1, "Y"        ; No error, acknowledge the packet we got.
  7348.     move t2, pktnum        ; This sequence number.
  7349.     setzb t3, t4        ; Assume no data.
  7350.     skipn cxseen        ;[62] Was ^X typed?
  7351.      skipe czseen        ;[62] Or ^Z?
  7352.      jrst [    move t3, [byte(8)"Z",0]    ;[62]  Yes, put a "Z"
  7353.         skipn czseen    ;[62] or
  7354.          move t3, [byte(8)"X",0] ;[62] an "X" in the
  7355.         movem t3, data    ;[62] data field of the ACK
  7356.         movei t3, 1    ;[62] (length of data is 1)
  7357.         move t4, [point 8, data] ;[62] and point to it.
  7358.         jrst .+1 ]    ;[62]
  7359.     call spack        ; Send the packet.
  7360.      jrst @[exp r, rdterr](t1) ;[60]  Handle fatal & nonfatal errors.
  7361.     move t2, numtry        ; Get the number of tries.
  7362.     movem t2, oldtry    ; Save it.
  7363.     setzm numtry        ; Reset the number of tries.
  7364.     aos t2, pktnum        ; Increment the packet number,
  7365.     andi t2, 77        ; modulo 100,
  7366.     movem t2, pktnum    ; and save it.
  7367.     ret
  7368.  
  7369.     ;...
  7370.  
  7371. ; RDATA, cont'd
  7372.  
  7373.  
  7374. ; Got a data packet, but it's the wrong one.
  7375.  
  7376. rdata2:    move q1, oldtry        ; Get the number of tries.
  7377.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  7378.      kermsg <Too many retries in RDATA2>,rdterr ; Yes.
  7379.     aos oldtry        ; Not too many, update number of tries.
  7380.     skipg q1, pktnum    ;[3]  Get the present packet number.
  7381.      movei q1, 100        ;[3]  If it just wrapped around, do this.
  7382.     caie t2, -1(q1)        ; Is it the previous packet?
  7383.      ret            ;[46] No, fail, don't change state, retry.
  7384.     setzm numtry        ; Yes, previous packet; start count over.
  7385.     movei t1, "Y"        ; Acknowledge it again.
  7386.     setzb t3, t4        ; No data.
  7387.     call spack        ; Send the ACK.
  7388.      jrst @[exp r, rdterr](t1) ;[60]  Handle fatal & nonfatal errors.
  7389.     ret            ; Otherwise return OK.
  7390.  
  7391. rdata3:    caie t1, "F"        ; File header?
  7392.      jrst rdata4        ;  Nope, try something else.
  7393.     caie t1, "X"        ; Text header?
  7394.      jrst rdata4        ;  Not that either.
  7395.     move q1, oldtry        ; Yes, "F" or "X". Get the number of tries.
  7396.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  7397.      kermsg <Can't ACK file header in RDATA3>,rdterr ; Yes, quit.
  7398.     aos oldtry        ; Not yet, update number of tries.
  7399.     skipg q1, pktnum    ;[3]  Get the present packet number.
  7400.      movei q1, 100        ;[3]  If it just wrapped around, do this.
  7401.     caie t2, -1(q1)        ;  Is the packet's number one less than now?
  7402.      ret            ;[46] No, fail, don't change state, retry.
  7403.     setzm numtry        ; Yes, so start count over.
  7404.     movei t1, "Y"        ; Acknowledge the file header again.
  7405.     setzb t3, t4        ; No data.
  7406.     call spack        ; Send the packet.
  7407.      jrst @[exp r, rdterr](t1) ;[60]  Handle fatal & nonfatal errors.
  7408.     ret            ; else try again to get data.
  7409.  
  7410. ; RDATA, cont'd
  7411.  
  7412.  
  7413. ; End Of File.
  7414.  
  7415. rdata4:    caie t1, "Z"        ; Is it an EOF?
  7416.      jrst rdata5        ;  No, try next thing...
  7417.     came t2, pktnum        ; Yes, is the packet number correct?
  7418.      ret            ;[46] No, ignore this packet, keep trying.
  7419.     jumpn t3, [        ; Was there any data in the EOF packet?
  7420.         ildb t3, t4    ; Yes, see what it is.
  7421.         caie t3, "D"    ; Code for Discard the file?
  7422.          jrst .+1     ;  No, proceed.
  7423.         call giveup    ; Yes, go "close/cancel" this one,
  7424.         jrst rdat5a ]    ;  and then proceed normally.
  7425.  
  7426.     call rdclos        ;[42] Not discarding, close the file normally.
  7427.      jrst rdterr        ;[174] If can't give up.
  7428.  
  7429. rdat4a:    aos files        ;[61] Count the file.
  7430.     hrroi t1, [asciz/[OK]/]    ;[19] Closed the file OK, make comforting msg.
  7431.     skipe local        ;[19] Print it if local.
  7432.      PSOUT%            ;[19]
  7433.  
  7434. rdat5a:    movei t1, "Y"        ; Acknowledge the eof packet.
  7435.     move t2, pktnum
  7436.     setzb t3, t4        ; normally (no data).
  7437.     call spack        ; Send the ACK.
  7438.      nop            ; On any error, just forge ahead.
  7439.  
  7440.     addm rchr, rtchr    ; Add character count for this file to total.
  7441.     setz rchr,        ; Reset for next file.
  7442.     move t2, numtry        ; Get the number of tries.
  7443.     movem t2, oldtry    ; Save it.
  7444.     setzm numtry        ; Reset the number of tries.
  7445.     aos t2, pktnum        ; Increment the packet number,
  7446.     andi t2, 77        ; modulo 100,
  7447.     movem t2, pktnum    ; and save it.
  7448.     movei state, "F"    ; Change state to "F"
  7449.     ret            ;  and go back to the state switcher.
  7450.  
  7451. ; Come here if there was a timeout or error.
  7452.  
  7453. rdata5:    cain t1, "T"        ; Timer interrupt pseudo packet?
  7454.      jrst [    movei t1, "N"    ; Yes, send a NAK.
  7455.         move t2, pktnum ;  for the expected packet.
  7456.         setzb t3, t4    ; No data.
  7457.         call spack    ; Try to send it.
  7458.          jrst rdterr    ;[46] Can't, set state to cAncel.
  7459.         ret ]        ; Return to state switcher.
  7460.     cain t1, "E"        ;[82] Error packet?
  7461.      call pxerr        ;[82]  Yes, print it, then fall thru...
  7462.     ;...
  7463.  
  7464. ;...RDATA (cont'd)
  7465.  
  7466.  
  7467. ; Handler for fatal errors reading/storing data, cancels the transfer.
  7468.  
  7469. rdterr:    call giveup        ; Go clean up the file.
  7470.     movei state, "A"    ; Change the state to cAncel.
  7471.     ret
  7472.  
  7473. ; Come here to close a partially received file.  It will be discarded or
  7474. ; kept, depending on setting of ABTFIL, i.e. SET INCOMPLETE (FILE DISPOSTION).
  7475. ;
  7476. giveup:    skipe abtfil        ;[134] Do we discard or keep?
  7477.      jrst [    wtlog <Incomplete File Kept: >, filjfn ;[134]  Keep.
  7478.         hrroi t1, [asciz/[keeping partial file]/]
  7479.         skipe local
  7480.          PSOUT
  7481.         call rdclos    ; Go close as much of it as we have.
  7482.          jrst .+1    ; Discard it if we have some problem.
  7483.         ret ]        ; Closed partial file OK.
  7484.  
  7485.     wtlog <Incomplete File Discarded: >,filjfn ;[126] Discard.
  7486.     hrroi t1, [asciz/[discarding]/]    ; Say what we're up to.
  7487.     skipe local        ; Print message if local.
  7488.      PSOUT            ;
  7489.     skipg filjfn        ; Real file?
  7490.      jrst givexx        ;  If not, done.
  7491.     call unmapo        ; Go unmap the file
  7492.      nop            ; Don't worry if we can't.
  7493.     hrrz t1, filjfn        ; Clear out any junk from left half.
  7494.     txo t1, cz%abt        ; Discarding, so cancel the file.
  7495.     CLOSF%            ; Close it.
  7496.      erjmp [move t1, filjfn ; On any error,
  7497.         RLJFN        ;  at least try to release the JFN.
  7498.          erjmp givexx    ;  ...
  7499.         jrst givexx ]
  7500.  
  7501. givexx:    setzm filjfn        ; Say we have no file.
  7502.     ret
  7503.  
  7504. ; UNMAPO - Clean up the file mapping page for an output file.
  7505. ;
  7506. ; Returns +1 on failure, +2 on success.
  7507. ;  On failure, an error packet is sent, which cancels the transfer.
  7508. ;
  7509. ; Uses t1,t2,t3.
  7510. ;
  7511. ; Note that unmapping the memory page also makes it disappear.  The next write
  7512. ; to the page will create a fresh page with all 0's.
  7513. ;
  7514. ; The trick at the beginning catches the case where the page has already been
  7515. ; unmapped because we just filled in the last byte.  Since this routine is
  7516. ; called both by the page filler (PUTCH) and by the file closer (RDCLOS, to
  7517. ; catch a final partial page), we must worry about files that end on a page
  7518. ; boundary.  Putting an ERJMP after any instruction that references memory will
  7519. ; catch "illegal memory read" errors, and will thus prevent us from attempting
  7520. ; to unmap a page that has already been unmapped and still has not been
  7521. ; written into.
  7522.  
  7523. unmapo:    move t1, mappag        ;[66] Has the page been used at all?
  7524.      erjmp rskp        ;[66]  No, done.
  7525.  
  7526.     movx t1, <.fhslf,,mappag> ; Yes, map them out, our fork,,mapping page
  7527.     hrl t2, filjfn        ;  file JFN,,...
  7528.     hrr t2, pagno        ;  ...page file page number.
  7529.     movx t3, pm%rd!pm%wr    ; Read and write access.
  7530.     PMAP%            ; Map it out.
  7531.      %jsker (,r)        ;  Can't - fail.
  7532.     retskp
  7533.  
  7534. ; RDCLOS -- Close the output file, update the FDB, etc...
  7535. ; Return +1 on error, +2 on success.
  7536.  
  7537. rdclos:    skipg filjfn        ;[103] Output was to a real file?
  7538.      jrst rdclsz        ;[103]  No, skip all this.
  7539.     call unmapo        ; First, clean out the PMAPping page.
  7540.      ret            ;  Oops, failed, pass it along...
  7541.  
  7542. ; Now close the file.
  7543.  
  7544. rdclsa:    movx t1, co%nrj        ; Flag for not releasing JFN.
  7545.     hrr t1, filjfn        ; Get the JFN.
  7546.     CLOSF%            ; Close it.
  7547.      %jsker <Can't close file>,r ; Return error.
  7548.  
  7549. ; Update FDB information about byte size, number of bytes.
  7550.  
  7551.     hrli t1, .fbsiz        ; OK, now fix FDB.  Set the number of bytes
  7552.     txo, t1, cf%nud        ; Don't update disk yet.
  7553.     hrr t1, filjfn        ; Move in the JFN.
  7554.     seto t2,        ; Change all bits in the word.
  7555.     move t3, rchr        ; The number of bytes in the file.
  7556.     CHFDB%
  7557.      erjmp .+1        ; Keep going if we get an error.
  7558.  
  7559. rdclsb:    hrli t1, .fbbyv        ; Set the byte size.
  7560.     hrr t1, filjfn
  7561.     movx t2, fb%bsz        ; Byte size field mask.
  7562.     movx t3, fld(7,fb%bsz)    ; Value
  7563.     skipn itsfil        ;[75] ITS binary file?
  7564.      skipe ebtflg        ; Or eight-bit mode?
  7565.      movx t3, fld(8,fb%bsz)    ; Set it that way, then.
  7566.     ldb t4, [pointr (t3,fb%bsz)] ; Get the bytesize in t4 as a number.
  7567.     CHFDB%
  7568.      erjmp .+1        ; Keep going if we get an error.
  7569.     ;...
  7570.  
  7571. ;...RDCLOS, cont'd
  7572.  
  7573.  
  7574. ;[126] Take care of any transaction logging.
  7575.  
  7576.     skiple filjfn        ; Real file?
  7577.      skipg t1, tlgjfn    ; Transaction log?
  7578.      jrst rdclsc        ;  No, skip this.
  7579.     hrroi t2, [asciz/   Written: /] ; Yes, log this info.
  7580.     push p, t4
  7581.     setzb t3, t4
  7582.     SOUT
  7583.      erjmp .+1
  7584.     move t2, rchr        ; Number of bytes.
  7585.     movei t3, ^d10
  7586.     NOUT
  7587.      erjmp .+1
  7588.     movei t2, 40        ; A space
  7589.     BOUT
  7590.      erjmp .+1
  7591.     pop p, t2        ; Byte size
  7592.     NOUT
  7593.      erjmp .+1
  7594.     hrroi t2, [asciz/-bit bytes
  7595. /]
  7596.     setz t3,
  7597.     SOUT
  7598.      erjmp .+1
  7599.  
  7600. ; Finish closing the output file by releasing its JFN.
  7601.  
  7602. rdclsc:    skiple filjfn        ;[126]
  7603.      wtlog <Closed: >,filjfn ;[126] Transaction log message.
  7604.     hrrz t1, filjfn        ; Release the JFN.
  7605.     RLJFN%
  7606.      nop
  7607. rdclsz:    setzm filjfn        ; Say we have no more file.
  7608.  
  7609.     retskp
  7610.  
  7611.     subttl    Utility protocol routines
  7612.  
  7613.  
  7614. ; SPAR - Get the arguments from a Send-Init packet.
  7615. ;
  7616. ;[47] Substitute them for our own unless we have given our own SET commands.
  7617. ;[47] The way this is done here is less than perfect, but will work most of
  7618. ;[47] the time (it won't work if the user SETs a value to be the same as the
  7619. ;[47] default, or if the remote sends different parameters each time, or...
  7620. ;[47] But it's better than it was before.  If it becomes an issue, we can
  7621. ;[47] add flags for each value saying who changed it, and figure out when
  7622. ;[47] to set it back to the default, etc...
  7623. ;
  7624. ;[50] Call with:
  7625. ;[50]  t3/ Length of Send-Init packet data field (number of parameters)
  7626. ;[50]  t4/ Pointer to Send-Init packet data field.
  7627. ;[50] The ACs t3-t4 are automatically set up this way upon return from RPACK,
  7628. ;[50] provided nothing has been done to them before calling SPAR.
  7629. ;
  7630. spar:    saveac<q1>        ;[48]
  7631.  
  7632. ; Packet Size
  7633.  
  7634. spar1:    move t2, spsiz        ;[168] Get current setting.
  7635.     sojl t3, spar1a        ;[100] Make sure the field is in packet.
  7636.     ildb t2, t4        ; It is, get it.
  7637.     subi t2, " "        ; Convert it to a number.
  7638. spar1a:    move q1, spsiz        ;[47] See what we have now.
  7639.     caie q1, dspsiz        ;[47] Has default been changed already?
  7640.      jrst spar2        ;[47] Yes, probably by SET command, keep that.
  7641.     caige t2, spmin        ;[47] No, check bounds for new value.
  7642.      movei t2, spmin    ;[47] If too small, use our minimum.
  7643.     caile t2, spmax        ;[47] Or if too great,
  7644.      movei t2, spmax    ;[47] use our maximum value.
  7645.     movem t2, spsiz        ; Set the maximum packet size to send.
  7646.  
  7647. ; Timeout.
  7648.  
  7649. spar2:    move t2, stimou        ;[168] Get current setting.
  7650.     sojl t3, spar2a        ;[100] Got a packet field for this?
  7651.     ildb t2, t4        ; Yes, get it.
  7652.     subi t2, " "        ; Convert the character to a number.
  7653. spar2a:    skipge t2        ;[49][168]  Make sure it's
  7654.      setz t2,        ;[43] not negative.
  7655.     move q1, stimou        ;[47] Has the default already been changed,
  7656.     caie q1, dstim        ;[47] for instance, by a SET command?
  7657.      jrst spar3        ;[47]  Yes it has, so let that take precedence.
  7658.     cain t2, rtimou        ;[131] Same as other side's timeout?
  7659.      aos t2            ;[131] If so, make it a little bit different.
  7660.     movem t2, stimou    ; Set the time out interval.
  7661.     movem t2, otimou    ;[26] Here too, in case we want to change it.
  7662.     ;...
  7663.  
  7664. ; SPAR, cont'd
  7665.  
  7666. ; Padding
  7667.  
  7668. spar3:    move t2, spadn        ;[100][168] Set up default.
  7669.     sojl t3, spar3a        ;[100] Make sure the field is there.
  7670.     ildb t2, t4        ; Get the 3rd field.
  7671.     subi t2, " "        ; Convert it to a number.
  7672. spar3a:    move q1, spadn        ;[47][168] Check if default already changed.
  7673.     caie q1, dspadn        ;[47]
  7674.      jrst spar4        ;[50] It has, don't do this.
  7675.     skipge t2        ;[50] Make sure the number makes sense.
  7676.      movem t2, spadn    ;[50] OK, set the padding.
  7677.  
  7678. ; Pad character
  7679.  
  7680. spar4:    move t2, spadch        ;[100][168] Set up default.
  7681.     sojl t3, spar4a        ;[100] Make sure the field is there.
  7682.     ildb t2, t4        ; Get the 4th field.
  7683.     addi t2, ^o100
  7684.     andi t2, ^o177
  7685. spar4a:    move q1, spadch        ;[47][168] Check for default already changed.
  7686.     caie q1, dspad        ;[50]
  7687.      jrst spar5        ;[50]
  7688.     cain t2, 177        ;[50] DEL?
  7689.      jrst spar4a        ;[50]  Yes, can use it.
  7690.     cail t2, 0        ;[50] No, some other control character?
  7691.      caile t2, 37        ;[50]  ...
  7692.      skipa            ;[50]  Nope, reject it.
  7693.      movem t2, spadch    ; OK, set the padding char.
  7694.  
  7695. ; End Of Line
  7696.  
  7697. spar5:    move t2, seolch        ;[168] Set up default.
  7698.     sojl t3, spar5a        ;[100] Make sure the field is there.
  7699.     ildb t2, t4        ; Get the 5th field.
  7700.     subi t2, " "        ; Convert it to a number.
  7701. spar5a:    move q1, seolch        ;[47][168] Default changed already?
  7702.     caie q1, dseol        ;[47]
  7703.      jrst spar6        ;[50]  Yes, so don't do this.
  7704.     cail t2, 0        ;[50] No, did they give a control character?
  7705.      caile t2, 37        ;[50]  ...
  7706.      skipa            ;[50]  Nope, reject it.
  7707.      movem t2, seolch    ; OK, in range, set the EOL character.
  7708.  
  7709. ; Control Prefix
  7710.  
  7711. spar6:    move t2, rquote        ;[168][132][100] Get current setting.
  7712.     sojl t3, spar6a        ;[100] Make sure the field is there.
  7713.     ildb t2, t4        ; Get the 6th field.
  7714. spar6a:    move q1, rquote        ;[168][132][47] Default already changed?
  7715.     caie q1, drquot        ;[132][50]
  7716.      jrst spar7        ;[50]  Yes, don't change it again.
  7717.     caile t2, " "        ;[50] No, check for printable character
  7718.      caile t2, "~"        ;[50]  other than space.
  7719.      skipa            ;[50]  Out of range, reject it.
  7720.      movem t2, rquote    ;[132] OK, set the quote character.
  7721.     ;...
  7722.  
  7723. ;...SPAR, cont'd
  7724.  
  7725. ; [88] 8th-bit prefix support added as edit 88.
  7726.  
  7727. spar7:    sojl t3, spar7x        ; Did they give one?  If not, do default.
  7728.     ildb t2, t4        ; They did, get it.
  7729.     caie t2, "Y"        ; Is it WILL?
  7730.      jrst spar7a        ;  No, go check for WON'T.
  7731.  
  7732. ; Other side sent "Y" (WILL).
  7733.  
  7734.     skipe ebqr        ; Did our user request prefixing?
  7735.      jrst [    move t2, ebq    ;[89]  Yes, use the specified prefix.
  7736.         movem t2, ebqfld ; Put it here to be sent to other side.
  7737.         setom ebqflg    ; Flag that we're doing this.
  7738.         cain t2, "N"    ; But did she request NOT to do it?
  7739.          setzm ebqflg    ;  In that case, don't.
  7740.         jrst spar8 ]
  7741.     jrst spar7x        ; Didn't request it, so DON'T.
  7742.  
  7743. ; Other side sent "N" (WON'T).
  7744.  
  7745. spar7a:    cain t2, "N"        ; Is it WON'T?
  7746.      jrst spar7x        ;[89] Yes, so DON'T.
  7747.  
  7748. ; Not "Y" or "N".  See if it's a valid prefix character.
  7749.  
  7750. spar7b:    call prechk        ; Call the prefix checking routine.
  7751.      jrst spar7x        ;  It's not valid.
  7752.  
  7753. ; Other side sent valid prefix character.
  7754.  
  7755. spar7c:    skipe $sendf        ;[89] Sending?
  7756.      jrst [    camn t2, ebq    ;[89] Yes, matches what we said?
  7757.          jrst spar7d    ;[89]  Yes, go ahead.
  7758.         move q1, ebqfld    ;[89] No, but...
  7759.         caie q1, "Y"    ;[89]  if this was "Y", then it's still OK.
  7760.          jrst spar7x    ;[89] Otherwise, forget it.    
  7761.         jrst .+1 ]    ;[89]
  7762.  
  7763. ; Got &/Y, Y/&, or &/& combination, so may be OK to do 8-bit prefixing.
  7764.  
  7765. spar7d:    caie t2, rquote        ; Same as one of the control quotes?
  7766.     cain t2, squote
  7767.      jrst [ movei t2, "N"    ;  One of those, must refuse.
  7768.         jrst spar7y ]
  7769.     movem t2, ebq        ; Unique, so save it as the 8b prefix.
  7770.     movei t2, "Y"        ; Acknowledge that we will use it.
  7771.     movem t2, ebqfld    ;   ...
  7772.     setom ebqflg        ; Set the flag saying we must do this.
  7773.     jrst spar8        ; On to next field.
  7774.  
  7775. ; Field was none of the above.  Take default action.
  7776.  
  7777. spar7x:    movei t2, "Y"        ; What we normally say.
  7778. spar7y:    movem t2, ebqfld    ; Put it where RPAR can find it.
  7779.     setzm ebqflg        ; No 8th-bit prefixing.
  7780.  
  7781. ; [88] (End of addition) ....
  7782.  
  7783. ;...SPAR, cont'd
  7784.  
  7785. ;[98] Block check type. (This section added as part of edit 98)
  7786.  
  7787. spar8:    movei t2, "1"        ;[100] Set default, in case this field omitted.
  7788.     sojl t3, spar8a        ;[100] See if there is one.
  7789.     ildb t2, t4        ; Here it is...
  7790.     cail t2, "1"        ; Between 1
  7791.      caile t2, "3"        ;  and 3?
  7792.      movei t2, "1"        ;  No, substitute default value.
  7793.     skipe $sendf        ; I'm sending?
  7794.      jrst [    came t2, bctr    ;  Yes, does this match what I requested?
  7795.          movei t2, "1"    ;  No, so fall back to default.
  7796.         jrst .+1]
  7797. spar8a:    movem t2, bctr        ; Save as block check type requested.
  7798.     subi t2, "0"        ; Convert to a number 1-3,
  7799.     movem t2, bctu        ; and save as block check type to be used.
  7800.  
  7801. ;...SPAR, cont'd
  7802.  
  7803.     
  7804. ; [92] Repeat count prefix support added as edit 92.
  7805.  
  7806. spar9:    sojl t3, spar9x        ; If they didn't give one, don't do this.
  7807.     ildb t2, t4        ; They did, see what it is.
  7808.         
  7809. ; Is it a valid prefix character?
  7810.  
  7811. spar9b:    call prechk        ; Call the prefix checking routine.
  7812.      jrst spar9x        ;  It's not valid.
  7813.  
  7814. ; Other side sent valid prefix character.
  7815.  
  7816. spar9c:    skipe $sendf        ; I'm sending?
  7817.      jrst [    caie t2, rptq    ; Yes, see if theirs matches what I said.
  7818.          jrst spar9d    ;  It does, proceed.
  7819.         jrst spar9x ]    ; It doesn't, don't do repeat counts.
  7820.  
  7821. ; Got a valid prefix, but make sure it's not already in use.
  7822.  
  7823. spar9d:    caie t2, rquote        ; Same as one of the control quotes?
  7824.      cain t2, squote
  7825.      jrst spar9y
  7826.     skipe ebqflg        ; Doing 8th-bit prefixing?
  7827.      caie t2, ebq        ; Yes, check that prefix too.
  7828.      skipa            ; It's OK.
  7829.      jrst spar9x        ; It's the same, don't do repeat counts.
  7830.  
  7831. ; OK, it's valid, it's unique.
  7832.  
  7833. spar9e:    movem t2, rptq        ; Save it as what we'll be using.
  7834.     movem t2, rptfld    ; What we'll reply, in case we're receiving.
  7835.     setom rptflg        ; Set the flag.
  7836.     jrst spar10        ; Go on to next field.
  7837.  
  7838. ; Come here if we're not going to do repeat counts.
  7839.  
  7840. spar9x:    movei t2, " "        ; Blank means default which is no repeat count.
  7841. spar9y:    movem t2, rptfld    ; Put it here to reply in case we're receiving,
  7842.     setzm rptflg        ; and flag that we're not going to do it.
  7843.  
  7844. ; [92] (End of addition)
  7845.  
  7846.     ;...
  7847.  
  7848. ;...SPAR, cont'd
  7849.  
  7850. ; [ 179] Capabilities mask, window size (not supported), and long packet size.
  7851.  
  7852. spar10:    sojl t3, sparx        ; [179] This field present?
  7853.     ildb t2, t4        ; [179] Yes, get it.
  7854.     subi t2, " "        ; [179] Convert it to a number.    
  7855.     trnn t2, 2        ; [179] Long Packets capability on?
  7856.      jrst sparx        ; [179] No, done.
  7857.     sojl t3, sparx        ; [179] Skip Window size
  7858.     ildb t2, t4        ; [179] ...
  7859.     sojl t3, sparx        ; [179] Big part
  7860.     ildb t1, t4        ; [179] ...
  7861.     subi t1, " "        ; [179] Convert it to a number.    
  7862.     imuli t1, ^d95        ; [179] ...
  7863.     sojl t3, sparx        ; [179] small part
  7864.     ildb t2, t4        ; [179] ...
  7865.     subi t2, " "        ; [179] Convert to number
  7866.     add t1, t2        ; [179] Add to big part
  7867.     movem t1, spsiz        ; [179] New packet length.
  7868.  
  7869. ; Exit.  Set up maximum data field size based on what transpired above.
  7870.  
  7871. sparx:    move t1, spsiz        ; Get the send packet size.
  7872.     subi t1, 4        ; Deduct the constant overhead,
  7873.         sub t1, bctu        ; and the length of the checksum.
  7874.     subi t1, 2        ; Room to leave at end: 2 for possible #X,
  7875.     skipe rptflg        ; and if doing repeat counts,
  7876.      subi t1, 2        ; another 2 for repeat prefix,
  7877.     skipe ebqflg        ; and if doing 8th-bit prefixing,
  7878.      subi t1, 1        ; another one for that.
  7879.     movem t1, maxdat    ; Save max length for data field here.
  7880.     ret
  7881.  
  7882.  
  7883. ; PRECHK - Check if character in T2 is valid prefix character.
  7884. ; Return +1 if not, +2 if it is.
  7885. ;
  7886. prechk:    cail t2, ^d33        ; Is it in the 33-62 range?
  7887.      caile t2, ^d62
  7888.      skipa            ; No, see if it's in the high range.
  7889.      retskp            ; Yes, it's in range.
  7890.     cail t2, ^d96        ; Or in the 96-126 range?
  7891.      caile t2, ^d126
  7892.      ret            ; No, something else, not a valid prefix.
  7893.     retskp            ; Yes, it's valid.
  7894.  
  7895. ; RPAR
  7896. ;
  7897. ; Sets up the data field of an init packet with the our own parameters,
  7898. ; which we want the other side to honor.
  7899. ;
  7900. ; Call with:
  7901. ;  t4/ Pointer to data field for S or I packet, or its ACK.
  7902. ;  EBQFLD contains the character to send in the 8-bit-quote field.
  7903. ; Returns with:
  7904. ;  t3/ Length of data field (number of elements).
  7905. ;  t4/ Original pointer to data field.
  7906. ; The ACs t3-t4 are returned suitably for a call to SPACK.
  7907. ;
  7908. rpar:    saveac <t1,t2,t4,q1>    ; Save temp ACs, and t4 for return.
  7909.     move q1, rpsiz        ; 1 Get the packet size.
  7910.     caile q1, ^d94        ;  Fix to compare correctly.
  7911.      movei q1, ^d94        ;[179] Yes, make it 94.
  7912.     addi q1, " "        ;   Make the char printable.
  7913.     idpb q1, t4        ;   Put it in the data block.
  7914.  
  7915. ;[128] Tell the other side how to time out, based on the current 15-min ldav.
  7916.  
  7917.     movei t1, 2        ; Request 15-minute load average.
  7918.     call ldav
  7919.     move t2, rtimou        ; Other side use this timeout when I'm recving.
  7920.     cain state, "S"        ;[131] But am I sending?
  7921.      subi t2, 2        ;[131]  Make it a little different.
  7922.     call adjtim        ; Adjust based on load average.
  7923.  
  7924.     movem t2, rrtimo    ;   Save time for reporting.
  7925.     addi t2, " "        ;   Make it printable.
  7926.     idpb t2, t4        ;   Put it in the data block.
  7927.     
  7928. ; Easy fields...
  7929.  
  7930.     move q1, rpadn        ; 3 Get the padding.
  7931.     addi q1, " "        ;   Make the char printable.
  7932.     idpb q1, t4        ;   Put it in the data block.
  7933.     move q1, rpadch        ; 4 Get the padding char.
  7934.     addi q1, ^o100        ;   De-controllify it.
  7935.     andi q1, ^o177        ;
  7936.     idpb q1, t4        ;   Put it in the data block.
  7937.     move q1, reolch        ; 5 Get the EOL char.
  7938.     addi q1, " "        ;   Make the char printable.
  7939.     idpb q1, t4        ;   Put it in the data block.
  7940.     move q1, squote        ; 6 [132] Get the quote char.
  7941.     idpb q1, t4        ;   Put it in the data block.
  7942.     move q1, ebqfld        ; 7 Say what we'll do about 8th-bit quoting.
  7943.     idpb q1, t4        ;   Put in the data block.
  7944.     move q1, bctr        ; 8 Block check type requested.
  7945.     idpb q1, t4        ;   Put in the data block.
  7946.     move q1, rptfld        ; 9 The repeat-count-prefix field.
  7947.     idpb q1, t4        ;   Put in the data block.
  7948.  
  7949. ; [179] Capabilities mask
  7950.  
  7951.     movei q1, 2        ; [179] 10 Set long-packet capability bit
  7952.     addi q1, " "        ; [179] Convert to ASCII
  7953.     idpb q1, t4        ; [179] Deposit in packet
  7954.     movei t3, ^d10        ; [179] Ten bytes of data so far
  7955.     move q1, rpsiz        ; [179] RECEIVE PACKET-LENGTH
  7956.     caig q1, ^d94        ; [179] Regular (short) packet?
  7957.      ret            ; [179] Done.
  7958.  
  7959. ; [179] Long packets requested
  7960.  
  7961.     movei q1, " "        ; [179] Window size is 0 (no sliding windows)
  7962.     idpb q1, t4        ; [179] Deposit
  7963.     aos t3            ; [179] Count
  7964.     move q1, rpsiz        ; [179] RECEIVE PACKET-LENGTH
  7965.     idivi q1, ^d95        ; [179] Big part (quotient)
  7966.     addi q1, " "        ; [179] Convert to ASCII
  7967.     idpb q1, t4        ; [179] Deposit
  7968.     aos t3            ; [179] Count
  7969.     addi q2, " "        ; [179] Small part (remainder)
  7970.     idpb q2, t4        ; [179] Deposit
  7971.     aos t3            ; [179] Count
  7972.  
  7973.     ret            ; Done
  7974.  
  7975. ; Miscellaneous small routines for NAKs & Error packets.
  7976.  
  7977.  
  7978. ; Send a NAK.  Expects to find the packet number to NAK in AC2.
  7979.  
  7980. nak:    stkvar <naktry>        ; Counter for NAKs.
  7981.     setom naktry
  7982.     
  7983. nak2:    aos t1, naktry        ; Count this try.
  7984.     camle t1, maxtry    ; Less than maximum?
  7985.      jrst nakx        ;  No, fail.
  7986.     movei t1, "N"        ; Send a NAK.
  7987.     setzb t3, t4        ; No data.
  7988.     call spack        ; Send the packet.
  7989.      jrst @[exp nak2, nakx](t1) ; Handle failures.
  7990.     aos nnak        ; Sent the NAK OK, count it.
  7991.     ret
  7992.  
  7993. nakx:    movei state, "A"    ;  If we can't, set state to cancel.
  7994.     ret
  7995.  
  7996. ; Print the contents of an error packet, if local.
  7997. ;
  7998. ; t1-t4 contain the packet parameters from RPACK.
  7999. ; Sets state to cAncel.
  8000. ; Returns +1 always.
  8001.  
  8002. pxerr:    movei state, "A"    ; Set state to cAncel.
  8003.     skipe iflg        ; Doing Info packet?
  8004.      ret            ;  Skip this.
  8005.     movem t4, errptr
  8006.     hrroi t1, [asciz/?Remote error -- /] ; Yes, print message.
  8007.     PSOUT%
  8008.     move t1, errptr        ; Get pointer to it,
  8009.     PSOUT%            ; and print it.
  8010.  
  8011. ;[126] Print the error in the transaction log too.
  8012.  
  8013.     skipn t1, tlgjfn    ; (if any)
  8014.      ret
  8015.     wtlog <Transaction Cancelled by Error from Other Kermit:>
  8016.     move t2, errptr
  8017.     setzb t3, t4
  8018.     SOUT
  8019.     hrroi t2, crlf
  8020.     SOUT
  8021.     ret
  8022.  
  8023.     subttl    SEND command
  8024.  
  8025. ; Help text.
  8026.  
  8027. hsend:    asciz |
  8028. SEND filespec (AS) [target-name]
  8029. SEND wild-filespec1 (INITIAL) [initial-file]
  8030.  
  8031. Send a file or file group from the DEC-20 to the other host.  If the filespec
  8032. contains wildcard characters (* or %) then all matching files will be sent, in
  8033. alphabetical order by name.  If a file can't be opened for read access, it will
  8034. be skipped.  The name of each file is passed to the other host in a file header
  8035. packet, so that the file can be stored there with the same or similar name.
  8036.  
  8037. If a single file is specified, you may optionally specify a diffent name for it
  8038. "target-name") to be sent in the file header packet.  This name is not parsed;
  8039. it is sent to the other system as is, except any lowercase letters are raised
  8040. to upper case.
  8041.  
  8042. If a wildcard file group is specified, you may optionally specify an initial
  8043. file to send.  This is handy to continue a previously interrupted wildcard
  8044. transfer from where it left off, or to skip some files that would be
  8045. transmitted first.
  8046.  
  8047. If running as a local Kermit, the name of each file will be displayed on your
  8048. screen as the transfer begins, a "." will be displayed for every 5 data packets
  8049. sucessfully sent, and a "%" for every retransmission or timeout that occurs
  8050. you may also elect other typeout options with the SET DEBUG command).  If you
  8051. see many "%" characters, you are probably suffering from a noisy connection.
  8052. You can type Control-A at any point during the transfer to get a brief status
  8053. report.
  8054.  
  8055. When running locally and sending files, you can cancel (stop sending) the
  8056. current file by typing Control-X.  If sending a file group, Control-X will
  8057. cause the current file to be skipped, and KERMIT-20 will go on to the next
  8058. file.  Control-Z will cancel sending the entire group and return you to
  8059. KERMIT-20 command level.
  8060.  
  8061. If running as a remote Kermit, you should escape back to your local Kermit and
  8062. give the RECEIVE command.  If you don't do this fast enough, several
  8063. "send-init" packets may arrive prematurely; don't worry, KERMIT-20 will keep
  8064. sending them until it gets a response.
  8065.  
  8066. If communication line parity is being used, KERMIT-20 will request that the
  8067. other KERMIT accept a special kind of prefix notation for binary files.  This
  8068. is an advanced feature, and not all KERMITs have it; if the other KERMIT does
  8069. not agree to use this feature, binary files cannot be sent correctly.  This
  8070. includes executable programs, relocatable object modules, files with EDIT line
  8071. sequence numbers (as produced by EDIT, SOS, or OTTO), etc.
  8072.  
  8073. KERMIT-20 will also ask the other KERMIT whether it can handle a special prefix
  8074. encoding for repeated characters.  If it can, then files with long strings of
  8075. repeated characters will be transmitted very efficiently.  Columnar data,
  8076. highly indented text, and binary files are the chief beneficiaries.
  8077. |
  8078.  
  8079. ;...SEND command, cont'd
  8080.  
  8081.  
  8082. ; SEND command parsing.
  8083.  
  8084. .send:    noise <from files>    ; Issue guide words.
  8085.     move t2, cjfnbk+.gjgen    ; Get the JFN flag bits.
  8086.     txo t2, gj%ifg!gj%old    ; Old file(s), allow wild cards.
  8087.     trz t2, -1        ;[172] Default to most recent generation only.
  8088.     movem t2, cjfnbk+.gjgen    ; Return the JFN flag bits.
  8089.     setzm cjfnbk+.gjext    ;[172] No default extension.
  8090.     movei t1, [flddb. (.cmfil,cm%sdh,,<input file spec (possibly wild)>,,)]
  8091.     call rfield        ; Parse a file spec or a confirm.
  8092.     movem t2, pars2        ;[111]
  8093.     tlnn t2, 770000        ; Any wildcards in it?
  8094.      jrst [    noise <as>    ;[96] No, then let them choose a new name.
  8095.         movei t1, [    ;[96]
  8096.          flddb. .cmtxt,cm%sdh,,<Carriage return to send with this name,
  8097.  or specify file name to use on target system>]    ;[96]
  8098.         jrst .send2 ]
  8099.     noise <initial>        ; Wildcard(s) given, prompt for initial.
  8100.     movei t1, [flddb. (.cmcfm,cm%sdh,,<Carriage return to send them all>,,[
  8101.            flddb. (.cmfil,cm%sdh,,<First file to send>)])]
  8102. .send2:    call rflde        ; Parse the field.
  8103.      jrst .sende        ;[63] Handle errors explicitly.
  8104.     ldb t3, [pointr (.cmfnp(t3),cm%fnc)] ; Get function code.
  8105.     movem t3, pars3        ;[96] Save it for execution.
  8106.     cain t3, .cmcfm        ; Confirmation?
  8107.      ret            ;  Yes, just return.
  8108.     cain t3, .cmfil        ;[96] File?
  8109.      jrst [    hrrm t2, pars2    ;[117] No, initial filespec - substitute it.
  8110.         movei t1, [flddb. .cmcfm] ; Get command confirmation.
  8111.         call rflde
  8112.          jrst .sende
  8113.         ret ]
  8114.  
  8115. ;[96] If they gave an alternate name, copy it out of the atom buffer.
  8116.  
  8117.     caie t3, .cmtxt        ; Text?
  8118.      jrst .sende        ;  No, error.
  8119.     move t1, [point 7, atmbuf] ; Copy the string out of the atom buffer.
  8120.     move t2, [point 7, buffer]
  8121.     setzm buffer
  8122.     call movstu
  8123.     jumpe t3, [        ; If nothing, act like we parsed a confirm.
  8124.         movei t3, .cmcfm
  8125.         movem t3, pars3
  8126.         ret ]
  8127.     ret
  8128.  
  8129. .sende:    move t1, filjfn        ; Error - get the JFN.
  8130.     RLJFN%            ; Release it.
  8131.      erjmp .+1        ;  Ignore any errors.
  8132.     setzm filjfn        ; Nullify the JFN.
  8133.     tmsg <?Not confirmed>
  8134.     jrst cmder1
  8135.  
  8136. ; MOVSTU -- Move string routine, uppercasing any lowercase letters.
  8137. ;  Eat any leading whitespace.
  8138. ;  Call with t1/ source pointer
  8139. ;            t2/ destination pointer
  8140. ;  Returns with t1, t2 updated, t3/ character count, t4/ 0.
  8141. ;
  8142. movstu:    seto t3,        ; Counter, started at -1.
  8143.  
  8144. movstx:    ildb t4, t1        ; Get a character.
  8145.     jumpn t3, movsty    ; Have we got at least one nonwhitespace?
  8146.     caie t4, 40        ; No, is this a blank?
  8147.      cain t4, 11        ;  or a tab?
  8148.      jrst movstx        ;  One of those, skip it.
  8149. movsty:    cail t4, "a"        ; Convert to upper case if necessary.
  8150.      caile t4, "z"
  8151.      skipa
  8152.      trz t4, 40
  8153.     idpb t4, t2        ; Copy it.
  8154.     aos t3            ; Count it.
  8155.     jumpn t4, movstx    ; Everything up to & including the first null.
  8156.  
  8157.     ret    
  8158.  
  8159. ; SEND command execution.
  8160.  
  8161. $send:    setom $sendf        ;[88] Executing SEND command,
  8162.     setzm $recvf        ;[88] not RECEIVE command.
  8163.     setzm ttildb        ;[180] (stats)
  8164.     setzm ttibin        ;[180] (stats)
  8165.     setzm ttisin        ;[180] (stats)
  8166.     setzm ttimax        ;[180] (stats)
  8167.     move t1, pars2        ;[111] Get JFN we just parsed.
  8168.     movem t1, ndxjfn    ;[111] Save the wildcard bits here.
  8169.     hrrzm t1, nxtjfn    ;[111] Initialize file lookahead.
  8170.     call gtnfil        ;[111] Get JFN of first file.
  8171.      ermsg <No files to send>,r ;[111] (if any).
  8172.     call caxzon        ;[59] Turn on ^A,^X,^Z interrupts.
  8173.     hrroi t1, [        ;[61] Tell about terminal interrupts,
  8174.      asciz/^A for status report, ^X to cancel file, ^Z to cancel batch./]
  8175.     skipe local        ;[61]  (if local).
  8176.      PSOUT%            ;[61]
  8177.     call inilin        ; Initialize the line
  8178.     call ccon        ;  and turn on ^C trap.
  8179.      jrst reslin        ;[10] on ^C, go reset line, return from there.
  8180.  
  8181. ; Entry point for server.
  8182.  
  8183. $sends:    setzm stot        ; Initialize statistics variables.
  8184.     setzm rtot
  8185.     setzb schr, stchr
  8186.     setzb rchr, rtchr
  8187.     setzm files
  8188.     setom sptot        ;[4] Init the sent-packet counter to -1.
  8189.     setom rptot
  8190.     setzm nnak        ;[54] Init the number of NAKs
  8191.     setzm ntimou        ;[54]  and the number of timeouts.
  8192.     setzm errptr        ; Zero the error message pointer.
  8193.     setzm timerx        ; Timer error counter.
  8194.     GTAD%            ; Get the time we start.
  8195.     movem t1, stdat        ; Save it for statistics.
  8196.  
  8197. ; Delay to give them time to escape back to other side and say "receive".
  8198.  
  8199.     skipn srvflg        ; Don't delay if server
  8200.      skipe local        ;  or if local.
  8201.      jrst $send1
  8202.     ;...
  8203.  
  8204. ;...$SEND, cont'd
  8205.  
  8206.  
  8207. ;[128] Remote, do the requested delay.
  8208.  
  8209.     move t4, delay        ; The specified delay in seconds.
  8210.     lsh t4, 1        ; Make it half seconds.
  8211.  
  8212. $sndxx:    sojl t4, $send1        ; Countdown.
  8213.     movei t1, ^d500        ; Sleep half a second.
  8214.     DISMS
  8215.  
  8216.     skipn t1, netjfn    ; Got a file transfer jfn?
  8217.      jrst $sndxx        ;  No reason why we shouldn't, but...
  8218.     SIBE            ; Anything in input buffer?
  8219.      skipa
  8220.     jrst $sndxx
  8221.  
  8222. ;[128] If user escapes back to micro & types CR to send NAK for packet 0,
  8223. ; no need to delay any longer -- start sending immediately.
  8224.  
  8225. $sndzz:    BIN            ; Just get first character.
  8226.     came t2, rsthdr        ; Start of packet?
  8227.      jrst $sndxx        ;  No, they're probably fumbling w/the keyboard
  8228.     CFIBF            ; Yes, assume it's a NAK for packet 0,
  8229.      erjmp .+1        ;  discard the rest and start sending.
  8230.  
  8231. ; We can be sending with either a File Header (F) or a Text Header (X).
  8232. ; XFLG nonzero means X header, XFLG zero means F header.
  8233. ; If sending with F header, start with the Send-Init, as packet 0.
  8234. ; If sending with X, we can skip the Send-Init and send X as packet 1.
  8235. ;
  8236. ;[124] BUT...  If type 2 or 3 block check requested and agreed upon,
  8237. ;[124] cannot skip Send-Init (even if I packet exchange just occurred).
  8238.  
  8239. $send1:    movei state, "S"    ; Set the state to Send-Initiate.
  8240.     move t1, bctu        ;[124] What kind of block check are we using?
  8241.     caie t1, 1        ;[124] 2 or 3 character block check?
  8242.      jrst [    setzm pktnum    ;[124] Yes, then must send a Send-Init.
  8243.         jrst $sendb ]    ;[124]
  8244.  
  8245. ; Type 1 block check.  Can obey XFLG.
  8246.  
  8247.     skipn xflg        ; X or F header?
  8248.      setzm pktnum        ;  F, so reset packet number.
  8249.     skipe xflg        ; X or F?
  8250.      movei state, "F"    ;  If X, go straight into file-sending state.
  8251.  
  8252. $sendb:    move t1, spause        ;[36] Get the requested send-pause interval
  8253.     movem t1, pause        ;[36]  and make it the current one.
  8254.     setzm numtry        ; Set the number of tries to zero.
  8255.  
  8256. $senda:    call setlog        ;[57] Set up any debugging log.
  8257.      nop
  8258.  
  8259. ; SEND command, cont'd...  State Table Switcher:
  8260.  
  8261.  
  8262. $send2:    cain state, "D"        ; Are we in the data send state?
  8263.      jrst [    call sdata
  8264.         jrst $send2 ]
  8265.     cain state, "F"        ; Are we in the file send state?
  8266.      jrst [    call sfile    ;  Call send file.
  8267.         jrst $send2 ]
  8268.     cain state, "Z"        ; Are we in the end of file state?
  8269.      jrst [    call seof
  8270.         jrst $send2 ]
  8271.     cain state, "S"        ; Are we in the send initiate state?
  8272.      jrst [    movei t1, "S"    ;[100] Packet type for Send-Init.
  8273.         call sinit    ; Call send-initiate routine.
  8274.         jrst $send2 ]
  8275.     cain state, "B"        ; Are we in the end of send state?
  8276.      jrst [    call seot
  8277.         jrst $send2 ]
  8278.     cain state, "C"        ; Are we in the send complete state?
  8279.      jrst [    movei t1, "C"
  8280.         move t2, pktnum
  8281.         call diamsg
  8282.         call caxzoff    ;[59] Turn off keyboard interrupts
  8283.         call reslin    ;  Restore the line.
  8284.         GTAD%        ;  Get the time we ended.
  8285.         subm t1, stdat    ;  Figure how long it all took.
  8286.         movei t1, .chbel ;[31] Give a beep
  8287.         skipe local    ;[31] if local
  8288.          PBOUT        ;[31]
  8289.         ret ]
  8290.     cain state, "A"        ; Are we in the send cAncel state?
  8291.      jrst [    movei t1, "A"
  8292.         move t2, pktnum
  8293.         call diamsg    ;[38]
  8294.         call reslin    ;  Restore the line.
  8295.         GTAD%        ;  Get the time we ended.
  8296.         subm t1, stdat    ;  Figure how long it all took.
  8297.         move t1, filjfn ;[134] Last-ditch effort to close the file.
  8298.         setzm filjfn    ;[134]
  8299.         jumple t1, r    ;[134]
  8300.          CLOSF        ;[134]
  8301.          erjmp r    ;[134]
  8302.         ret ]
  8303.     movei t1, "U"        ; Some undefined state???
  8304.     move t2, pktnum
  8305.     call diamsg        ;[38]
  8306.         call caxzof        ;[59] Turn off ^A,^X,^Z traps.
  8307.     call reslin
  8308.     ret
  8309.  
  8310.     subttl Send routines
  8311.  
  8312. ; SINIT: Call with t1/packet type, "S" for Send-Init, "I" for Init-Info.
  8313. ;
  8314. sinit:    saveac <q1>
  8315.     move q1, numtry        ; Get the number of tries.
  8316.     caml q1, imxtry        ; Have we reached the maximum number of tries?
  8317.      jrst [    skipe local    ;[5] Yes.
  8318.          ermsg <Send-Init not ACK'd>,sinitx
  8319.         jrst sinitx ]    ; Go cancel the transfer
  8320.     aos numtry        ; Save updated number of tries.
  8321.     movei t4, "Y"        ;[88] Say we agree to do 8-bit prefixing.
  8322.     skipe ebqr        ;[88] Did our user explicitly ask for it?
  8323.      move t4, ebq        ;[89] In that case, specify requested prefix.
  8324.     movem t4, ebqfld    ;[88] Put it here.
  8325.     movei t4, drept        ;[92] Want to use this as repeat count prefix.
  8326.     movem t4, rptfld    ;[92] Put it here.
  8327.     move t4, [point 8, data] ;[50] The address of the data.
  8328.     call rpar        ; Set the information.
  8329.     move t2, pktnum        ; Packet number.  T1 already has packet type.
  8330.     setom bctone        ;[98] Force single char checksums.
  8331.     call spack        ; Send the packet.
  8332.      jrst @[exp r, sinitx](t1) ; Handle errors.
  8333.     call rpack        ; Get a packet.
  8334.      ret            ;  Trashed packet don't change state, retry.
  8335.  
  8336. sinity:    caie t1, "Y"        ; Check packet type.  ACK?
  8337.      jrst sinitn        ;  No, go see if it's a NAK.
  8338.     came t2, pktnum        ; ACK.  But is it the right ACK?
  8339.      ret            ;  No, don't settle, hold out for right one.
  8340.     call spar        ; Yes, get the information.
  8341.     setzm numtry        ; Reset the number of tries.
  8342.     aos t2, pktnum        ; Increment the packet number,
  8343.     andi t2, 77        ; modulo 100,
  8344.     movem t2, pktnum    ; and save it.
  8345.     call ebqmsg        ;[89] Go warn if problem w/8-bit prefixing.
  8346.     setzm bctone        ;[98] Finished with initialization.
  8347.     movei state, "F"    ; Set the state to file send.
  8348.  
  8349. ;[126] Start entry in transaction log.
  8350.  
  8351.     skipn t1, tlgjfn    ; (if any)
  8352.      ret
  8353.     skipe iflg        ; Not an I packet, is it?
  8354.      ret
  8355.     wtlog <-- Send Begins -->
  8356.     callret rrlog        ; Go log details.
  8357.  
  8358. sinitn:    cain t1, "N"        ;[30][54] NAK?
  8359.      aosa nnak        ;[54] Yes, count it & return.
  8360. sinitt:    cain t1, "T"        ; Timer interrupt pseudo packet?
  8361.      ret            ;[30] One of those, just keep trying.
  8362.     cain t1, "E"        ; But also print message if error packet.
  8363.      jrst pxerr        ;[82]
  8364. sinitx:    movei state, "A"    ; Anything else, just cancel.
  8365.     ret
  8366.  
  8367. ; SFILE - Send File Header
  8368.  
  8369. sfile:    setzm bctone        ; Don't require single-character checksum.
  8370.     setzm cxseen        ; Zero these here, since they apply on
  8371.     setzm czseen        ;  on a per-file basis.
  8372.     move t1, numtry        ; Get the number of tries.
  8373.     caml t1, maxtry        ; Have we reached the maximum number of tries?
  8374.      jrst [    movei state, "A" ;  Change the state to cAncel.
  8375.         kermsg <Can't send file header>, r ]
  8376.     aos numtry        ; No, count this try.
  8377.     jumpg t1, sfild3    ; After first try, skip opening file, etc.
  8378.  
  8379. sfilea:    skipn local        ;[12] Local Kermit?
  8380.      jrst sfileb        ;[12] No, skip this.
  8381.     movei t1, .priou    ;[12] Yes, print the file name.
  8382.     RFPOS%            ;[12] First see if we need to start a new line.
  8383.     hrroi t1, crlf        ;[12]  ...
  8384.     trne t2, -1        ;[12]  ...
  8385.      PSOUT%            ;[12]
  8386.     movei t1, .priou    ;[12] Now print the file name.
  8387.     hrrz t2, filjfn        ;[12]
  8388.     setz t3,        ;[12]
  8389.     JFNS%            ;[12]
  8390.      erjmp .+1        ;[12]
  8391.     movei t1, pars3        ;[96] Did we have another name to use?
  8392.     cain t1, .cmtxt        ;[96]
  8393.      jrst [    tmsg < as >    ;[96] Yes, say what it was.
  8394.         hrroi t1, buffer ;[96]
  8395.         PSOUT         ;[96]
  8396.         jrst .+1]    ;[96]
  8397.     movei t1, " "        ;[12] Leave a space.
  8398.     PBOUT%            ;[12]
  8399.     ;...
  8400.  
  8401. ; SFILE, cont'd
  8402.  
  8403. sfileb:    skipn source        ; Are we getting data from a file?
  8404.      jrst sfilb2        ; Yes, go open the file, etc.
  8405.     movei t1, "X"        ; No, so send X packet.
  8406.     move t2, pktnum        ; This packet number.
  8407.     setzb t3, t4        ; No data.
  8408.     jrst sfildy        ; Skip around all the file name baloney.
  8409.     
  8410. sfilb2:    move t1, filjfn        ;[15] JFN of file
  8411.     movx t2, fld(^d36,of%bsz)+of%rd ;[15]
  8412.     OPENF%            ;[15]
  8413.      erjmp sfilec        ;[44]
  8414.     skipn xflg        ;[126]
  8415.      wtlog <Opened File: >,filjfn ;[126]
  8416.     jrst sfiled        ;[44] Opened OK, proceed.
  8417.  
  8418. sfilec:    cain t1, opnx1        ;[44] Got an error.  "File already open"?
  8419.      jrst sfiled        ;[44] Yes, so it's not really an error.
  8420.     skipe t1, tlgjfn    ;[126] Log this failure in transaction log.
  8421.      jrst [    wtlog <Can't Send >,filjfn
  8422.         hrroi t2, [asciz/   Because: /]
  8423.         setzb t3, t4
  8424.         SOUT
  8425.         hrloi t2, .fhslf ; Tell why.
  8426.         setz t3,
  8427.         ERSTR
  8428.          nop
  8429.          nop
  8430.         hrroi t2, crlf
  8431.         setzb t3, t4
  8432.         SOUT
  8433.         jrst .+1 ]
  8434.  
  8435.     skipe local        ;[15] No, really an error.  Local?
  8436.      call [    hrroi t1, [asciz/ %Not sent because: /]
  8437.         PSOUT
  8438.         movei t1, .priou
  8439.         hrloi t2, .fhslf
  8440.         setz t3,
  8441.         ERSTR%
  8442.          nop
  8443.          nop
  8444.         ret ]
  8445.     call gtnfil        ; Try to get the next file.
  8446.      jrst [    setzm filjfn
  8447.         movei state, "B" ; No more, break transmission.
  8448.         ret ]
  8449.     jrst sfilea        ; Got one, go try to open it.
  8450.     ;...
  8451.  
  8452. ;...SFILE, Cont'd
  8453.  
  8454.  
  8455. ;[96] See if user wants to send the file with a different name.
  8456.  
  8457. sfiled:    move t1, pars3        ; Use another name?
  8458.     caie t1, .cmtxt        ;
  8459.      jrst sfild2        ; No, use the file's actual name.
  8460.     move t1, [point 7, buffer] ; Yes, copy the string the user gave us,
  8461.     move t2, [point 7, filbuf] ;[102] converting to upper case.
  8462.     call movstu        ; Returns length in t3.
  8463.     jrst sfild3        ; Proceed.
  8464.  
  8465. ; Come here to use the file's actual name.
  8466.  
  8467. sfild2:    move t1, [point 7, filbuf] ;[102] Put string in file name buffer.
  8468.     move t2, filjfn        ; The file's JFN.
  8469.     movx t3, js%nam+js%typ+js%paf ; Only name, type, and punctuation.
  8470.     setzb t4, filbuf
  8471.     JFNS%            ; Get the file name.
  8472.      erjmp [move t1, [point 7, [asciz/XXXXXX.XXX/]]    ; If any error
  8473.         movei t3, ^d10    ; substitute this string.
  8474.         jrst sfild4 ]
  8475.     ldb t3, t1        ;[175] See what the last character is.
  8476.     cain t3, "."        ;[175] Dot?
  8477.      jrst [    dpb t4, t1    ;[175] Yes, zero it out.
  8478.         seto t4,    ;[175] And remember.
  8479.         jrst .+1 ]    ;[175]
  8480.     move t2, t1        ; Set up to subtract the byte pointers.
  8481.     idpb t4, t1        ; Terminate the string
  8482.     move t1, [point 7, filbuf] ;[102] Get a pointer to our data block.
  8483.     call subbp        ; Subtract the byte pointers, get length in t3.
  8484.      ret            ;  Uh oh...  this should never happen.
  8485.     skipe t4        ;[175] Last char was dot?
  8486.      sos t3            ;[175] Yes, so count one less character.
  8487.     ;...
  8488.  
  8489. ;...SFILE, cont'd.
  8490.  
  8491. ;[84] Strip out ^V's, convert filename to "normal form" if requested.
  8492. ;[102] Do this using normal packet encoding & filling technique, but calling
  8493. ;[102] an alternate GETCH routine.
  8494.  
  8495. sfild3:    skipn filjfn        ;[128] Really a file?
  8496.      jrst [    movei t1, "X"    ; No, just send an empty X header.
  8497.         move t2, pktnum    ; Current packet number.
  8498.         setzb t3, t4    ; No data.
  8499.         jrst sfildy ]
  8500.  
  8501. ; Really a file.
  8502.  
  8503.     move t1, [point 7, filbuf] ;[102] Keep file buffer pointer in memory.
  8504.  
  8505. sfild4:    movem t1, filptr    ;[102] ...
  8506.     movei t1, gtfch        ;[102] Address alternate GETCH routine
  8507.     movem t1, source    ;[102] to call while getting characters.
  8508.     setom fildot        ;[102] Initialize filename dot counter.
  8509.     setom next        ;[102] Initialize character lookahead.
  8510.     move t1, maxdat        ;[102] Set up maximum length.
  8511.     call getbuf        ;[102] Fill up the packet with the filename.
  8512.      jumpn t1, [
  8513.         movei state, "A" ;[102] Shouldn't be any error here, but...
  8514.         ret ]        ;[102]  ...
  8515.     move t3, t1        ;[102] Set up length for call to SPACK.
  8516.  
  8517. ; Send the file header packet.
  8518.  
  8519. sfildx:    setzm source        ;[102] Done with alternate GETCH routine.
  8520.     movei t1, "F"        ; Packet type is File Header.
  8521.     skipe xflg        ; Unless it's teXt header...
  8522.      movei t1, "X"        ;  ...
  8523.     move t2, pktnum        ; Packet number.
  8524.     move t4, [point 8, data] ; Get a pointer to our data block.
  8525.  
  8526. sfildy:    call spack        ; Send the file header packet.
  8527.      skipa state, "A"    ; Failed, set state to cAncel & return.
  8528.     call rpack        ; Sent the file header OK, get reply.
  8529.      ret            ;  Trashed packet, don't change state, retry.
  8530.     ;...
  8531.  
  8532. ; SFILE, cont'd
  8533.  
  8534. ; Got a response, check for & handle ACKs.
  8535.  
  8536.     caie t1, "Y"        ; Check the packet, is it an ACK?
  8537.      jrst sfile3        ;  No.
  8538.  
  8539. sfile2:    came t2, pktnum        ; Yes, but is it the right ACK?
  8540.      ret            ;   No, don't settle, hold out for right one.
  8541.     setzm rcving        ; Indicate we're sending a file.
  8542.     aos rcving        ;  ...
  8543.     setzm numtry        ; Yes, reset the number of tries.
  8544.     aos t2, pktnum        ; Increment the packet number,
  8545.     andi t2, 77        ; modulo 100,
  8546.     movem t2, pktnum    ; and save it.
  8547.     skipn xflg        ;[126] Don't log if not sending a real file.
  8548.      jrst [    skipn t1, tlgjfn ;[126] Logging transactions?
  8549.          jrst .+1
  8550.         hrroi t2, [asciz/   Sending As "/] ; Yes, log this.
  8551.         setzb t3, t4
  8552.         SOUT
  8553.         hrroi t2, filbuf
  8554.         SOUT
  8555.         hrroi t2, [asciz/"
  8556. /]
  8557.         SOUT
  8558.         jrst sfil3a ]
  8559.     jrst sfil3a        ;[52] Join common code.
  8560.  
  8561. ; Check for & handle NAKs.
  8562.  
  8563. sfile3:    caie t1, "N"        ; NAK?
  8564.      jrst sfile4        ;  No.
  8565.  
  8566.     aos nnak        ;[54] Yes, count it.
  8567.     move t1, pktnum        ;[51] Get the expected packet number.
  8568.     aos t1            ;[51] Figure out what the next one would be,
  8569.     andi t1, 77        ;[51] mod 64.
  8570.     caie t1, (t2)        ;[51] Is the NAK for the next packet?
  8571.      ret            ;  No, so must send this packet again.
  8572.     setzm numtry        ; Yes, for next, same as ACK for this.
  8573.     movem t1, pktnum    ; Save incremented packet number.
  8574.     ;...
  8575.  
  8576. ; SFILE, cont'd
  8577.  
  8578.  
  8579. ;[75] Check for ITS binary format file.
  8580.  
  8581. sfil3a:    setzm itsfil        ; Assume this isn't an ITS file.
  8582.     skipn source        ; Skip this if it's not really a file.
  8583.      skipn itsflg        ; Looking for ITS files?
  8584.      jrst sfil3b        ;  No.
  8585.     setz t2,        ; Yes, do a 36-bit BIN.
  8586.     skiple t1, filjfn    ; ...
  8587.      BIN            ; ...
  8588.      erjmp sfil3b        ;  If there's some error, catch it later.
  8589.     came t2, [sixbit/DSK8/] ; Is it an ITS binary file?
  8590.      jrst sfil3b        ; No, then handle normally.
  8591.     setom itsfil        ; Yes, flag this file as ITS.
  8592.     hrroi t1, [asciz/(ITS binary format) /]
  8593.     skipe local        ; Say what happened if local.
  8594.      PSOUT
  8595.         
  8596. ; Get first chunk of data.
  8597.  
  8598. sfil3b:    setzm mapflg        ;[52] Say no pages mapped in yet.
  8599.     setzm eoflag        ;[72] Not EOF yet.
  8600.     setom next        ;[63] Initialize input character lookahead.
  8601.     move t1, maxdat        ;[63] Maximum length for data field.
  8602.     setz schr,        ;[128] Init number of file characters sent.
  8603.     call getbuf        ;[63] Fill the first data packet.
  8604.      jrst [    movem t1, cxseen ;[70] If error, send "discard" in EOF message.
  8605.         movei state, "Z" ; Get into EOF state.
  8606.         ret ]
  8607.     movei state, "D"    ; Got data, set the state to file send.
  8608.     movem t1, size        ; Save the length of the data.
  8609.     ret            ; Back to state switcher.
  8610.  
  8611. ; Catch-all for other states.
  8612.  
  8613. sfile4:    cain t1, "T"        ; Timer interrupt pseudo packet?
  8614.      ret            ; Yes, return without changing state.
  8615.     cain t1, "E"        ;[80] Error packet?
  8616.      call pxerr        ;[82] If so, print remote error message.
  8617.     movei state, "A"    ; Cancel the transaction.
  8618.     skiple t1, filjfn    ;[80] Close the file.
  8619.      CLOSF            ;[80]
  8620.      erjmp .+1        ;[80]
  8621.     setzm filjfn        ;[80]
  8622.     ret
  8623.  
  8624. ; GETCH replacement routine for getting characters from a filename string.
  8625. ; Uses global FILPTR for input string, FILDOT for counting dots in filename.
  8626. ; Strips any ^V used as a quote, and if requested converts name to normal form.
  8627. ;
  8628. ; Returns:
  8629. ;   +1 never (no reason to fail).
  8630. ;   +2 always, with NEXT containing next character, -1 if no more.
  8631. ;
  8632. gtfch:    ildb t1, filptr        ;[102] Get next character.
  8633.     jumpe t1, gtfchz    ;[102] If zero, must be done.
  8634.     cain t1, 26        ;[84]  Control-V?
  8635.      ildb t1, filptr    ;[102]  Yes, it's just a prefix, get next char.
  8636.     skipn xfnflg        ;[101] Converting to normal form?
  8637.      jrst gtfchx        ;[101] No, skip other conversions.
  8638.     cain t1, "."        ;[84]  Yes, is this a period?
  8639.      jrst [ aose fildot    ;[84]  Yes, don't put more than one.
  8640.          movei t1, "X"    ;[84]  Substitute "X" for any extra dots.
  8641.         jrst gtfchx ]    ;[84]  ...
  8642.  
  8643. gtfchy:    move t1, xfntab(t1)    ;[84] Translate it.
  8644.  
  8645. ; Return with character like GETCH.
  8646.  
  8647. gtfchx:    movem t1, next        ;[102] Put result in NEXT, as GETCH does.
  8648.     retskp            ;[102] Done.
  8649.  
  8650. ; "EOF" return, like GETCH
  8651.  
  8652. gtfchz:    setz t1,
  8653.     setom next
  8654.     ret
  8655.  
  8656. ; SDATA - Send a data packet.
  8657.  
  8658. sdata:    skipn cxseen        ;[59] Control-X typed?
  8659.      skipe czseen        ;[59] Or Control-Z?
  8660.      jrst [    call unmapi    ;[59] Yes, must unmap current input file page.
  8661.          nop        ;[59] Ignore any errors.
  8662.         movei state, "Z" ;[59] Get into EOF state.
  8663.         ret ]        ;[59] Back to state switcher.
  8664.  
  8665.     saveac <q1>        ; ^X/^Z not typed, normal case.
  8666. sdatab:    move q1, numtry        ; Get the number of tries.
  8667.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  8668.      jrst [ movei state, "A" ;  Change the state to cAncel.
  8669.         ermsg <Too many retries>, r ]
  8670.     aos numtry        ; Increment number of tries.
  8671.     movei t1, "D"        ; File send packet.
  8672.     move t2, pktnum        ; Packet number.
  8673.     move t3, size        ; Get the data length.
  8674.     move t4, [point 8, data] ; Get a pointer to our data block.
  8675.     call spack        ; Send the data packet.
  8676.      jrst @[exp sdatab,sdatax](t1) ; Handle errors.
  8677.     call rpack        ; Get a packet.
  8678.      ret            ;  Trashed packet, don't change state, retry.
  8679.  
  8680. sdatay:    caie t1, "Y"        ; Got one, check the type.  Is it ACK?
  8681.      jrst sdatan        ;  No, go check for NAK.
  8682.     came t2, pktnum        ; Yes, but is it the right ACK?
  8683.      ret            ;  No, don't settle, hold out for right one.
  8684.     soje t3, [        ;[62] Any data (interested in one & only char)?
  8685.         ildb t3, t4    ;[62] Yes, what?
  8686.         cain t3, "X"    ;[62] Is it an "X"?
  8687.          jrst [    setom cxseen ;[140] Yes, set the C-X flag.
  8688.             move t3, source    ;[140] What's the source of our data?
  8689.             cain t3, dirch ;[140] A directory listing?
  8690.              setom czseen ;[140] If so, set C-Z flag, too.
  8691.             jrst sdaty2 ] ;[140]
  8692.         cain t3, "Z"    ;[62] Is it an "Z"?
  8693.          setom czseen    ;[62]  Yes, pretend ^Z was typed...
  8694.         jrst .+1 ]    ;[62] Go thru one more time, then out.
  8695.  
  8696. sdaty2:    setzm numtry        ; Correct normal packet, reset retry counter.
  8697.     aos t2          ;[51] Increment the packet number,
  8698.     andi t2, 77        ; modulo 100,
  8699.     movem t2, pktnum    ; and remember it.
  8700.     jrst sdata2        ;[52] Go get some more data to send.
  8701.  
  8702. sdatan:    cain t1, "N"        ; NAK?
  8703.      jrst [    move t1, pktnum    ;[51] Yes, get the expected packet number.
  8704.         aos nnak    ;[54] Count the NAK.
  8705.         aos t1        ;[51] Figure out what the next one would be,
  8706.         andi t1, 77    ;[51] mod 64.
  8707.         caie t1, (t2)    ;[51] Is the NAK for the next packet?
  8708.          ret        ;  No, then must send current one again.
  8709.         setzm numtry    ; Yes, a NAK for n+1(mod 64) = ACK for n,
  8710.         movem t1, pktnum ; so play like we got an ACK,
  8711.         jrst sdata2 ]    ;[52] and go get next packetful of data.
  8712.  
  8713.     ;...
  8714.  
  8715. ;...SDATA, cont'd
  8716.  
  8717.  
  8718. ; Handle timeout or unexpected packet types.
  8719.  
  8720. sdatat:    cain t1, "T"        ; Timer interrupt pseudo packet?
  8721.      ret
  8722.     cain t1, "E"        ;[82] Error packet?
  8723.      jrst pxerr        ;[82]  Yes, print it & cancel.
  8724. sdatax:    movei state, "A"    ; Anything else, just cancel..
  8725.     ret
  8726.  
  8727.  
  8728. ; Fill up the next buffer of data.
  8729.  
  8730. sdata2:    move t1, maxdat        ;[63] Length to work with.
  8731.     call getbuf        ;[63] Try to get next bufferful.
  8732.      jrst [    movem t1, cxseen ;[70] If error, tell other side to discard.
  8733.         movei state, "Z" ; Set state to EOF.
  8734.         ret ]        ;  Go back to state switcher.
  8735.     movem t1, size        ; Got more data, save length, and
  8736.     ret            ; return, remaining in state "D".
  8737.  
  8738. ; SEOF - Send End Of File packet.
  8739.  
  8740.  
  8741. seof:    move t1, numtry        ; No ^X/^Z, get the number of tries.
  8742.     caml t1, maxtry        ; Have we reached the maximum number of tries?
  8743.      jrst [    movei state, "A" ;  Change the state to cAncel.
  8744.         ermsg <Can't send EOF>, r ]
  8745.     aos numtry        ; Still within our limit, bump retry count.
  8746.     movei t1, "Z"        ; Send a Z (EOF) packet.
  8747.     move t2, pktnum        ; Packet number.
  8748.     skipn cxseen        ;[59] Are we discarding this file?
  8749.      skipe czseen        ;[59]
  8750.      jrst [    move t3, [point 8, data] ;[59] Yes,
  8751.         movei t4, "D"    ;[59] put a "D" for Discard in data field
  8752.         idpb t4, t3    ;[59] ...
  8753.         movei t3, 1    ;[59] Say the data length is 1
  8754.         move t4, [point 8, data] ;[59] point to it again...
  8755.         jrst .+2 ]    ;[59] Skip next instruction!
  8756.      setzb t3, t4        ; Normal case -- no data field.
  8757.     call spack        ; Send the packet.
  8758.      jrst @[exp seof, seofx](t1) ; Handle any errors.
  8759.     call rpack        ; Get a packet.
  8760.      ret            ;  Trashed packet, don't change state, retry.
  8761.  
  8762. ; Got a response.  Check for ACK and handle it.
  8763.  
  8764.     caie t1, "Y"        ;[52] Check the packet type.  Is it an ACK?
  8765.      jrst seof2        ;[52]  No...
  8766.     came t2, pktnum        ; Yes but, is it the right ACK?
  8767.      ret            ;  No, don't settle, hold out for right one.
  8768.     aos t2, pktnum        ; Increment the packet number,
  8769.     andi t2, 77        ; mod 100,
  8770.     movem t2, pktnum    ; and save it.
  8771.     jrst seof4        ;[52] Join common code.
  8772.  
  8773. ; Check for NAK and handle it.
  8774.  
  8775. seof2:    caie t1, "N"        ; NAK?
  8776.      jrst seof3        ;  No.
  8777.     aos nnak        ;[54] Yes, count it.
  8778.     move t1, pktnum        ;[51] What packet were we looking for?
  8779.     aos t1            ;[51] Is the NAK for the next packet?
  8780.     andi t1, 77        ;[51] (mod 64)
  8781.     caie t1, (t2)        ;[51]
  8782.      ret            ;  No, then must send this one again.
  8783.     movem t1, pktnum    ; Yes, behave like it was an ACK for this one.
  8784.     jrst seof4        ;[52] Join common code.
  8785.  
  8786. ; SEOF, cont'd
  8787.  
  8788.  
  8789. ; Check for other types & handle.
  8790.  
  8791. seof3:    cain t1, "T"        ; Timer interrupt pseudo-packet?
  8792.      ret            ; If so, just keep going.
  8793.     cain t1, "E"        ;[80] Error packet?
  8794.      call pxerr        ;[82] If so, print it.
  8795.     skiple t1, filjfn    ;[80] Close the file.    
  8796.      CLOSF            ;[80]
  8797.      erjmp .+1        ;[80]
  8798.     setzm filjfn        ;[80]
  8799. seofx:    movei state, "A"    ; Otherwise cancel.
  8800.     ret
  8801.  
  8802. ; EOF packet was ACK'd OK, close the file, get the next one (if any).
  8803.  
  8804. seof4:    skipn xflg        ;[126] Sending a real file?
  8805.      jrst [    skipn t1, tlgjfn ;[126] Transaction log?
  8806.          jrst .+1
  8807.         hrroi t2, [asciz/   Sent: /] ; Yes, log this info.
  8808.         setzb t3, t4
  8809.         SOUT
  8810.         move t2, schr    ; Number of bytes.
  8811.         movei t3, ^d10
  8812.         NOUT
  8813.          nop
  8814.         movei t2, 40    ; A space
  8815.         BOUT
  8816.         movei t2, 7    ; Bytesize
  8817.         skipe ebtflg
  8818.          aos t2
  8819.         NOUT
  8820.          nop
  8821.         hrroi t2, [asciz/-bit bytes
  8822. /]
  8823.         setzb t3, t4
  8824.         SOUT
  8825.         jrst .+1 ]
  8826.  
  8827.     setzm numtry        ;[52] Reset the retry counter.
  8828.     addm schr, stchr    ; Add the last file's size to the total.
  8829.     setz schr,        ; Zero the present count.
  8830.     aos files        ;[61] Count the file.
  8831.     skipn source        ;[128] Sending a file?
  8832.      jrst [    skipg t1, filjfn ;[128] Yes, get the JFN of the file just sent.
  8833.          jrst .+1    ;[128]  If no valid JFN, don't bother closing.
  8834.         txo t1, co%nrj    ; Don't release it, GNJFN still needs it.
  8835.         CLOSF%        ; Close the file.
  8836.          %jserr (,.+1)    ;[59] Print msg but continue if error.
  8837.         jrst .+1 ]    ;[121]
  8838.     ;...
  8839.  
  8840. ;...SEOF, cont'd
  8841.  
  8842.  
  8843. ; Messages to screen and transaction log.
  8844.  
  8845.     skiple filjfn        ;[127] Transaction log stuff.
  8846.      skipe xflg        ;[126]  Don't bother if not a real file.
  8847.      skipa            ;[126]
  8848.      wtlog <Closed >,filjfn    ;[126]
  8849.     hrroi t1, [asciz/[OK]/]    ; Normal comforting message.
  8850.     skipe cxseen        ; But was sending interrupted this way?
  8851.      hrroi t1, [asciz/[interrupted]/] ; Yes, say so.
  8852.     skipe czseen        ; Or this way?
  8853.      hrroi t1, [asciz/[group interrupted]/] ; Yes, say so.
  8854.     move t4, t1        ; Keep for log.
  8855.     skipe local        ; Local use?
  8856.      PSOUT            ; Yes, print selected message.
  8857.     skipe t1, tlgjfn    ;[126] If we have a transaction log, there too.
  8858.      jrst [    move t2, t4
  8859.         setz t3,
  8860.         skipn cxseen
  8861.          skipe czseen
  8862.         SOUT        
  8863.         jrst .+1 ]
  8864.  
  8865. seof5:    skipn source        ;[121] Really doing files?
  8866.      call gtnfil        ; If so, get the next file to send.
  8867.      jrst [    setzm filjfn    ;  If not, or if no more, zero the JFN,
  8868.         movei state, "B" ; set state to complete,
  8869.         ret ]        ;[59]  and return to state switcher.
  8870.     movei state, "F"    ; OK, switch to File-send state.
  8871.     ret
  8872.  
  8873. ; SEOT -- Send End Of Transmission packet.
  8874.  
  8875.  
  8876. seot:    saveac <q1>
  8877. seotb:    move q1, numtry        ; Get the number of tries.
  8878.     caml q1, maxtry        ; Have we reached the maximum number of tries?
  8879.      jrst [    movei state, "A" ;  Change the state to cAncel.
  8880.         ermsg <Can't send EOT>, r ]
  8881.     aos numtry        ; Increment number of tries.
  8882.     movei t1, "B"        ; Packet type is Break (EOT).
  8883.     move t2, pktnum        ; Packet number.
  8884.     setzb t3, t4        ; No data.
  8885.     call spack        ; Send the packet.
  8886.      jrst @[exp seotb, seotx](t1) ; Handle any errors.
  8887.     call rpack        ; Get a packet.
  8888.      ret            ;  Trashed packet don't change state, retry.
  8889.     cain t1, "Y"        ; Check the packet.
  8890.      jrst [    came t2, pktnum    ;  Is it the right ACK?
  8891.          ret        ;   No, don't settle, hold out for right one.
  8892.         setzm numtry    ;  Reset the number of tries.
  8893.         aos t2, pktnum    ; Increment packet number
  8894.         andi t2, 77    ; mod 100
  8895.         movem t2, pktnum ; save it back.
  8896.         movei state, "C" ;  Complete state.
  8897.         skipn xflg    ;[126] Put message in transaction log,
  8898.          wtlog <Send Complete> ;[126] if it was a real file transfer.
  8899.         ret ]
  8900.     cain t1, "N"        ; NAK?
  8901.      jrst [    aos nnak    ;[54] Yes, count the NAK.
  8902.         move t1, pktnum    ;[51] Is the NAK for the next packet?
  8903.         aos t1        ;[51]
  8904.         andi t1, 77    ;[51]
  8905.         caie t1, (t2)    ;[51]
  8906.          ret        ;  No, must send current one again.
  8907.         movem t1, pktnum ; Yes, behave like it was an ACK for this one.
  8908.         setzm numtry    ; Reset the number of tries.
  8909.         movei state, "C" ; Complete state.
  8910.         ret ]
  8911.     cain t1, "T"        ; Timer interrupt pseudo packet?
  8912.      ret
  8913.     cain t1, "E"        ;[82] Error packet?
  8914.      jrst pxerr        ;[82]  Yes, print it & cancel.
  8915. seotx:    movei state, "A"    ; Otherwise cancel.
  8916.     ret
  8917.  
  8918. ;[63] Rewrite file routines.
  8919. ;
  8920. ; GETBUF - Get buffer (i.e. packet) full of characters from input file.
  8921. ;
  8922. ; Call with
  8923. ;  AC1/ desired number of characters to get (i.e. data buffer size)
  8924. ; Returns:
  8925. ;  +1, failure, with AC1/ 0 if end of input file, or nonzero if other error.
  8926. ;  +2, success, with AC1/ number of characters actually gotten, and
  8927. ;      the result accessible by [point 8, data].
  8928. ;
  8929. getbuf:    saveac<q1,q2,q3,q4>
  8930.  
  8931.     skipg t1         ; Make sure the number is not 0 or negative.
  8932.      ret            ;  This gives the right return code.
  8933.     caile t1, ^d9000    ; Make sure the number is not too big.
  8934.      movei t1, ^d9000
  8935.     move q4, t1        ; Maximum number of characters to return.
  8936.     setz q2,        ; Counter for actual characters returned.
  8937.     move q3, [point 8, data] ; Where to put the result.
  8938.     setzm rpt        ;[126] Clear leftover repeat counts from last.
  8939.  
  8940. getbfa:    skipge next        ; First time through, get first character.
  8941.      jrst [    call getch
  8942.          jumpn t1, r    ;[64] Pass along any failure
  8943.         setz t1,    ; Since GETCH puts the character it got in NEXT
  8944.         exch t1, next    ; it has to be moved to CH, just this once.
  8945.         movem t1, ch
  8946.         jrst .+1 ]
  8947.     
  8948. getbfb:    skipl ch        ; Do we have one?  If not, must be EOF.
  8949.      caml q2, q4        ; Or buffer full?
  8950.      jrst getbfx        ; If so, return it.
  8951.  
  8952. ; Get next character for lookahead.
  8953.  
  8954. getbfc:    call getch        ; Get next one.
  8955.      jumpn t1, r        ;[64] Pass along any failure
  8956.     call encode        ; Go do any prefixing.
  8957.     skipge t1, next        ; Set up for next time through.
  8958.      jrst getbfx        ;  If no next, we're done.
  8959.     movem t1, ch        ; Otherwise next is now current.
  8960.     jrst getbfa        ; Loop till done.
  8961.  
  8962. ; Return the buffer.
  8963.  
  8964. getbfx:    skipg t1, q2        ; Return length of data
  8965.     ret            ; +1 if 0 (= EOF)
  8966.     retskp            ; +2 if greater than zero.
  8967.  
  8968. ;[63] This routine added as part of edit 63.
  8969. ;
  8970. ; ENCODE - Process a character -- do any prefixing, etc, necessary to
  8971. ; insert the character into a data packet.
  8972. ;
  8973. ; Call with character in global CH, global RPTFLG and EBQFLG indicating
  8974. ; whether repeat and 8th-bit prefixing are to be done.
  8975. ;
  8976. ; Returns:
  8977. ;  +1 always, with CH unmodified, q2/ updated packet length.
  8978. ;  Uses t2-t4.
  8979. ;
  8980. encode:    move t4, ch        ; Get current character.
  8981.     skipn rptflg        ; Doing repeat count prefixing?
  8982.      jrst enco8        ;  No, skip to next part.
  8983.  
  8984. ; Repeat count processing.  Check if this character same as next.
  8985.  
  8986. encor:    camn t4, next        ; Same as next one?
  8987.      jrst [    aos t2, rpt    ; Yes, just count it.
  8988.         caige t2, ^d94    ; Count within bounds?
  8989.          ret        ;  Yes, done.
  8990.         sos t2        ;[93] No, adjust as though next char different.
  8991.         jrst encor4 ]    ; Go emit a repeat sequence for this much.
  8992.  
  8993. ; Different, see if there were any repeats.
  8994.  
  8995. encor2:    skipg t2, rpt        ; CH not same as next.  Any repeats?
  8996.      jrst enco8        ; No, on to next part.
  8997.     caige q2, (q4)        ;[93] Yes, near end of buffer?
  8998.      cain t2, 1        ; Or only repeated once?
  8999.      jrst [    setzm rpt    ;[144] Set all the repeat count back to zero.
  9000.         call enco8    ;[144] Call self, skipping around this part,
  9001.         move t4, ch    ;[144] and again.
  9002.         call enco8    ;[144]
  9003.         ret ]        ;[93] and return.
  9004.  
  9005. ; Repeated more than once -- general case.
  9006.  
  9007. encor4:    move t3, rptq        ; Emit a repeat sequence --
  9008.     idpb t3, q3        ; the repeat prefix character,
  9009.     addi t2, <40+1>        ;[93] followed by 'tochar(count+1)'
  9010.     idpb t2, q3        ;  because if it's repeated 1x there are 2...
  9011.     addi q2, 2        ; Account for these prefix characters.
  9012.     setzb t2, rpt        ; Clear repeat count.
  9013.  
  9014.     ;...
  9015.  
  9016. ;...ENCODE, cont'd
  9017.  
  9018.  
  9019. ; 8th-bit prefixing.
  9020.  
  9021. enco8:    setz t2,        ; Bit-8 flag.
  9022.     trzn t4, 200        ; Test & clear parity bit.
  9023.      jrst encoc        ;  Not set, on to next part.
  9024.     seto t2,        ; Remember it was on.
  9025.     skipn ebqflg        ; Doing 8th-bit quoting?
  9026.      jrst encoc        ;  No, so skip this.
  9027.     move t3, ebq        ; Yes, stick in an 8th-bit prefix.
  9028.     idpb t3, q3    
  9029.     aos q2            ; Count it.
  9030.  
  9031. ; Control prefixing.
  9032.  
  9033. encoc:    cail t4, 40        ; Control character
  9034.      cain t4, .chdel    ; or DEL?
  9035.      jrst [ xori t4, 100    ; Yes, convert to printable
  9036.         jrst encoc4 ]    ; and go insert a control prefix.
  9037.  
  9038. ; Prefix prefixing.
  9039.  
  9040. encoc1:    camn t4, squote        ; Control Prefix?
  9041.      jrst encoc4        ;  Yes.
  9042.  
  9043. encoc2:    skipn rptflg        ; Repeat processing?
  9044.      jrst encoc3        ;  No.
  9045.     camn t4, rptq        ; Yes, is the character the repeat prefix?
  9046.      jrst encoc4        ;  Yes, insert a control prefix before it.
  9047.  
  9048. encoc3:    skipe ebqflg        ; Eighth-bit prefixing?
  9049.     came t4, ebq        ; Is the character the 8th-bit prefix?
  9050.      jrst encocx
  9051.  
  9052. encoc4:    move t3, squote        ; Insert a control prefix.
  9053.     idpb t3, q3
  9054.     aos q2            ; Count it.
  9055.  
  9056. ; Now, finally, insert the character itself.
  9057.  
  9058. encocx:    skipe t2        ; Was 8th bit on originally?
  9059.      skipe ebqflg        ;[109] Yes, but did we quote it already?
  9060.      skipa            ;[109] In that case, don't put it back.
  9061.      tro t4, 200        ;  It was on & wasn't quoted so put it back.
  9062.     idpb t4, q3        ; Deposit it.
  9063.     aos q2            ; Count it.
  9064.  
  9065.     ret
  9066.  
  9067.     subttl File routines
  9068.  
  9069. ;[63] This routine added as part of edit 63.
  9070. ;
  9071. ; GETCH - Get a character from the disk file.
  9072. ; If global SOURCE is nonzero, it is assumed to contain an address of a
  9073. ; routine to be used instead of this one.
  9074. ;
  9075. ; Returns:
  9076. ;  +1 on failure, with t1/0 if EOF, t1/-1 if real error getting character.
  9077. ;  +2 on success, with global NEXT containing the character, -1 if EOF.
  9078. ;
  9079. getch:    skipe t1, source    ;[102] Alternate routine to call?
  9080.      jrst (t1)        ;[102]  Yes, go there instead.
  9081.     saveac <q1,q2,q3>    ; Save permanent ACs.
  9082.     skipe eoflag        ; Is the end of file flag set?
  9083.      jrst [    setzm eoflag    ; Yes, reset EOF flag for next time,
  9084.         jrst getchz ]    ;  and return EOF.
  9085.     skipe mapflg        ; Do we have anything mapped in?
  9086.      jrst getch3        ;  Yes, don't have to do mapping.
  9087.  
  9088. getch1:    move t1, filjfn        ; No, must do mapping, here's the JFN.
  9089.     movx t2, <2,,.fbbyv>    ; Get number of pages and bytes
  9090.     movei t3, pagcnt    ;  into pagcnt and bytcnt,
  9091.     GTFDB%            ;  from the file descriptor block.
  9092.      %jsker <Can't get file length>,getchx ; Return error.
  9093.     skipn bytcnt        ; Any bytes in the file?
  9094.      jrst [    setom eoflag    ;  No, set end-of-file flag.
  9095.         jrst getchz ]    ;  And return EOF.
  9096.     ldb t2, [point 6, pagcnt, 11] ; Get the file byte size.
  9097.     movem t2, bytsiz    ; Save it.
  9098.  
  9099. ; 7- or 8-bit input from the file?  First, check for ITS binary format.
  9100.  
  9101.     skipe itsfil        ;[75] ITS binary format file?
  9102.      jrst getcha        ;[75] Yes, then skip "autobyte" stuff.
  9103.  
  9104. ; Next, if doing "autobyte", use the file byte size.
  9105.  
  9106.     skipe autbyt        ;[81] Are we using autobyte?
  9107.      jrst [    setzm ebtflg    ; Yes, assume seven-bit bytes.
  9108.         cain t2, ^d8    ; Really 8-bit?
  9109.          setom ebtflg    ;  Yes, act like user requested 8-bit.
  9110.         jrst .+1 ]
  9111.  
  9112. ; Now, if we're to do 8-bit input, convert the byte count if necessary.
  9113.  
  9114. getcha:    skipn itsfil        ; ITS binary file?
  9115.      skipe ebtflg        ; Or eight bit mode?
  9116.      jrst [    cain t2, ^d8    ; Yes, is the byte size 8?
  9117.           jrst getchb    ;[170] If so go adjust byte count if necessary.
  9118.         movei t3, ^d36    ; Get the size of a word.
  9119.         idiv t3, t2    ; Divide by the byte size.
  9120.         move q1, bytcnt    ; Get the number of bytes in file.
  9121.         idiv q1, t3    ; Divide by the bytes/word to get words.
  9122.         imuli q1, 4    ; Multiply by 4 (as if 8-bit bytes).
  9123.         movem q1, bytcnt ; Save the new byte count.
  9124.         jrst getchb ]    ;[170] Go adjust byte count.
  9125.     ;...
  9126.  
  9127. ;...GETCH, cont'd
  9128.  
  9129. ; Or, if we're to do 7-bit input, fix the byte count for that.
  9130.  
  9131.     caie t2, 7        ; If the bytesize is not 7 or 8, treat as 7.
  9132.      cain t2, ^d8        ;[170] (don't do this to 8-bit files!
  9133.      skipa            ;[170]  ...)
  9134.      jrst [    movei t3, ^d36    ; Must convert, get the size of a word.
  9135.         idiv t3, t2    ; Divide by the byte size.
  9136.         move q1, bytcnt    ; Get the number of bytes in file.
  9137.         idiv q1, t3    ; Divide by the bytes/word to get words.
  9138.         imuli q1, 5    ; Multiply by 5 (as if 7bit bytes).
  9139.         movem q1, bytcnt ; Save the new byte count.
  9140.         jrst getch2 ]    ; Go map in page.
  9141.  
  9142. getchb:    skipn itsfil        ;[86][170] ITS binary file?
  9143.      jrst getch2        ;[86]  No, proceed.
  9144.     move q1, bytcnt        ;[86] Yes, get byte count.
  9145.     subi q1, 4        ;[86] Subtract 4 to account for header.
  9146.     movem q1, bytcnt    ;[86] Save it back.
  9147.  
  9148. ; Byte size figured out, now map in the first page.
  9149.  
  9150. getch2:    hrlzs t1        ; Form file JFN,, page 0
  9151.     hrlm t1, pagcnt        ; Zero the left half of pagcnt.
  9152.     call mapi        ; Map it in.
  9153.      jrst getchx        ;  Pass along any failure.
  9154.     skipe itsfil        ;[75] ITS binary file?
  9155.      aos pagptr        ;[75] Yes, skip first word of it.
  9156.     setzm pagno        ; Present page is zero.
  9157.     setom mapflg        ; Say we've got a page mapped in.
  9158.  
  9159. ; Come here if/when/after page is mapped in...
  9160.  
  9161. getch3:    caml schr, bytcnt    ; Any more bytes in file?
  9162.      jrst [    setom eoflag    ; No, Set the end of file flag.
  9163.         call unmapi    ; Unmap the input file page.
  9164.          ret        ;  Fail if we can't
  9165.         setzm mapflg    ; Say nothing mapped in.
  9166.         jrst getchz ]    ; Return EOF.
  9167.  
  9168.     ildb t2, pagptr        ; There are more; get the next one.
  9169.      erjmp getch%        ;[70] (illegal memory read, hole in file...)
  9170.     aos schr        ;[64] Got it OK, count it.
  9171.     ;...
  9172.  
  9173. ;...GETCH, cont'd
  9174.  
  9175. getch4:    hrrz t1, pagptr        ; Are we at the end of the page yet?
  9176.     caige t1, <mappag+1>*1000 ;[64]...
  9177.      jrst getch5        ; No, go return the character.
  9178.     call unmapi        ; Yes, unmap the input page.
  9179.      jrst getchx        ;  Pass along any failure.
  9180.     move t1, pagno        ; Get the present page number.
  9181.     aos t1            ; Increment it.
  9182.     caml t1, pagcnt        ; Any more pages?
  9183.      jrst [    setom eoflag    ; No, set the end of file flag for next time.
  9184.         setzm mapflg    ; Say nothing mapped in,
  9185.         jrst getch6 ]    ; and return normally with the char we got.
  9186.     movem t1, pagno        ; Save the new number.
  9187.     hrl t1, filjfn        ;  <file JFN,, page 0>
  9188.     call mapi        ; Map in the page.
  9189.      jrst getchx        ;  Pass along any failure.
  9190.     ildb t2, pagptr        ; Get the next character.
  9191.      erjmp getch%        ;[70] (Illegal memory read, hole in file...)
  9192.  
  9193. ; Got the character in t2.  Worry about bit 35 if doing 7-bit i/o.  The trick
  9194. ; is to set the parity bit ("b8") of every 5th character to the value of b35
  9195. ; of the PDP-10 word it came from.  The same trick is used by TOPS-20 when
  9196. ; writing ANSI-ASCII tapes.  This allows DEC-10/20 .EXE and other 36-bit binary
  9197. ; files, and SOS-line numbered files, to be sent to 8-bit systems and retrieved
  9198. ; intact.  No adverse effects are suffered by ordinary text files.
  9199.  
  9200. getch5:    move q1, schr        ;[64] Count the character.
  9201.     skipn itsfil        ;[75] ITS binary file?
  9202.      skipe ebtflg        ; Eight bit mode?
  9203.      jrst getch6        ;  One of those, no need to do this.
  9204.                 ;
  9205.     idivi q1, 5        ; No, 7-bit, divide character number by 5.
  9206.     skipn q2        ; Last character of word if remainder is 0.
  9207.      jrst [    move q1, pagptr ;  In that case, get the entire contents.
  9208.         move q1, (q1)    ;
  9209.         trne q1, 1    ; Bit 35 on?
  9210.          tro t2, 200    ; Yes, turn on bit 8 of this character.
  9211.         jrst .+1 ]
  9212.  
  9213. getch6:    movem t2, next        ; Return the character.
  9214.     retskp
  9215.  
  9216. ; EOF return.
  9217.  
  9218. getchz:    setz t1,        ; Return zero error code,
  9219.     setom next        ; and character -1.
  9220.     ret
  9221.     ;...
  9222.  
  9223. ;...GETCH, cont'd
  9224.  
  9225.  
  9226. ; Error return.
  9227.  
  9228. getch%:    skipe local        ;[70]
  9229.      ermsg <Illegal memory read> ;[70]
  9230.  
  9231. getchx:    setob t1, next        ; Return -1 error code, and character -1.
  9232.     movx t2, <.fhslf,,mappag> ;[70] Unmap any page that's still mapped in.    
  9233.     setz t3,        ;[70]
  9234.     PMAP%            ;[70]
  9235.      erjmp .+1        ;[70] Ignore errors.
  9236.     setzm mapflg        ;[70]
  9237.     ret
  9238.  
  9239.  
  9240. ; MAPI - Map in file page.
  9241. ;
  9242. ; Call with
  9243. ;  t1/ jfn,,page number.
  9244. ;
  9245. ; Returns
  9246. ;  +1 on failure.
  9247. ;  +2 on success, with PAGPTR adjusted to point back to beginning of page.
  9248. ;
  9249. mapi:    movx t2, <.fhslf,,mappag> ; Form our fork,,mapping page
  9250.     movx t3, pm%rd        ; Just want to read it.
  9251.     PMAP%            ; Map it in.
  9252.      %jsker <Can't map in file page>,r ;  Error, fail.
  9253.     move t3, [point 7, mappag*1000]    ; Success, get a pointer to the page.
  9254.     skipn itsfil        ;[75] An ITS binary file?
  9255.      skipe ebtflg        ; Or eight bit access?
  9256.      hrli t3, (point 8,)    ; Yes, then use 8-bit pointer.
  9257.     movem t3, pagptr
  9258.     retskp            ; Return successfully.
  9259.  
  9260.  
  9261. ; UNMAPI -- Unmap an input file page.
  9262. ;
  9263. ; Returns +1 on error, +2 on success.
  9264.  
  9265.  
  9266. ; First check to see where we're getting our input from.
  9267. ;
  9268. unmapi:    skipn t1, source    ;[139] But are we really reading from a file?
  9269.      jrst unmap3        ;[139]  Yes, really unmap.
  9270.     caie t1, dirch        ;[139] No, is it a directory listing?
  9271.      jrst unmap2        ;[139] No, something else.
  9272.  
  9273. ; From a directory listing buffer.  Clear it & reset pointers for next time.
  9274.  
  9275.     call dmpbuf        ;[139] Yes, directory listing; clear buffer.
  9276.     setzm source        ;[139] Indicate no more alternate source.
  9277.     ret            ;[139] Done.
  9278.  
  9279. ; From some other source (add others here).
  9280.  
  9281. unmap2:    ret
  9282.  
  9283. ; Source is really a file, unmap the current file page.
  9284.  
  9285. unmap3:    seto t1,        ; Indicate unmap.
  9286.     movx t2, <.fhslf,,mappag> ; This process.
  9287.     setz t3,
  9288.     PMAP%            ; Unmap the page.
  9289.      %jsker <Error unmapping page>,r
  9290.     retskp
  9291.  
  9292. ;[66] PUTBUF -- Write the contents of the data field of a packet out to a file.
  9293. ;
  9294. ; Call with:
  9295. ;  t1/ pointer to data buffer.
  9296. ;  t2/ number of characters.
  9297. ;  pagptr/ output file page byte pointer.
  9298. ; Returns:
  9299. ;  +1: Failure, Couldn't write the whole buffer, Error packet already sent.
  9300. ;  +2: Success
  9301. ;
  9302. putbuf:    saveac <q1,q2>        ; Preserve these ACs.
  9303.     dmove q1, t1        ; Save the arguments.
  9304.  
  9305. putbf2:    jumple q2, rskp        ; Are we done?
  9306.     ildb t2, q1        ; Not yet, get the next character from the pkt.
  9307.     call decode        ; Go decode and store it.
  9308.      ret            ;  Pass along any error.
  9309.     cain rchr, 4        ;[75] Just finished 4th character?
  9310.      call itschk        ;[75]  Yes, see if it was the ITS binary hdr.
  9311.     soja q2, putbf2        ; Loop.
  9312.  
  9313.  
  9314. ;[75] ITSCHK -- See if first 4 bytes of file are ITS binary file header.
  9315. ;
  9316. ; Uses t1-t3.
  9317. ; Returns +1 always, with ITSFIL set if the first 4 bytes are the ITS binary
  9318. ;  file header, sixbit/DSK8/, and with the various pointers and counters
  9319. ;  adjusted appropriately.  By the way, since this routine sets RCHR back to
  9320. ;  zero, it gets called again 4 characters later -- this should do no harm.
  9321. ;
  9322. itschk: skiple itscnt        ; No header characters counted?
  9323.      skipn itsflg        ; Is ITS checking enabled?
  9324.      ret            ;  No, forget it.
  9325.     move t1, itscnt        ; We were counting the matching characters...
  9326.     setzm itscnt        ; Reset the counter.
  9327.     caie t1, 4        ; The four characters matched?
  9328.      ret            ;  No, done.
  9329.     setom itsfil        ; Yes, flag it.
  9330.     move t1, [point 8, <mappag*1000>] ; Set up page pointer for 8 bit.
  9331.     movem t1, pagptr
  9332.     setz rchr,        ; Rewind the character counter.
  9333.     movei t1, 8        ; Record file bytesize correctly
  9334.     movem t1, bytsiz    ;  ...
  9335.     hrroi t1, [asciz/(ITS binary format) /]
  9336.     skipe local        ; Say what happened if local.
  9337.      PSOUT
  9338.     ret
  9339.  
  9340. ;[66] DECODE -- Convert data in Kermit packet to its original form.
  9341. ;
  9342. ; Call with:
  9343. ;  t2/ Character to decode
  9344. ;  q1/ Buffer pointer
  9345. ;  q2/ Position in buffer
  9346. ; Returns:
  9347. ;  +1: Failure, if output could not be done.
  9348. ;  +2: Success, with q1,q2 updated.
  9349. ;
  9350. ; Note: If the input character is a prefix of any kind, this routine
  9351. ; will input all further characters necessary to complete the prefixed
  9352. ; sequence, and update the counts and pointers appropriately.
  9353. ;
  9354. decode:    saveac<q4>        ; Preserve this one.
  9355.  
  9356. decod0:    move t3, t2        ; Make a copy with the parity bit intact.
  9357.     andi t2, 177        ; And without, so comparisons will work.
  9358.  
  9359. decod1:    setzm rpt        ; Reset repeat count.
  9360.     skipn rptflg        ; Repeat count processing?
  9361.      jrst decod2        ;  No.
  9362.     camn t2, rptq        ; Yes.  Is this the repeat prefix?
  9363.      jrst [    ildb t2, q1    ; Yes.  Get the count.
  9364.         andi t2, 177    ; Let's be cautious...
  9365.         subi t2, 40    ; Convert from character to number.
  9366.         movem t2, rpt    ; Save the repeat count.
  9367.         ildb t2, q1    ; Get the next character.
  9368.         move t3, t2    ; Copy with parity (in case it's not a prefix)
  9369.         trz t2, 200    ;  and without...
  9370.         subi q2, 2    ; Account for the repeat prefix sequence.
  9371.         jrst .+1 ]
  9372.     ;...
  9373.  
  9374. ;...DECODE, cont'd
  9375.  
  9376.  
  9377. decod2:    setzm ebqchr        ;[90] Say no 8th-bit prefix on this character.
  9378.     skipn ebqflg        ; Doing 8th-bit quoting?
  9379.      jrst decod3        ;  No.
  9380.     camn t2, ebq        ; Yes, is this the 8th-bit prefix?
  9381.      jrst [    ildb t2, q1    ; Yes, get the character it is prefix of.
  9382.         move t3, t2    ; Copy with parity in case not ctl prefix
  9383.         tro t3, 200    ;  ...
  9384.         trz t2, 200    ;  and without (this shouldn't anyway, but...)
  9385.         setom ebqchr    ;[90] Flag that we did this.
  9386.         sos q2        ; Account for it.
  9387.         jrst .+1 ]
  9388.  
  9389. decod3:    came t2, rquote        ; Control Prefix?
  9390.      jrst decod4        ;  No...
  9391.     ildb t2, q1        ; Yes, get its argument.
  9392.     move t3, t2        ; Copy with parity
  9393.     trz t2, 200        ;  and without...
  9394.     skipe ebqchr        ;[90] Was there an 8th-bit prefix?
  9395.      tro t3, 200        ;[90]  If so, set the 8th bit.
  9396.     sos q2            ; Account for the ctl prefix.
  9397.     cail t2, "@"        ; Check if the character is in the sequence
  9398.      caile t2, "_"        ;  "@ABC...XYZ[\]^_"
  9399.      skipa            ;  No, take it literally.
  9400.      xori t2, 100        ; Yes, controllify.
  9401.     cain t2, "?"        ; Or is it a question mark?
  9402.      movei t2, 177        ; Yes, then it's really a DEL.
  9403.  
  9404. decod4:    trne t3, 200        ; 8th bit was on?
  9405.      tro t2, 200        ;  Yes, then put it on in the result.
  9406.  
  9407. decod5:    skipn q4, rpt        ; Repeat Count.
  9408.      movei q4, 1        ; If zero, make it 1.
  9409.  
  9410. decod6:    jumple q4, decodz    ; Loop for repeat count.
  9411.     aos rchr        ; Count the data character.
  9412.     
  9413. ; The following check must be done here.  We can't look directly at RECPKT,
  9414. ; because it will contain quoting characters which must be evaluated by this
  9415. ; routine.  We can't do it by looking at the result in MAPPAG after calling
  9416. ; PUTCH, because we might be writing to MAPPAG with a 7-bit pointer.
  9417.  
  9418.     caile rchr, 4        ;[75] Check for the ITS header in 1st 4 chars.
  9419.      jrst decod7        ;[75] If past first 4, don't check.
  9420.     camn t2, [exp 0, 223, 72, 330, 0](rchr) ;[75] Check this character.
  9421.      aos itscnt        ;[75] If it matches, count it.
  9422.  
  9423. decod7:    call putch        ; Output the character.
  9424.      ret            ; Pass along any failure.
  9425.     soja q4, decod6        ; Until done.
  9426.     
  9427. decodz:    retskp            ; Success.
  9428.  
  9429. ;[66] PUTCH -- Output a character to a file.
  9430. ;
  9431. ; Call with:
  9432. ;  t2/ Character to output.
  9433. ;  pagptr/ Pointer to where to put it (if disk file).
  9434. ; Returns:
  9435. ;  +1: Failure (disk full, etc).
  9436. ;  +2: Success, pagptr updated. (Uses t1-t4)
  9437. ;
  9438. putch:    skipe t1, dest        ; Alternate PUTCH routine?
  9439.      jrst (t1)        ;  Yes, go to it.
  9440.     skiple filjfn        ;[177] To file?
  9441.      jrst putch2        ;[177] Yes, go do that.
  9442.     skipn local        ;[177] No, to screen.
  9443.      retskp            ;[177] But if remote, skip it.
  9444.     move t1, t2        ; No, then just put it on the screen.
  9445.     PBOUT            ;* Pretty dumb, make this more efficient
  9446.     retskp             ;* later...
  9447.  
  9448. ; File output.  Test to see if page is full.
  9449.  
  9450. putch2:    move t1, pagptr        ; Copy the byte pointer.
  9451.     ibp t1            ; Increment the copy.
  9452.     hrrzs t1        ; Clear out the LH.
  9453.     caig t1, <<<mappag+1>*1000>-1> ; At the end yet?
  9454.      jrst putch5        ;  No, proceed.
  9455.  
  9456. ; A page is filled up -- map it out.
  9457.  
  9458. putch3:    move t4, t2        ; Yes, save the character around this.
  9459.     call unmapo        ; Go unmap the current page.
  9460.      ret            ;  Pass along any failure.
  9461.     move t2, t4        ; Get back the character.
  9462.     aos pagno        ; Advance the file page number.
  9463.  
  9464. ; Rewind the memory page back to word 0.
  9465.  
  9466. putch4:    move t1, [point 7, mappag*1000]    ; Success, make a pointer
  9467.     skipn itsfil        ;[75]
  9468.      skipe ebtflg        ; of the appropriate
  9469.      hrli t1, (point 8,)    ; byte size.
  9470.     movem t1, pagptr    ; Store it.
  9471.  
  9472. ; Deposit the character into the memory page.
  9473.  
  9474. putch5:    idpb t2, pagptr        ; Put it in the page.
  9475.     ;...
  9476.  
  9477. ;...PUTCH, cont'd
  9478.  
  9479.  
  9480. ; Worry about bit 35.
  9481.  
  9482. putch6: skipe itsfil        ;[75][81] ITS binary file?
  9483.      retskp            ;[75]  Yes, don't worry about this.
  9484.     skipn ebtflg        ; Output to 7-bit file?
  9485.      trnn t2, 200        ; AND parity bit is on?
  9486.      retskp            ; No, done.
  9487.  
  9488. putch7:    move t3, rchr        ; Yes, both, get the char count,
  9489.     idivi t3, 5        ; modulo 5.
  9490.     jumpg t4, rskp        ; Is this the last char in the word?
  9491.  
  9492. putch8:    move t3, pagptr        ; Yes, get its contents.
  9493.     move t4, (t3)        ; ...
  9494.     tro t4, 1        ; Turn on bit 35.
  9495.     movem t4, (t3)        ; Put it back.
  9496.     retskp            ; Done.
  9497.  
  9498.     subttl File Routines
  9499.  
  9500. ; GTNFIL - Get next file from wild file specification.
  9501. ; Return +1 with AC1/0 if no more, or +2 with JFN of next file in AC1.
  9502. ;
  9503. ;[111] Rewritten to do 1-file lookahead as part of edit 111.
  9504. ;
  9505. gtnfil:    move t1, filjfn        ; Release the JFN of the previous file.
  9506.     RLJFN
  9507.      erjmp .+1
  9508.     setzm filjfn
  9509.  
  9510. ; Check to see if we really want to or can get the next file.
  9511.  
  9512.     setz t1,        ; Assume no more files.
  9513.     skipn czseen        ;[59] If CTRL-Z seen, then get no more files.
  9514.      skipn t1, nxtjfn    ; No CTRL-Z.  Get next JFN.
  9515.      ret            ; None, so we're done.
  9516.  
  9517. ; Make a separate JFN for the file so that wildcard stepping won't be wiped
  9518. ; out by anything we do to it, like deleting it, renaming it, etc.
  9519.  
  9520.     hrrz t2, t1        ; Get the filename string.
  9521.     hrroi t1, strbuf
  9522.     setz t3,
  9523.     JFNS
  9524.      erjmp r
  9525.     movx t1, gj%old!gj%sht    ; Get a new JFN on it.
  9526.     hrroi t2, strbuf
  9527.     GTJFN
  9528.      erjmp r
  9529.     hrrzm t1, filjfn    ; Save it here.
  9530.     setzm strbuf
  9531.  
  9532. ; Get new next JFN.
  9533.  
  9534.     move t1, nxtjfn        ; Get the JFN again.
  9535.     hll t1, ndxjfn        ; Get wildcard flags into left half.
  9536.     GNJFN            ; Get the next JFN.
  9537.      setz t1,        ; If no more, set this to zero.
  9538.     movem t1, nxtjfn    ; Save result for next time.
  9539.  
  9540. ; Return with current JFN.
  9541.  
  9542.     move t1, filjfn        ; Return JFN of current file in t1.
  9543.     retskp            ; Return +2 indicating another file was found.
  9544.  
  9545. ;[119] MAKFIL - Rewritten as part of edit 119.
  9546. ;
  9547. ; Construct an output filespec from name given in file header packet.
  9548. ;
  9549. ; Call with:
  9550. ;  T1/ Pointer to a file name from packet.
  9551. ;  T2/ Number of characters.
  9552. ;
  9553. ; Return:
  9554. ;  +1: Failure
  9555. ;  +2, Success, with JFN in T1.
  9556. ;
  9557. makfil:    skipe filjfn        ; Do we have a file yet?
  9558.      jrst [ move t1, filjfn    ;  If so just return its JFN.
  9559.         retskp ]
  9560.     skipg t2        ; Are there at least a few chars?
  9561.      jrst [    setz t1,
  9562.         kermsg <File name not specified>, r ]
  9563.  
  9564.     call decodf        ;[141] Decode the file name.
  9565.      kermsg <Can't decode filename>, r
  9566.  
  9567. ; Now fix up the name, if desired, and get a JFN on it.
  9568.  
  9569.     call filfix        ; Go check & fix the filename syntax.
  9570.     movx t1, gj%sht!gj%fou    ; Short form.
  9571.     GTJFN%
  9572.      erjmp makfix        ;[132] On error, go do something else.
  9573.     retskp
  9574.  
  9575. ;[132] Despite all efforts, couldn't construct legal name for file.
  9576.  
  9577. makfix:    movx t1, gj%sht!gj%fou    ; Get a JFN for...
  9578.     hrroi t2, [asciz/-UNTRANSLATABLE-FILENAME-.KERMIT.-1/]    ; ...this.
  9579.     GTJFN    
  9580.      %jsker <Can't get JFN in MAKFIL>,r ; This should never fail, but...
  9581.     move q1, t1        ; Log what happened.
  9582.     wtlog <Illegal incoming name changed to >,q1
  9583.     move t1, q1        ; Get this back.
  9584.     retskp
  9585.  
  9586. ;[141] Moved to separate routine as part of edit 141.
  9587. ;
  9588. ; Decode a file found in the data field of a KERMIT packet.
  9589. ; Call with:
  9590. ;  t1/ pointer to data field.
  9591. ;  t2/ number of characters in data field.
  9592. ;
  9593. ; Returns:
  9594. ;  +1 on failure,
  9595. ;  +2 on success, with pointer to decoded filename in t1.
  9596. ;
  9597. decodf:    saveac <q1>        ; Preserve this.
  9598.     move q1, t1        ; Save argument for a sec.
  9599.     move t1, [point 7, strbuf] ; Build decoded name here.
  9600.     movem t1, strptr
  9601.     setzm strbuf        ; Clear out the string buffer
  9602.         move t1, [strbuf,,strbuf+1] ; so result will be asciz.
  9603.     blt t1, strbz        ; ...
  9604.  
  9605.     movei t1, putsch    ; Routine to deposit decoded characters.
  9606.     movem t1, dest        ; ...
  9607.     move t1, q1        ; Get argument back.
  9608.     call putbuf        ; Decode the file name string.
  9609.      ret            ;  Failed for some reason, pass it along.
  9610.     setzm dest        ; Decoded OK, restore normal destination.
  9611.     move t1, [point 7, strbuf] ; Return pointer to decoded file name.
  9612.     retskp            ; +2.
  9613.  
  9614. ; FILFIX - Fix incoming file names by quoting illegal characters with ^V.
  9615. ;*(Should also make sure length is no greater than 39.39)
  9616. ;
  9617. ; Call with t1/ Pointer to filename
  9618. ; Returns +1 always, with t2 pointing to legal TOPS-20 filename.
  9619. ;
  9620. filfix:    skipe xfnflg        ;[84] Doing filename conversion?
  9621.      jrst filcnv        ;[84]  Yes, then go do that.
  9622.     move t3, [point 7, filbuf] ; No, but still have to quote funnies.
  9623.     setzm filbuf        ;[174]
  9624.     setom fildot        ; Count dots.
  9625.  
  9626. filfx2:    ildb t2, t1        ; Get the next character.
  9627.     jumpe t2, [        ; No more, done.
  9628.         idpb t2, t3    ; Put the null in.
  9629.         move t2, [point 7, filbuf] ; Return a pointer to the filename.
  9630.         ret ]
  9631.  
  9632. ; Got a character, validate it.
  9633.  
  9634.     cail t2, "A"        ; Upper case letters are legal.
  9635.      caile t2, "Z"    
  9636.      skipa
  9637.      jrst filfx4
  9638.     cail t2, "0"        ; Digits are legal.
  9639.      caile t2, "9"
  9640.      skipa
  9641.      jrst filfx4
  9642.     caie t2, "$"        ; Dollar sign is legal
  9643.      cain t2, "-"        ; So is dash.
  9644.      jrst filfx4
  9645.     caie t2, "_"        ; Underscore is legal.
  9646.      cain t2, 73        ; Allow semicolon for attributes.
  9647.      jrst filfx4
  9648.     cain t2, "."        ; Dot?
  9649.      jrst [    aosg fildot    ; Yes, count it.
  9650.          jrst filfx4    ; First dot, ok to use it.
  9651.         jrst filfx3 ]    ; Not first, go prefix it.
  9652.     cail t2, "a"        ;[153] A lower case letter?
  9653.      caile t2, "z"        ;[153] ...
  9654.      skipa            ;[153]  No, something very illegal then.
  9655.      jrst [    trz t2, 40    ;[153] Yes, convert to upper and
  9656.         jrst filfx4 ]    ;[153] use it.
  9657.  
  9658. ; Get here with illegal character that must be prefixed with control-V.
  9659.  
  9660. filfx3:    movei t4, ^o26        ; Control-V.
  9661.     idpb t4, t3        ; Insert it before the character.
  9662.  
  9663. ;[174] Deposit the character, but if first and a dot, insert an X before it.
  9664.  
  9665. filfx4:    skipn filbuf        ; Something in buffer already?
  9666.      caie t2, "."        ; No, first character is a dot?
  9667.      jrst filfxx        ; OK to go ahead.
  9668.     movei t4, "X"        ; 1st char would be a dot, so...    
  9669.     idpb t4, t3        ;[174]
  9670.  
  9671. filfxx:    idpb t2, t3        ; Now deposit the actual character.
  9672.     jrst filfx2        ; Loop till done.
  9673.  
  9674. ;[84] Convert incoming filename to "normal form".
  9675. ; This routine added as part of edit 84.
  9676.  
  9677. filcnv:    move t3, [point 7, filbuf] ; Where to put new file name.
  9678.     setzm filbuf        ;[174]
  9679.     movei q1, 1        ; Dot counter.
  9680.  
  9681. filcn2:    ildb t4, t1        ; Get next character.
  9682.     jumpe t4, filcnx    ;[142] If null, done.
  9683.     caie t4, "."        ; Dot?
  9684.      jrst filcn4        ;  No.
  9685.  
  9686. ;[174] check for names starting with dot.
  9687.  
  9688.     skipn filbuf        ; Anything in name yet?
  9689.      jrst [    movei t4, "X"    ;  No, insert an X.
  9690.         idpb t4, t3
  9691.         movei t4, "."
  9692.         jrst .+1 ]    ;[174]
  9693.      soje q1, filcn4        ; Yes, make sure there's only one dot.
  9694.     movei t4, "X"        ; If more, translate extra dots to X's.
  9695.     jrst filcn5
  9696.  
  9697. filcn4:    move t4, xfntab(t4)    ; Translate it.
  9698. filcn5:    idpb t4, t3        ; Put it back.
  9699.     jrst filcn2        ; Loop till done.
  9700.  
  9701. filcnx:    setz t2,        ; Put a null at the end.
  9702.     idpb t2, t3
  9703.     move t2, [point 7, filbuf] ; Return a pointer to the file.
  9704.     ret
  9705.  
  9706. ; Translate table to turn funny characters into X's, raise lower case
  9707. ; letters, leave upper case letters and digits, and periods alone.
  9708. ; For translating file names to "normal form".
  9709.  
  9710. xfntab:    repeat <^d46>,<exp "X">
  9711.     exp ".","X"
  9712.     exp "0","1","2","3","4","5","6","7","8","9"
  9713.     repeat <7>,<exp "X">
  9714.     exp "A","B","C","D","E","F","G","H","I","J","K","L","M","N"
  9715.     exp "O","P","Q","R","S","T","U","V","W","X","Y","Z"
  9716.     repeat <6>,<exp "X">
  9717.     exp "A","B","C","D","E","F","G","H","I","J","K","L","M","N"
  9718.     exp "O","P","Q","R","S","T","U","V","W","X","Y","Z"
  9719.     repeat <5>,<exp "X">
  9720.     0
  9721.  
  9722.     subttl    Line routines
  9723.  
  9724.  
  9725. ; INILIN -- Initialize the communication line for file transfer.
  9726. ;
  9727. inilin:    skipe inited        ;[177] Already init'd?  Don't do it again.
  9728.      ret            ;[177]
  9729.     call gtclas        ;[130] Check status of class scheduler.
  9730.  
  9731. ; Set all the terminal mode bits for transparent i/o.
  9732.  
  9733. inil2:    call dobits        ; Go do the bits.
  9734.      ret            ;  Pass along any failures.
  9735.     call doarpa        ; Set up any Arpanet stuff.
  9736.  
  9737. ; Clear the comm line's input buffer.
  9738.  
  9739.     move t1, netjfn        ;[82] Clear the line in case a bunch of NAKs
  9740.     CFIBF            ;[1]  have piled up.
  9741.      erjmp .+1        ;[147] Ignore any errors.
  9742.     setom inited        ;[177] Flag we've done this.
  9743.     ret
  9744.  
  9745. ; Get Scheduler Class information.
  9746. ;
  9747. gtclas:    setzm class        ; Start out assuming scheduler class 0.
  9748.     movei t1, .skrcv    ; Class scheduler on?
  9749.     movei t2, t3
  9750.     movei t3, 2        ; Just want 2 words.
  9751.     SKED%
  9752.      erjmp gtclsa        ; Not R4 or above?  Say it's not on.
  9753.     txnn t4, sk%stp        ; Class scheduler on?
  9754.      skipa            ; Yes, it's on - t4 nonzero.
  9755. gtclsa:     setz t4,        ; No, it's off - t4 zero.
  9756.     movem t4, skdflg    ; Set scheduler flag accordingly.
  9757.     jumpe t4, r        ; If no scheduler, go on to next part.
  9758.  
  9759. ;[130] Scheduler is on, get my scheduler class.
  9760.  
  9761.     movei t2, skdblk    ; Get job's scheduler class.  Here's arg block.
  9762.     movei t1, 5        ; Store length of arg block
  9763.     movem t1, .sacnt(t2)    ;  in arg block.
  9764.     move t1, myjob        ; My job number.
  9765.     movem t1, .sajob(t2)    ; Also into arg block.
  9766.     movx t1, .skrjp        ; Function code for getting job class info.
  9767.     SKED%
  9768.      erjmp .+2        ; Leap frog
  9769.      skipa            ;  to set class to -1 if there was an error.
  9770.      setom .sajcl(t2)    ;
  9771.     move t1, skdblk+.sajcl    ; Now get class.
  9772.     movem t1, class        ; Save it here.
  9773.     ret
  9774.  
  9775. ; Set communication line bits for transparent i/o.
  9776. ; Returns +1 on failure, +2 on success.
  9777. ;
  9778. dobits:    move t1, netjfn        ; JFN for connection to other system.
  9779.     movx t2, .mornt        ; Read system message status.
  9780.     MTOPR
  9781.      %jserr (,dobit2)
  9782.     movem t3, sysmsg    ; Save here for later restoral.
  9783.     movx t2, .mosnt        ; Now refuse system messages.
  9784.     movx t3, .mosmn
  9785.     MTOPR
  9786.      %jserr (,dobit2)
  9787.  
  9788. dobit2:    movx t1, <tl%cro!tl%cor!tl%sab!tl%sta> ;[147] Clear/Refuse links,
  9789.     hrr t1, ttynum        ;[147]  on the line used for file transfer.
  9790.     txo t1, .ttdes        ;[147] (TLINK wants a device designator.)
  9791.     seto t2,
  9792.     TLINK
  9793.      erjmp dobit3        ;[147] Ignore any failure.
  9794.  
  9795. dobit3:    move t1, netjfn        ; JFN for the file transfer line.
  9796.     movei t2, .morxo    ; Get terminal pause end-of-page status.
  9797.     MTOPR%
  9798.      %jserr (,r)
  9799.     movem t3, oldpau    ; Save the old pause mode.
  9800.     movei t2, .moxof    ; Now set to...
  9801.     movei t3, .mooff    ;  no pause on end.
  9802.     MTOPR%
  9803.      %jserr (,r)
  9804.     movei t2, olddim    ;[185] Point to line block
  9805.     call savlnw        ;[185] Save this JFN's length and width
  9806.     RFMOD%            ; Get current mode for this line.
  9807.      %jserr (,r)
  9808.     setom carier
  9809.     setzm mdmlin        ;[130] Assume line not modem-controlled.
  9810.     txne t2, tt%car        ;[130] Is it?
  9811.      setom mdmlin        ;[130]  Yes, flag.
  9812.     movem t2, oldmod    ; Save the present mode.
  9813.  
  9814. ;[97] Turn off undesired bits (program echoing, links, translation).
  9815. ;[97] Turn on desired bits (full duplex; TTY has form feed, tab, lowercase).
  9816. ;[97] Note that any other settings are left intact, in particular TT%ECM, which
  9817. ;[97] can cause a TAC to do its own echoing if turned off.
  9818.  
  9819. dobit4:    ; No echo, no links, no advice, no data mode, full duplex.
  9820.     txz t2, <tt%eco!tt%alk!tt%aad!tt%dam!tt%dum!tt%lic> ;[129] Add TT$DUM
  9821. ; No wakeup stuff, infinite width & length.
  9822.     txz t2, <tt%wkf!tt%wkn!tt%wkp!tt%wka!tt%wid!tt%len!tt%uoc> ;[127]
  9823. ; No formfeed/tab/case interpretation, use XON/XOFF.
  9824.     txo t2, <tt%mff!tt%tab!tt%lca!tt%pgm> ;[129] REMOVE TT%DUM!!!
  9825.  
  9826.     skipn handsh        ;[155] Doing handshake?
  9827.      skipn flow        ;[155] Doing flow control?
  9828.      txz t2, tt%pgm        ; Handshake, or no flow - don't do XON/XOFF.
  9829.     SFMOD%            ; Set the bits.
  9830.      %jserr (,.+1)
  9831.     STPAR%
  9832.      %jserr (,.+1)
  9833.     retskp
  9834.  
  9835. ;[181] PANDA Network Binary Mode routines
  9836.  
  9837. panda <                ;[181] Only if doing Panda
  9838.  
  9839. ;[181] Returns true if we have network binary mode MTOPR%
  9840. ;[181] Preserves ACs, always returns +1, havnbm: is side-effected
  9841.  
  9842. chknbm:    saveac <t1,t2,t3>    ;[181] Save the registers that MTOPR% trashes
  9843.     dmove t1,[ exp .CTTRM,.MORLT ] ;[181] Read local status
  9844.     MTOPR%            ;[181] Can the monitor process this request?
  9845.      erjmp [ setzm havnbm    ;[181]  No, assume this isn't in the monitor
  9846.          setzm setlts    ;[181]   so don't try to use it
  9847.              ret ]        ;[181]   and never try to restore status
  9848.     setom havnbm        ;[181] Otherwise, we have winning 
  9849.     ret            ;[181] Panda Network Binary Mode!
  9850.  
  9851. ;[181] Sets network binary mode
  9852. ;[181] Assumes it can stomp acumulators t1 through t3
  9853. ;[181] Returns to doarpa's caller on success
  9854. ;[181] on failure, assumes we don't have network binary mode,
  9855. ;[181] clears the flag and tries it the old way
  9856.  
  9857. setnbm:    skipe setlts        ;[181] Did we already sucessfully set this?
  9858.      ret            ;[181]  Yes, why bother doing it twice?
  9859.     move t1,netjfn        ;[181] Use current line
  9860.     movx t2,.MORLT        ;[181] Read local status
  9861.     MTOPR%
  9862.      erjmp nbmerr
  9863.     movem t3,OLDLTS        ;[181] save old terminal status
  9864.     txo t3,MO%NBI!MO%NBO    ;[181] network binary mode (input AND output)
  9865.     movx t2,.MOSLT        ;[181] want to set it
  9866.     MTOPR%
  9867.      erjmp nbmerr
  9868.     movx t2,.MORLT        ;[181] now see what actually happened
  9869.     MTOPR%
  9870.      erjmp nbmerr
  9871.     xorx t3,MO%NBI!MO%NBO    ;[181] flip binary mode status
  9872.     txne t3,MO%NBI!MO%NBO    ;[181] they should have been BOTH set ...
  9873.      jrst nbmerr
  9874.     aos setlts        ;[181] flag that we set terminal line status
  9875.     ret
  9876.  
  9877. nbmerr:    setzm havnbm        ;[181] We don't have network binary mode
  9878.      callret doarpa        ;[181]  Maybe the olde fashioned way works?
  9879.  
  9880.  
  9881. ;[181] un-Sets network binary mode
  9882. ;[181] Assumes it can stomp acumulators t1 through t3
  9883. ;[181] Returns to unarpa's caller on success
  9884. ;[181] on failure, assumes we don't have network binary mode,
  9885. ;[181] clears the flag and tries it the old way
  9886.  
  9887. unsnbm:    setz t1,        ;[181] whatever the current state is,
  9888.     exch t1,setlts        ;[181] say that it is no longer set
  9889.      jumpe t1,r        ;[181]  However: did we ever set nbm??
  9890.  
  9891.     move t1,netjfn        ;[181] Use current line
  9892.     movx t2,.MOSLT        ;[181] Read local status
  9893.     move t3,OLDLTS        ;[181] get former status
  9894.     MTOPR%            ;[181] try to restore it
  9895.      erjmp [ setzm havnbm      ;[181]  Use this no longer
  9896.              callret unarpa ] ;[181]  How could this have failed?
  9897.     ret
  9898.  
  9899. >                ;[181] End Panda conditional
  9900. ;[129] Do any required ARPAnet stuff.
  9901. ;
  9902. ; Important Note: The ability to send binary mode telnet negotiations
  9903. ; depends on the monitor NOT doubling IACs on TVT lines.  Some versions of
  9904. ; TOPS-20 (particularly BBN's TCP monitor) will do this.
  9905. ;
  9906. ;[181] Use SOUTR% instead of SOUT% to ensure that 
  9907. ;[181] we flush the data to the TAC
  9908. ;
  9909. ; Returns +1 always, but prints warning on failure.
  9910. ;
  9911. doarpa:    skipn tvtflg        ; Are we on tvt?
  9912.      ret
  9913.  
  9914. panda <    skipe havnbm        ;[181] Does the monitor support network
  9915.      callret setnbm >    ;[181]  binary mode?
  9916.  
  9917.     move t1,netjfn        ; Yes, talk binary.
  9918.     dmove t2,[exp <point 8,[byte(8) iac,will,trnbin]>,-3]
  9919.     SOUTR%            ;[181] This code adapted from MODEM.MAC
  9920.      %jserr(,doarpx)
  9921.     movei t1,^d4000        ; Sleep four seconds.
  9922.     DISMS%
  9923.     move t1,netjfn        ;[181] Tell TVT "do binary".
  9924.     dmove t2,[exp <point 8,[byte(8) iac,do,trnbin]>,-3]
  9925.     SOUTR%
  9926.      %jserr(,doarpx)
  9927.     movei t1,^d4000
  9928.     DISMS
  9929.     ret
  9930.  
  9931. doarpx:    tmsg <
  9932. %KERMIT-20: Warning -- Can't negotiate binary mode with TAC
  9933. >
  9934.     ret
  9935.  
  9936. ; RESLIN -- Reset/Restore the communications line.
  9937. ;
  9938. ; Restore old terminal modes, links, length & width, etc.
  9939. ; Turn off control-C trap.
  9940. ;
  9941. ; CALL RESLIN does nothing if server.
  9942. ; CALL RRSLIN restores the line even if server.
  9943. ;
  9944. reslin: skipe srvflg        ; Server?
  9945.      ret            ;  Yes, forget it.
  9946.  
  9947. rrslin:    call ccoff2        ; REALLY reset the line.
  9948. rrsl2:    skiple filjfn        ; Were we doing something with a file?
  9949.      jrst [    hrrz t1, filjfn    ; If so, try to close it.
  9950.         setzm filjfn
  9951.         CLOSF
  9952.          erjmp .+1
  9953.         jrst .+1 ]
  9954.  
  9955.     call unarpa        ; Undo Arpanet TAC binary mode.
  9956.     call unbits        ; Restore terminal bits.
  9957.     call ttxon        ; Clear up any XOFF condition.
  9958.     move t1,netjfn        ;[181] TLINK leaves trash in AC1
  9959.     CFIBF%            ; Also clear out any piled up junk.
  9960.      erjmp .+1
  9961.     setzm inited        ;[177] Flag we're back to normal.
  9962.     ret
  9963.  
  9964. ; Undo the effect of DOBITS -- restore all the communication line's
  9965. ; old bits & modes.
  9966. ;
  9967. unbits:    move t1, netjfn        ; Get the line.
  9968.     movei t2, .moxof    ; Set the terminal pause on end mode...
  9969.     move t3, oldpau        ;  to what it was before.
  9970.     MTOPR%
  9971.      %jserr (,.+1)
  9972.     move t1, netjfn        ; Communication line JFN.
  9973.     move t2, oldmod        ; Get the previous mode.
  9974.     SFMOD%
  9975.      %jserr (,.+1)
  9976.     STPAR%
  9977.      %jserr (,.+1)
  9978.     movei t2, olddim    ;[185] Point to this JFN's dimensions
  9979.     call rstlnw        ;[185] Restore length and width
  9980.     movx t2, .mosnt        ; Restore system msg refuse/accept.
  9981.     move t3, sysmsg
  9982.     MTOPR
  9983.      %jserr (,.+1)
  9984.  
  9985. ; Restore links and advice if necessary.
  9986.  
  9987.     setz t1,         ; Restore links & advice.
  9988.     move t2, oldmod        ; From old tty mode word.
  9989.     txne t2, tt%alk        ; Was receiving links before?
  9990.      txo t1, <tl%sab!tl%abs> ; Yes, so receive links.
  9991.     txne t2, tt%aad        ; Was receiving advice before?
  9992.      txo t1, <tl%sta!tl%aad> ; Yes, so receive links.
  9993.     jumpe t1, r        ; Skip to next part if no bits to set.
  9994.     hrr t1, ttynum        ; Must set bits, form tty designator
  9995.     txo t1, .ttdes        ;  ...
  9996.     setz t2,        ; Don't leave garbage in here...
  9997.     TLINK            ; Restore the settings.
  9998.      erjmp .+1        ; Ignore any errors.
  9999.     ret
  10000.  
  10001. ; Turn off Arpanet TAC binary mode.
  10002.  
  10003. unarpa:    skipn tvtflg        ; Are we on a tvt?
  10004.      ret            ; No, skip this.
  10005.     
  10006. panda <    skipe havnbm        ;[181] Does the monitor support network
  10007.      callret unsnbm >    ;[181]  binary mode?
  10008.  
  10009.     move t1, netjfn        ;[181] Get the line.
  10010.     dmove t2, [exp <point 8,[byte(8) iac,wont,trnbin]>,-3]
  10011.     SOUT%            ; Yes, turn off binary mode.
  10012.      %jserr(,unarpx)
  10013.     movei t1, ^d4000    ; Wait 4 secs.
  10014.     DISMS%
  10015.     move t1, netjfn        ; Send the command.
  10016.     dmove t2, [exp <point 8,[byte(8) iac,dont,trnbin]>,-3]
  10017.     SOUT%
  10018.      %jserr(,unarpx)
  10019.     movei t1, ^d4000    ; Wait another 4 secs.
  10020.     DISMS%
  10021.     ret            ; Done.
  10022.  
  10023. unarpx:    tmsg <
  10024. %KERMIT-20: Warning -- Can't clear binary mode with TAC
  10025. >                ;[129] Error message for any of the above.
  10026.     ret
  10027.  
  10028. ;[91] Routine to unstop an XOFF'd line, added as edit 91.
  10029.  
  10030. ttxon:    saveac <t1,t2,t3>    ; Save these.
  10031.     move t1, netjfn        ; In case line was XOFF'd, this will
  10032.     CFOBF%            ;  turn it back on (see monitor source).
  10033.      erjmp r
  10034.  
  10035. ;[157] If we're doing flow control, send a ^Q (XON) to unstick the other side.
  10036.  
  10037.     skipn flow        ; Doing flow control?
  10038.      ret            ;  No, done.
  10039.     RFMOD            ; Yes, get terminal mode.
  10040.      erjmp r        
  10041.     move t3, t2        ; Save it.
  10042.     txzn t2, tt%dam        ; Data mode?
  10043.      jrst ttxon3        ;  No, binary, just send it.
  10044.  
  10045. ttxon2:    SFMOD            ; Put in binary mode.
  10046.      erjmp r
  10047.     call ttxon3        ; Send the XON.
  10048.     move t2, t3
  10049.     SFMOD            ; Put back in data mode.
  10050.      erjmp r
  10051.     ret
  10052.  
  10053. ttxon3:    movei t2, xon        ; Send an XON.
  10054.     BOUT
  10055.      erjmp r
  10056.     ret
  10057.  
  10058.     subttl Packet routines
  10059.  
  10060.  
  10061. ;[114] DIAMSG
  10062. ;
  10063. ; Print packet type and number if debugging "states".
  10064. ; Enter with:
  10065. ;   t1/ packet type
  10066. ;   t2/ packet number
  10067. ;   t4/ pointer to data
  10068. ;   logjfn/ debugging log file jfn
  10069. ; Returns +1 always, with all ACs unchanged.
  10070. ;
  10071. diamsg:    cain debug, 1        ; Only for protocol debugging.
  10072.      skipn logjfn        ; Got a log JFN?
  10073.      ret            ;  Nope, forget it.
  10074.     saveac <t1,t2,t3>    ; Save these.
  10075.     push p, t1        ; Save this for sec.
  10076.     move t1, logjfn        ; Get debugging log file JFN.
  10077.     movei t3, ^d10        ; in decimal.
  10078.     NOUT%
  10079.      erjmp deberr        ;[174]
  10080.     pop p, t2        ; Pop packet type
  10081.     BOUT
  10082.      erjmp deberr        ;[174]
  10083.     cain t2, "G"        ; Generic command?
  10084.      jrst [    move t3, t4    ; Log the first character of the data packet.
  10085.         ildb t2, t3
  10086.         BOUT
  10087.          erjmp deberr    ;[174]
  10088.         jrst .+1 ]
  10089. diamsz:    movei t2, " "        ; A space for delimitation.
  10090.     BOUT
  10091.      erjmp deberr        ;[174]
  10092.     ret
  10093.  
  10094. ;[174] Handle i/o errors writing to debugging log file.
  10095.  
  10096. deberr:    tmsg <
  10097. %KERMIT-20: Error writing debug log file - >
  10098.     movei t1, .priou
  10099.     hrloi t2, .fhslf
  10100.     setz t3,
  10101.     ERSTR
  10102.      nop
  10103.      nop
  10104.     tmsg <
  10105. >
  10106.     setz t1,        ; Close the log file if possible
  10107.     call $closd        ; and turn off debug log.
  10108.     ret
  10109.  
  10110. ; SPACK (Send-Packet)
  10111. ;
  10112. ; Assembles & sends a packet from the given arguments.   Assumes all quoting,
  10113. ; prefixing, condensing, etc, already done.  Sends the fields in the proper
  10114. ; order, validating the control fields to some extent, adding desired parity
  10115. ; (if any) to each character, calculates and appends the checksum, appends any
  10116. ; desired padding or eol characters, and does any required pause or handshake.
  10117. ;
  10118. ; Call with:
  10119. ;    AC1 - Type of packet (D,Y,N,S,R,E,F,Z,T,I, or any uppercase letter)
  10120. ;    AC2 - Packet sequence number (binary)
  10121. ;    AC3 - Number (binary) of characters in data field
  10122. ;    AC4 - 8-bit byte pointer to data characters
  10123. ; Returns: +1 on failure, with:
  10124. ;          AC1 - 0: SOUT failed or timeout on handshake (can retry).
  10125. ;              1: invalid argument (no point retrying).
  10126. ;          (These values are suitable indexes for a jump table)
  10127. ;       +2 on success, with ACs 1-4 unchanged.
  10128. ;
  10129. spack:    saveac <q1,q2,q3>    ; Preserve us!
  10130.  
  10131. ; Set things up.
  10132.  
  10133.     dmovem t1, actmp    ; Save what we were called with in a way that
  10134.     dmovem t3, actmp+2    ;  that they only are restored if we want to.
  10135.     movem t1, type        ; Save the type.
  10136.     call diamsg        ; Print diagnostic if desired.
  10137.     setz q2,        ; Zero the checksum AC.
  10138.     move q1, [point 8, sndpkt] ; Get a byte pointer to the send packet.
  10139.  
  10140. ; Start of packet.
  10141.  
  10142.     move t1, ssthdr        ;[18] Get the start of header char.
  10143.     call @parity        ; Call the appropriate parity routine.
  10144.     idpb t1, q1        ; Put in the packet.
  10145.  
  10146. ; Packet length.
  10147. ;
  10148. ;[98] This section changed to allow for different block check types.
  10149.  
  10150.     movem t3, datlen    ; Remember data length for later.
  10151.     skipe bctone        ; Forcing single-character checksum?
  10152.      aosa t3        ;  Yes, then always use type 1.
  10153.      add t3, bctu        ;  Otherwise add the block check length.
  10154.     addi t3, 2        ;[179] Account for SEQ and TYPE.
  10155.     movem t3, pktlen    ;[179] Remember value of packet length field.
  10156. ;[179]    cail t3, 5        ; Does the packet have the minimum length?
  10157.      camle t3, spsiz    ;  And is it below the maximum?
  10158.       kermsg <SPACK: Illegal message length>,spxx2 ; No, fatal.
  10159.     addm t3, stot        ;[22] It's OK, account for the whole packet.
  10160.  
  10161.     setzm islong        ;[179] Assume regular (short) packet
  10162.     caile t3, ^d94        ;[179] Long packet?
  10163.      setom islong        ;[179] Set flag.
  10164.  
  10165.     addi t3, " "        ;[179] Convert to ASCII.
  10166.     skipe islong        ;[179] Long?
  10167.      movei t3, " "        ;[179] Put a blank here
  10168.  
  10169.     add q2, t3        ; Add the LEN field to the checksum.
  10170.     move t1, t3
  10171.     call @parity        ; Call the appropriate parity routine.
  10172.     idpb t1, q1        ; Put the LEN field into the packet.
  10173.     ;...
  10174.  
  10175. ; SPACK, cont'd
  10176.  
  10177.  
  10178. ; Packet sequence number.
  10179.  
  10180.     skipl t1, t2        ; Is the sequence number valid? (0-64)?
  10181.      cail t2, ^o100
  10182.      ermsg <SPACK: Illegal packet sequence number>,spxx2 ; No, fatal.
  10183.     addi t1, " "        ; Add a space so the number is printable.
  10184.     add q2, t1        ; Add the number to the checksum.
  10185.     call @parity        ; Call the appropriate parity routine.
  10186.     idpb t1, q1        ; Put the sequence number into the packet.
  10187.  
  10188. ; Packet type.
  10189.  
  10190.     move t1, type        ; Get the type.
  10191.     cail t1, "A"        ; Check if the type is a capital letter.
  10192.      caile t1, "Z"
  10193.      ermsg <SPACK: Illegal message type>, spxx2 ;[60] Not, fatal.
  10194.     add q2, t1        ; Add in the message type to the checksum.
  10195.     call @parity        ; Call the appropriate parity routine.
  10196.     idpb t1, q1        ; Put the type into the packet.
  10197.     skipg t3, datlen    ; Is there any data?
  10198.      jrst spack3        ;  No, finish up.
  10199.  
  10200. ;[179] Extended header for long packet.
  10201.  
  10202.     skipn islong        ;[179] Long packet?
  10203.      jrst spack2        ;[179] No
  10204.     move t1, pktlen        ;[179] Yes, length
  10205.     subi t1, 2        ;[179] This time we only count data + checksum
  10206.     idivi t1, ^d95        ;[179] Big part of length (quotient)
  10207.     addi t1, " "        ;[179] Convert to ASCII
  10208.     add q2, t1        ;[179] Add to checksum
  10209.     call @parity        ;[179] Tack on parity
  10210.     idpb t1, q1        ;[179] Deposit in packet
  10211.     addi t2, " "        ;[179] Same deal for small part (remainder)
  10212.     add q2, t2        ;[179] Add to checksum
  10213.     move t1, t2        ;[179] Move remainder to t1 for parity routine
  10214.     call @parity        ;[179]
  10215.     idpb t1, q1        ;[179]
  10216.     push p, q2         ;[179] Save current packet checksum
  10217.     move t2, q2        ;[179] Form header checksum
  10218.     andi q2, ^o300        ;[179] ...
  10219.     lsh q2, -6        ;[179]
  10220.     add q2, t2        ;[179]
  10221.     ldb t1, [point 6, q2, 35] ;[179]
  10222.     addi t1, " "        ;[179]
  10223.     pop p, q2        ;[179] Restore packet checksum
  10224.     add q2, t1        ;[179] Include header checksum in it
  10225.     call @parity        ;[179] Add parity to header checksum
  10226.     idpb t1, q1        ;[179] Put it in the packet
  10227.     move t3, datlen        ;[179] Set t3 as spack2 expects to find it.
  10228.  
  10229. ; Loop to put each data character in the packet.
  10230.  
  10231. spack2:    ildb t1, t4        ; Get the next character.
  10232.     add q2, t1        ; Add it to the checksum.
  10233.     call @parity        ; Call the appropriate parity routine.
  10234.     idpb t1, q1        ; Put the character into the packet.
  10235.     sojg t3, spack2        ; Loop for all characters.
  10236.     ;...
  10237.  
  10238. ; SPACK, cont'd.
  10239.  
  10240. ;[98] SPACK3-SPAK3X rewritten as part of edit 98.
  10241.  
  10242.  
  10243. ; Done with the data, now append the appropriate kind of block check.
  10244.  
  10245. spack3:    skipe bctone        ; Doing send-init exchange?
  10246.      jrst spak3a        ;  Then always use type 1.
  10247.     move t1, bctu        ; Get block check type,
  10248.     jrst @[exp spxx2, spak3a, spak3b, spak3c](t1) ; and do it.
  10249.  
  10250. ; Single-character 6-bit checksum.
  10251.  
  10252. spak3a:    move t3, q2        ; Make an extra copy of the checksum.
  10253.     andi q2, ^o300        ; AND out all but 2 bits.
  10254.     lsh q2, -6        ; Shift them to the far right.
  10255.     add q2, t3        ; Add in the original value.
  10256.     ldb t1, [point 6, q2, 35] ; Take modulo 64.
  10257.     addi t1, " "        ; Add a space so the result is printable.
  10258.     call @parity        ; Call the appropriate parity routine.
  10259.     idpb t1, q1        ; Put the checksum into the packet.
  10260.     jrst spak3x        ; Done with checksum.
  10261.  
  10262. ; 2-Character 12-bit checksum.
  10263.  
  10264. spak3b:    ldb t1, [point 6, q2, 29] ; Get bits 24-29 (high order 6 bits).
  10265.     addi t1, " "        ; CHAR of that.
  10266.     call @parity        ; Do any parity.
  10267.     idpb t1, q1        ; Deposit this as first character of checksum.
  10268.     ldb t1, [point 6, q2, 35] ; Get bits 30-35 (low order 6 bits).
  10269.     addi t1, " "        ; CHAR of that.
  10270.     call @parity        ; Do any parity.
  10271.     idpb t1, q1        ; Deposit this as second checksum character.
  10272.     jrst spak3x        ; Done with checksum.
  10273.  
  10274. ; 3-character 16-bit CRC CCITT.
  10275.  
  10276. spak3c:    move t1, datlen        ; Length of the data field.
  10277.     addi t1, 3        ; Plus LEN, SEQ, and TYPE fields.
  10278.     skipe islong        ;[179] Long packet?
  10279.      addi t1, 3        ;[179] Add length of header.
  10280.     move t2, [point 8, sndpkt, 7] ; Point to packet starting at LEN field.
  10281.     call crcclc        ; Go compute the CRC.
  10282.     move q2, t1        ; Here it is.
  10283.     ldb t1, [point 4, q2, 23] ; Get bits 20-23 (high order 4 bits).
  10284.     addi t1, " "        ; CHAR of that.
  10285.     call @parity        ; Do any parity.
  10286.     idpb t1, q1        ; Deposit this as first CRC character.
  10287.     jrst spak3b        ; Go back and do other two CRC characters.
  10288.     ;...
  10289.  
  10290. ; SPACK, cont'd
  10291.  
  10292.  
  10293. ; Supply requested End-of-Line.
  10294.  
  10295. spak3x:    move t1, seolch        ; Get the requested EOL char.
  10296.     call @parity        ; Call the appropriate parity routine.
  10297.     idpb t1, q1        ; Add it to the packet.
  10298.     setz t1,        ; Get a null.
  10299.     idpb t1, q1        ; Put it at the end.
  10300.  
  10301. ;[36] Do any requested interpacket pausing.
  10302.  
  10303. spack5:    skipe t1, pause        ; Pausing?
  10304.      jrst [    fmp t1, [1000.0] ; Yes, convert to milliseconds.
  10305.         fixr t1, t1    ; And then to an integer.
  10306.         DISMS        ; Sleep for that long.
  10307.         jrst .+1 ]
  10308.  
  10309. ; Do any requested padding.
  10310.  
  10311. spak5a:    skipg t4, spadn        ;[34] Sending pad characters?
  10312.      jrst spack6        ;[34]  No, just send the packet.
  10313.     move t1, spadch        ;[34] Yes, this is the character.
  10314.     call @parity        ;[34] Tack on desired parity.
  10315.     move t2, t1        ;[34] Shuffle ACs...
  10316.     move t1, netjfn        ;[34] Where to send the padding.
  10317. spak5b:    BOUT            ;[34] Output the padding character.
  10318.      %jserr <SPACK: Can't send padding>,spack6 ;[34] Warn about errors.
  10319.     sojg t4, spak5b        ;[34] This many pad characters.
  10320.  
  10321.     ;...
  10322.  
  10323. ; SPACK, cont'd
  10324.  
  10325. ;[131] If ARPANET TVT then must double any hex FF's (TELNET IAC).
  10326. ; Note, since IAC is DEL with parity bit on, we should never see one, right?
  10327. ;
  10328. spack6:    move t2, [point 8, sndpkt] ; The address of the packet.
  10329.     skipn tvtflg        ; TVT-Binary mode?
  10330.      jrst spak6x        ; No, just go send it.
  10331.  
  10332.     move t2, [point 8, sndpkt] ; Yes, must double any IACs.
  10333.     move t3, [point 8, tvtbuf] ; Copy data field to this place.
  10334. spak6a:    ildb t1, t2        ; Byte loop.  Get one.
  10335.     jumpe t1, spak6b    ; Done?
  10336.     idpb t1, t3        ; No, copy it.
  10337.     cain t1, iac        ; IAC?
  10338.      idpb t1, t3        ;  Yes, copy it again.
  10339.     jrst spak6a        ; Till done.
  10340. spak6b:    setz t1,        ; Done, make result asciz.
  10341.     idpb t1, t3        ;  ...
  10342.     move t2, [point 8, tvtbuf] ; Point to result.
  10343.  
  10344. ;[131] End.  Now, finally send the packet.
  10345.  
  10346. spak6x:    move t1, netjfn        ; JFN for sending the packet.
  10347.     setzb t3, t4        ; Terminate on a null.
  10348.     SOUT%            ; Send the string.
  10349.      erjmp spxx1        ;  JSYS error, go handle.
  10350.  
  10351. spak6y:    aos sptot        ;[4] Count the packet we sent.
  10352.     skipn debug        ;[128] Debugging?
  10353.      jrst spackb        ;  No, how about blips?
  10354.     caie debug, 2        ;[128] Yes, packets?
  10355.      jrst spackz        ; No, states, that's taken care of elsewhere.
  10356.  
  10357. ; Debugging -- Log the packet.
  10358.  
  10359.     skipn t1, logjfn    ; Yes, but make sure we have a destination.
  10360.      jrst spackz        ;  We don't, skip this.
  10361.     hrroi t2, [asciz/
  10362. S,/]                ; We do, give a crlf and "S," first.
  10363.     setzb t3, t4
  10364.     SOUT
  10365.      erjmp spkder
  10366.     seto t2,        ; Include time stamp, current date/time.
  10367.     movx t3, ot%nda        ; But no date.
  10368.     ODTIM
  10369.      erjmp spkder
  10370. spackd:    movei t2, ","        ; Comma,
  10371.     BOUT
  10372.      erjmp spkder
  10373.     setzb t3, t4
  10374.     move t2, [point 8, sndpkt] ; Now the packet itself.
  10375.     SOUT
  10376.      erjmp spkder
  10377.     hrroi t2, crlf        ; Another crlf
  10378.     SOUT
  10379.      erjmp spkder
  10380.     jrst spackz
  10381.     ;...
  10382.  
  10383. ;...SPACK, cont'd
  10384.  
  10385. ;[174] Recover from errors writing to debugging log.
  10386.  
  10387. spkder:    call deberr
  10388.     jrst spackz
  10389.  
  10390. ;[4] Put blips on user's screen if local.
  10391.  
  10392. spackb:    skipl filjfn        ;[106] No blips if output is to TTY.
  10393.      skipn local        ; Not debugging, but still local?
  10394.      jrst spackz        ;  Remote, don't make blips.
  10395.     move t3, type        ; Local, am I sending a NAK packet?
  10396.     movei t1, "%"        ; Print a "%" for each one I send.
  10397.     move t2, numtry        ; Or each resend I have to do.
  10398.     caig t2, 1        ;
  10399.      cain t3, "N"        ;
  10400.      jrst spackx        ;
  10401.     setz t3,        ; Not a NAK, is it time to blip?
  10402.     move t4, sptot        ; Check the absolute packet number.
  10403.     divi t3, blip        ; We do it every "blip" packets.
  10404.     jumpn t4, spackz    ; Not time for a blip.
  10405.     movei t1, "."        ; It's time, here's the blip.
  10406. spackx:    PBOUT%            ; "."
  10407.  
  10408. ; Common exit point for successful exit.
  10409.  
  10410. spackz:    dmove t1, actmp        ;[60] Restore what we were called with
  10411.     dmove t3, actmp+2    ;[60]
  10412.     retskp
  10413.  
  10414. ; Exit point for nonfatal errors.
  10415.  
  10416. spxx1:    skipe mdmlin        ; Modem line?
  10417.      jrst [    move t1, netjfn    ;  Yes, see if we just dropped carrier.
  10418.         call chkli2
  10419.         skipn carier    ; Still have it?
  10420.          jrst spxx2    ;  No, then fatal.
  10421.         jrst .+1 ]    ; Yes, can continue trying.
  10422.     setz t1,        ;[60] Indicate nonfatal.
  10423.     ret
  10424.  
  10425. ; Exit for fatal errors.
  10426.  
  10427. spxx2:    movei t1, 1        ;[60] Indicate fatal.
  10428.     ret
  10429.  
  10430. ; RPACK -- Receive-Packet
  10431. ;
  10432. ; This routine waits for a packet to arrive.  It reads characters until it
  10433. ; finds the start-of-packet character, normally SOH.  It then reads the packet
  10434. ; into RECPKT based on the length supplied in the length field (no termination
  10435. ; character necessary).
  10436. ;
  10437. ; Returns:
  10438. ;   +1 failure (if the checksum is wrong or the packet trashed)
  10439. ;   +2 success with:
  10440. ;       t1/ Packet type
  10441. ;       t2/ Packet number
  10442. ;       t3/ Length of data field
  10443. ;       t4/ 8-bit byte pointer to data field
  10444. ;
  10445. rpack:    saveac <q1,q2,q3>    ; Save these ACs.
  10446.     stkvar <pktbct>        ; Block check type for this packet.
  10447.  
  10448.     setzm islong        ;[179] Assume packet is not long.
  10449.  
  10450.     cain debug, 2        ; Logging packets?
  10451.      skipn t1, logjfn    ; Yes, make sure there's a log.
  10452.      jrst rpackb
  10453.  
  10454.     hrroi t2, [asciz/
  10455. R,/]                ; "R" for Receive
  10456.     setzb t3, t4
  10457.     SOUT
  10458.      erjmp [call deberr    ;[174] Recover from debug log errors.
  10459.         jrst rpacka ]
  10460.     seto t2,        ; Time stamp, current date/time.
  10461.     movx t3, ot%nda        ; But no date.
  10462.     ODTIM
  10463.      erjmp [call deberr    ;[174]
  10464.         jrst rpacka ]
  10465.     movei t2, "/"        ; Current timeout interval.
  10466.     BOUT
  10467.      erjmp [call deberr    ;[174]
  10468.         jrst rpacka ]
  10469.     movei t1, tmout        ; Place to go on timeout.
  10470.     call timeit        ; Set the timer
  10471.     move t1, logjfn
  10472.     move t2, curtim        ; Log current time interval
  10473.     movei t3, ^d10
  10474.     NOUT
  10475.      erjmp [call deberr    ;[174]
  10476.         jrst rpacka ]
  10477.  
  10478. rpacka:    movei t2, ","
  10479.     BOUT
  10480.      erjmp [call deberr    ;[174]
  10481.         jrst rpackb ]
  10482.     move t1, netjfn        ; JFN of the communication line.
  10483.     jrst rpack0        ; Already set timer...
  10484.  
  10485. ; Here if not logging packets.
  10486.  
  10487. rpackb:    movei t1, tmout        ; Place to go on timeout.
  10488.     call timeit        ; Time out if it takes too long.
  10489.     move t1, netjfn        ; JFN of the communication line.
  10490.     ;...
  10491.  
  10492. ;...RPACK, cont'd
  10493.  
  10494. ; Eat interpacket garbage, read up to start-of-packet character.
  10495.  
  10496. rpack0:    call inchar        ; Get a character from the line.
  10497.      jrst rperr        ;  If we can't, go fail.
  10498.     came t2, rsthdr        ;[18] Is the char the start of header char?
  10499.      jrst rpack0        ;  No, go until it is (or we are timed out).
  10500.  
  10501. ; Now read the packet.
  10502.  
  10503. rpack1:    move q1, [point 8, recpkt] ; OK, now point to the packet buffer.
  10504.     idpb t2, q1        ; Put the start character into the packet.
  10505.  
  10506.  
  10507. ; Packet length field = number of characters to follow the length field,
  10508. ; up to and including the last block check character.
  10509.  
  10510.     call inchar        ; Get next character from the line.
  10511.      jrst rperr
  10512.     camn t2, rsthdr        ;[18] Is the char the start of header char?
  10513.      jrst rpack1        ;  Yes, then go start over.
  10514.     idpb t2, q1        ; Copy character to packet buffer.
  10515.     move q2, t2        ; Start the checksum.
  10516.     move q3, t2        ; Save the length here for later.
  10517.  
  10518. ; Packet sequence number.
  10519.  
  10520.     call inchar        ; Get the next character
  10521.      jrst rperr
  10522.     camn t2, rsthdr        ;[18] Start of header?
  10523.      jrst rpack1        ;  Yes, go start over.
  10524.     idpb t2, q1        ; No, put it in the packet.
  10525.     add q2, t2        ; Add it to the checksum.
  10526.     subi t2, " "        ; Get the real packet number.
  10527.     movem t2, num        ; Save it for later.
  10528.  
  10529. ; Packet type.
  10530.  
  10531.     call inchar        ; Next character.
  10532.      jrst rperr
  10533.     camn t2, rsthdr        ;[18] SOH?
  10534.      jrst rpack1        ;  Yes, go back.
  10535.     idpb t2, q1        ; Not SOH, keep it.
  10536.     add q2, t2        ; Add it to the checksum.
  10537.     movem t2, type        ; It's the message type, remember it.
  10538.     ;...
  10539.  
  10540. ;...RPACK, cont'd
  10541.  
  10542.  
  10543. ;[123] Beginning of change
  10544. ;
  10545. ; Now determine block check type for this packet.  Here we violate the layered
  10546. ; nature of the protocol by inspecting the packet type in order to detect when
  10547. ; the two sides get out of sync.  Two heuristics allow us to resync here:
  10548. ;
  10549. ;   a. An S packet always has a type 1 checksum.
  10550. ;   b. A NAK never contains data, so its block check type is LEN-2.
  10551.  
  10552.     subi q3, " "        ;[179] Convert ASCII length to number.
  10553.     skipn q3        ;[179] Is it zero?
  10554.      setom islong        ;[179] Yes - long packet.
  10555.     skipn islong        ;[179] Long?
  10556.      subi q3, 2        ;[179] No, subtract 2 for SEQ & TYPE fields.
  10557.     move t1, bctu        ; Expected block check type.
  10558.     skipn bctone        ; But if type 1 is required,
  10559.      cain t2, "S"        ; or if this is an S packet,
  10560.      movei t1, 1        ; then force the type to 1.
  10561.     cain t2, "N"        ; But, is this a NAK?
  10562.      move t1, q3        ; Yes, so this must be the block check type.
  10563.     movem t1, pktbct    ; Save the block check type we have determined.
  10564.  
  10565.     skipn islong        ;[179] Long packet?
  10566.      jrst rpackc        ;[179] No, go get data.
  10567.     move t1, netjfn        ;[179] Set up for inchar.
  10568.     call inchar        ;[179] Get next character.
  10569.      jrst rperr        ;[179]
  10570.     idpb t2, q1        ;[179] Save it.
  10571.     add q2, t2        ;[179] Add to checksum.
  10572.     subi t2, " "        ;[179] Convert to number.
  10573.     move q3, t2        ;[179] Set to make...
  10574.     imuli q3, ^d95        ;[179] big part of length.
  10575.     call inchar        ;[179] Get next character.
  10576.      jrst rperr        ;[179]
  10577.     idpb t2, q1        ;[179] Save it.
  10578.     add q2, t2        ;[179] Add to checksum.
  10579.     subi t2, " "        ;[179] Convert to number.
  10580.     add q3, t2        ;[179] Add to big part of length.
  10581.     call inchar        ;[179] Get next character (header checksum)
  10582.      jrst rperr        ;[179]
  10583.     idpb t2, q1        ;[179] Save it.
  10584.     add q2, t2        ;[179] Add to checksum.
  10585.  
  10586. ; [179] HERE WE SHOULD CHECK THE HEADER CHECKSUM...
  10587. ; [179] But no big deal since overall checksum will catch any errors later.
  10588.  
  10589. ; Now subtract the block check length from the packet length, which gives the
  10590. ; length of the data field.
  10591.  
  10592. rpackc:    sub q3, pktbct        ; Calculate the data length.
  10593.     movem q3, datlen    ; Save it.
  10594.  
  10595. ; Take in the data field.
  10596.  
  10597.     move t1, netjfn        ; Get the packet input jfn back again.
  10598.  
  10599. ;[123] End of change.
  10600.  
  10601.     movem q1, datptr    ; Return pointer to the data buffer.
  10602.     skipg q3, datlen    ; Use character count for loop control.
  10603.      jrst rpbc        ;[99] If none, go get the block check.
  10604.  
  10605. ; Loop to get the specified number of data characters.
  10606.  
  10607. rpack2:    hrrz t2, q1        ;[117] Check for buffer overflow.
  10608.     cail t2, recpkz        ;[117] If we're past the end, go back and
  10609.      jrst rpack0        ;[117]  eat characters until a ^A.
  10610.     call inchar        ; Get a character from the line.
  10611.      jrst rperr        ;  Oops, can't.
  10612.     camn t2, rsthdr        ; Is the char the start of header char?
  10613.      jrst rpack1        ;  Yes, then go start over.
  10614.     idpb t2, q1        ; Put the char into the packet.
  10615.     add q2, t2        ; Add it to the checksum.
  10616.     sojg q3, rpack2        ; Get next character, if any.
  10617.     ;...
  10618.  
  10619. ;...RPACK, cont'd
  10620.  
  10621.  
  10622. ; Count exhausted, next characters will be the block check.
  10623. ;
  10624. ;[98] This section, thru RPACK4, mostly rewritten as part of edit 98.
  10625.  
  10626. rpbc:    movem q1, bctemp    ; Save pointer to block check.
  10627.     move q3, pktbct        ;[123] Length of block check for this packet.
  10628.  
  10629. ;[123]    skipl datlen        ;[99] If data len negative, must be type 1 NAK!
  10630. ;[123]     skipe bctone        ;  or if this flag is set,
  10631. ;[123]     movei q3, 1        ;  must look for single-character checksum.
  10632.  
  10633. ; Get the checksum bytes and add them up.
  10634.  
  10635.     setz t3,        ; Accumulator for checksum.
  10636. rpack3:    call inchar        ; Get a character.
  10637.      jrst rperr
  10638.     camn t2, rsthdr        ;[18] Is the char the start of header char?
  10639.      jrst rpack1        ;  Yes, then go start over.
  10640.     idpb t2, q1        ; Got one, deposit it.
  10641.     lsh t3, 6        ; Accumulate numeric value
  10642.     addi t3, -40(t2)    ;  ...
  10643.     sojg q3, rpack3        ; Go back and get the rest.
  10644.     
  10645.     setz t1,        ; Make the string ASCIZ.
  10646.     idpb t1, q1
  10647.  
  10648. ;[135] If doing handshake, look for that now.
  10649. ;[135] (This code moved from beginning of SPACK)
  10650.  
  10651. rpakh1:    skipn handsh        ; Doing handshake?
  10652.      jrst rpakcc        ;  Nope.
  10653. rpakh2:    move t1, netjfn        ; Try to get a character
  10654.     call inchar        ;  from the line.
  10655.      jrst rpakhx        ; If there was an error, try to proceed
  10656.     andi t2, 177        ; Strip the high bit.
  10657.     came t2, handsh        ; Is it the handshake character?
  10658.      jrst rpakh2        ;  No, keep going till it is.
  10659. rpakhx:    ;...
  10660.  
  10661. ;[135](end of change)
  10662.  
  10663. ;...RPACK, cont'd
  10664.  
  10665.  
  10666. ; Check the checksum.
  10667.  
  10668. rpakcc:    skipl datlen        ;[99] If negative data length, or
  10669.      skipe bctone        ;  explicitly requested to,
  10670.      jrst rpak3a        ;  then compute 1 character checksum.
  10671.     move t1, bctu        ; Otherwise get the type which we're using.
  10672.     jrst @[exp rperr, rpak3a, rpak3b, rpak3c](t1)
  10673.  
  10674. ; Here for single-character 6-bit checksum.
  10675.  
  10676. rpak3a:    move q3, q2        ; Make a copy of the arithmetic checksum.
  10677.     andi q2, ^o300        ; And out all but 2 bits.
  10678.     lsh q2, -6        ; Shift them to the far right.
  10679.     add q2, q3        ; Add in the original value.
  10680.     andi q2, 77        ; Get the modulo 64 of the char total.
  10681.     jrst rpak3x        ; Go check it.
  10682.  
  10683. ; Two-character 12-bit checksum.
  10684.  
  10685. rpak3b:    andi q2, 7777        ;[100] Mask out all but 12 bits.
  10686.     jrst rpak3x        ; Go compare.
  10687.  
  10688. ; 3-character 16-bit CRC CCITT.
  10689.  
  10690. rpak3c:    move t1, datlen        ; Get the data length.
  10691.     addi t1, 3        ; Account for LEN, SEQ, and TYPE fields.
  10692.     skipe islong        ;[179] Long packet?
  10693.      addi t1, 3        ;[179] Also account for extended header.
  10694.     move t2, [point 8, recpkt, 7] ; Point to packet starting at LEN field.
  10695.     call crcclc        ; Compute CRC.
  10696.     ldb q2, [point 16, t1, 35] ;[100] Get exactly 16 bits worth.
  10697.     ;...
  10698.  
  10699. ;...RPACK, cont'd
  10700.  
  10701.  
  10702. ; Compare the two block checks.
  10703.  
  10704. rpak3x:    caie t3, (q2)        ; Are they equal?
  10705.      jrst badbc        ;  No, bad block check.
  10706.  
  10707. ; All OK, turn off timer, flush buffer.
  10708.  
  10709. rpack4:    call timoff        ; Got packet OK, turn off the timer.
  10710.     move t1, netjfn        ;[17] Clear out any further junk from input
  10711.     CFIBF%            ;[17] buffer, there should be nothing there
  10712.      erjmp .+1        ;[17] till after we reply.
  10713.  
  10714. ; Set up ACs 1-4 with results and return successfully.
  10715.  
  10716. rpackx:    aos rptot        ; Count the packet we received.
  10717.     move q1, bctemp        ; Pointer to first character of block check.
  10718.     setz t1,        ; Terminate the data string, nullifying
  10719.     idpb t1, q1        ;  the block check.
  10720.  
  10721.     move t1, type        ; Return the packet type in T1,
  10722.     move t2, num        ;  the sequence number in T2,
  10723.     call diamsg        ; Log the packet type & number if desired.
  10724.     skipge t3, datlen    ;  the number of data characters in T3,
  10725.      setz t3,        ;***
  10726.     move t4, datptr        ; and a pointer to the data in t4.
  10727.     retskp            ; Return +2.
  10728.  
  10729. ; Come here if block checks don't compare.
  10730.  
  10731. badbc:    skipn t1, logjfn    ;[38] No, do we have a debugging log?
  10732.      jrst rperr        ;[38]  No, skip messages.
  10733.     setzb t3, t4        ;[38] Yes, say checksum was bad.
  10734.     hrroi t2, [asciz/
  10735. %chksum /]            ;[29]
  10736.     SOUT
  10737.      erjmp [call deberr    ;[174]
  10738.         jrst .+1 ]
  10739.  
  10740. ; Exit thru here upon any kind of error except a timeout.
  10741.  
  10742. rperr:    call timoff        ; Cancel the time out.
  10743.     move t1, netjfn        ;[17] Flush any stacked up packets from the
  10744.     CFIBF%            ;[17] input buffer.  If anything's there, we
  10745.      erjmp .+1        ;[17] don't want it!
  10746.     ret            ; Return unsuccessfully.
  10747.  
  10748.     subttl Support Routines for RPACK.
  10749.  
  10750.  
  10751. ; INCHAR -  Get a character from the communication line.
  10752. ;
  10753. ; Call with:
  10754. ;  t1/ JFN of comm line.
  10755. ;
  10756. ; Returns:
  10757. ;  +1 on failure, with state set to "A" if carrier dropped.
  10758. ;  +2 on success with:
  10759. ;     t1/ unchanged
  10760. ;     t2/ character, with parity bit stripped if parity is being used.
  10761. ;
  10762. inchar:    saveac <t1>        ; Save the JFN.
  10763.  
  10764. ;[180] Begin buffering communications input change.
  10765.  
  10766.     skiple tticnt        ; Something in buffer?
  10767.      jrst [    sos tticnt    ; Yes, decrement count
  10768.         ildb t2, ttiptr    ; Load next byte.
  10769.         aos ttildb    ; (stats)
  10770.         jrst inch3 ]    ; Go handle byte.
  10771.     SIBE%            ; Buffer empty - see if anything is waiting.
  10772.      jrst [ caile t2, IOBUF     ; Adjust if more than buffer size.
  10773.          movei t2, IOBUF
  10774.         movem t2, tticnt ; Remember how many we asked for
  10775.         movn t3, t2     ; Negative version for SIN
  10776.         move t2, [point 8, ttibuf] ; Where to put them
  10777.         movem t2, ttiptr ; Reset buffer pointer
  10778.         SIN%         ; Try to read
  10779.          erjmp inchxx     ; Error...
  10780.         aos ttisin     ; Number of SINs for stats
  10781.         add t3, tticnt     ; How many we got (t3 is negative)
  10782.         camle t3, ttimax ; Maximum size of a SIN for stats
  10783.          movem t3, ttimax
  10784.         movem t3, tticnt ; Save the input byte count
  10785.         skipg tticnt     ; More than zero
  10786.          jrst inch2     ; Less than one - go do blocking BIN
  10787.         sos tticnt     ; Decrement count
  10788.         ildb t2, ttiptr     ; Load next byte.
  10789.         aos ttildb     ; (stats)
  10790.         jrst inch3 ]     ; Go handle byte.
  10791.  
  10792. ; Do BIN if SIBE sees nothing waiting or if SIN gets nothing.
  10793. ;[180] End buffering change.
  10794.  
  10795. inch2:    setzm tticnt        ;[180]
  10796.     setz t2,        ; (in case of error)
  10797.     BIN%            ; Get a character from the line.
  10798.      erjmp inchxx        ;[130] Error, go see what.
  10799.     aos ttibin        ;[180] (stats)
  10800. inch3:                ;[180] (label added).
  10801.     cain debug, 2        ; Logging packets?
  10802.      call [    skipn t1, logjfn ; Yes, make sure there's a log.
  10803.          ret
  10804.         BOUT        ; Record the character.
  10805.          erjmp deberr    ;[174]
  10806.         ret ]
  10807.     aos rtot        ; Increment total character count.
  10808.     move t1, parity        ; What type of parity?
  10809.     caie t1, none        ; If none, don't touch the parity.
  10810.      andi t2, ^o177        ;  Else, take out parity.
  10811.     retskp            ; Done, return successfully.
  10812.  
  10813. ;[130] Error handler to check for carrier dropped.
  10814.  
  10815. inchxx:    skipn mdmlin        ; Modem controlled line?
  10816.      ret            ;  No, just return +1 to indicate error.
  10817.     move t1, netjfn        ; Yes, see if we still have carrier
  10818.     call chkli2        ; ...
  10819.     skipe carier        ; Do we?
  10820.      ret            ;  Yes, so some other error, handle normally.
  10821.     wtlog <Carrier Dropped, Connection Terminated> ; No, lost it.  Log.
  10822.     movei state, "A"    ; Cancel this transaction.
  10823.     setzm carier        ; Say no more carrier.
  10824.      ret
  10825.  
  10826.  
  10827. ; Come here on timeout, via interrupt handler.
  10828.  
  10829. tmout:    call rperr        ;[46] Clean up timers & buffer...
  10830.     call ttxon        ;[91] Unstop the line in case it was XOFF'd.
  10831.     movei t1, "T"        ; Make believe we got a "Timeout" packet
  10832.     move t2, pktnum
  10833.     setzb t3, t4        ; No data.
  10834.     call diamsg
  10835.     retskp            ; Return successfully as if with real packet.
  10836.  
  10837.     subttl CRC and Parity Routines
  10838.  
  10839.  
  10840. ;[66] CRC calculation
  10841. ;
  10842. ; This routine will calculate the CRC for a string, using the
  10843. ; CRC-CCITT polynomial.
  10844. ;
  10845. ; The string should be the fields of the packet between but not including
  10846. ; the <mark> and the block check, which is treated as a string of bits with
  10847. ; the low order bit of the first character first and the high order bit of the
  10848. ; last character last -- this is how the bits arrive on the transmission line.
  10849. ; The bit string is divided by the polynomial
  10850. ;
  10851. ;  x^16+x^12+x^5+1
  10852. ;
  10853. ; The initial value of the CRC is 0.  The result is the remainder of this
  10854. ; division, used as-is (i.e. not complemented).
  10855. ;
  10856. ; Contributed by Nick Bush, Stevens Institute of Technology.
  10857. ;
  10858. ; Call with
  10859. ;  t1/ length of string
  10860. ;  t2/ 8-bit byte pointer to string
  10861. ; Returns +1 always, with t1/ 16-bit CRC, t2 unchanged.
  10862. ;
  10863. ; AC usage:
  10864. ;    t1/ Accumulated CRC
  10865. ;    q4/ Remaining length
  10866. ;    q3/ Byte pointer to string
  10867. ;    q2/ temp
  10868. ;    q1/ temp
  10869. ;
  10870. crcclc:    saveac <q1,q2,q3,q4,t2>    ; Save q1-q4, and t2.
  10871.     dmove q3,t1        ; Get arguments.
  10872.     setz t1,        ; Initial CRC is 0.
  10873.     move t2, parity        ;[136] Get parity.
  10874.  
  10875. crcc.1:    ildb q1, q4        ; Get a character.
  10876.     caie t2, none        ;[136] Parity = NONE?
  10877.      andi q1, ^o177        ;[136] No, doing parity, strip parity bit.
  10878.     xori q1, (t1)        ; Add in with current CRC.
  10879.     ldb q2, [point 4,q1,31]    ; Get high 4 bits.
  10880.     andi q1, ^o17        ; And low 4 bits.
  10881.     move q1, crctb2(q1)    ; Get low portion of CRC factor.
  10882.     xor q1, crctab(q2)    ; Plus high portion.
  10883.     lsh t1, -^d8        ; Shift off a byte from previous CRC.
  10884.     xor t1, q1        ; Add in new value.
  10885.     sojg q3, crcc.1        ; Loop for all characters.
  10886.     
  10887.     ret            ; Done, return +1 with CRC in t1.
  10888.  
  10889. ; Data tables for CRC-CCITT generation
  10890.  
  10891. crctab:    oct    0
  10892.     oct    10201
  10893.     oct    20402
  10894.     oct    30603
  10895.     oct    41004
  10896.     oct    51205
  10897.     oct    61406
  10898.     oct    71607
  10899.     oct    102010
  10900.     oct    112211
  10901.     oct    122412
  10902.     oct    132613
  10903.     oct    143014
  10904.     oct    153215
  10905.     oct    163416
  10906.     oct    173617
  10907.  
  10908. crctb2:    oct    0
  10909.     oct    10611
  10910.     oct    21422
  10911.     oct    31233
  10912.     oct    43044
  10913.     oct    53655
  10914.     oct    62466
  10915.     oct    72277
  10916.     oct    106110
  10917.     oct    116701
  10918.     oct    127532
  10919.     oct    137323
  10920.     oct    145154
  10921.     oct    155745
  10922.     oct    164576
  10923.     oct    174367
  10924.  
  10925.     subttl    Parity routines
  10926.  
  10927. ; Default, don't touch the eighth bit.
  10928.  
  10929. none:    ret
  10930.  
  10931. ; Mark, bit 8 is always 1.
  10932.  
  10933. mark:    ori t1, ^o200        ; Turn on the parity bit.
  10934.     ret
  10935.  
  10936. ; Space, opposite of mark, bit 8 is always zero.
  10937.  
  10938. space:    andi t1, ^o177        ; Turn off the parity bit.
  10939.     ret
  10940.  
  10941. ; Even, the total number of on bits should be even.
  10942.  
  10943. even:    saveac <t2>
  10944.     andi t1, ^o177        ; Start off with bit 8 = 0.
  10945.     move t2, t1
  10946.     jrst evnodd
  10947.  
  10948. ; Odd, the total number of on bits should be odd.
  10949.  
  10950. odd:    saveac <t2>
  10951.     andi t1, ^o177        ; Turn off the parity bit.
  10952.     movei t2, ^o200(t1)    ; Start off with bit 8 = 1.
  10953.  
  10954. evnodd:    lsh t2, -4        ; Get high order 4 bits of character
  10955.     xori t2, (t1)        ; Fold into 4 bits.
  10956.     trce t2, 14        ; Left two bits both 0 or 1?
  10957.      trnn t2, 14        ;  or both 1?
  10958.      xori t1, 200        ; Yes, set parity
  10959.     trce t2, 3        ; Right two bits both 0?
  10960.      trnn t2, 3        ;  or both 1?
  10961.      xori t1, 200        ; Yes, set parity.
  10962.     ret
  10963.  
  10964.     subttl Server Operation
  10965.  
  10966. ; GETCOM
  10967. ;
  10968. ; We come here if we are in server mode.  We just wait for a packet of one of
  10969. ; the following types:
  10970. ;
  10971. ;    S    Send init - just follow the normal path from here
  10972. ;    R    Receive init - like a local "send filespec"
  10973. ;    I    Init (all-purpose exchange of parameters)
  10974. ;    G    Generic command:
  10975. ;        L    Logout - the other side is done, log out this job
  10976. ;        F    Finish - exit from Kermit
  10977. ;        U    Disk Usage query
  10978. ;        T    Type a file
  10979. ;        etc
  10980. ;
  10981. ; First, issue a message telling the user what to do.
  10982. ;
  10983. getcom:    movei t1, [        ;[157] In case line gets XOFF'd while
  10984.         call ttxon    ;[157] typing the message, unstick it,
  10985.         jrst getcm2 ]    ;[157] and proceed.
  10986.     call timeit        ;[157] Set the timer.
  10987.     skipe local        ;[174] Local mode?
  10988.      jrst [    tmsg <
  10989.  Entering server mode on TTY>    ;[174] Yes, give appropriate message.
  10990.         numout ttynum, 8
  10991.         skipl speed
  10992.          jrst [    tmsg <, >
  10993.             numout speed
  10994.             tmsg < baud>
  10995.             jrst getcmm ]
  10996.         jrst getcmm ]    ;[174]
  10997.     tmsg <
  10998.  Kermit Server running on DEC-20 host.  Please type your escape
  10999.  sequence to return to your local machine.  Shut down the server by
  11000.  typing the BYE command to KERMIT on your local machine.>
  11001.  
  11002. getcmm:    tmsg <
  11003. >
  11004. getcm2:    call timoff        ;[157] Turn off timer.
  11005.     setom srvflg        ; Flag that we are serving.
  11006.     call inilin        ; Initialize the line.
  11007.     call ccon        ; Don't let someone ^C without reseting line.
  11008.      jrst xgfin2        ;  On control-C, go "finish".
  11009.     setzm delay        ; No delay in server mode.
  11010.     setzb t3, t4        ; Set default parameters in case we get some
  11011.     call spar        ;  command before first Send-Init or Info.
  11012.     jrst xxwait        ; Go wait for a command packet.
  11013.  
  11014. ; Server command loop.  Server commands should always jrst back to here,
  11015. ; even upon error, except for those that specify exit from server mode.
  11016. ;
  11017. xxwait:    skipe mdmlin        ;[130] Modem line?
  11018.      skipe carier        ;[130] Did carrier drop?
  11019.      skipa            ;[130] No.
  11020.      jrst xgfin2        ;[130] Yes, go clean up.
  11021.  
  11022.     setom sptot        ;[134] Clear packet statistics counters
  11023.     setom rptot        ;[134] ...
  11024.     setzm xflg        ; Clear the server "type" flag.
  11025.     setzm source        ; Ditto for GETCH source.
  11026.     setzm dest        ; Ditto for PUTCH destination.
  11027.     setzm ffunc        ; And for file function.
  11028.     move t1, srvtim        ; Get the default server packet time out.
  11029.     movem t1, stimou    ; Set it so we don't time out as often.
  11030. xxwt2:    setom bctone        ;[98] Set this so we use type 1 checksum.
  11031.     setzm pktnum        ; Initial packet sequence number.
  11032.     call rpack        ; Get a packet.
  11033.      skipa            ;  On error, NAK what we're looking for.
  11034.     cain t1, "T"        ; Timer interrupt pseudo packet?
  11035.      jrst [    move t2, pktnum    ; Yes, NAK that "packet".
  11036.         call nak    ;
  11037.          jrst xxwt2    ; Go round again.
  11038.         jrst xxwt2 ]    ; (no matter what)
  11039.     cail t1, "A"        ;[150] Packet type in range?
  11040.      caile t1, "Z"        ;[150]
  11041.      kermsg <Packet type out of range>,xxwait ;[150] No.
  11042.  
  11043. ; Got a real command.  Restore the normal timeout interval and do the command.
  11044.  
  11045.     movem t2, pktnum    ; Save packet number.
  11046.     push p, t1        ; We can't use any normal AC's here...
  11047.     move t1, otimou        ; Put normal timeout back.
  11048.     movem t1, stimou
  11049.     pop p, t1
  11050.     jrst @<xxcmd-<"A">>(t1)    ;[150] Go do the indicated command.
  11051.  
  11052. ;[150] Server command dispatch table and error message routines.
  11053.  
  11054.  
  11055. xxcmd:    xxinv            ; A - Attributes, shouldn't come now
  11056.     xxinv            ; B - EOT, shouldn't come now
  11057.     xhost            ; C - Host Command
  11058.     xxinv            ; D - Data, shouldn't come now
  11059.     xxwait            ; E - Error, just ignore
  11060.     xxinv            ; F - File header, shouldn't come now
  11061.     xgen            ; G - Generic Command
  11062.     xxunk            ; H - Undefined
  11063.     xinfo            ; I - Info Packet
  11064.     xxunk            ; J - Undefined
  11065.     xxunk            ; K - Undefined
  11066.     xxunk            ; L - Undefined
  11067.     xxunk            ; M - Undefined
  11068.     xxwait            ; N - NAK, ignore
  11069.     xxunk            ; O - Undefined
  11070.     xxunk            ; P - Undefined
  11071.     xxunk            ; Q - Undefined
  11072.     xrecv            ; R - Receive (GET), server sends
  11073.     xsend            ; S - Send, server receives
  11074.     xxwait            ; T - (Already handled specially above)
  11075.     xxunk            ; U - Undefined
  11076.     xxunk            ; V - Undefined
  11077.     xxunk            ; W - Undefined
  11078.     xxinv            ; X - Text Header, shouldn't come now
  11079.     xxwait            ; Y - ACK, ignore
  11080.     xxinv            ; Z - EOF, shouldn't come now
  11081.     0            ; (superstition)
  11082.  
  11083. ; Routine to issue informative error messages.
  11084.  
  11085. xxunk:    move t4, [point 7, xxumsg] ; Get "unknown command" message.
  11086.     movei t3, xxulen    ; And its length
  11087.     jrst xxmsg
  11088.     
  11089. xxinv:    move t4, [point 7, xxbmsg] ; Get "invalid use of..." message.
  11090.     movei t3, xxblen    ; And its lentgh.
  11091.  
  11092. xxmsg:    push p, t4        ; Save msg pointer.
  11093.     ibp t4            ; Point past opening quote.
  11094.     idpb t1, t4        ; Deposit the packet type.
  11095.     movei t1, "E"        ; Send an Error packet.
  11096.     move t2, pktnum        ; This is the packet number.
  11097.     pop p, t4        ; Get original pointer back.
  11098.     call spack        ; Send the error packet.
  11099.      nop
  11100.     jrst xxwait        ; Go back to command wait.
  11101.  
  11102.     subttl Server commands.
  11103.  
  11104. ; Server SEND command (i.e. send to me, I'm the server, I receive the files.)
  11105. ;
  11106. ; We've just received a Send-Init.
  11107. ;
  11108. xsend:    setzm numtry        ; Packet retry counter.
  11109.     movem t2, pktnum    ; Synchronize packet numbers.
  11110.     call spar        ; Get the Send-Init parameters.
  11111.     move t4, [point 8, data] ;[50] Now send back our own,
  11112.     call rpar        ; which we put in the data field of our ACK.
  11113.     movei t1, "Y"        ; Set up the ACK.
  11114.     move t2, pktnum        ; Packet number.
  11115.     call spack        ; Send the packet.
  11116.      jrst xxwait        ;* Give up if we can't.(?)
  11117.     call rrinit        ;[126] Set things up for receiving.
  11118.     movei state, "F"    ; Set the state to file send.
  11119.     call $recvs        ;[42] Go look like we're receiving.
  11120.      nop            ;
  11121.     jrst xxwait        ; Get another command when done.
  11122.  
  11123.  
  11124.  
  11125. ; Server RECEIVE (or GET) command -- Server sends files.
  11126. ;
  11127. ; We've just received a Receive-Init packet, containing a filename.
  11128. ; (Or a remote TYPE command).  T1-T4 contain packet parameters returned
  11129. ; by RPACK.
  11130. ;
  11131. xrecv:    move t1, t4        ;[141] Pointer to encoded filespec.
  11132.     move t2, t3        ;[141] Number of characters.
  11133.     call decodf        ;[141] Decode it.
  11134.      kermsg <Can't decode filename>, xxwait ;[141] Can't? Give message.
  11135.     move t2, t1        ;[141] Decoded OK, point to decoded filespec.
  11136.  
  11137. ; Entry point when filespec already decoded.
  11138.  
  11139. xrecv2:    movx t1, gj%sht!gj%old!gj%ifg ; Old file and allow wildcarding.
  11140.     GTJFN%            ; Get a JFN.
  11141.      %jsker (,xxwait)    ; Can't, send error packet and loop.
  11142.     movem t1, ndxjfn    ;[111] Got JFN, save wildcard bits here.
  11143.     hrrzm t1, nxtjfn    ;[111] Initialize file lookahead.
  11144.     call gtnfil        ;[111] Get next (in this case, first) file.
  11145.      nop            ;[111] Could never fail, right?
  11146.     call $sends        ; Go send the file(s).
  11147.      nop            ;  (in case it skips for some reason...)
  11148.     jrst xxwait        ; Go back & get another command.
  11149.  
  11150.  
  11151. ; HOST command.
  11152.  
  11153. xhost:    kermsg <Host commands not implemented>, xxwait
  11154.  
  11155. ;[150] Server GENERIC command.  Get the subcommand and execute it.
  11156.  
  11157.  
  11158. xgen:    ildb t1, t4        ; Get the first character of the data field.
  11159.     cail t1, "A"        ; Validate.
  11160.      caile t1, "Z"
  11161.      kermsg <Generic command out of range>, xxwait ; Bad.
  11162.     sos t3            ; Command in range, account for it.
  11163.     jrst @<xxgcmd-<"A">>(t1) ; Dispatch to it.
  11164.  
  11165.  
  11166. ;[150] Server generic command dispatch table.
  11167.  
  11168. xxgcmd:    xgundf            ; A - Undefined
  11169.     xgundf            ; B - Undefined
  11170.     xgcwd            ; C - CWD
  11171.     xgdir            ; D - Directory
  11172.     xgdel            ; E - Erase (delete)
  11173.     xgfin            ; F - Finish
  11174.     xgundf            ; G - Undefined
  11175.     xghelp            ; H - Help
  11176.     xgnyi            ; I - Login (not yet implemented)
  11177.     xgnyi            ; J - Journal control (nyi)
  11178.     xgnyi            ; K - Copy (nyi)
  11179.     xglogo            ; L - Logout, Bye
  11180.     xgnyi            ; M - Short message
  11181.     xgundf            ; N - Undef
  11182.     xgundf            ; O - Undef
  11183.     xgnyi            ; P - Program invocation (nyi)
  11184.     xgnyi            ; Q - Server status query (nyi)
  11185.     xgnyi            ; R - Rename (nyi)
  11186.     xgundf            ; S - Undef
  11187.     xgtype            ; T - Type
  11188.     xgdisk            ; U - Disk Usage
  11189.     xgnyi            ; V - Variable Set/Query
  11190.     xgnyi            ; W - Who (Finger)
  11191.     xgundf            ; X - Undef
  11192.     xgundf            ; Y - Undef
  11193.     xgundf            ; Z - Undef
  11194.     0
  11195.  
  11196. xgundf:    move t4, [point 7, xxgums] ; Issue message for undefined command.
  11197.     movei t3, xxguln
  11198.     jrst xxmsg
  11199.  
  11200. xgnyi:    move t4, [point 7, xxgnms] ; Issue msg for unimplemented command.
  11201.     movei t3, xxgnln
  11202.     jrst xxmsg
  11203.  
  11204. ; Generic commands...
  11205.  
  11206.  
  11207. ; FINISH.  Shut down the server, but don't log out.
  11208.  
  11209. xgfin:    movei t1, "Y"        ;  Acknowledge packet.
  11210.     setzb t3, t4        ;  No data.
  11211.     call spack        ;  Send the packet.
  11212.      nop            ;[56]
  11213.     move t1, netjfn        ;[158] Wait for the ACK to get there.
  11214.     DOBE            ;[158] ...
  11215.      erjmp .+1        ;[158] ...
  11216.     setom f$exit        ;[137] Say we want to go back to command level.
  11217.  
  11218. xgfin2:    call rrslin        ;[121] Put line back in interactive state.
  11219.     move t1, odelay        ;[27] Restore normal delay
  11220.     movem t1, delay        ;[27]
  11221.     move t1, otimou        ;[27] and timout interval
  11222.     movem t1, stimou    ;[27]
  11223.     setzm srvflg        ;[27] and reset the server flag
  11224.     skipe t1, logjfn    ;[38] If we were logging,
  11225.      CLOSF            ;[38]  close the log.
  11226.      erjmp .+1        ;[38]  (Ignore any errors here.)
  11227.     setzm logjfn        ;[38]
  11228.     ret            ; Done
  11229.  
  11230. ; LOGOUT (or BYE) -- Shut down the server and log out.
  11231.  
  11232. xglogo:    movei t1, "Y"        ; Acknowledge the command.
  11233.     setzb t3, t4        ; No data.
  11234.     call spack        ; Send the packet.
  11235.      nop            ;
  11236.     move t1, netjfn        ;[158] Wait for the packet to arrive.
  11237.     DOBE            ;[158]...
  11238.      erjmp .+1        ;[158]...
  11239.     call rrslin        ; Restore the line for interactive use.
  11240.     move t1, odelay        ; Restore normal delay
  11241.     movem t1, delay        ;
  11242.     move t1, otimou        ; and timout interval
  11243.     movem t1, stimou    ;
  11244.     setzm srvflg        ; and reset the server flag.
  11245.     wtlog <BYE Received>    ;[126] Log the BYE.
  11246.     call clenup        ;[126] Close all logs.
  11247.     setom f$exit        ; Just in case we can't logout, set exit flag.
  11248.     seto t1,        ; -1 = Myself.
  11249.     LGOUT%            ; Log me out.
  11250.     %jsker (,r)        ; If this fails, print msg & go back.
  11251.  
  11252. ; Command to TYPE a file.  Just like sending a file, except must send "X"
  11253. ; packet instead of file header.
  11254.  
  11255. xgtype:    call getarg        ; Get the argument.
  11256.     setom xflg        ; Send file with X header.
  11257.     move t2, t4        ;[141] Point to filespec.
  11258.     jrst xrecv2        ;[141] Do like when we get an R packet.
  11259.  
  11260. ;[58] Init-Info mechanism added as edit 58.
  11261. ;
  11262. ; Get an "I" parameters packet from the user, record the parameters, and send
  11263. ; our own back in return.  This exchange is optional, but should take place
  11264. ; before any server/user transaction except file transfer, where it is required
  11265. ; and always takes place via the Send-Init mechanism.
  11266. ;
  11267. xinfo:    movem t2, pktnum    ; Set the parameters we just got.
  11268.     call spar
  11269.     setzm numtry
  11270.     move t4, [point 8, data] ; Respond with ours.
  11271.     call rpar
  11272.     movei t1, "Y"
  11273.     move t2, pktnum
  11274.     call spack
  11275.      nop            ; If they don't get it, they'll ask again...
  11276.     jrst xxwait
  11277.  
  11278. ; GTSCH -- Get String Character
  11279. ;
  11280. ; Alternate GETCH routine for getting a character from an ASCIZ string in
  11281. ; memory.  Uses global STRPTR for input string.
  11282. ;
  11283. ; Returns:
  11284. ;   +1 if no more characters left in string.
  11285. ;   +2 always, with NEXT containing next character, -1 if no more.
  11286. ;
  11287. gtsch:    ildb t1, strptr        ; Get next character.
  11288.     jumpe t1, gtschz    ; If zero, must be done.
  11289.  
  11290. ; Return with character like GETCH.
  11291.  
  11292. gtschx:    movem t1, next        ; Put result in NEXT, as GETCH does.
  11293.     retskp            ; Done.
  11294.  
  11295. ; "EOF" return, like GETCH
  11296.  
  11297. gtschz:    setz t1,
  11298.     setom next
  11299.     ret
  11300.  
  11301. ; PUTSCH
  11302. ;
  11303. ; Alternate PUTCH routine.  Just writes the character to a string in memory.
  11304. ; Call with t2/ character to write.
  11305. ;
  11306. putsch:    idpb t2, strptr        ; Here's the alternate PUTCH routine.
  11307.     retskp            ; It always succeeds.
  11308.  
  11309.  
  11310. ; PUTTCH
  11311. ;
  11312. ; Another alternate PUTCH routine.  Writes the character to the terminal.
  11313. ; Call like PUTCH and PUTSCH.
  11314. ;
  11315. puttch:    skipe local        ;[177] But only if in remote mode.
  11316.      retskp            ;[177]  ...
  11317.     push p, t1
  11318.     movei t1, .priou
  11319.     BOUT    
  11320.      erjmp .+1
  11321.     pop p, t1
  11322.     retskp
  11323.  
  11324.  
  11325. ; GETARG
  11326. ;
  11327. ; Decode server command packet, set up pointers, get first argument.
  11328. ;
  11329. ; Return +1 with:
  11330. ;  t3/ Length of first argument
  11331. ;  t4/ pointer to first argument
  11332. ;
  11333. getarg:    movei t1, putsch    ; Address of alternate PUTCH routine.
  11334.     movem t1, dest
  11335.     setzm strbuf        ; Clear decoding area.
  11336.     move t1, [strbuf,,strbuf+1]
  11337.     blt t1, strbz
  11338.     move t1, [point 7, strbuf] ; Where to put the decoded string.
  11339.     movem t1, strptr
  11340.     move t1, t4        ; Pointer to data to decode.
  11341.     move t2, t3        ; Length.
  11342.     call putbuf        ; Go decode the packet.
  11343.      jrst [    setzm dest
  11344.         kermsg <Can't decode server command>, xxwait ]
  11345.     setzm dest        ; Put PUTCH back to normal.
  11346.     move t4, [point 7, strbuf] ; Point to decoded string.
  11347.     ildb t3, t4        ; Get CHAR(length) of directory string.
  11348.     caige t3, 40        ;[128] If null, no need to convert.
  11349.      movei t3, 40        ;[128] This also catches funny cases.
  11350.     subi t3, 40        ; UNCHAR of that to make a number.
  11351.     ret
  11352.  
  11353. ;[107] CWD server command (Connect to directory in DEC-20 parlance).
  11354. ;
  11355. ; Changes Working Directory, sends new directory name back in ACK, or else
  11356. ; error packet if there's a problem.
  11357. ;
  11358. ; Arrive here with t4 containing pointer to argument string of form
  11359. ;  <length><directory><length><password>
  11360. ; where <length> is a single character (offset by CHAR),
  11361. ; and t3 containing the length of the string.
  11362. ;
  11363. xgcwd:    call getarg        ; Get the first argument.
  11364.     jumpg t3, xgcwd3    ; If positive, go handle string.
  11365.     jumpe t3, xgcwd5    ; If null, go connect back to own directory.
  11366.  
  11367.     kermsg <Bad length field in CWD packet>,xxwait ; Negative length???
  11368.  
  11369. ; Set up argument block for ACCES
  11370.  
  11371. xgcwd3:    move q1, t4        ; Byte pointer to directory string.
  11372.     adjbp t3, t4        ; Now point to password.
  11373.     ildb t4, t3        ; Get its length.
  11374.     move q2, t3        ; Put pointer in ACCES arg block.
  11375.     subi t4, 40        ; UNCHAR to make it a number.
  11376.     skipge t4        ; Normal kind of number?
  11377.      setz t4,        ;  No, must have fallen off end, so no pswd.
  11378.     setz t2,        ; Zero the length to make directory asciz.
  11379.     dpb t2, t3        ;  ...
  11380.     adjbp t4, t3        ; Make sure password is asciz.
  11381.     idpb t2, t4
  11382.  
  11383. ; Access the directory. ** Maybe should also mount structure if necessary?
  11384.  
  11385. xgcwd4:    move t1, [ac%con!<3>]    ; Function is Connect, arg block has 2 words.
  11386.     movei t2, q1        ; Address of argument block.
  11387.     seto q3,        ; Own job.
  11388.     ACCES
  11389.      %jsker (,xxwait)    ; Send any error message in error packet.
  11390.     jrst xgcwdz        ; Done connecting, go send ACK.
  11391.  
  11392. ;...XGCWD, cont'd
  11393.  
  11394.  
  11395. ; Come here to connect to own directory.
  11396.  
  11397. xgcwd5:    seto t1,        ; This job.
  11398.     hrroi t2, q1        ; Want one word, put it in q1.
  11399.     movei t3, .jilno    ; Logged-in directory number.
  11400.     GETJI
  11401.      %jsker (,xxwait)
  11402.     move t1, [ac%con!<3>]    ; Function is connect.
  11403.     setz q2,        ; No password needed
  11404.     seto q3,        ; Own job.
  11405.     movei t2, q1        ; Address of arg block.
  11406.     ACCES            ; Connect to own directory.
  11407.      %jsker (,xxwait)
  11408.     ;...
  11409.  
  11410. ;...XGCWD, cont'd
  11411.  
  11412.  
  11413. ; Done, send back ACK with directory string in it.
  11414.  
  11415. xgcwdz:    GJINF
  11416.     move t1, [point 7, strbuf]
  11417.     movem t1, strptr
  11418.     DIRST
  11419.      %jsker (,xxwait)
  11420.  
  11421.     movei t1, gtsch        ; Indicate routine to be used for getting
  11422.     movem t1, source    ;  characters.
  11423.     setom next        ; Set initial condition.
  11424.     move t1, maxdat        ; Get a buffer full of data.
  11425.     call getbuf        ; ...
  11426.      jumpn t1, xxwait    ;
  11427.     setzm source        ; Put GETCH back to normal.
  11428.     move t3, t1        ; Length
  11429.     movei t1, "Y"        ; Y for Yes (ACK)
  11430.     setz t2,        ; Packet number 0.
  11431.     move t4, [point 8, data] ; Point to string built by getbuf.
  11432.     call spack        ; Send the ACK.
  11433.      nop            ;  Nothing much we can do here...
  11434.     jrst xxwait        ; Done.
  11435.  
  11436. ;[56] Disk USAGE server query added in edit 56.
  11437. ;
  11438. ; Assumes reply will fit in data field of ACK packet; does not use
  11439. ; text header ("X") protocol.  Sends as much of reply as will fit.
  11440. ;
  11441. xgdisk:    seto t1,        ; Get disk usage of connected directory.
  11442.     GTDAL%
  11443.      %jsker <Can't get disk usage>,r
  11444.     dmove q1, t1        ; Save the numbers in q1,q2.
  11445.  
  11446.     move t1, [point 7, strbuf] ;[103] String pointer to data field.
  11447.     movem t1, strptr    ;[103]
  11448.     hrroi t2, [asciz/Quota: /]
  11449.     setzb t3, t4        ; Source string is null-terminated.
  11450.     SOUT%
  11451.      erjmp xgdis2
  11452.  
  11453.     move t2, q1        ; Quota, or "+Inf"
  11454.     cail t2, [^d100000000]
  11455.      jrst [    hrroi t2, [asciz/+Inf/]
  11456.         SOUT
  11457.         jrst xgdsk2 ]
  11458.  
  11459.     movei t3, ^d10        ;  in decimal
  11460.     NOUT%
  11461.      erjmp xgdis2
  11462.  
  11463. xgdsk2:    hrroi t2, [asciz/, used: /]
  11464.     setzb t3, t4
  11465.     SOUT%
  11466.      erjmp xgdis2
  11467.     move t2, q2        ; Pages used,
  11468.     movei t3, ^d10        ;  in decimal
  11469.     NOUT%
  11470.      erjmp xgdis2
  11471.     hrroi t2, [asciz/ (pages)/] ; Specify units
  11472.     setzb t3, t4
  11473.     SOUT%
  11474.      erjmp xgdis2
  11475.  
  11476. xgdis2:    move t2, strptr        ;[103] Check length
  11477.     exch t1, t2
  11478.     call subbp
  11479.      %jsker <subbp foulup>,r
  11480.     idpb t4, t2        ; Done constructing string, make it asciz
  11481.     move q1, spsiz        ; Is the string bigger than max size to send?
  11482.     subi q1, 5
  11483.     caig q1, (t3)        ; (it should always fit).
  11484.      move t3, q1        ;  Yes, so cut it off at the limit.
  11485.     ;..
  11486.  
  11487. ;...XGDISK, cont'd
  11488.  
  11489.  
  11490. ;[103] Begin Change: Use standard packet filling technique to send this.
  11491.  
  11492.     movei t1, gtsch        ; Indicate routine to be used for getting
  11493.     movem t1, source    ;  characters.
  11494.     setom next        ; Set initial condition.
  11495.     move t1, maxdat        ; Get a buffer full of data.
  11496.     call getbuf        ; ...
  11497.      jumpn t1, xxwait    ;
  11498.     move t3, t1        ; Set up length.
  11499.     setzm source        ; Put GETCH back to normal.
  11500.  
  11501. ;[103] End Change.   Now send the packet.
  11502.  
  11503. xgdisz:    movei t1, "Y"        ; Formulate the ACK
  11504.     setz t2,        ; (Packet number should be 0, right?)
  11505.     move t4, [point 8, data] ; The data itself
  11506.     call spack        ; Send it off.
  11507.      nop            ;* What if it fails?
  11508.     jrst xxwait
  11509.  
  11510. ;[120] HELP server command.
  11511.  
  11512. srvhlp:    asciz /
  11513. The DECSYSTEM-20 KERMIT server is capable of the following:
  11514.  
  11515.                                     Command you would normally type to your
  11516.   Server Function:                  local KERMIT to invoke the server function:
  11517.  
  11518.   Receive a file or file group      SEND filespec
  11519.   Send a file or file group         GET filespec
  11520.   Logout                            BYE
  11521.   Exit to TOPS-20                   FINISH
  11522.   Delete a file or file group       REMOTE DELETE filespec
  11523.   List file(s) at the terminal      REMOTE TYPE filespec
  11524.   Provide a directory listing       REMOTE DIRECTORY filespec
  11525.   Change working directory          REMOTE CWD directory [password]
  11526.   Report disk usage                 REMOTE SPACE
  11527.   Send this message                 REMOTE HELP
  11528. /
  11529. srvhz:    0
  11530.     0            ; This padding seems to be necessary...
  11531.  
  11532. xghelp:    move t1, [point 7, srvhlp] ; Point to help text.
  11533.     movem t1, strptr    ; Put pointer here, where
  11534.     movei t1, gtsch        ;  routine for getting chars from a string
  11535.     movem t1, source    ;  can find it.
  11536.     setom next        ; Init char lookahead
  11537.     setom xflg        ; Send with X rather than F header.
  11538.     call $sends        ; Go send the text like a file
  11539.      nop
  11540.     setzm source        ;[121] Put send source back to normal.
  11541.     jrst xxwait
  11542.  
  11543. ;[116] DIRECTORY server command.
  11544.  
  11545. ; DIRCH
  11546. ;
  11547. ; Alternate GETCH routine for getting characters from a directory listing
  11548. ; in a memory buffer, and for refilling the buffer when it gets empty.
  11549. ;
  11550. dirch:    ildb t1, getptr        ; Get character.
  11551.     skipe t1        ; Null?
  11552.      jrst dirchx        ;  No, return the character.
  11553.  
  11554. ; No characters in buffer, try to refill.
  11555.  
  11556. dirch2:    call dmpbuf        ; If so, reset the buffer pointers, etc.
  11557.     call dirlst        ; And try to fill the listing buffer again.
  11558.     jumpe t1, dirchz    ; No more, done.
  11559.     move t1, [point 7, srvbuf] ; Get new listing buffer pointer.
  11560.     movem t1, getptr    ; Save it for getting characters.
  11561.     ildb t1, getptr        ; Get first character of new buffer.
  11562.     jumpe t1, dirchz    ; This shouldn't happen...
  11563.  
  11564. ; Return with character like GETCH.
  11565.  
  11566. dirchx:    movem t1, next
  11567.     retskp
  11568.  
  11569. ; "EOF" return, like GETCH.
  11570.  
  11571. dirchz:    setz t1,
  11572.     setom next
  11573.     ret
  11574.  
  11575. ; XGDIR - Server provides directory listing.
  11576.  
  11577. xgdir:    call getarg        ; Get the first (& only) argument
  11578.     jumpg t3, xgdir2    ; Got something, go do it.
  11579.     jumpe t3, [        ; Got nothing, do default directory.
  11580.         move t4, [point 7, [asciz/*.*.*/]] ;[174] (not hrroi!)
  11581.         jrst xgdir2 ]
  11582.  
  11583.     kermsg <Bad length field in DIRECTORY command>,xxwait ; Got junk.
  11584.  
  11585. ; Get JFN on the string we got, supply normal defaults like Exec does.
  11586.  
  11587. xgdir2:    move t2, t4        ; Point to filespec
  11588.     adjbp t3, t4        ; Make it asciz
  11589.     setz t4,
  11590.     idpb t4, t3
  11591.     movei t1, sdirbk    ; JFN block containing flags & defaults.
  11592.     GTJFN            ; Do long form GTJFN.
  11593.      %jsker (,xxwait)    ; Send error packet if we can't.
  11594.     move t2, t1        ; Construct heading in string buffer.
  11595.     setzm ffunc        ; Function is "directory".
  11596.     call dirhdr
  11597.     move t1, [point 7, srvbuf] ; Point to beginning of text buffer.
  11598.     movem t1, getptr    ; This is where we'll get characters from.
  11599.     movei t1, dirch        ; And this routine will do the getting.
  11600.     movem t1, source    ;  ...
  11601.     setom next        ; Initialize character lookahead.
  11602.     setom xflg        ; This produces some desired effects...
  11603.     call $sends        ; Go send the listing like it's a file.
  11604.      nop            ;  Ignore any skipping...
  11605.     jrst xxwait
  11606.  
  11607. sdirbk:    gj%old!gj%ifg!.gjall    ; Flags,,All generations.
  11608.     .nulio,,.nulio        ; No i/o.
  11609.     repeat <2>,<0>        ; Default device and directory.
  11610.     repeat <2>,<-1,,[asciz/*/]> ; Default name is "*.*"
  11611.     repeat <4>,<0>        ; Nothing special for the rest.
  11612.  
  11613.  
  11614. ;[118] XGDEL - Server provides file deletion.
  11615.  
  11616. xgdel:    call getarg        ; Get the first (& only) argument
  11617.     jumpg t3, xgdel2    ; Got something, go do it.
  11618.  
  11619.     kermsg <No file specified for deletion>,xxwait
  11620.  
  11621. ; Get JFN on the string we got, supply normal defaults like Exec does.
  11622.  
  11623. xgdel2:    move t2, t4        ; Point to filespec
  11624.     adjbp t3, t4        ; Make it asciz
  11625.     setz t4,
  11626.     idpb t4, t3
  11627.     movei t1, sdelbk    ; JFN block containing flags & defaults.
  11628.     GTJFN            ; Do long form GTJFN.
  11629.      %jsker (,xxwait)    ; Send error packet if we can't.
  11630.     move t2, t1        ; Construct heading in string buffer.
  11631.     movei t1, delfil    ; Routine for deleting a file.
  11632.     movem t1, ffunc        ; Make it the file function.
  11633.     call dirhdr        ; Start things off.
  11634.     move t1, [point 7, srvbuf] ; Point to beginning of text buffer.
  11635.     movem t1, getptr    ; This is where we'll get characters from.
  11636.     movei t1, dirch        ; And this routine will do the getting.
  11637.     movem t1, source    ;  ...
  11638.     setom next        ; Initialize character lookahead.
  11639.     setom xflg        ; This produces some desired effects...
  11640.     call $sends        ; Go send the listing like it's a file.
  11641.      nop            ;  Ignore any skipping...
  11642.     jrst xxwait
  11643.  
  11644. sdelbk:    gj%old!gj%ifg!.gjall    ; Flags,,All generations.
  11645.     .nulio,,.nulio        ; No i/o.
  11646.     repeat <^d8>,<0>    ; No other defaults.
  11647.  
  11648.     subttl    Timer Routines
  11649.  
  11650. ; Set a timer.  Call with t1/ Address of where to go upon timout.
  11651.  
  11652. timeit:    skipg stimou        ;[43] Doing timeouts?
  11653.      ret            ;[43]  No, skip this.
  11654.     pop p, t2        ; Get the return address off the stack.
  11655.     movem p, intstk        ; Save the stack.
  11656.     push p, t2        ; Restore stack.
  11657.     hrr t2, t1        ; Make interrupt PC point to time out addr.
  11658.     movem t2, intpc        ; Save the PC.
  11659.     movei t1, .fhslf
  11660.     movx t2, 1b0        ; Turn on channel 0.
  11661.     AIC
  11662.      %jserr <TIMEIT - Can't turn on timer channel>, <.+1>
  11663.  
  11664. ;[132] Remove any pending timer requests.
  11665.  
  11666. timei2:    move t1, [.fhslf,,.timal] ; Remove all pending timer requests.
  11667.     setzb t2, t3
  11668.     TIMER
  11669.      aos timerx        ; If we get a timer error, just count it.
  11670.  
  11671. timei3:    setz t1,        ;[130] Get 1-minute load average.
  11672.     call ldav        ;[130]
  11673.     move t2, stimou        ;[130] Minimum acceptable.
  11674.     call adjtim        ;[128] Adjust based on load average.
  11675.     move t1, [.fhslf,,.timel] ; Our process and time from now.
  11676.     movem t2, curtim    ;[131] Remember this for reporting.
  11677.     imuli t2, ^d1000    ; Make time into milliseconds.
  11678.     setz t3,        ; Channel zero.
  11679.     TIMER
  11680.      aos timerx        ; If we get an error, count it.
  11681.     ret
  11682.  
  11683. ; TIMOFF -- Turn off timer.
  11684.  
  11685. timoff:    skipg stimou        ;[43] Doing timeouts?
  11686.      ret            ;[43]  No, skip this.
  11687.     saveac <t1,t2>        ; Yes, save these ACs.
  11688.     move t1, [.fhslf,,.timbf] ; Turn off timer interrupts for this fork.
  11689.     hrloi t2, 377777    ; For all times before this (far in future).
  11690.     TIMER            ;
  11691.      aos timerx        ;  Count any error.
  11692.     movx t1, .fhslf        ; Deactivate the channel.
  11693.     movx t2, 1b0
  11694.     DIC
  11695.     ret
  11696.  
  11697. ; TMTRAP -- Timer interrupt handler.
  11698.  
  11699. tmtrap:    push p, t1        ; Get a work AC.
  11700.     move t1, intpc        ; Get the PC we want.
  11701.     hrli t1, (1b5)        ;[132] Set user mode to escape from any jsys.
  11702.     movem t1, pc1        ; Restore as if we came from there.
  11703.     pop p, t1
  11704.     move p, intstk        ; Pop any junk off the stack.
  11705.     aos ntimou        ; Count the timeout.
  11706.     DEBRK
  11707.  
  11708. ;[128] Make this a separate routine.
  11709. ;
  11710. ; ADJTIM -- Adjust timeout interval based on load average (ldav).
  11711. ;
  11712. ; Calculate Timeout = mintim + (ldav-MINLOD)*((MAXTIM-mintim)/MAXLOD)
  11713. ; If the load is low, this gives the minimum acceptable timeout, mintim.
  11714. ; If the load is very high, this gives the maximum timeout, MAXTIM.
  11715. ; In between, the timeout goes up linearly with given load average.
  11716. ; MINLOD, MAXLOD, and MAXTIM are defined as global symbols.
  11717. ;
  11718. ; Call with:
  11719. ;  t1/ 1, 5, or 15 minute ldav, floating point number as returned by GETAB.
  11720. ;  t2/ minimum acceptable timeout (mintim), seconds (integer).
  11721. ; Returns +1 always, with
  11722. ;  t2/ adjusted timeout interval, in seconds (integer).
  11723. ;
  11724. adjtim:    stkvar <mintim>        ; Local storage for second argument.
  11725.     movem t2, mintim    ; Save the minimum for later.
  11726.     fsb t1, [minlod]    ; Adjust load by subtracting the minimum.
  11727.     skipg t1        ; If negative, make it zero.
  11728.      setz t1,
  11729.     caml t1, [maxlod]    ; If too big, cut it off.
  11730.      move t1, [maxlod]
  11731.     movei t2, maxtim    ; Maximum timeout, seconds.
  11732.     sub t2, mintim        ; Less specified timeout interval.
  11733.     fltr t2, t2        ; Floated.
  11734.     fdv t2, [maxlod]    ; Divided by maximum load.
  11735.     fmp t1, t2        ; Multiplied by actual (adjusted) load.
  11736.     fixr t2, t1        ; Fixed & rounded.
  11737.     add t2, mintim        ; Add in requested minimum timeout.
  11738.     ret            ; Return with result in t2.
  11739.  
  11740. ;[130] This routine added as part of edit 130.
  11741. ;
  11742. ; LDAV -- Get the current load average.  Takes class scheduling into account.
  11743. ;
  11744. ; Call with
  11745. ;  t1/ 0 for 1-min, 1 for 5-min, 2 for 15-min ldav.
  11746. ;  SKDFLG/ -1 for class scheduler running, 0 for no class scheduler.
  11747. ;  CLASS/  This job's scheduler class.
  11748. ;
  11749. ; Returns +1 always, with requested load average in t1.
  11750. ;
  11751. ldav:    saveac <q1>        ; Save this.
  11752.     cail t1, 0        ; Argument in range?
  11753.      caile t1, 2
  11754.      setz t1,        ; Force to 0.
  11755.     move q1, t1        ; Save argument here.
  11756.     skipe skdflg        ; Class scheduler on?
  11757.      jrst ldav3        ;  Yes, go do it the special way.
  11758.  
  11759. ; Class scheduler off, use GETAB for system-wide load average.
  11760.  
  11761. ldav2:    hrlz t1, q1        ; Desired load average.
  11762.     add t1, [14,,.systa]    ; Scheduler off,
  11763.     GETAB            ;  use load avg from SYSTAT monitor table.
  11764.      erjmp ldavx
  11765.     ret
  11766.  
  11767. ; Class scheduler on, get load avg for this class from SKED%.
  11768.  
  11769. ldav3:    skipge t1, class    ; This job's scheduler class.
  11770.      jrst ldav2        ; Unless there was some error getting it...
  11771.  
  11772.     movem t1, skdblk+.sacls    ; Put it in the SKED% arg block.
  11773.     movei t1, 10        ; Arg block length
  11774.     movem t1, skdblk+.sacnt
  11775.     movei t1, .skrcs    ; Function is read class parameters.
  11776.     movei t2, skdblk    ;  into this arg block.
  11777.     SKED%
  11778.      %jserr (,ldavx)
  11779.     move t1, skdblk+.sa1ml(q1) ; Return the desired value.
  11780.     ret
  11781.  
  11782. ldavx:    move t1, [minlod]    ; Return this in case of any error.
  11783.     ret
  11784.  
  11785.     subttl    Interrupt Routines
  11786.  
  11787.  
  11788. ; Initialize the Priority Interrupt system.
  11789.  
  11790. pinit:    movei t1, .fhslf    ; This fork.
  11791.     move t2, [levtab,,chntab] ; Say where our tables are.
  11792.     SIR
  11793.     EIR            ; Enable the interrupt system.
  11794.     ret
  11795.  
  11796.  
  11797. ; Turn Control-C trap on.  Sets things up so that ^C will return control
  11798. ; to the instruction FOLLOWING the the call to this routine, with the
  11799. ; stack fixed up appropriately, e.g.
  11800. ;
  11801. ;    call ccon        ; Turn on ^C trap
  11802. ;     jrst foo        ; What to do if ^C is typed.
  11803. ;    move x, y        ; Execute this after the call to CCON.
  11804. ;
  11805. ; Returns +2 always.
  11806. ;    
  11807. $ccn==2                ; Number of ^C's to get out of ^C trap.
  11808.  
  11809. ccon:    movei t1, .fhslf    ; Read current process capabilities.
  11810.     RPCAP%
  11811.  
  11812. ;[10] Try to enable ^C capabilities unless under batch.
  11813.  
  11814.     tloe t3, (sc%ctc)    ; Do we have Control-C capas?
  11815.      jrst ccon2        ;  Yes, go on.
  11816.     EPCAP%            ; Nope, try to get them.
  11817.     RPCAP%            ; Did we?
  11818.     skipn jobtab+.jibat    ; Under batch?
  11819.      tloe t3, (sc%ctc)    ; Check the ^C bit.
  11820.      jrst ccon2        ;  If under batch
  11821.     ermsg <Can't enable ^C capability>,r ; Not under batch, give up.
  11822.  
  11823. ccon2:    movem t3, capas        ; Save them.
  11824.     movei t1, $ccn         ; Initialize ^C count to this.
  11825.     movem t1, ccn
  11826.     movem p, psave        ;[27] Save stack pointer.
  11827.     move t1, (p)        ;[27] And what it points to...
  11828.     movem t1, psave2    ;[27]
  11829.     movx t1, .fhslf        ; Now, for this fork,
  11830.     movx t2, 1b1        ;  activate channel 1
  11831.     AIC            ;  ...
  11832.      erjmp .+1        ;[10]
  11833.     move t1, [.ticcc,,1]    ;  for ^C.
  11834.     ATI            ;
  11835.      erjmp .+1        ;[10]
  11836.     retskp
  11837.  
  11838. ; Turn Control-C trap off.
  11839.  
  11840. ccoff:    skipe srvflg        ;[81] Being a server?
  11841.      ret            ;[81] Yes, so don't turn off the ^C trap.
  11842.  
  11843. ; Entry point for REALLY turning it off, even if server.
  11844.  
  11845. ccoff2:    saveac <t1,t2,t3>    ; Save these.
  11846.     setzm ccn        ; Put ^C count back to 0.
  11847.     movx t1, .fhslf        ; This fork.
  11848.     movx t2, 1b1        ; Deactivate channel 1.
  11849.     DIC
  11850.     RTIW            ; Fix up the interrupt mask
  11851.     tlz t2, (1b3)        ;  for ^C... (^C = ASCII 3 = bit 3)
  11852.     STIW            ;  ...
  11853.     move t3, capas        ; Restore capabilities.
  11854.     EPCAP
  11855.      erjmp .+1
  11856.     ret
  11857.  
  11858. ;[59] ^A, ^X, and ^Z interrupt control added as part of edit 59.
  11859.  
  11860. caxzon:    Remark - Turn on ^A, ^X, and ^Z interrupts.
  11861.  
  11862.     setzm cxseen        ; Say we haven't seen a ^X yet,
  11863.     setzm czseen        ; nor a ^Z.
  11864.     setzm caseen        ;  ...
  11865.     skipn local        ; Only do this if local!
  11866.      ret
  11867.     movei t1, .fhslf    ; This fork.
  11868.     movx t2, 1b<cachan>!1b<cxchan>!1b<czchan> ; Turn on the channels.
  11869.     AIC%
  11870.     move t1, [.ticca,,cachan] ; Put ^A on its channel.
  11871.     ATI%
  11872.     move t1, [.ticcx,,cxchan] ; Put ^X on its channel.
  11873.     ATI%
  11874.     move t1, [.ticcz,,czchan] ; And ^Z on its.
  11875.     ATI%
  11876.     ret
  11877.  
  11878. cmpon:    Remark - ^M, ^P interrupts on.
  11879.     movei t1, .fhslf    ; This fork.
  11880.     movx t2, 1b<cmchan>!1b<cpchan> ; These channels.
  11881.     AIC            ; Activate interrupt system.
  11882.     move t1, [.ticcm,,cmchan] ; Assign ^M to this channel.
  11883.     ATI
  11884.     setzm cmseen
  11885.     move t1, [.ticcp,,cpchan] ; Assign ^P to this one.
  11886.     ATI
  11887.     setzm cpseen
  11888.     ret
  11889.  
  11890. caxzof: Remark - Turn off ^A,^X,^Z interrupts.
  11891.  
  11892.     setzm cxseen        ; Turn off the flags
  11893.     setzm czseen        ;  ...
  11894.     setzm caseen        ;  ...
  11895.     skipn local        ; Nothing to do if remote, the interrupts
  11896.      ret            ;  weren't on anyway.
  11897.     movx t1, .fhslf        ; Turn off ^A,^X,^Z traps.
  11898.     movx t2, 1b<cachan>!1b<cxchan>!1b<czchan> ; Turn off these channels.
  11899.     DIC%            ; ...
  11900.     RTIW%            ; Fix up the interrupt mask
  11901.     tdz t2, [<1b1+1b24+1b26>] ; for ^A,^X,^Z
  11902.     STIW%            ;  ...
  11903.      %jserr (,.+1)
  11904.     ret
  11905.  
  11906. ; ^M, ^P interrupts off.
  11907.  
  11908. cmpoff:    setzm cmseen
  11909.     setzm cpseen
  11910.     movx t1, .fhslf        ; Turn off ^M trap.
  11911.     movx t2, 1b<cmchan>!1b<cpchan> ; Turn off channels.
  11912.     DIC            ; ...
  11913.     RTIW            ; Fix up the terminal interrupt mask
  11914.     tdz t2, [<1b13>!<1b16>]    ; for ^M, ^P
  11915.     STIW
  11916.      %jserr (,.+1)
  11917.     ret
  11918.  
  11919. cctrap:    sosle ccn        ; Count the ^C's.
  11920.      DEBRK%            ; If they haven't typed enough, just resume.
  11921.     call timoff        ; Turn off any timer.
  11922.     hrroi t1, [asciz/^C
  11923. /]
  11924.     PSOUT%            ; Echo the ^C.
  11925.  
  11926.     move p, psave        ;[27] Make sure stack pointer is right.
  11927.     move t1, psave2        ;[27] And stack top.
  11928.     movem t1, (p)        ;[27]
  11929.     hrli t1, (1b5)        ;[27] Get into user mode.
  11930.     movem t1, pc1        ; Put this place into our PC.
  11931.     pop p, t1        ;[80] Don't need it on the stack any more.
  11932.     DEBRK%            ; Resume where stack pointer points.
  11933.  
  11934. ;[61] Control-A trap handler.  Give brief progress report at terminal.
  11935. ;
  11936. catrap:    push p, t1        ; Save all ACs we might use.
  11937.     push p, t2
  11938.     push p, t3
  11939.     skipn rcving        ; Sending or receiving a file?
  11940.      jrst catrp1        ;  No.
  11941.     hrroi t1, [asciz/^A
  11942.  Sending /]            ; Yes, one...
  11943.     skipg rcving
  11944.      hrroi t1, [asciz/^A
  11945.  Receiving /]            ; ...or the other.
  11946.     PSOUT%
  11947.     movei t1, .priou    ; Say the filename
  11948.     setz t3,
  11949.     skipe t2, filjfn
  11950.      JFNS%
  11951.      erjmp .+1
  11952.     tmsg <, file bytesize >    ; File bytesize
  11953.     numout bytsiz
  11954.     skipl rcving        ; I/O bytesize, only if sending
  11955.      jrst [    tmsg <, i/o bytesize >
  11956.         movei t2, 7
  11957.         skipn itsfil    ;[75]
  11958.          skipe ebtflg
  11959.          movei t2, 8
  11960.         numout t2
  11961.         jrst .+1 ]
  11962.     tmsg <
  11963. >                ;[92]
  11964.     hrroi t1, [asciz/ (ITS binary)/] ;[75]
  11965.     skipe itsfil        ;[75]
  11966.      PSOUT            ;[75]
  11967.     hrroi t1, [asciz/ (8th-bit prefixing)/] ;[88]
  11968.     skipe ebqflg        ;[88]
  11969.      PSOUT            ;[88]
  11970.     hrroi t1, [asciz/ (compression)/] ;[92]
  11971.     skipe rptflg        ;[92]
  11972.      PSOUT            ;[92]
  11973.     hrroi t1, [asciz/ (block check type /] ;[98]
  11974.     PSOUT
  11975.     numout bctu        ;[98]
  11976.     movei t1, ")"        ;[98]
  11977.     PBOUT            ;[98]
  11978.     tmsg <
  11979.  At page >            ; What page we're at.
  11980.     move t2, pagno
  11981.     aos t2
  11982.     numout t2
  11983.     skipl rcving        ; Out of how many
  11984.      jrst [    tmsg < of >    ; (which we know only if we're sending)
  11985.         numout pagcnt
  11986.         jrst .+1 ]
  11987.  
  11988.     ;...
  11989.  
  11990. ;...CATRAP, cont'd
  11991.  
  11992.  
  11993. catrp1:    tmsg <
  11994.  Files: >            ; Say how many files,
  11995.     numout files
  11996.     tmsg <, packets: >    ; packets,
  11997.     skipl rcving
  11998.      numout sptot
  11999.     skipg rcving
  12000.      numout rptot
  12001.     tmsg <, chars: >    ; characters,
  12002.     move t2, stchr
  12003.     add t2, schr
  12004.     skipl rcving
  12005.      numout t2
  12006.     move t2, rtchr
  12007.     add t2, rchr
  12008.     skipg rcving
  12009.      numout rtot
  12010.     tmsg <
  12011.  NAKs: >            ; NAKS & timeouts.
  12012.     numout nnak
  12013.     tmsg <, timeouts: >
  12014.     numout ntimou
  12015.     tmsg <
  12016. >                ; End up with a CRLF
  12017.  
  12018.     pop p, t3        ; Restore ACs.
  12019.     pop p, t2
  12020.     pop p, t1
  12021.  
  12022.     DEBRK%            ; Resume.
  12023.  
  12024. ;[59] Control-X trap handler.
  12025.  
  12026. cxtrap:    setom cxseen        ; Just set the flag & echo the character.
  12027.     push p, t1
  12028.     move t1, source        ;[140] What's the source of our data?
  12029.     cain t1, dirch        ;[140] Is it a directory listing?
  12030.      setom czseen        ;[140] If so, set C-Z flag, too.
  12031. cxtrp2:    hrroi t1, [asciz\^X// \]
  12032.     PSOUT%
  12033.     pop p, t1
  12034.     DEBRK%
  12035.  
  12036.  
  12037. ;[59] Control-Z trap handler.
  12038.  
  12039. cztrap:    setom czseen        ; Just set the flag & echo the character.
  12040.     push p, t1
  12041.     hrroi t1, [asciz\^Z// \]
  12042.     PSOUT%
  12043.     pop p, t1
  12044.     DEBRK
  12045.  
  12046.  
  12047. ;[165] Control-M and -P trap handlers
  12048.  
  12049. cmtrap:    setom cmseen        ; Set ^M flag
  12050.     push p, t1        ; Echo CRLF
  12051.     tmsg <
  12052. >
  12053.     move t1, cmloc        ; Get place to resume.
  12054.     jrst cmptr2
  12055.  
  12056. cptrap:    setom cpseen        ; Set ^P flag
  12057.     push p, t1        ; Echo ^P
  12058.     tmsg <
  12059. ^P>
  12060.     move t1, cploc        ; Get place to resume.
  12061.  
  12062. cmptr2:    hrli t1, (1b5)        ; Get into user mode.
  12063.     movem t1, pc2        ; Resume at desired PC.
  12064.     pop p, t1
  12065.     DEBRK
  12066.  
  12067.  
  12068.     subttl subbp - Subtract two arbitrary byte pointers
  12069.  
  12070. ; Subroutine to subtract two byte pointers in current section.
  12071. ; The two byte pointers must point to bytes of the same size.
  12072. ;
  12073. ; Call with:
  12074. ;   t1/ First byte pointer.
  12075. ;   t2/ Second byte pointer.
  12076. ;    CALL SUBBP
  12077. ;
  12078. ; Returns:
  12079. ;   +1 if the byte sizes are different, with t1-t3 unchanged, or else
  12080. ;   +2 with:
  12081. ;      t1,t2/ Unchanged.
  12082. ;      t3/ The number of bytes of the specified bytesize in the string pointed
  12083. ;          to by the first byte pointer (in t1) up to, but not including, the
  12084. ;          byte pointed to by the second byte pointer (in t2).
  12085.  
  12086. subbp:    saveac    <q1,q2,q3,q4>    ; Save permanent regs for work below.
  12087.     ldb q1, [point 6, t1, 11] ; q1 := bytesize 1.
  12088.     ldb q2, [point 6, t2, 11] ; q2 := bytesize 2.
  12089.     came q1, q2        ; Are they equal?
  12090.      ret            ; No, failure
  12091.  
  12092. ; Byte sizes are equal, can do arithmetic.
  12093.  
  12094.     movei q2, @t1        ; Do address calculation for t1
  12095.     movei q4, @t2        ;  and t2.
  12096.     sub q4, q2        ; q4 := (A1 - A2) = N words.
  12097.     movei q2, ^d36        ; q2 := bits/word.
  12098.     idiv q2, q1        ; q2 := bytes/word.
  12099.     imul q4, q2        ; q4 := bytes in N words.
  12100.     move q2, q4        ; (to leave q3-q4 free for IDIV)
  12101.     ldb q3, [point 6, t2, 5] ; q3 := Q2
  12102.     ldb t3, [point 6, t1, 5] ; t3 := Q1
  12103.     sub t3, q3        ; t3 := (Q1 - Q2)
  12104.     idiv t3, q1        ; t3 := (Q1 - Q2) / S
  12105.     add t3, q2        ; Adjust previous count.
  12106.     retskp            ; And return, with success.
  12107.  
  12108. ;[6] (this whole routine, just for fun...)
  12109.  
  12110. moon:    saveac <5,6>
  12111.  
  12112. ; This code stolen from MOON.MAC (anybody know who wrote it?).
  12113. ; Just changed OUTCHR's to PBOUT%'s via a macro.  - Frank.
  12114. ;
  12115.     setzb 3,4
  12116.     seto 2,
  12117.     ODCNV%
  12118.      erjmp r
  12119.     tlz 4,77
  12120.     IDCNV%
  12121.      erjmp r        ; Return upon any error.
  12122.     tmsg <, Moon: >        ; OK so far, say what we're doing.
  12123.  
  12124. ; AC2= Universal time adjusted for time zone.
  12125.  
  12126.     move 1,2        ; Right place.
  12127.     sub 1,newmn        ; Sub off base new moon
  12128.     idiv 1,period        ; Divide by the period
  12129.     idiv 2,perio4        ; Get fractions of a period
  12130.     camg 3,perio8        ; Check for pahse + or -
  12131.      jrst moon1        ; Not more than 3+ days
  12132.  
  12133.     sub 3,perio4        ; Make it next phase -n days
  12134.     cain 2,3        ; Is it LQ+3D+?
  12135.      tdza 2,2        ; It is
  12136.      aoj 2,            ; Increment phase
  12137.  
  12138. moon1:    hllz 1,table(2)        ; Get SIXBIT phase
  12139.     skipge 3        ; 3 < 0 then minus phase output
  12140.      tloa 1,'-'        ; -
  12141.      tloa 1,'+'        ; +
  12142.      movms 3        ; Fix mag of 3
  12143.     move 2,[point 6,1]    ; Byte pointer
  12144.     movei 5,2        ; Loop 3 times
  12145.  
  12146. moon2:    ildb 4,2        ; Get a character
  12147.     addi 4," "        ; Make ASCII
  12148.     OUTCHR 4        ; Type it
  12149.     sojge 5,moon2        ; Loop
  12150.  
  12151.     movsi 4,-4        ; Make aobjn pointer
  12152.     ;...
  12153.  
  12154. moon3:    hrrz 2,table(4)        ; Get a multiplier
  12155.     trz 2,774000        ; Strip off ascii character
  12156.     imuli 3,(2)        ; Get the value decoded
  12157.     hlrz 1,3        ; Get value
  12158.     tlz 3,-1        ; Zap old LH
  12159.     move 5,1        ; Use 5 & 6 here
  12160.     idivi 5,12        ; Radix 10
  12161.     addi 5,60        ; Make ASCII
  12162.     caile 5,60        ; Check for leading zero
  12163.      OUTCHR 5        ;  Type it.
  12164.     addi 6,60        ; Make ASCII
  12165.     OUTCHR 6
  12166.     ldb 5,[point 7,table(4),24] ; Get d/h/m/s
  12167.     OUTCHR 5        ; Type it.
  12168.     OUTCHR ["."]        ; Follow with a dot.
  12169.     aobjn 4,moon3        ; Loop.
  12170.  
  12171.     tmsg <
  12172. >                ; A CRLF at the end.
  12173.     ret            ; Done, return.
  12174.  
  12175.     subttl Pure Data
  12176.  
  12177.  
  12178. ; Pure data for moon.
  12179.  
  12180. newmn:    125575,,34343        ; 28-jan-79 0120 est
  12181. per==35,,422752            ; 29d.12h.53m.19s
  12182. period:    per
  12183. perio4:    per/4
  12184. perio8:    per/10
  12185.  
  12186. table:    byte(18)'NM '(7)"d"(11)^D1 ; New moon - days - 1
  12187.     byte(18)'FQ '(7)"h"(11)^D24 ; First quarter - hours - 24
  12188.     byte(18)'FM '(7)"m"(11)^D60 ; Full moon - minutes - 60
  12189.     byte(18)'LQ '(7)"s"(11)^D60 ; Last quarter - seconds - 60
  12190.  
  12191.  
  12192.  
  12193. ; Some other miscellaneous pure data
  12194.  
  12195. crlf:    asciz/
  12196. /                ; A carriage-return-linefeed.
  12197.  
  12198.     Remark    Interrupt storage (pure)
  12199.  
  12200. levtab:    pc1
  12201.     pc2
  12202.     pc3
  12203.  
  12204. chntab:    phase 0
  12205. tmchan:    1,,tmtrap        ; Timer trap on channel 0, priority 1.
  12206. ccchan:    1,,cctrap        ; ^C trap on channel 1, same priority.
  12207. cachan:    2,,catrap        ; ^A trap on channel 2, lower priority.
  12208. cxchan:    2,,cxtrap        ; ^X trap on channel 3...
  12209. czchan:    2,,cztrap        ; ^Y trap ....       4
  12210. cmchan:    2,,cmtrap        ; ^M trap ....       5
  12211.     repeat <^d23-.>,<0>    ; (Skip reserved area, can't use these)
  12212. cpchan:    2,,cptrap        ; ^P trap on channel 6
  12213.     block ^d36-.
  12214.     dephase
  12215.     0            ; (superstition)
  12216. lits:    lit            ; Assemble literals here.
  12217.  
  12218.     subttl    Impure data storage
  12219.  
  12220. CMDSTG                ; Allocate COMND JSYS storage
  12221. pdl:    block pdlsiz        ;  and stack.
  12222. pc1:    0            ; Interrupt PC storage, levels 1,
  12223. pc2:    0            ;  2,
  12224. pc3:    0            ;  and 3.
  12225. intpc:    0            ; PC to restore on timer interrupt.
  12226. intstk:    0            ; Stack pointer to restore on timer interrupt.
  12227. ccn:    0            ; Number of ^C's typed.
  12228. caseen:    0            ; Flag for ^A trap.
  12229. psave:    0            ; Stack pointer for ^C interrupt.
  12230. psave2:    0            ; Stack top for ^C interrupt.
  12231. tsave:    0            ;[132] Same as above, but for timer interrupts.
  12232. tsave2:    0            ;[132]  ...
  12233. cmseen:    0            ;[165] Flag for ^M interrupt seen.
  12234. cmloc:    0            ;[165] Where to go on ^M interrupt.
  12235. cpseen:    0            ;[165] Flag for ^P interrupt seen.
  12236. cploc:    0            ;[165] Where to go on ^P interrupt.
  12237. cxseen:    0            ;[59] Flag for ^X interrupt seen.
  12238. czseen:    0            ;[59] Flag for ^Z interrupt seen.
  12239. capas:    0            ; Process capabilities.
  12240. inited:    0            ;[177] inilin/reslin flag.
  12241.  
  12242. pars1:    0            ; Data from first parse.
  12243. pars2:    0            ; Data from second parse.
  12244. pars3:    0            ; Data from third parse.
  12245. pars4:    0            ; Data from fourth parse.
  12246. pars5:    0            ;[41] ...
  12247. srvflg:    0            ; Are we serving?  Erase if we go for command.
  12248. iflg:    0            ;[100] -1 if sending INFO packet, else 0.
  12249. lcflg:    0            ;[56] LOCAL command (-1 = LOCAL, 0 = REMOTE).
  12250. definf:    0            ;[77] DEFINE flag nonzero if parsing DEFINE.
  12251. undeff:    0            ;[77] UNDEFF flag nonzero if DEFINE x <cr>.
  12252. source:    0            ;[102] Source routine for GETCH.
  12253. dest:    0            ;[107] Destination routine for PUTCH.
  12254. ffunc:    0            ;[118] File function (dir, del, ren, etc).
  12255. parsx==.-1            ; For zeroing the above.
  12256.     
  12257. dfstrt:    PROMP            ; Are we to be a SERVER or go to the PROMPT?
  12258.                 ;  (PROMP not PROMPT, which CMD package uses)
  12259. f$exit:    0            ; Exit flag for EXIT command or rescan entry.
  12260. ttyjfn:    .priin            ; JFN for controlling terminal.
  12261. logjfn:    0            ;[38] Debugging log file JFN.
  12262. tlgjfn:    0            ;[126] Transaction log file JFN.
  12263. sesjfn:    0            ;[128] Session log file JFN.
  12264. savjfn:    0            ; Place to save session log JFN.
  12265. logbsz:    0            ;[41] Log file byte size.
  12266. filjfn:    0            ; JFN of file being sent.
  12267. ndxjfn:    0            ; Indexable JFN, for wildcard stepping.
  12268. nxtjfn:    0            ;[111] JFN of next file to be sent.
  12269. netjfn:    0            ; Line for packet transmission.
  12270. ttymod:    0            ; Current mode word for controlling tty.
  12271. ttydim:    0            ;[185] Current controlling tty dimensions
  12272. oldjfn:    0            ; JFN on previous line.
  12273. oldmod:    0            ; Previous mode of the line.
  12274. olddim:    0            ;[185] Old line dimensions
  12275. oldpau:    0            ; Previous terminal pause on end mode.
  12276. tiword:    0            ; Terminal interrupt word
  12277. sysmsg:    0            ;[82] Accept/refuse system message status.
  12278. ttynum:    0            ; Number of the TTY being used.
  12279. oldnum:    0            ;[7] Number of previous TTY in case of change.
  12280. mytty:    0            ;[4] TTY number of job's controlling terminal.
  12281. myccoc:    0            ;[161] CCOC words for my tty.
  12282.     0            ;[161] (two of them)
  12283. ttpau:    0            ;[161] Controlling TTY's pause chars.
  12284. myjob:    0            ;[7] My job number.
  12285. skdflg:    0            ;[130] Nonzero if class scheduler on.
  12286. class:    0            ;[130] My scheduler class.
  12287. job:    0            ;[7] Number of job that has TTY I want.
  12288.     ;...
  12289.  
  12290. ; Impure Data, cont'd
  12291.  
  12292. pname:    0            ; Name of this process
  12293.     0            ;  (need 2 words)
  12294. ttfork:    0            ; Fork number of the connect receive fork.
  12295. rufork:    0            ; Fork number for LOCAL RUN program fork.
  12296. rujfn:    0            ; JFN for LOCAL RUN program.
  12297. execf:    0            ; Fork number of PUSH (to Exec) fork.
  12298. errptr:    0            ; Pointer to most recent error string.
  12299. atmptr:    0            ; Atom buffer pointer.
  12300. xfnflg:    0            ;[84] Flag for file name conversion.
  12301. xflg:    0            ;[104] Flag for sending with X header.
  12302. ebtflg:    0            ; One if file is to be used in 8-bit mode.
  12303. autbyt:    1            ; One if auto-byte is to be used.
  12304. handsh:    0            ;[76] Handshake.
  12305. flow:    1            ;[143] Flow-Control (nonzero = XON/XOFF)
  12306. itsflg:    defits            ;[75] Flag for handling ITS-binary format files
  12307. itsfil:    0            ;[75] Flag for this file is ITS format.
  12308. itscnt:    0            ;[75] Counter for ITS header chars matched.
  12309. tvtflg:    0            ;[129] Negotiate binary mode on ARPANET TVT.
  12310. tvtchk: 1            ;[182] TVT discovery (MUST BE AFTER tvtflg!)
  12311. ntiblk: block ntblen        ;[182] NTINF% block for TVT
  12312. panda <                ;[181] PANDA monitor TVT support
  12313. havnbm:    0            ;[181] Non-zero if we have network binary mode
  12314. setlts:    0            ;[181] set if we set terminal status
  12315. oldlts:    0 >            ;[181] Old terminal status
  12316. incase:    defics            ;[160] Case conversion flag for INPUT search.
  12317. indeft:    defito            ;[160] Default timeout for INPUT search.
  12318. intima:    defita            ;[160] Timeout action for INPUT search.
  12319. asgflg:    0            ;[7] -1 if I asg'd the TTY, 0 if already asg'd.
  12320. oasflg:    0            ;[7] Same, but for previous TTY.
  12321. actmp:    block 20        ;[59] A place for short-term saving of ACs.
  12322. pktacs:    block 6            ;[112] Place to save RPACK/SPACK ACs.
  12323. parity: defpar            ; Type of parity to use.
  12324. gotx:    0            ; Flag for "already got an X-packet".
  12325. gots:    0            ; Flag for "already got an S-packet".
  12326. mapflg:    0            ; One if a page is mapped in.  (Init to 0.)
  12327. mdmlin:    0            ;[130] -1 = modem-controlled line, 0 = not.
  12328. carier:    0            ;[130] Flag for carrier dropped.
  12329. monv:    0            ;[146] Monitor version (0 if less than 6.0).
  12330. speed:    0            ;[130] Ostensible line speed -- input,,output.
  12331. setspd:    0            ;[161] Flag speed was explicitly SET.
  12332. defbrk==3            ;[16] default nulls to send on break
  12333. brk:    defbrk            ;[16] nulls to send on BREAK key
  12334. local:    0            ; -1 = local Kermit, 0 = remote.
  12335. rcving:    0            ; -1=actually recving, +1=sending, 0=neither.
  12336. $sendf:    0            ; SEND command in progress.
  12337. $recvf:    0            ; RECEIVE command in progress.
  12338. pagptr:    0            ; Pointer into the page.
  12339. ;**************
  12340. pagcnt:    0            ; Number of pages in the file,
  12341. bytcnt:    0            ; and byte count
  12342. crdate:    0            ; and creation date (these 3 must be adjacent!)
  12343. ;**************
  12344. bytsiz:    0            ; Byte size of file.
  12345. abtfil:    0            ;[42] 0 = discard incomplete file, -1 = keep.
  12346. expung:    0            ;[143] Automatically expunge when deleting.
  12347. pagno:    0            ; Present page number.
  12348. stdat:    0            ; Time taken in transmitting.
  12349. size:    0            ; Size of the present data.
  12350. spsiz:    dspsiz            ; Maximum size packet to send.
  12351. rpsiz:    drpsiz            ; Maximum size packet to receive.
  12352. maxdat:    dspsiz-5        ;[63] Max length for data field.
  12353. srvtim:    dsrvtm            ;[137] Server command wait timeout interval.
  12354. stimou:    dstim            ; Interval for my own timer.
  12355. otimou:    dstim            ;[26] Place to save old timout interval.
  12356. rtimou:    drtim            ; Minimum timeout interval I need.
  12357. rrtimo:    drtim            ;[128] Above, adjusted for 15-min load avg.
  12358. ntimou:    0            ;[54] Timeout counter.
  12359. curtim:    0            ;[131] Current load-adjusted timeout interval.
  12360. timerx:    0            ;[132] Counter for timer errors.
  12361. nnak:    0            ;[54] NAK counter.
  12362.     ;...
  12363.  
  12364. ; Impure Data, cont'd
  12365.  
  12366. rpause:    drpaus            ;[35] Pause before ACKing data packet.
  12367. spause: dspaus            ;[36] Pause before sending data packet.
  12368. pause:    0            ;[36] Pause currently in effect.
  12369. spadch:    dspad            ; Pad char micro wants.
  12370. rpadch:    drpad            ; Pad char I want.
  12371. spadn:    dspadn            ; Number of pad chars for micro.
  12372. rpadn:    drpadn            ; Number for me.
  12373. seolch:    dseol            ; EOL char micro needs.
  12374. reolch:    dreol            ; EOL I need.
  12375. squote:    dsquot            ; Quote character micro wants.
  12376. rquote:    drquot            ; Quote character I want.
  12377. delay:    ddelay            ; How long before I send the first packet.
  12378. odelay:    ddelay            ;[27] For saving & restoring delay.
  12379. escape:    defesc            ; Escape character for connecting (default ^Y).
  12380. duplex:    dxfull            ; Duplex for connecting.
  12381. ssthdr:    SOH            ; Start of header character to send.
  12382. rsthdr:    SOH            ; Start of header character to receive.
  12383. rtchr:    0            ; Total characters received.
  12384. stchr:    0            ;  ... sent.
  12385. rtot:    0            ; Some more counters..
  12386. stot:    0            ;
  12387. otot:    0
  12388. numtry:    0            ; Number of tries on a packet.
  12389. oldtry:    0            ; Number of tries for previous packet.
  12390. maxtry:    dmxtry            ; Maximum retries for an ordinary packet.
  12391. imxtry: dimxtr            ; Maximum retries in send initiate.
  12392. pktnum:    0            ; Current packet sequence number.
  12393. num:    0            ; Number of packet just received.
  12394. type:    0            ; Type of same.
  12395. datlen:    0            ; Length of data field of same.
  12396. pktlen: 0            ;[179] Packet length.
  12397. islong:    0            ;[179] Packet is long.
  12398. datptr:    0            ; Pointer to data field of same.
  12399. gclen:    0            ; Generic command data field length.
  12400. rptot:    0            ;[4] Counter for received packets.
  12401. sptot:    0            ;[4] Counter for sent packets.
  12402. files:    0            ; File counter.
  12403. sec:    0            ; Seconds (for figuring baud rate)
  12404. eoflag:    0            ; End of file flag.
  12405. temp:    0            ; Temporary location, to be used only for
  12406. temp2:    0            ;  very brief periods.
  12407. ch:    0            ;[63] Current character.
  12408. next:    0            ;[63] Next character.
  12409. rpt:    0            ;[63] Repeat count of current character.
  12410. rptq:    drept            ;[63] Repeat count prefix.
  12411. rptflg:    0            ;[63] Repeat count processing flag.
  12412. rptfld:    drept            ;[92] Repeat count field for Send-Init.
  12413. ebq:    "Y"            ;[63] 8th-bit-on prefix.
  12414. ebqflg:    0            ;[63] 8th-bit prefixing flag.
  12415. ebqr:    0            ;[88] 8th-bit prefixing requested flag.
  12416. ebqfld:    "Y"            ;[88] 8th-bit prefix field for Send-Init.
  12417. ebqchr:    0            ;[90] Current character has 8th-bit prefix.
  12418. bctr:    "1"            ;[98] Block check type requested (character).
  12419. bctu:    1            ;[98] Block check type in use (number).
  12420. bctone:    0            ;[98] Use type 1 for this packet regardless...
  12421. bctemp:    0            ;[98] Place to store incoming block check.
  12422.     0            ;[98]
  12423.  
  12424. ; Impure Data, cont'd
  12425.  
  12426.  
  12427. xxumsg:    asciz/"x" - Unknown server command/ ; Server message (fill in the x)
  12428. xxulen=^d28            ; Number of characters in xxumsg.
  12429. xxbmsg:    asciz/"x" - Not valid as server command/ ; Another.
  12430. xxblen=^d33            ; Number of characters in xxbmsg.
  12431. xxgums:    asciz/"x" - Undefined generic command/
  12432. xxguln=^d31
  12433. xxgnms:    asciz/"x" - Unimplemented generic command/
  12434. xxgnln=^d35
  12435.  
  12436. dirbuf:    asciz/PS:</        ;[79] User's logged-in ID string.
  12437.     block ^d30        ;[79]
  12438.  
  12439. iniflg:    0            ;[83] Init file in progress.
  12440. takjfn:    0            ;[78] JFN of current TAKE command file.
  12441. takdep:    0            ;[78] Depth of TAKE file JFN stack.
  12442. takep:    0            ;[78] TAKE file JFN stack pointer.
  12443. takpdl:    block <takel+2>        ;[78] TAKE file JFN stack itself.
  12444.  
  12445. mdone:    0            ;[77] Flag for macro execution done.
  12446. macrof:    0            ;[77] Flag on if executing a SET macro.
  12447. macbp:    point 7, macbuf        ;[77] Pointer into macro text buffer.
  12448. omacbp:    0            ;[77] Previous MACBP.
  12449. macxp:    0            ;[77] Macro execution pointer.
  12450. namp:    point 7, nambuf        ;[77] Pointer into macro name buffer.
  12451. onamp:    0            ;[77] Previous NAMP.
  12452. macptr:    0            ;[77] Pointer to start of macro text in CSB.
  12453. nambuf:    block MNBLEN        ;[77] Buffer for DEFINE macro name.
  12454. namx:    block ^d10        ;[77] Some protection against spills.
  12455. filptr:    0            ;[102] Pointer into file name buffer.
  12456. fildot:    0            ;[102] Counter for dots in filename.
  12457. filbuf:    block ^d30        ; Buffer for file name building.
  12458. filbfz:    -1            ; End of same...
  12459. filcnt:    0            ; File counter for directory listings.
  12460. dirfin:    0            ; Flag for directory listing finished.
  12461.     ;...
  12462.  
  12463. ; Impure Data, cont'd -- big stuff at end.
  12464.  
  12465.  
  12466. jobtab:    block ^d30        ; Job info table for GETJI
  12467. skdblk:    block ^d20        ; Argument block for SKED% jsys.
  12468. prompx:    asciz/Kermit-20>/    ; Program prompt text (replacable)
  12469.     block ^d10        ; ...and some padding.
  12470. pasptr:    0            ; Pointer into...
  12471. pasbuf:    block MAXPKT/4+1    ; Buffer for remote password.
  12472. pasbfl==.-pasbuf        ; Length of above.
  12473.     0            ; Superstition
  12474. ttibuf:    block IOBUF/4+1        ;[180] Communications device input buffer
  12475. ttiptr:    point 8, ttibuf        ;[180] Pointer to communications input buffer
  12476. tticnt:    0            ;[180] Communications input buffer count
  12477. ttisin: 0            ;[180] Statistics counters...
  12478. ttibin:    0            ;[180]
  12479. ttildb:    0            ;[180]
  12480. ttimax: 0            ;[180]
  12481. buffer:    block MAXBUF/4+1    ; Buffer for file I/O.
  12482.     block ^d20        ; Superstition
  12483. data:    block MAXBUF/4+1    ; Data field of packet.
  12484.     block ^d20        ; Superstition
  12485. sndpkt:    block MAXBUF/4+1    ; Place for building outbound packets.
  12486.     block ^d20        ; Superstition
  12487. recpkt:    block MAXBUF/4+1    ; Place for putting incoming packets.
  12488. recpkz:    block ^d20        ; Superstition
  12489. tvtbuf:    block MAXBUF/4+1    ;[131] For doubled-iac version of send packet.
  12490.     block ^d20        ; Superstition
  12491. %%krbf:    block MAXPKT/4+1    ;[40] Place for packetized error messages.
  12492.     block ^d20        ; Superstition
  12493. macbuf:    repeat <MTBLEN>,<0>    ;[77] Macro text buffer.
  12494. macx:    block ^d20        ;[77] End of macro text buffer, with padding.
  12495. ;
  12496. ; Macro table, with one predefined macro, for Columbia's IBM system.
  12497. ; Users can remove this definition by typing "define ibm", or they can
  12498. ; replace it.  KERMIT-20 maintainers can remove it for their site by replacing
  12499. ; the contents of MACTAB (first word) with 0,,MACMAX, or can change it to be
  12500. ; anything they like.
  12501. ;
  12502. mactab:    1,,MACMAX        ;[77] Macro keyword TBLUK format table.
  12503.     [asciz/IBM/],,[asciz/parity mark, duplex half, handshake xon
  12504. /]                ;[77] Custom IBM mainframe definition.
  12505.     repeat <MACMAX-1>,<0>    ;[77] Macro keyword table.
  12506. mactbx:    repeat <100>,<0>    ; A small reserve tank...
  12507.     lit            ; Expand remaining literals here.
  12508.     0
  12509.  
  12510. strc:    0            ; Counter for, and...
  12511. strptr:    0            ; Pointer into...
  12512. strbuf:    repeat <1000>,<0>    ; String buffer for big strings.
  12513. strbf2:    repeat <1000>,<0>    ; More of string buffer for big strings.
  12514. strbln=.-strbuf            ; Length of whole thing.
  12515. strbz:    0            ; Where the padding ends.
  12516.  
  12517. getptr:    0            ; Pointer for emptying...
  12518. srvptr:    0            ; And pointer for filling...
  12519. srvbuf:    repeat <1000>,<0>    ; Big buffer for server responses.
  12520. srvbz:    repeat <100>,<0>    ; End of buffer, with some padding.
  12521. srvbzz:    0            ; Where the padding ends.
  12522.  
  12523.     end    <evlen,,kermit>
  12524.  
  12525. ;Old Edit history moved to after END statement...
  12526. ;
  12527. ;*************** Major Version 4.0 ****************
  12528. ;PS:<TIMREK>KERMIT.MAC.491,  5-Jan-84 18:49:24, Frank
  12529. ;[102] Have SFILE call GETBUF to put filename in file header packet with
  12530. ; full prefixing.  This is the first use of GETBUF/ENCODE on non-file data.
  12531. ;PS:<TIMREK>KERMIT.MAC.487,  3-Jan-84 18:42:38, Frank
  12532. ;[101] Strip ^V quote characters from outgoing file names.
  12533. ;PS:<TIMREK>KERMIT.MAC.472, 30-Dec-83 11:29:03, Frank
  12534. ;[100] More debugging of [98]; got 3-char CRC to work.  Also:
  12535. ;.Make GET command send an I packet before the R packet, to tell other side
  12536. ; what block check & other parameters to use when sending.  Replace SINFO
  12537. ; with a simple call to SINIT -- they do the same thing.
  12538. ;.New headings for SHOW PACKET display.
  12539. ;.If local, say delay is 0 in SHOW TIMING.
  12540. ;PS:<TIMREK>KERMIT.MAC.469, 29-Dec-83 20:53:36, Frank
  12541. ;[99] Debugging of [98]; Got 2-character checksum actually working.  Also:
  12542. ;.In RPACK, allow receipt of 1-char checksummed null packet, even if doing
  12543. ; 2 or 3 char block checks.  Other side might have restarted & sent a NAK.
  12544. ;.Tightened up various much-used loops.
  12545. ;.Improved packet logging -- now every character sent or received is logged.
  12546. ;PS:<SY.FDC>KERMIT.MAC.2, 28-Dec-83 09:25:32, Frank
  12547. ;[98] Added support for 2- and 3-character checksums.
  12548. ;*************  Version 3.4 **************
  12549. ;PS:<TIMREK>KERMIT.MAC.448, 23-Dec-83 13:59:52, Frank
  12550. ;[97] In INILIN, preserve TTY mode word settings that don't effect KERMIT, so
  12551. ; as not to cause undesired side effects with TACs, etc.  Fixes(?) bug reported
  12552. ; by Keith Petersen, diagnosed by Mark Crispin.
  12553. ;PS:<TIMREK>KERMIT.MAC.442, 20-Dec-83 19:47:03, Frank
  12554. ;[96] Add SEND (AS) remote-filespec when sending a single file.
  12555. ; Don't confuse user by displaying escape character in SHOW LINE when remote.
  12556. ;PS:<TIMREK>KERMIT.MAC.437, 15-Dec-83 19:20:10, Frank
  12557. ;[95] Remove SET EIGHTH-BIT-PREFIX command, always request it if parity is
  12558. ; being used.  Minor cleanups of help & program text.  Change version number
  12559. ; typeout to agree with the way the Exec now does it: major.minor(edit)-who.
  12560. ; Get rid of old GTCHR and PTCHR routines, and SET IBM routines.
  12561. ;PS:<TIMREK>KERMIT.MAC.431, 14-Dec-83 18:21:44, Frank
  12562. ;[94] Don't allow user to type RECEIVE or SERVER commands when local.
  12563. ;PS:<TIMREK>KERMIT.MAC.428, 14-Dec-83 15:18:03, Frank
  12564. ;[93] Minor corrections in ENCODE for off-by-1 errors doing repeat counts.
  12565. ;PS:<TIMREK>KERMIT.MAC.420, 14-Dec-83 12:39:32, Frank
  12566. ;[92] Add repeat count processing to SPAR, RPAR, SINIT, RINIT.
  12567. ; (It was already in the i/o routines, but never used.)
  12568. ;PS:<TIMREK>KERMIT.MAC.419, 13-Dec-83 18:25:55, Frank
  12569. ;[91] Add routine TTXON, call it whenever there's a timeout.
  12570. ; This should unstick the two sides in case of an XOFF deadlock.
  12571. ;PS:<TIMREK>KERMIT.MAC.415, 12-Dec-83 13:04:35, Frank
  12572. ;[90] Make 8th-bit prefixing work with PDP-10 36-bit binary files.
  12573. ;PS:<TIMREK>KERMIT.MAC.405,  9-Dec-83 15:15:39, Frank
  12574. ;[89] Polish up previous edit.  Turn on prefixing if using parity.
  12575. ;PS:<TIMREK>KERMIT.MAC.400,  8-Dec-83 16:40:28, Frank
  12576. ;[88] Turn on 8th-bit prefixing in RPAR & SPAR, add SET & SHOW stuff for it.
  12577. ;****************** Version 3C **********************
  12578. ;PS:<TIMREK>KERMIT.MAC.394,  2-Dec-83 14:50:55, Frank
  12579. ;[87] Fix bugs in [85]; make sure line does not change after halt/cont.
  12580. ;PS:<TIMREK>KERMIT.MAC.382,  1-Dec-83 14:15:24, Frank
  12581. ;[86] Don't send 4 extra characters if file is ITS binary.
  12582. ;PS:<TIMREK>KERMIT.MAC.381,  1-Dec-83 13:58:23, Frank
  12583. ;[85] Make rescan work even if no KERMIT.INI file.
  12584. ; Make sure line is set up correctly after exit and continue.
  12585. ;PS:<TIMREK>KERMIT.MAC.379, 25-Nov-83 17:13:16, Frank
  12586. ;[84] Add SET option to convert file names to "normal form".
  12587. ; SET FILE-BYTE-SIZE changed to SET FILE BYTESIZE to allow other file
  12588. ; options, like this new one (SET FILE NAMING).
  12589. ; Still allow "SET FILE 8", etc, for compatibility with the old way.
  12590. ;PS:<TIMREK>KERMIT.MAC.361, 25-Nov-83 11:34:54, Frank
  12591. ;[83] Return properly from SHOW ALL command.
  12592. ; Allow init file to be taken even when there is a command line argument.
  12593. ; Init file is always taken before looking at any other commands.
  12594. ;PS:<TIMREK>KERMIT.MAC.355, 11-Nov-83 19:14:43, Frank
  12595. ;[82] Clear/refuse links, system messages during file transfer.
  12596. ; Also, make sure we print the contents of any incoming error packet if
  12597. ; in local mode.  Also, don't echo back DEFINEs any more.
  12598. ;PS:<TIMREK>KERMIT.MAC.354,  9-Nov-83 18:35:53, Frank
  12599. ;[81] More miscellaneous fixes:
  12600. ; . Since CCOFF is called whenever RESLIN is called, have RESLIN call CCOFF.
  12601. ; . Don't turn ^C trap off between transactions if running in server mode.
  12602. ; . Fix broken autobyte code (skipn/skipe, sigh...)
  12603. ; . Fix broken "bit35" code in PUTCH for SOS & PDP-10 binary files.
  12604. ; . Remove debugging output for DEFINE & SET macro stuff.
  12605. ;PS:<TIMREK>KERMIT.MAC.338,  8-Nov-83 11:39:11, Frank
  12606. ;[80] Fix miscellaneous bugs:
  12607. ; . Communication line JFNs improperly juggled in $SETLN.
  12608. ; . Control-C trap was leaving an extra entry on the stack.
  12609. ; . Turn off Control-C trap after ^C out of send, receive, or server mode.
  12610. ; . Close file we're sending if other side sends an error packet.
  12611. ; . Time transfer started not always properly initialized.
  12612. ; . Remove garbage at end of set-macro body string.
  12613. ; . Clean up code at $SEND and $RECV for server entry.
  12614. ;PS:<TIMREK>KERMIT.MAC.331, 28-Oct-83 20:35:46, Frank
  12615. ;[79] Do an implicit TAKE of KERMIT.INI upon initial startup.
  12616. ;PS:<TIMREK>KERMIT.MAC.309, 28-Oct-83 15:29:45, Frank
  12617. ;[78] Add TAKE command to allow (nested) command files.
  12618. ;PS:<TIMREK>KERMIT.MAC.288, 27-Oct-83 18:55:44, Frank
  12619. ;[77] Add DEFINE command for SET macros.  Remove hardwired SET IBM.
  12620. ;PS:<TIMREK>KERMIT.MAC.268, 26-Oct-83 14:15:23, Frank
  12621. ;[76] Add SET HANDSHAKE.
  12622. ;PS:<TIMREK>KERMIT.MAC.251, 12-Oct-83 10:51:56, Frank
  12623. ;[75] Add ITS binary format file handling, as specified in KRFC #3.
  12624. ;PS:<TIMREK>KERMIT.MAC.243, 10-Oct-83 13:33:53, Frank
  12625. ;[74] Fix bug that truncated JSYS error messages in error packet text.
  12626. ;PS:<TIMREK>KERMIT.MAC.241, 10-Oct-83 13:07:33, Frank
  12627. ;[73] Make sure old JFN's on assigned TTYs are released properly.
  12628. ;PS:<TIMREK>KERMIT.MAC.240, 10-Oct-83 11:44:47, Frank
  12629. ;[72] Fix bug that made any file sent after a null file also null.
  12630. ; Fix bug in which last send from server sets byte size for next receive.
  12631. ;PS:<TIMREK>KERMIT.MAC.237,  7-Oct-83 16:47:24, Frank
  12632. ;[71] Fix SHOW DEBUG not to foul up if log JFN is .PRIOU.
  12633. ;PS:<TIMREK>KERMIT.MAC.230,  7-Oct-83 14:02:35, Frank
  12634. ;[70] Catch illegal memory references when mapping in a nonexistent page.
  12635. ; If i/o error sending a file, don't cancel, tell other side to discard.
  12636. ; This allows wildcard sends to proceed after a memory access error.
  12637. ; Also, allow ^C's to interrupt a nonworking FINISH or BYE command gracefully.
  12638. ;PS:<TIMREK>KERMIT.MAC.224,  6-Oct-83 18:56:09, Frank
  12639. ;[69] Fix bug that prevented interrupts from working after EXIT & continue.
  12640. ;PS:<TIMREK>KERMIT.MAC.219,  6-Oct-83 15:13:33, Frank
  12641. ;[68] Separate local and remote mode top-level command tables.
  12642. ; Make remote commands invisible in local mode & vice versa.
  12643. ; Move command keyword tables to where they are used.
  12644. ;PS:<TIMREK>KERMIT.MAC.212,  6-Oct-83 10:18:30, Frank
  12645. ;[67] Remove REMOTE & LOCAL commands for now -- these will be added later.
  12646. ; Update help text to reflect changes since last release, mainly ^A,^X,^Z.
  12647. ; Rename SET ABORTED-FILE to SET INCOMPLETE to avoid emotionally toned word.
  12648. ; Rename SET IBM-FLAG to SET IBM (flags are for programmers).
  12649. ; Break up help text for SET command.
  12650. ; Move help text for each command to same area as command itself.
  12651. ;PS:<TIMREK>KERMIT.MAC.202,  4-Oct-83 19:16:37, Frank
  12652. ;[66] Same deal as [63], but for file output routines.
  12653. ; Old PTCHR replaced by PUTBUF, DECODE, and PUTCH.
  12654. ; Also, include Nick Bush's CRC routine, but don't use it yet.
  12655. ;PS:<TIMREK>KERMIT.MAC.199, 30-Sep-83 19:48:52, Frank
  12656. ;[65] Clean up SEND command parsing, don't parse for initial filespec if no
  12657. ; wildcards given.
  12658. ;PS:<TIMREK>KERMIT.MAC.196, 29-Sep-83 19:13:45, Frank
  12659. ;[64] Debug the previous edit for basic service.
  12660. ;PS:<TIMREK>KERMIT.MAC.184, 28-Sep-83 18:53:21, Frank
  12661. ;[63] Rewrite file input routines to separate i/o from packet formation.
  12662. ; New routines are GETBUF to fill a packet buffer,
  12663. ; GETCH to get an input character,
  12664. ; ENCODE to process the character, performing control quoting, prefix quoting,
  12665. ;  and, if selected, 8th-bit quoting and repeat count processing.
  12666. ; GTCHR is still present, but not used at all.
  12667. ;PS:<TIMREK>KERMIT.MAC.169, 19-Sep-83 17:56:27, Frank
  12668. ;[62] Add ^X and ^Z to interrupt receiving a file or a batch, respectively.
  12669. ; Required insertion of data ("D") in ACK for data packet.
  12670. ;PS:<TIMREK>KERMIT.MAC.163, 16-Sep-83 19:19:13, Frank
  12671. ;[61] Put brief status report on ^A, like NFT has.
  12672. ;PS:<TIMREK>KERMIT.MAC.156, 16-Sep-83 15:45:56, Frank
  12673. ;[60] Add return code to SPACK to distinguish different kinds of failures.
  12674. ;PS:<TIMREK>KERMIT.MAC.151, 15-Sep-83 19:32:57, Frank
  12675. ;[59] Add ^X and ^Z to interrupt sending a file or a batch, respectively.
  12676. ; Required addition of data ("X" or "Z") to Z packet.
  12677. ;PS:<TIMREK>KERMIT.MAC.146, 15-Sep-83 16:18:26, Frank
  12678. ;[58] Add sending of "I" packets before server commands.
  12679. ;PS:<TIMREK>KERMIT.MAC.137,  8-Sep-83 20:20:28, Frank
  12680. ;[57] Add debugging log capability to server commands as well as file xfer.
  12681. ;PS:<TIMREK>KERMIT.MAC.130,  8-Sep-83 18:55:05, Frank
  12682. ;[56] Begin adding new server commands.  First, add LOCAL and REMOTE
  12683. ; top level commands, with operands like DELETE, TYPE, DISK, etc.
  12684. ; Implement DISK first, that's the easiest test of sending back info in
  12685. ; the data field of an ACK.  Also, catch a couple places where the nonskip
  12686. ; return from SPACK was not being accounted for (oops!).
  12687. ;**************** Version 3B *******************************
  12688. ;PS:<TIMREK>KERMIT.MAC.126,  8-Sep-83 15:14:37, Frank
  12689. ;[55] Add CFIBFs in BYE and FINISH; all commands to servers should do this.
  12690. ;PS:<TIMREK>KERMIT.MAC.123,  8-Sep-83 14:02:38, Frank
  12691. ;[54] Report number of NAKs and timeouts in STATISTICS command.
  12692. ;PS:<SY.FDC>KERMIT.MAC.7,  2-Sep-83 17:56:19, Frank
  12693. ;[53] When receiving a file, NAK a trashed packet immediately, don't just wait
  12694. ; for it to come again and only NAK after timeout.  This should result in a
  12695. ; major speed improvement over noisy lines.  The book has always said to do it
  12696. ; this way.  Fix is in RINIT, RFILE, RDATA.  Other KERMITs may need this too.
  12697. ;PS:<SY.FDC>KERMIT.MAC.4,  2-Sep-83 16:43:22, Frank
  12698. ;[52] Combine some common code in the send routines, and improve comments.
  12699. ;PS:<KERMIT>20KERMIT.MAC.40, 25-Aug-83 15:28:36, Frank
  12700. ;[51] Fix packet number compares for mod 64 in SFILE, SDATA, SEOF, SEOT.
  12701. ; This eliminates canceling whenever a retransmission of packet 0 occurs.
  12702. ;CU20D::PS:[SY.FDC]KERMIT.MAC.32, 29 June 1983, 5:39PM, Frank
  12703. ;[50] Change and document the calling conventions of RPAR & SPAR to eliminate
  12704. ; the mess from the last few edits.  Do even more validation in SPAR.
  12705. ;PS:<TIMREK>KERMIT.MAC.118, 29-Jun-83 14:31:52, Frank
  12706. ;[49] Fix another bug in SPAR, change method of incrementing packet numbers.
  12707. ;PS:<TIMREK>KERMIT.MAC.114, 28-Jun-83 16:43:09, Frank
  12708. ;[48] Point to data buffer correctly in SPAR & RPAR. This was lost in some
  12709. ; previous edit.
  12710. ;PS:<TIMREK>KERMIT.MAC.110, 28-Jun-83 15:10:26, Frank
  12711. ;[47] Fix bad checksum reporting, again.  Print most recent JSYS err in STAT.
  12712. ; Don't let other side's Send-Init parameters override any local SET commands.
  12713. ;PS:<TIMREK>KERMIT.MAC.104, 27-Jun-83 17:37:54, Frank
  12714. ;[46] CFIBF after timeout in RPACK.  Be more consistent about how errors
  12715. ; are handled in receive routines.  Clean up server command loop a little.
  12716. ;[PS:<TIMREK>KERMIT.MAC.101, 24-Jun-83 20:18:42, Frank
  12717. ;[45] Fix SHOW command for timing info.
  12718. ;[PS:<TIMREK>KERMIT.MAC.99, 24-Jun-83 17:54:07, Frank
  12719. ;[44] In SFILE, don't give up if OPENF failed because file already open.
  12720. ;PS:<TIMREK>KERMIT.MAC.92, 24-Jun-83 16:55:38, Frank
  12721. ;[43] Don't do timeouts if STIMOU is 0, as protocol says.  Kermit-65 was
  12722. ; sending a space (which translates to 0) in this field of the send-init by
  12723. ; mistake, and Kermit-20 was doing rapid-fire timeouts.
  12724. ;CU20D::PS:[SY.FDC]KERMIT.MAC.19, 22 Jun 83 17:12:33, Frank
  12725. ;[42] Release any piled up log jfns.  Issue KERMSGs any time we cancel.
  12726. ; Add SET ABORTED-FILE (DISPOSITION) DISCARD | KEEP
  12727. ;PS:<TIMREK>KERMIT.MAC.89, 17-Jun-83 11:48:26, Frank
  12728. ;[3A(41)] Clean up listing & help messages, declare minor version "A".
  12729. ;************************ Version 3A ******************************
  12730. ;PS:<TIMREK>KERMIT.MAC.83, 16-Jun-83 16:10:47, Frank
  12731. ;[41] Add bytesize selection option for debugging log file (7 or 8 bit),
  12732. ; for use when debugging binary file transfers.  Force debugging on
  12733. ; when log file requested.
  12734. ;PS:<TIMREK>KERMIT.MAC.75, 16-Jun-83 12:32:34, Frank
  12735. ;[40] Remove the last remaining long lines.  Get rid of hairy %CLEAR macro.
  12736. ; Don't send an error packet longer than the other side's maximum packet size.
  12737. ; Always blank out the error message packet buffer before filling.
  12738. ;PS:<TIMREK>KERMIT.MAC.71, 16-Jun-83 11:36:51, Frank
  12739. ;[39] Change STATUS to STATISTICS, give optional arguments to SHOW command.
  12740. ; Print program version upon startup.
  12741. ;CU20D::PS:<SY.FDC>KERMIT.MAC.13, 15-Jun-83 18:12:37, Frank
  12742. ;[38] Allow debugging output to go to a file.  Thus can even get debugging
  12743. ; information when running remotely.  Suggested by Dave King at CMU.
  12744. ;CU20D::PS:<SY.FDC>KERMIT.MAC.6, 15-Jun-83 14:34:19, Frank
  12745. ;[37] Add SET RETRY, fix FLDDB's so none are more than 80 chars wide.
  12746. ;PS:<TIMREK>KERMIT.MAC.68, 15-Jun-83 11:47:19, Frank
  12747. ;[36] Add SET SEND PAUSE, and include pause info in SHOW & STATUS commands.
  12748. ;PS:<TIMREK>KERMIT.MAC.64, 14-Jun-83 19:25:45, Frank
  12749. ;[35] Add SET RECEIVE PAUSE, suggested by Dave King at CMU.
  12750. ;PS:<TIMREK>KERMIT.MAC.61, 14-Jun-83 18:40:48, Frank
  12751. ;[34] In SPACK, send padding if requested.
  12752. ;PS:<KERMIT>20KERMIT.MAC.34, 10-Jun-83 12:55:42, Frank
  12753. ;[33] Cancel correctly if the output file can't be opened.
  12754. ; Enclose checksum characters in quotes in debugging messages.
  12755. ;*********** Version 3(40) Shipped to over 100 sites May 5 ************
  12756. ;PS:<TIMREK>KERMIT.MAC.56,  4-May-83 09:01:16, Frank
  12757. ;[32] Report bad checksums correctly when debugging.
  12758. ; Report error message from server & cancel if it can't get a file.
  12759. ;PS:<TIMREK>KERMIT.MAC.54, 26-Apr-83 19:08:00, Frank
  12760. ;[31] Beep when done with a transfer, if local.
  12761. ;PS:<KERMIT>20KERMIT.MAC.8, 15-Apr-83 14:45:36, Frank
  12762. ;[30] A NAK for the next packet is *not* the same as an ACK for the current
  12763. ; packet if the current packet is Send-Init.
  12764. ;PS:<TIMREK>KERMIT.MAC.42, 15-Apr-83 11:39:08, Frank
  12765. ;[29] When debugging packets, print checksum of incoming packets, and
  12766. ; print bad packets.
  12767. ;PS:<TIMREK>KERMIT.MAC.41,  8-Apr-83 19:31:28, Frank
  12768. ;[28] Add FINISH command.
  12769. ;PS:<TIMREK>KERMIT.MAC.29,  8-Apr-83 12:43:02, Frank
  12770. ;[27] Fix ^C trap to DEBRK to the right place in all cases.
  12771. ;PS:<TIMREK>KERMIT.MAC.28,  8-Apr-83 09:38:49, Frank
  12772. ;[26] Save and restore normal send timeout when going in & out of server
  12773. ; command-wait.
  12774. ;PS:<TIMREK>KERMIT.MAC.27,  7-Apr-83 20:20:15, Bill C.
  12775. ;[25] Neaten up SERVER mode time out changes.
  12776. ;PS:<TIMREK>KERMIT.MAC.20,  5-Apr-83 18:14:14, Frank
  12777. ;[24] Fix SPAR to account for the actual length of an incoming SEND-INIT.
  12778. ;PS:<TIMREK>KERMIT.MAC.19,  5-Apr-83 17:46:23, Frank
  12779. ;[23] Include both send and receieve parameters in SHOW command.
  12780. ;PS:<TIMREK>KERMIT.MAC.4, 3:20pm  Tuesday, 5 April 1983, Frank
  12781. ;[22] Add debugging options.  Remove i/o to DIAJFN and just test LOCAL and
  12782. ; DEBUG flag values.  Make DEBUG an AC, move RTOT & STOT to memory.
  12783. ;PS:<TIMREK>KERMIT.MAC.81,  1-Apr-83 15:59:19, Frank
  12784. ;[21] Change SET SEND/RECEIVE QUOTE to parse an octal number.  The hairy
  12785. ; .CMUQS/breakmask/.CMTOK parsing tended to hang the program...
  12786. ;PS:<TIMREK>KERMIT.MAC.75,  1-Apr-83 15:13:43, Bill C.
  12787. ;[20] Make packet time outs longer if in server mode awaiting commands.
  12788. ;PS:<TIMREK>KERMIT.MAC.72,  1-Apr-83 12:55:40, Frank
  12789. ;[19] Print "[OK]" for each file successfully sent or received, if local.
  12790. ;PS:<TIMREK>KERMIT.MAC.65, 31-Mar-83 16:43:20, Frank
  12791. ;[18] Expanded help text, with individual help for each command.
  12792. ; Added SET DUPLEX, SET SEND/RECEIVE START-OF-PACKET.
  12793. ;PS:<TIMREK>KERMIT.MAC.58, 31-Mar-83 13:35:57, Bill C.
  12794. ;[17] Restore CFIBFs of yore.  Clears up packet echoing and stacking.
  12795. ;PS:<TIMREK>KERMIT.MAC.52, 31-Mar-83 10:58:12, Frank
  12796. ;[16] Add SET ESCAPE (for CONNECT), try to print remote message after BYE.
  12797. ;PS:<TIMREK>KERMIT.MAC.48, 30-Mar-83 19:54:32, Frank
  12798. ;[15] Don't bomb if we can't open a file to be sent, just print nice msg.
  12799. ;PS:<TIMREK>KERMIT.MAC.47, 30-Mar-83 18:16:53, Frank
  12800. ;[14] Add code for ^B interrupts, but don't use it for anything yet.
  12801. ;PS:<TIMREK>KERMIT.MAC.45, 30-Mar-83 15:06:42, Frank
  12802. ;[13] Don't delay before send if local.
  12803. ;PS:<TIMREK>KERMIT.MAC.41, 30-Mar-83 13:52:57, Frank
  12804. ;[12] When local, print name of file being sent or received.
  12805. ;PS:<TIMREK>KERMIT.MAC.33, 29-Mar-83 17:59:47, Frank
  12806. ;[11] Talk to Kermit server.  Added BYE and GET commands.
  12807. ;************* Version 3 ****************
  12808. ;PS:<TIMREK>KERMIT.MAC.22, 28-Mar-83 14:56:39, Frank
  12809. ;[10] Enable ^C capability if not on already (reported by Willis Dair, SCU).
  12810. ; If we can't enable it, don't go on unless we're running under batch.
  12811. ;PS:<TIMREK>KERMIT.MAC.21, 20-Mar-83 17:55:27, Bill C.
  12812. ;[9] Fixed SHOW command to print number of blips correctly.
  12813. ;PS:<TIMREK>KERMIT.MAC.17, 18-Mar-83 20:31:00, Frank
  12814. ;[8] Added some help to the help text.
  12815. ;PS:<TIMREK>KERMIT.MAC.15, 18-Mar-83 19:03:51, Frank
  12816. ;[7] Assign & deassign line if not already assigned.  This prevents
  12817. ; "?Line is not active" and similar errors if Kermit is run on top of TTLINK
  12818. ; rather than vice versa, and not under DIAL (both TTLINK and DIAL will do
  12819. ; their own assigning, if necessary).  Thanks to Willis Dair, Santa Clara
  12820. ; University, for pointing out the bug.
  12821. ;PS:<TIMREK>KERMIT.MAC.14, 18-Mar-83 18:44:39, Frank
  12822. ;[6] Differentiate between remote & local timeouts in SHOW command.
  12823. ; Add version #, date/time, etc, to SHOW.
  12824. ; Replace a zillion NOUTs with NUMOUT macro.
  12825. ;PS:<TIMREK>KERMIT.MAC.12, 17-Mar-83 18:47:21, Frank
  12826. ;[5] Give error message when initial connection can't be made, if local.
  12827. ;PS:<TIMREK>KERMIT.MAC.7, 17-Mar-83 15:54:33, Frank
  12828. ;[4] When acting as local Kermit, show packet traffic by typing blips.
  12829. ;PS:<TIMREK>KERMIT.MAC.6, 17-Mar-83 15:31:30, Frank
  12830. ;[3] When comparing packet numbers, allow for wraparound.
  12831. ;PS:<TIMREK>KERMIT.MAC.3, 17-Mar-83 10:53:03, Frank
  12832. ;[2] Cont'd... Show range of timeouts in SHOW command.
  12833. ;PS:<TIMREK>KERMIT.MAC.2, 15-Mar-83 12:51:12, Frank da Cruz
  12834. ;[2] Make timeouts load-dependent.  Fix spelling of "interrupt" everywhere.
  12835. ;PS:<KERMIT>20KERMIT.MAC.22, 20-Feb-83 14:13:19, Bill C.
  12836. ;[1] Put in a CFIBF% in the INILIN code to clear the line at the beginning
  12837. ; of each send or receive of backed up NAKs.  This may not be just right.  This
  12838. ; can lose a Send Init packet some times.  This will work til the problem can
  12839. ; be looked at more closely.
  12840. ;*************************** Major Version 2 ********************************
  12841. ;PS:<SY.WBC3>KERMIT.MAC.20,  8-Feb-83 14:43:48, Bill C.
  12842. ; Put in (FINALLY!) the SHOW command.
  12843. ;PS:<SY.WBC3>KERMIT.MAC.11,  8-Feb-83 10:04:10, Bill C.
  12844. ; Add SET PARITY command.  Eliminate IGNORE-PARITY as its functionality is
  12845. ; replaced by SET PARITY SPACE.
  12846. ;PS:<KERMIT>20KERMIT.MAC.3,  4-Feb-83 11:04:08, Bill C.
  12847. ; Change TELNET to TTLINK (by FdC) and remove TELNET command.
  12848. ;PS:<SY.WBC3>KERMIT.MAC.38, 26-Jan-83 15:35:37, Bill C.
  12849. ; Make Kermit able to act as a SERVER.
  12850. ;PS:<KERMIT>20-KERMIT.MAC.29, 18-Jan-83 14:08:45, Bill C.
  12851. ; Take care of the case where user set terminal pause char to ^A.
  12852. ;PS:<KERMIT>20-KERMIT.MAC.27, 11-Jan-83 13:19:06, Bill C.
  12853. ; Fix ^C trap bug that caused illegal instruction.
  12854. ;PS:<KERMIT>20-KERMIT.MAC.22, 11-Jan-83 11:40:01, Bill C.
  12855. ; Fix bug in SET IGNORE-PARITY COMMAND.
  12856. ;PS:<KERMIT>20-KERMIT.MAC.11, 10-Jan-83 16:52:03, Bill C.
  12857. ; Add turn around char for the IBM running VM/CMS.
  12858. ;PS:<KERMIT>20-KERMIT.MAC.8,  7-Jan-83 17:59:01, Bill C.
  12859. ; Fix numerous mispellings of received.
  12860. ;PS:<KERMIT>20-KERMIT.MAC.3,  7-Jan-83 16:06:04, Bill C.
  12861. ; Clean up the diagnostic and error message code.
  12862. ;PS:<KERMIT>20-KERMIT.MAC.2,  7-Jan-83 15:06:02, Bill C.
  12863. ; Add the TELNET command (thanks to Bill Schilit.)  Change EXIT/CONT
  12864. ;    sequence to not throw away JFN.
  12865. ;PS:<KERMIT>KERMIT-20.MAC.2, 14-Dec-82 15:25:40, Bill C.
  12866. ; Be scrupulous in PMAP use after errors.  Don't make files with holes.
  12867. ;PS:<KERMIT>KERMIT.MAC.44, 28-Sep-82 09:47:32, Bill C.
  12868. ; Add ignore parity option for some UNIX systems.
  12869. ;PS:<KERMIT>KERMIT.MAC.19, 28-Apr-82 16:00:31, Bill C.
  12870. ; Big clean up.  Consolidate duplicate sections of code.  Also,
  12871. ;    no longer die on bad packet type, just NAK or retransmit.
  12872. ;    Removed empty show command.
  12873. ;PS:<KERMIT>KERMIT.MAC.18, 21-Apr-82 16:31:04, Bill C.
  12874. ; Clean up line on ^C from transfer.
  12875. ;PS:<KERMIT>KERMIT.MAC.17, 17-Feb-82 16:16:10, Bill C.
  12876. ; Add eight bit file mode.
  12877. ;PS:<KERMIT>KERMIT.MAC.16, 28-Jan-82 12:31:09, Bill C.
  12878. ; Clean up better on some error conditions.
  12879. ;PS:<KERMIT>KERMIT.MAC.15,  6-Jan-82 12:18:06, Bill C.
  12880. ; Fill out some of the SET command options.
  12881.  
  12882. ;[181]
  12883.  
  12884. ; Local Modes:
  12885. ; Mode:MACRO
  12886. ; Comment Column:32
  12887. ; Comment Start:;[185] 
  12888. ; Auto Fill Mode: 0
  12889. ; End:
  12890.