          IDENT  KERMIT,XSTORE,KERMIT
          ABS
          ENTRY  KERMIT
          TITLE  KERMIT -- FILE TRANSFER UTILITY
          SYSCOM B1
 OPL      XTEXT  COMCMAC
 OPL      XTEXT  COMCCMD
 KERMIT   SPACE  4,10
*****  SUMMARY
*
* CYBER KERMIT  IS  A PROGRAM TO TRANSFER FILES TO AND FROM A MACHINE
* RUNNING NOS, USING THE KERMIT FILE TRANSFER PROTOCOL AS  DEFINED AT
* COLUMBIA UNIVERSITY.
 KERMIT   SPACE  4,10
***    REVISION HISTORY
*
* WRITTEN BY  A. V. LE BLANC, UMRCC, FEB. 1986
*
* COPYRIGHT, UNIVERSITY OF MANCHESTER.
*
* THIS  PROGRAM IS AVAILABLE TO ANYONE; ANYONE MAY COPY OR DISTRIBUTE
* IT, PROVIDED THERE IS NO CHARGE EXCEPT MEDIUM AND SHIPPING COSTS.
 EXTERN   SPACE  4,10
***    EXTERNAL INTERFACE
*
* CONTROL CARD FORMAT:  KERMIT
*
* ANY PARAMETERS ARE IGNORED.
 EXTERN   SPACE  4,10
***    DAYFILE MESSAGES
*
*    OCCASION:                ERROR MESSAGE:
*
* INPUT IS MASS STORAGE    INPUT AND OUTPUT MUST BE TERMINAL FILES
* OUTPUT IS MASS STORAGE   INPUT AND OUTPUT MUST BE TERMINAL FILES
* ZZZKHLP NOT ASSIGNED     FILE ZZZKHLP IS MISSING
* ZZZKDAT DOES NOT CONTAIN
*   EXACTLY 12 WORDS       FILE ZZZKDAT IS CORRUPT
 CONSTANT SPACE  4,10
****   ASSEMBLY CONSTANTS
*
 PARIT    EQU    2           PARITY: 0 = ZERO, 1 = ODD, 2 = EVEN
 TBUFL    EQU    301B        BUFFER LENGTH FOR TERMINAL FILES
 WBUFL    EQU    501B        BUFFER LENGTH FOR MASS STORAGE FILES
 LBUFL    EQU    301B        BUFFER LENGTH FOR LOG FILE
 DEFPLEN  EQU    94          DEFAULT PACKET LENGTH TO REQUEST
 DEFESCA  EQU    3           DEFAULT (ASCII CODE) LOCAL ESCAPE CHAR
 DEFTIME  EQU    20          DEFAULT TIMEOUT TO REQUEST IN SECONDS
 DEFRETR  EQU    5           DEFAULT RETRIES ALLOWED PER PACKET
****
 DESIGN   SPACE  4,10
**     THE DESIGN OF CYBER KERMIT
*
* CYBER KERMIT WAS DESIGNED BY THE METHOD OF ABSTRACTION FROM DETAIL.
* AT MOST TIMES WHEN THIS PROGRAM IS RUNNING, DATA PASSES IN A STREAM
* FROM A PRODUCER OF SOME KIND TO A CONSUMER OF SOME KIND.  GENERALLY
* THE PRODUCER MAKES USE OF REGISTERS  B2, B3, B4, AND X3,  WHILE THE
* CONSUMER USES REGISTERS B5, B6, B7, AND X7.   REGISTER X5 IS COMMON
* TO BOTH HALVES OF THIS PROCESS, BEING THE PLACE DATA IS TRANSFERRED
* FROM THE PRODUCER TO THE CONSUMER.  BOTH CONSUMPTION AND PRODUCTION
* CONTAIN  SEVERAL LAYERS OF SUBROUTINES,  EACH DESIGNED TO HIDE SOME
* UNSIGHTLY DETAILS FROM THE HIGHER LEVELS.
*
* THIS PROGRAM TOOK TWO WEEKS TO WRITE AND DEBUG, AND ANOTHER WEEK TO
* DOCUMENT AND ANNOTATE.   OBVIOUSLY IN SUCH A SHORT PERIOD OF TIME I
* WAS MUCH LESS CONCERNED WITH GARNISH AND TRIMMINGS, AND VERY LITTLE
* INTERESTED IN POTENTIAL USERS OF CYBER KERMIT  OUTSIDE  MANCHESTER.
* NEVERTHELESS, I HOPE SOME OTHER SITES MAY FIND THIS VERSION USEFUL,
* OR AT LEAST MORE USEFUL THAN THE UNIVERSITY OF TEXAS'S  KERMIT 170,
* WHICH WE WERE UTTERLY UNABLE TO RUN -- OR EVEN INTERPRET, SINCE THE
* COPY WE RECEIVED IS IN A CHARACTER SET UNKNOWN TO US.
*
* THE PROGRAM CODE  CONTAINS CONDITIONS WHICH SHOULD DETERMINE DURING
* ASSEMBLY WHETHER THE SITE IS A 63- OR 64-CHARACTER SITE AND PRODUCE
* AN APPROPRIATE BINARY.
 IOSTORE  TITLE  STORAGE, CONSTANTS, TABLES, AND OTHER DATA
**     I/O STORAGE AND FILE ENVIRONMENT TABLES
*
* XSTORE AND REGIST ARE USED TO SAVE VARIOUS REGISTER CONTENTS DURING
* I/O  OPERATIONS.   ALSO THE TERMINAL BUFFER  TBUF  MAY OCCASIONALLY
* UNDERFLOW INTO THE TOP WORD OF REGIST DURING READ OPERATIONS -- THE
* INPUT SUBROUTINE  SREAD  STORES A ZERO IN THIS WORD  UNDER  CERTAIN
* CIRCUMSTANCES.  SIMILARLY THE MASS STORAGE BUFFER  WBUF  IS ALLOWED
* TO  UNDERFLOW ONE WORD, WHICH EXPLAINS WHY  TBUF  HAS AN EXTRA WORD
* AT THE TOP.   THE BUFFER  LBUF  IS RESERVED EXCLUSIVELY FOR THE LOG
* FILE  ZZZKLOG.  THE BUFFER  CBUF IS ACTUALLY A PAIR OF BUFFERS USED
* TO STORE PACKETS BEFORE SENDING THEM AND AFTER RECEIVING THEM.
*
* LOFS IS THE LIST-OF-FILES TABLE.  IT SERVES TWO PURPOSES: IF KERMIT
* IS  INTERRUPTED,  THIS  TABLE ENSURES THAT THE LAST PART OF ZZZKLOG
* GETS WRITTEN TO THE FILE BEFORE THE PROGRAM ABORTS, IN CASE THE LOG
* IS NEEDED TO SHED LIGHT ON THE PROBLEM.   ORDINARILY THE LOFS TABLE
* ENSURES THAT THE OUTPUT BUFFER GETS FLUSHED AUTOMATICALLY  WHENEVER
* INPUT IS READ.   FOR THIS REASON,  CYBER KERMIT NEVER WRITES OUTPUT
* EXPLICITLY EXCEPT WHEN RESPONDING TO A GENERIC LOGOUT COMMAND.
*
* IN MOST CASES THE  FILE ENVIRONMENT TABLE  IS EXTENDED BACKWARDS BY
* TWO  WORDS.   THE FIRST OF THESE CONTAINS THE NEGATIVE SHIFT COUNT,
* WHICH REACHES 0 WHEN AN INPUT WORD HAS BEEN EMPTIED  OR  AN  OUTPUT
* WORD  HAS BEEN FILLED;  THE SECOND WORD CONTAINS THE WORD CURRENTLY
* BEING FILLED OR EMPTIED.
*
* HELPLOC  IS USED TO RECORD THE CURRENT POSITION OF  THE  STRUCTURED
* HELP FILE  ZZZKHLP.  IT IS 0 WHEN ZZZKHLP HAS NOT BEEN OPENED,  AND
* OTHERWISE CONTAINS THE NUMBER OF THE RECORD  WHICH WOULD BE READ BY
* A  READ  MACRO AT THE MOMENT  --  THAT IS, ONE MORE THAN THE NUMBER
* OF THE LAST RECORD READ.
*
* THE DUMMY FET IS A TEMPLATE  FROM WHICH THE FILE FET IS CONSTRUCTED
* WHEN A FILE IS TO BE TRANSFERRED.
*
* INFI AND OUTFI ARE POINTERS TO CURRENTLY ACTIVE FET'S,  SIMPLIFYING
* I/O OPERATIONS SUCH AS BUFFER FILLING AND FLUSHING.
 IOSTORE  SPACE  4,12
          ORG    110B
 XSTORE   BSS    6           TEMPORARY STORAGE WHEN GETTNG ACK FOR
 REGIST   BSS    6           PACKETS, AND DURING CIO CALLS
 TBUF     BSS    TBUFL+1     INPUT, OUTPUT
 WBUF     BSS    WBUFL       FILE, ZZZKHLP, ZZZKDAT
 LBUF     BSS    LBUFL       ZZZKLOG
 CBUF     BSS    192         ASCII CODED PACKETS
 LOFS     VFD    30/LOFS+1,30/0,42/0,18/4
          VFD    42/0ZOUTPUT,18/OUTPUT
          VFD    42/0ZZZZKLOG,18/ZZZKLOG,60/0
          BSSZ   2
 INPUT    FILEB  TBUF,TBUFL
          BSSZ   2
 OUTPUT   FILEB  TBUF,TBUFL
 HELPLOC  DATA   0
 ZZZKHLP  FILEB  WBUF,WBUFL
 ZZZKDAT  FILEB  WBUF,WBUFL
          DATA   -9,45       THIS INITIALISES THE LOG FILE
 ZZZKLOG  FILEB  LBUF,LBUFL
          BSSZ   2
 FILE     FILEB  WBUF,WBUFL
 DUMMY    FILEB  WBUF,WBUFL
 INFI     DATA   0           ADDRESS OF FET OF FILE BEING READ
 OUTFI    DATA   0           ADDRESS OF FET OF FILE BEING WRITTEN
 CONSVARS SPACE  4,15
*      CONSTANTS AND VARIABLES
 CONSVARS SPACE  3,10
 CURN     DATA   0           CURRENT PACKET NUMBER
 FILNAM   DATA   0,0         TENTATIVE AND PREVIOUS NAMES OF FILES
 KMODE    DATA   0           SERVER OR NOT; SEND, RECEIVE, OR COMMAND
 NPAD     DATA   0,0         NUMBER OF PAD CHARS TO SEND, PAD CHAR
 EOLN     DATA   -1          HIS REQUESTED EOLN
 BITPREF  DATA   38          DEFAULT BIT-PREFIX
 QBIN     DATA   0           CURRENT BIT-PREFIX
 DEBUGW   DATA   0           0 = DEBUG IS OFF; 1 = DEBUG IS ON
 DEFAULF  DATA   1           NUMBER TO CONSTRUCT DEFAULT FILE NAME
 ESCAPEC  CON    DEFESCA     INTERNAL ESCAPE CHAR (LITERAL)
 FILETYP  DATA   0,0         0 ASC, 1 BIN, 2 KER, 3 DIS, 4 ASC8
 SYNCM    DATA   1           PACKET START (LITERAL)
 PLENGTH  CON    DEFPLEN     PACKET LENGTH TO REQUEST
 SLENGTH  DATA   80          MAXIMUM PACKET LENGTH TO SEND
 QUOTEC   DATA   35          DEFAULT QUOTE CHAR
 QCTL     DATA   0           QUOTE CHAR BEING USED
 RPCH     DATA   0           REPEAT CHAR BEING USED
 REPETC   DATA   126         DEFAULT REPEAT CHAR
 TIMEOUT  CON    DEFTIME     TIMEOUT TO REQUEST FROM LOCAL KERMIT
 FILETOT  DATA   0           FILES TRANSFERRED
 PSENT    DATA   0           PACKETS SENT
 PRECD    DATA   0           PACKETS RECEIVED
 PKERRS   DATA   0           ERRORS IN RECEIVED PACKETS
 RETRYT   DATA   0           TOTAL RETRIES
 RETRYC   DATA   0           CURRENT NO OF RETRIES
 RETRYN   CON    DEFRETR     MAXIMUM RETRIES TO HAVE
 TIMWORD  DATA   0           CURRENT TIME
 UPDAT    DATA   0           TEMPORARY STORAGE
 TABLES   SPACE  4,10
**     TABLES
*
* THE TABLE PTYPES IS USED TO SELECT  C, E, G, I, K, R, AND S PACKETS
* FOR SPECIAL TREATMENT.
*
* ILLEGIT IS USED TO SELECT CONTROL CHARACTERS WHICH ARE FORBIDDEN AS
* PACKET SYNC MARKERS AND AS LOCAL ESCAPE CHARACTERS BECAUSE OF THEIR
* SPECIAL SIGNIFICANCE TO THE OPERATING SYSTEM.  IN GENERAL, A BIT  N
* IS SET WHEN THE CHARACTER WITH ASCII VALUE  N  IS FORBIDDEN.   HERE
* IN MANCHESTER THE VALUES 8 (BACKSPACE), 10 (LINEFEED), 13 (CARRIAGE
* RETURN), 16 (INTERRUPT), 17 (XOFF), 19 (XON), 20 (TERMINATION), AND
* 24 (CANCEL LINE) ARE FORBIDDEN.
*
* DITAB  IS  USED FOR CHARACTER CODE CONVERSION FROM DISPLAY CODE AND
* FROM  6/12 ASCII CODE TO ASCII PROPER;  ATTAB  IS ALSO USED FOR THE
* LATTER CONVERSION.  ASCTAB  IS USED TO CONVERT FROM ASCII PROPER TO
* DISPLAY CODE OR TO 6/12 ASCII.
*
* THE TABLES  BEGINNING AT THE WORD AFTER  KNAME  ARE USED BY  CREAD,
* THE CYBER KERMIT COMMAND PROCESSOR.   EACH TABLE CONTAINS ONE ENTRY
* FOR EACH ACCEPTABLE COMMAND AND ENDS WITH A 0.  EACH TABLE ALSO HAS
* ONE ENTRY EACH FOR THE LONGEST (AMBIGUOUS) EXPRESSION COMMON TO TWO
* OR MORE COMMANDS (PROVIDED THE ACTION TO BE TAKEN ACTUALLY DIFFERS)
* AND PRECEDING THE COMMANDS IN QUESTION.  THE TABLES ARE SEARCHED IN
* SEQUENCE, SO THE ALPHABETICAL ORDER IS COINCIDENTAL.
*
* THE  EXPRESSION  TPARAMS  IS A CODED INSTRUCTION THAT REDIFINES THE
* TERMINAL CHARACTERISTICS WHEN KERMIT EXECUTES.  THE CODES ARE:
*
*     0016       REDEFINE TERMINAL CHARACTERISTICS (CONTROL BYTE)
*     40624002   SET PARITY EVEN
*     40454000   TURN OFF PAGING
*     40434377   SET PAGE WIDTH TO 255 CHARACTERS
 TABLES   SPACE  4,10
 PTYPES   DATA   3005250B    SPECIAL PACKET TYPES TO SELECT
 ILLEGIT  DATA   106622400B  SPECIAL CONTROL CHARACTERS TO AVOID
 DITAB    DATA   43,45,42,47,40,41,36,61,32
          IFEQ   1R:,0
          DATA   44,46,35,91,93,37,34,95,33
          ELSE   1
          DATA   44,46,35,91,93,58,34,95,33
          DATA   38,39,63,60,62,64,92,94,59
          IFEQ   1R:,0
 ATTAB    DATA   32,64,94,32,58,32,32,96
 ASCTAB   DATA   54,52,48,43,51,55,56,41,42,39,37
          DATA   46,38,47,40,00,63,58,44,59,57,60
          ELSE   3
 ATTAB    DATA   32,64,94,32,37,32,32,96
 ASCTAB   DATA   54,52,48,43,40,55,56,41,42,39,37
          DATA   46,38,47,40,51,63,58,44,59,57,60
          DATA   49,61,50,62,53,56,49,61,50,62,45
 KNAME    DATA   0ZKERMIT,0ZO,0ZOFF,0ZON
 COMTAB   DATA   0,0ZEXIT,0ZPUSH,0ZQUIT,0ZRECEIVE,0ZSE
          DATA   0ZSEND,0ZSERVER,0ZSET,0ZSHOW,0ZSTATUS
 SETTAB   DATA   0,0ZBITPREFIX,0ZDE,0ZDEBUG,0ZDELAY,0ZESCAPE
          DATA   0ZFILETYPE,0ZMARKER,0ZPACKETLEN,0ZQUOTECHAR
          DATA   0ZRE,0ZREPEATCHA,0ZRETRY
          IFEQ   1R:,0
 FTYPES   DATA   0,0ZASCII64,0ZASCII8,0ZBINARY,0ZDISPLAY,0ZDIS64
          ELSE   1
 FTYPES   DATA   0,0ZASCII63,0ZASCII8,0ZBINARY,0ZDISPLAY,0ZDIS63
          DATA   0ZEIGHT,0ZKERMIT,0ZNORMAL,0Z8
 SERVTAB  DATA   0,0ZS,0ZSETFILETY,0ZSHOW,0ZSTATUS,0ZTYPE,0
 TPARAMS  VFD    27/1640624B,9/PARIT,24/40454000B
          DATA   40434377000000000000B
 MESSAGES SPACE  4,19
**     MESSAGES AND TEXTS
*
* THE SPECIAL TEXTS  OFFLIST, CMDLIST, FTLIST, AND  SETLIST  ARE USED
* BY THE LIST FORMATTER LWRITE AND BY VARIOUS OTHER ROUTINES.  LWRITE
* IS DISCUSSED IN DETAIL LATER.  THE FORMAT PRESCRIBED BY  LWRITE OC-
* CASIONALLY REQUIRES AN APPARENTLY SUPERFLUOUS BLANK.
 MESSAGES SPACE  3,9
          IFEQ   1R:,0
 OFFLIST  DIS    ,/D^E^B^U^G ^M^A^Y ^B^E ^S^E^T ^T^O@D/
          ELSE   1
 OFFLIST  DIS    ,/D^E^B^U^G ^M^A^Y ^B^E ^S^E^T ^T^O:/
          VFD    60/0,24/4LOF^F,12/23,24/0,12/2LON,48/0,12/1,48/0
          IFEQ   1R:,0
 CMDLIST  DIS    ,/T^H^E K^E^R^M^I^T ^C^O^M^M^A^N^D^S ^A^R^E@D/
          ELSE   1
 CMDLIST  DIS    ,/T^H^E K^E^R^M^I^T ^C^O^M^M^A^N^D^S ^A^R^E:/
          VFD    60/0,42/7LE^X^I^T,12/22,6/0,60/10LR^E^C^E^I^
          VFD    18/3LV^E,12/19,30/0,60/0LSET
          VFD    42/7LP^U^S^H,12/22,6/0,30/5LSEN^D,12/22,18/0
          VFD    60/6LSH^O^W,42/7LQ^U^I^T,12/22,6/0
          VFD    60/10LSER^V^E^R ,12/19,48/0,60/10LST^A^T^U^S
          VFD    60/0,12/1,48/0
          IFEQ   1R:,0
 FTLIST   DIS    ,/F^I^L^E^S ^M^A^Y ^B^E@D/
          ELSE   1
 FTLIST   DIS    ,/F^I^L^E^S ^M^A^Y ^B^E:/
          VFD    60/0,60/10LA^S^C^I^I ,12/20,48/0
          VFD    60/10LE^I^G^H^T ,60/0,60/10LB^I^N^A^R^
          VFD    6/0LY,12/19,42/0,60/10LK^E^R^M^I^,6/0LT,54/0
          VFD    60/10LD^I^S^P^L^,18/3LA^Y,42/0,12/1,48/0
          IFEQ   1R:,0
 SETLIST  DIS    ,/Y^O^U ^M^A^Y ^S^E^T@D/
          ELSE   1
 SETLIST  DIS    ,/Y^O^U ^M^A^Y ^S^E^T: /
          VFD    60/0,60/10LB^I^T-^P^R,48/8L^E^F^I^X,12/16
          VFD    60/10LF^I^L^E-^T,36/6L^Y^P^E,12/17,12/0
          DIS    ,/Q^U^O^T^E-^C^H^A^R/
          VFD    42/7LDEB^U^G,12/21,6/0,60/10LM^A^R^K^E^
          VFD    6/0LR,12/20,42/0
          DIS    ,/REP^E^A^T-^C^H^A^R/
          VFD    42/7LDEL^A^Y,12/21,6/0,60/10LP^A^C^K^E^
          VFD    60/10LT-^L^E^N^G,24/4L^T^H,12/13,24/0
          DIS    ,/RET^R^Y/
          DIS    ,/E^S^C^A^P^E/
          VFD    12/1,48/0
 TRANSFM  DIS    ,/ F^I^L^E^S ^T^R^A^N^S^F^E^R^R^E^D/
          DIS    ,/ P^A^C^K^E^T^S ^S^E^N^T/
          DIS    ,/ P^A^C^K^E^T^S ^R^E^C^E^I^V^E^D/
          DIS    ,/ D^A^T^A ^E^R^R^O^R^S/
          DIS    ,/ R^E^P^E^T^I^T^I^O^N^S/
 KPROMPT  DIS    ,/ C^Y^B^E^R K^E^R^M^I^T> /
 BLOCKM   DIS    ,/^B^L^O^C^K ^C^H^E^C^K^S        1-^C^H^A^R/
 DEFAULM  DIS    ,/^D^E^F^A^U^L^T ^F^I^L^E ^N^A^M^E   /
 CTRLHYP  DIS    ,/CTRL-/
          IFEQ   PARIT,0,1
 PAREVEN  DIS    ,/^P^A^R^I^T^Y              ^Z^E^R^O/
          IFEQ   PARIT,1,1
 PAREVEN  DIS    ,/^P^A^R^I^T^Y              ^O^D^D/
          IFEQ   PARIT,2,1
 PAREVEN  DIS    ,/^P^A^R^I^T^Y              ^E^V^E^N/
 INTERM   DIS    ,/I^N^T^E^R^R^U^P^T^E^D/
 RETRYM   DIS    ,/T^O^O ^M^A^N^Y ^R^E^P^E^T^I^T^I^O^N^S/
 NOTHIGM  DIS    ,/N^O^T^H^I^N^G/
          IFEQ   1R:,0
 RECEIVM  DIS    ,/R^E^C^E^I^V^E@D /
          CON    10LS^E^N^D@D
          ELSE   2
 RECEIVM  DIS    ,/R^E^C^E^I^V^E: /
          CON    10LS^E^N^D:
 PACKNUM  DIS    ,/P^A^C^K^E^T ^N^U^M^B^E^R /
 CKERRM   DIS    ,/C^H^E^C^K^S^U^M ^E^R^R^O^R/
 FNCHGM   DIS    ,/C^H^A^N^G^E ^F^I^L^E ^N^A^M^E ^T^O /
 FRABTM   DIS    ,/T^R^A^N^S^F^E^R ^A^B^O^R^T^E^D/
 BREAKM   DIS    ,/B^R^E^A^K.  /
 ERRORM   DIS    ,/E^R^R^O^R.  /
          IFEQ   1R:,0
 LASTFM   DIS    ,/ L^A^S^T ^F^I^L^E@D/
          ELSE   1
 LASTFM   DIS    ,/ L^A^S^T ^F^I^L^E:/
 BINERM   DATA   10LB^I^T ^P^R,10L^E^F^I^X ^,10LI^S ^R^E^Q
          DIS    ,/^U^I^R^E^D ^F^O^R ^B^I^N^A^R^Y ^F^I^L^E^S/
 OPENFM   DIS    ,/R^E^C^E^I^V^I^N^G ^F^I^L^E  /
 DISCARM  DIS    ,/I^N^S^T^R^U^C^T^E^D ^T^O ^D^I^S^C^A^R^D ^F^I^L^E/
 EOFM     DIS    ,/E^N^D ^O^F ^F^I^L^E /
 KDATERM  DIS    ,/F^A^T^A^L ^P^R^O^T^O^C^O^L ^V^I^O^L^A^T^I^O^N/
 NONEXTM  DIS    ,/T^H^I^S ^F^I^L^E ^D^O^E^S ^N^O^T ^E^X^I^S^T/
 LOGOUTM  DIS    ,/L^O^G^O^U^T/
 FINISHM  DIS    ,/F^I^N^I^S^H/
 NOTIMP   DIS    ,/N^O^T ^I^M^P^L^E^M^E^N^T^E^D/
 TYPEM    DIS    ,/T^Y^P^E/
 TYPERM   DIS    ,/Y^O^U ^C^A^N^N^O^T T^Y^P^E ^B^I^N^A^R^Y ^F^I^L^E^S/
 HELPM    DIS    ,/H^E^L^P/
 EOPMSG   DIS    ,/(EOP)/
 BADTERM  DIS    ,/ INPUT AND OUTPUT MUST BE TERMINAL FILES/
 NOHELPM  DIS    ,/ FILE ZZZKHLP IS MISSING/
 BADKDAT  DIS    ,/ FILE ZZZKDAT IS CORRUPT/
 DEBACL   SPACE  4,21
**     DEALING WITH FATAL ERRORS
*
* IF WE LEARN THAT THE LINK FILE WRITTEN BY A  PUSH  COMMAND HAS BEEN
* CORRUPTED, OR THAT THE HELP FILE ZZZKHLP IS MISSING, OR THAT EITHER
* INPUT  OR  OUTPUT IS NOT ASSIGNED TO A TERMINAL,  WE HAVE NO CHOICE
* BUT TO ABORT.   DEBACLD IS THE ENTRY POINT FOR CORRUPT LINK  FILES,
* DEBACL - 2 FOR NONEXISTENCE OF ZZZKHLP,  AND DEBACL-1 WHEN INPUT OR
* OUTPUT IS A MASS STORAGE FILE.
 DEBACL   SPACE  3,9
 DEBACLD  RETURN ZZZKDAT     DESTROY THE INFAMOUS THING!
          SX1    BADKDAT     THEN CONFESS
          EQ     DEBACL
          SX1    NOHELPM     A USER HAS BEEN TAMPERING WITH FILES
          EQ     DEBACL
          SX1    BADTERM     OR WITH FANCY 'ASSIGN' STATEMENTS
 DEBACL   MESSAGE X1,4
          ABORT
 NCONV    TITLE  SUBROUTINES THAT MANIPULATE DATA
**     SUBROUTINES THAT MANIPULATE DATA
*
*  THESE  ELEMENTARY ROUTINES ARE CALLED FREQUENTLY BY SEVERAL LATER,
*  MORE COMPLEX ROUTINES.
*
*  NCONV CONVERTS A BINARY NUMBER IN X3 TO DISPLAY CODE IN X5,  USING
*  B2 FOR UNPACKING AND SHIFT OPERATIONS.  X5 MUST BE 0 ON ENTRY.
 NCONV    SPACE  3,10
 NCONV    PS
          SX0    10
          PX1    X0          X1 := FLOATING POINT 10
          NX1    X1          NORMALISE X1
          PX2    X3          CONVERT X3 TO FLOATING POINT
          FX2    X2/X1       DIVIDE
          SX4    X3+27       THIS WILL LEAVE A PRINTABLE DIGIT
          UX3    B2,X2
          LX3    B2,X3       X3 NOW CONTAINS THE INTEGER QUOTIENT
          IX2    X3*X0
          IX4    X4-X2       THIS IS THE RIGHTMOST DIGIT FROM X3
          BX5    X5+X4       ADD IT TO X5
          LX5    54          SHIFT IT INTO THE UPPER END OF X5
          NZ     X2,*-2
          EQ     NCONV
 DEFFILE  SPACE  4,18
** DEFFILE  PREPARES THE CURRENT DEFAULT FILE NAME IN X6 USING NCONV.
*  AT EXIT A3 CONTAINS DEFAULF, THE ADDRESS OF THE SEQUENCE NUMBER OF
*  THE DEFAULT FILE, WHILE X6 CONTAINS THE CURRENT DEFAULT FILE NAME,
*  LOGICALLY ADDED TO THE CODE FOR A BINARY FET.
 DEFFILE  SPACE  3,10
          SA0    B2          SAVE CONTENTS OF B2 (USED BY NCONV)
          BX5    X5-X5       X5 := 0
          RJ     NCONV       CONVERT X3 TO DISPLAY CODE
          SB2    A0          RESTORE CONTENTS OF B2
          MX0    24          4-CHARACTER MASK
          SX4    3RKER       START OF DEFAULT FILE NAME
          BX2    -X0*X5      X2 SHOULD BE 0
          ZR     X2,*+2      UNLESS THE NUMBER IS TOO LARGE
          BX6    X6-X6       IN WHICH CASE USE 0
          SA6    A3          AND SAVE IT (A3 STILL = DEFAULF)
          SX5    27
          LX5    54          SHIFT TO AVOID OVERLAP
          BX6    X4+X5       AND COMBINE TWO PARTS OF FILE NAME
          LX6    42          SHIFT INTO POSITION
          SX5    3           AND ADD BINARY FET CODE
          BX6    X6+X5       TO FILE NAME
 DEFFILE  PS
          SA3    DEFAULF     X3 := DEFAULT FILE NUMBER
          EQ     DEFFILE-6
 PUTVAL   SPACE  4,23
** PUTVAL  STORES  THE  NEXT  8-BIT VALUE FROM X5 INTO A PACKET BEING
*  PREPARED FOR SENDING.  IT ACTUALLY KEEPS THE LAST VALUE IN X7, FOR
*  WE SOMETIMES WISH TO STRIP ONE OR MORE VALUES.  B5 HOLDS THE COUNT
*  OF THE NUMBER OF TIMES THE VALUE IN  X7 HAS BEEN REPEATED,  AND B6
*  HOLDS THE OFFSET OF THE CURRENT STORAGE ADDRESS,  WHICH IS A SHORT
*  DISTANCE FROM END-OF-PACKET TO BE SAFE.   THIS 'PADDED' ADDRESS IS
*  IN B7.   PUTVAL MAY RETURN WITHOUT COMPLETING THE  'PUTTING'  WHEN
*  B6 GOES POSITIVE.   THE 'PUTTING' IS COMPLETE WHENEVER B6 < 0, AND
*  IF B6 >= 0, THE PUTTING IS COMPLETE IF X5 = X7.
 PUTVAL   SPACE  3,10
 PUTVAL   PS
          BX4    X7-X5       IS THIS A NEW VALUE, OR DOES IT REPEAT
          NZ     X4,*+2      X4 = 0 IF THIS IS NOT A NEW VALUE
          SB5    B5+B1       NEW VALUE = LAST; INCREMENT COUNT
          EQ     PUTVAL
          SA1    RPCH
          SB5    B5-B1       B5 := ONE LESS THAN THE REPEAT COUNT
          MX0    53
          LE     B5,B1,*+6   WE NEED AT LEAST 3 TO USE REPEAT
          MI     X1,*+6      AND WE CAN'T REPEAT WITH NO RPCH
          BX6    X1
          SA6    B6+B7       SEND THE REPEAT PREFIX
          SX6    B5+34
          BX2    X0*X6       TEST FOR OVERLARGE COUNTS
          ZR     X2,*+1      X2 = 0 IF THE COUNT IS <= 126
          BX6    -X0         OTHERWISE LIMIT THEM TO 126
          BX4    -X6
          SX4    X4+B1
          BX6    -X4         X6 := REPEAT COUNT TO BE SENT
          SB5    X4+B5       B5 := REMAINING REPEAT COUNT
          SB5    B5+33       THEN CORRECT THE TOTAL
          SB6    B6+B1
          SA6    B6+B7       STORE CODED REPEAT COUNT
          SB6    B6+B1
 +        SX0    B1
          LX0    7           X0 := 128
          SA2    BITPREF
          BX6    X7
          BX4    X0*X7       TEST TO SEE IF BIT 8 IS SET
          ZR     X4,*+2
          BX6    X2
          SA6    B6+B7       BIT-PREFIX
          SB6    B6+B1
          BX6    X0-X7
          SA4    QUOTEC      QUOTE PREFIX
          BX1    X1-X6
          BX0    X6
          ZR     X1,*+5      RPCH REQUIRES A PREFIX
          SX1    B1
          LX1    6           X1 := 64
          BX2    X2-X6
          ZR     X2,*+4      QBIN REQUIRES A PREFIX
          BX2    X4-X6
          ZR     X2,*+3      QCTL REQUIRES A PREFIX
          MX2    53
          BX2    -X2-X6
          ZR     X2,*+1      DEL REQUIRES A PREFIX AND DECONTROL
          MX2    55
          BX2    X2*X6
          NZ     X2,*+2      CHARS LESS THAN 32 REQUIRE PREFIX
          BX0    X0-X1
 +        BX6    X4
          SA6    B6+B7       PUT QUOTE PREFIX
          SB6    B6+B1
          BX6    X0
          SA6    B6+B7       FINALLY, STORE THE CHAR
          SB6    B6+B1
          ZR     B5,*+2      DONE IF B5 = 0
          MI     B6,PUTVAL+3
          EQ     PUTVAL      WE CANNOT GO ON IN THIS PACKET
          BX7    X5
          SB5    B1
          EQ     PUTVAL
 UNPACK   SPACE  4,17
** UNPACK GETS THE NEXT 8-BIT VALUE FROM A PACKET INTO X5.  X5 < 0 AT
*  END-OF-PACKET,  IN WHICH CASE ANOTHER PACKET MAY BE REQUESTED WHEN
*  MORE DATA IS EXPECTED.
 UNPACK   SPACE  3,10
          MX3    47
 UNPACK   PS
          BX5    X3          X3 CONTAINS NEXT CHARACTER IN THE PACKET
          MI     X3,UNPACK   OR A NEGATIVE NUMBER IF PACKET IS EMPTY
          SB2    B2-B1       B2 CONTAINS THE REPEAT COUNT
          GT     B2,B0,UNPACK  IF THIS WAS > 1 AND IS > 0, THEN DONE
          SA3    B4          OTHERWISE TRY TO GET NEXT CHAR
          SB2    B1          WHICH PROBABLY OCCURS ONLY ONCE
          MI     X3,UNPACK   X3 < 0 AT END OF PACKET
          SA1    QCTL
          SA2    A1+B1       RPCH
          BX0    X2-X3       IS THIS A REPEATED VALUE
          NZ     X0,*+3      IF X2 = X3, THEN NEXT VALUE FOLLOWS COUNT
          SA3    A3+B1
          SB2    X3-32       B2 := REPEAT COUNT
          SA3    A3+B1       AND X3 := VALUE
          MI     X3,UNPACK   JUST IN CASE THERE IS A DATA ERROR
          LE     B2,B0,UNPACK-1  WE LEAVE THIS ROUTINE WITH NO ERROR
          SA4    QBIN
          BX0    X3-X4
          BX6    X6-X6       IS THE EIGHTH BIT TRUE
          NZ     X0,*+2      IF X6 = 0, THIS IS A BIT PREFIX
          SA3    A3+B1       IN WHICH CASE, GET THE VALUE
          SX6    B1
          MI     X3,UNPACK   THIS SHOULD NEVER OCCUR (BUT WHO KNOWS?)
          LX6    7           X6 := 128
 +        BX0    X3-X1       IS IT A QUOTED CHARACTER
          NZ     X0,*+4
          SA3    A3+B1
          BX0    X1-X3       IS IT QCTL
          ZR     X0,*+3
          BX0    X4-X3       IS IT QBIN
          ZR     X0,*+2
          BX0    X2-X3       IS IT RPCH
          SX4    B1
          ZR     X0,*+1
          LX4    6           X4 := 64
          BX3    X3-X4
          BX3    X3+X6
          SB4    A3+B1
          EQ     UNPACK
 PREAD    SPACE  4,18
** PREAD 'READS' ONE CHARACTER FROM A 6/12 TEXT AND TRANSLATES IT INTO
*  ASCII CODE.  IT USES THE SUBROUTINE PREADSUB TO GET THE NEXT 6 BITS
*  OF THE TEXT.   NOTE THAT PREAD MAKES NO ATTEMPT TO DETECT ERRORS IN
*  SUCH A TEXT.
 PREAD    SPACE  3,10
          MX0    54
          LX3    6
          BX5    -X0*X3      GET NEXT SIX BITS OF WORD INTO X5
          SB2    B2+B1       AND INCREMENT CHARACTER COUNT
 PREADSB  PS
          MI     B2,*-2      B2 < 0 IF THERE IS MORE IN THIS WORD
          SA3    B3          GET NEXT WORD
          SB3    B3+B1       (INCREMENTING THE POINTER)
          SB2    -10         WHICH CONTAINS 10 6-BIT CHARACTERS
          EQ     *-3
*
 PREAD    PS
          RJ     PREADSB     GET THE NEXT SIX BITS
          ZR     X5,PREAD    WHICH ARE 0 AT END OF TEXT
          SX4    X5-62       TEST FOR UP-ARROW
          ZR     X4,PREAD1   WHICH IS HANDLED AT PREAD1
          SX4    X4+B1
          SX4    X4+B1
          NZ     X4,*+2      NOW TEST FOR AT-SIGN
          RJ     PREADSB
          SA5    X5+ATTAB    AND CONVERT USING TABLE
          EQ     PREAD
          SX5    X5-27       TEST FOR UPPER-CASE LETTER
          PL     X5,*+2      X5 >= 0 UNLESS CHAR IS LETTER
          SX5    X5+91
          EQ     PREAD
          SX5    X5-10       TEST FOR DIGIT
          PL     X5,*+2      X5 >= 0 UNLESS CHAR IS DIGIT
          SX5    X5+58
          EQ     PREAD
          SA5    X5+DITAB    CONVERT USING TABLE
          EQ     PREAD
 PREAD1   RJ     PREADSB     AFTER UP-ARROW, GET NEXT SIX BITS
          SX5    X5-32       IF THESE ARE >= 32, ASCII VALUE IS
          PL     X5,PREAD    BITS - 32
          SX5    X5+128      OTHERWISE ASCII VALUE IS BITS + 96
          EQ     PREAD
 PACKTEX  SPACE  4,13
** THE  PACKTEX  UTILITY ROUTINE WORKS WITH PREAD TO PACK TEXT INTO A
*  PACKET.   IT IS USEFUL WHEN SENDING ERROR MESSAGES AND OTHER SHORT
*  COMMUNICATIONS.
 PACKTEX  SPACE  3,6
 PACKTEX  PS
          RJ     PREAD       UNPACK NEXT CHARACTER OF MESSAGE
          ZR     X5,*-2      IT IS 0 AT END-OF-TEXT
          RJ     PUTVAL      STORE IT IN THE PACKET
          MI     B6,*-2      AND REPEAT IF B6 < 0
          EQ     *-3         B6 >= 0 WHEN PACKET IS FULL
 MAKEFN   SPACE  4,17
** THE ROUTINE MAKEFN BUILDS A FILE NAME ONE CHARACTER AT A TIME FROM
*  ASCII CODED CHARACTERS INPUT IN X5.  OUTPUT IS LEFT-JUSTIFIED FILE
*  NAME IN DISPLAY CODE IN X7.
 MAKEFN   SPACE  3,10
          SX2    X4-26       TEST FOR LOWER-CASE LETTER
          PL     X2,*+3      X2 >= 0 IF NOT A LETTER
          SX4    X4+B1       CONVERT LETTERS TO DISPLAY CODE
          LX7    6
          BX7    X7+X4       AND ADD TO FILE NAME
          SB5    B5+B1
          MI     B5,*+1      IF B5 < 0, THEN FILE NAME IS NOT FULL
          LX7    18          IF FULL, JUSTIFY IT
 MAKEFN   PS
          PL     B5,*-1      B5 >= 0 WHEN FILE NAME IS COMPLETE
          PL     X5,*+3      X5 < 0 WHEN THERE IS NO MORE INPUT
          LX7    6           IF THERE IS NO MORE INPUT, THEN
          SB5    B5+B1       JUSTIFY THE FILE NAME IN X7
          MI     B5,*
          LX7    18
          EQ     MAKEFN
          SX4    X5-65       DIVIDE ASCII CHARS; LETTERS >= 65
          MI     X4,*+3      TREAT NON-LETTERS LATER
          SX2    X4-32       TEST FOR LOWER-CASE LETTERS
          MI     X2,MAKEFN-3 AND TREAT THEM ELSEWHERE
          BX4    X2
          EQ     MAKEFN-3    TREAT UPPER-CASE LETTERS
          ZR     X7,MAKEFN   DO NOT STORE NON-LETTERS AS 1ST CHAR
          SX4    X5-22       CONVERT DIGITS TO DISPLAY CODE
          SX2    X4-26       TEST THAT THEY ARE IN FACT DIGITS
          MI     X2,MAKEFN   IF X2 < 0 THEN THEY ARE NOT DIGITS
          SX2    X2-10
          MI     X2,MAKEFN-2 IF X2 < 0 HERE, THEY ARE DIGITS
          EQ     MAKEFN      OTHERWISE THEY ARE NOT
 UNPCFIL  SPACE  4,17
** UNPCFIL EXTRACTS A FILE NAME FROM A PACKET.  IT PRESUMES THAT X3 =
*  0 AND THAT THE FILE NAME BEGINS AT THE FOURTH WORD OF THE RECEIVED
*  PACKET;  HENCE THIS ROUTINE CANNOT EXTRACT FILE NAMES FROM PACKETS
*  CARRYING REMOTE COMMANDS TO 'TYPE' A FILE.
 UNPCFIL  SPACE  3,10
 UNPCFIL  PS
          BX7    X7-X7       X7 := 0
          SB5    -7          7 CHARS IN FILE NAME
          SB2    B1          FIRST CHAR WILL BE REPEATED ONCE
          SB4    CBUF+99
          RJ     UNPACK      GET DUMMY FIRST CHAR
          RJ     UNPACK      GET A CHAR OUT OF THE PACKET
          RJ     MAKEFN      AND TRY TO ADD IT TO THE FILE NAME
          MI     B5,*-2      REPEAT UNTIL FILE NAME IS COMPLETE
          EQ     UNPCFIL
 FREAD    TITLE  PRIMARY INPUT ROUTINES
**     PRIMARY INPUT ROUTINES
*
*  FREAD FILLS A FILE BUFFER.  NOTE: INFI MUST CONTAIN ADDRESS OF FET
*  OF FILE BEING READ, AS DOES X2 ON ENTRY.  THIS ALWAYS RETURNS X6 =
*  0 AND SETS B4 AND B3 TO END-OF-INPUT AND OFFSET ADDRESS OF THE 1ST
*  WORD READ.
 FREAD    SPACE  3,10
 FREAD    PS
          SA7    REGIST      REGIST CONTAINS X7
          MX0    42
          SX1    B2          PREPARE TO SAVE CONTENTS OF B REGISTERS
          SX4    B5
          SX6    B6
          SX7    B7
          BX1    -X0*X1      MASK OFF ALL SIGN EXTENSIONS
          BX4    -X0*X4
          BX6    -X0*X6
          BX7    -X0*X7
          LX6    18          AND PREPARE TO COMBINE
          LX7    18
          BX6    X6+X1
          BX7    X7+X4
          SA6    A7+B1       REGIST + 1 CONTAINS B6, B2
          SA7    A6+B1       REGIST + 2 CONTAINS B7, B5
          BX7    X3
          BX6    X5
          SA7    A7+B1       REGIST + 3 CONTAINS X3
          SA6    A7+B1       REGIST + 4 CONTAINS X5
          SA1    X2+B1       FET + 1
          BX6    -X0*X1      X6 CONTAINS START OF BUFFER
          SA6    A1+B1       IN
          SA6    A6+B1       OUT
          READ   X2,R
          SA1    REGIST      X7
          SA2    A1+B1       B6, B2
          SA4    A2+B1       B7, B5
          SA3    A4+B1       X3
          SA5    A3+B1       X5
          BX7    X1
          SB2    X2
          SB5    X4
          LX2    42
          LX4    42
          SB6    X2
          SB7    X4
          SA2    INFI        X2 = FET ADDRESS
          SB3    X2+B1
          SA1    B3+B1       IN
          SA4    A1+B1       OUT
          SB4    X1          END OF DATA
          IX4    X4-X1
          SB3    X4          OFFSET
          BX6    X6-X6
          EQ     FREAD
 WREAD    SPACE  4,18
* WREAD  READS  ONE WORD FROM AN INPUT FILE;  IT IS USED BY ALL INPUT
* ROUTINES.   NOTE THAT INFI MUST CONTAIN ADDRESS OF THE FET OF  FILE
* BEING READ.  WREAD RETURNS X1 = 0 WHEN DATA IS READ, WITH DATA READ
* IN X6, OR X1 <> 0 WHEN NO DATA IS READ, WITH X6 = 0.
 WREAD    SPACE  3,10
          SA4    B3+B4       X4 = NEXT WORD
          SB3    B3+B1
          BX6    X4
          BX1    X1-X1       SIGNAL THAT DATA WAS READ
 WREAD    PS
          MI     B3,*-2      B3 < 0 WHEN BUFFER IS NOT YET EMPTY
          SA2    INFI        X2 := FET ADDRESS
          SA1    X2          X1 := I/O STATUS
          LX1    55          X1 > 1 WHEN THIS RECORD IS NOT FINISHED
          BX6    X6-X6
          MI     X1,WREAD    X1 < 0 AT EOR, EOF, EOI
          RJ     FREAD       FILL BUFFER
          MI     B3,WREAD-1  B3 < 0 WHEN DATA WAS READ
          EQ     WREAD
 SREAD    SPACE  4,18
** SREAD  READS ONE SIX-BIT CHARACTER FROM A FILE.  ALL TEXTUAL INPUT
*  WHETHER FROM THE TERMINAL OR FROM MASS STORAGE USES SREAD.   EXITS
*  WITH NEXT 6 BITS IN X5 OR WITH X5 < 0 AT EOLN AND EOR.   B2 = 0 AT
*  EOLN, B2 > 0 AT EOR, EOF, EOI, AND B2 < 0 WHEN DATA IS IN X5.
 SREAD    SPACE  3,10
          MI     B3,SREAD
          RJ     WREAD       FILL BUFFER
          SB3    B3-B1
          ZR     X1,*+1      X1 = 0 IF DATA WAS READ
          SA6    B3+B4       INSERT MISSING END-OF-LINE
 SREAD    PS
          PL     B2,SREAD1   EOLN OR EOR
          SB2    B2+B1
          MX0    54
          BX5    -X0*X3      GET NEXT CHAR
          LX3    6
          MI     B2,SREAD    B2 < 0 WHEN X3 HOLDS MORE CHARS
          SA3    B3+B4       GET NEXT WORD
          SB3    B3+B1
          ZR     X3,SREAD    EOLN IS NEXT
          MX1    48
          SB2    -10
          BX6    -X1*X3      TEST FOR END OF LINE
          ZR     X6,*+5      X6 = 0 WHEN WORD ENDS WITH EOLN
          BX6    -X0*X3      TEST FOR POSSIBLE END OF LINE
          LX3    6
          NZ     X6,SREAD-2  NO POSSIBLE END OF LINE
          RJ     WREAD       GET NEXT WORD
          SB3    B3-B1
          ZR     X1,*+1      X1 = 0 WHEN THERE IS MORE DATA
          SA6    B3+B4       OTHERWISE ADD MISSING EOLN
          NZ     X6,SREAD    X6 <> 0 WHEN THERE IS NO EOLN
          SB2    B2+B1       B2 = -9; 9 CHARS ARE IN WORD IN X3
          EQ     SREAD
          SB2    B2+B1       B2 = -9
          BX2    X3          EXTRA COPY OF DATA
          SB3    B3-B1
          SA6    B3+B4       SAVE EOLN
          LX2    54
          BX4    -X1*X2      TEST EXTENT OF EOLN IN WORD
          SB2    B2+B1
          ZR     X4,*-1      X4 = 0 WHEN THIS IS PART OF THE EOLN
          LX3    6
          EQ     SREAD
 SREAD1   SX5    -B1         NO CHAR MESSAGE
          NZ     B2,SREAD    B2 > 0 AT EOR, EOF, OR EOI
          SB2    B1
          RJ     WREAD
          NZ     X1,SREAD    X1 <> 0 AT EOR, EOF, EOI
          SB2    B0
          BX3    X6
          ZR     X6,SREAD    EOLN
          MX0    54
          EQ     SREAD+4     TEST FOR EOLN
 BREAD    SPACE  4,19
** BREAD READS EIGHT BITS FROM A BINARY FILE.   THESE ARE RETURNED IN
*  X5; X5 < 0 AT EOR, EOI, EOF.  BREAD ALLOWS ITS INPUT TO CROSS WORD
*  BOUNDARIES.  IF THE LAST DATA IN THE FILE IS ONLY FOUR BITS, BREAD
*  PADS THIS WITH ZEROS, UNLESS THE FOUR BITS ARE 0, IN WHICH CASE IT
*  DROPS THEM.
 BREAD    SPACE  3,10
          SX5    -B1         RETURN END OF FILE
          EQ     BREAD
          SB2    B1          FLAG EOF
          ZR     X5,*-1
          LX5    4           AND FILL WITH 0
 BREAD    PS
          PL     B2,*-3      END OF FILE?
          MX0    56
          BX5    -X0*X3      GET NEXT 4 BITS
          SB2    B2+B1
          MI     B2,*+3      B2 < 0 IF THERE IS MORE IN THIS WORD
          SB2    -15         1 WORD = 15 * 4 BITS
          RJ     WREAD       GET NEXT WORD
          NZ     X1,BREAD-1  ADD 0 AT END OF FILE
          MX0    56
          BX3    X6          TRANSFER WORD READ TO X3
          LX3    4
          BX4    -X0*X3      GET SECOND FOUR BITS
          SB2    B2+B1       UPDATE SHIFT COUNT
          LX5    4
          BX5    X5+X4       COMBINE TWO PARTS OF 8-BIT DATUM
          LX3    4
          MI     B2,BREAD    B2 < 0 UNLESS WE MUST READ A WORD
          SB2    B1          PREPARE IN ADVANCE FOR EOR
          RJ     WREAD
          NZ     X1,BREAD    X1 <> 0 AT EOR, EOF, OR EOI
          SB2    -15         15 4-BIT PARCELS PER WORD
          BX3    X6          X3 := WORD READ
          LX3    4
          EQ     BREAD
 KREAD    SPACE  4,19
** KREAD READS FROM A KERMIT-FORMAT BINARY FILE.  THE UPPER FOUR BITS
*  OF EACH WORD OF SUCH A FILE SHOULD CONTAIN  SEVEN MINUS THE NUMBER
*  OF 8-BIT BYTES IN THE REST OF THE WORD.   HENCE IT IS AN ERROR FOR
*  THIS NUMBER TO BE GREATER THAN 6, BUT WE IGNORE SUCH ERRORS.  DATA
*  ARE RETURNED IN X5; X5 < 0 AT EOR, EOF, EOI.
 KREAD    SPACE  3,10
          MX0    52          MASK OFF EIGHT BITS
          LX3    8
          BX5    -X0*X3      PUT THEM IN X5
          SB2    B2+B1       UPDATE SHIFT COUNT
 KREAD    PS
          MI     B2,*-2      B2 < 0 IF MORE BYTES IN THIS WORD
          RJ     WREAD
          NZ     X1,*+3      X1 <> 0 AT EOR, EOF, EOI
          BX3    X6          X3 := WORD READ
          LX3    4
          MX0    56
          BX5    -X0*X3      X5 := 7 - NUMBER OF BYTES IN THIS WORD
          SB2    X5-7        B2 := - NUMBER OF BYTES
          EQ     *-3
          MX5    45          SEND EOR MESSAGE
          EQ     KREAD
 ISAVE    SPACE  4,16
** ISAVE  SAVES ALL REGISTERS ASSOCIATED WITH AN INPUT FILE;  FET - 2
*  RECEIVES THE SHIFT COUNT, FET - 1 THE WORD BEING READ, AND FET + 3
*  THE ADDRESS OF THE NEXT WORD TO BE READ.
 ISAVE    SPACE  3,9
          SX6    B2
          SA6    X1-2        SHIFT COUNT
          BX6    X3
          SA6    A6+B1       SAVE WORD BEING READ
          SX6    B3+B4
          SA6    X1+3        OUT
 ISAVE    PS
          SA1    INFI        GET FET ADDRESS
          EQ     ISAVE-2
 IREST    SPACE  4,18
** IREST RESTORES ALL REGISTERS ASSOCIATED WITH AN INPUT FILE;  SHIFT
*  COUNT IN B2, B4 := ADDRESS OF WORD AFTER LAST WORD TO BE READ,  B3
*  IS THE OFFSET FROM B4 OF THE NEXT WORD TO BE READ, AND  X3 := WORD
*  CURRENTLY BEING READ.
 IREST    SPACE  3,10
 IREST    PS
          SB2    X1          SHIFT COUNT
          SA3    A1+B1       WORD BEING READ
          SA2    A3+3        IN
          SA4    A2+B1       OUT
          SX6    A3+B1       FET ADDRESS
          SA6    INFI
          SB4    X2          END OF DATA
          IX4    X4-X2       OFFSET
          SB3    X4
          EQ     IREST
 INSTART  SPACE  4,19
** INSTART READS NEW INPUT FROM THE TERMINAL, STORING THE FET ADDRESS
*  OF INPUT IN INFI, CALLING FREAD,  AND PREPARING THE OUTPUT FET FOR
*  NEW OUTPUT,  SINCE IT HAS JUST BEEN FLUSHED BY READING FROM INPUT.
*  IT RETURNS WITH X7 = 0.
 INSTART  SPACE  3,11
 INSTART  PS
          SB2    B0
          SX2    INPUT       ADDRESS OF FET
          BX6    X2
          SA6    INFI
          RJ     FREAD       FILL BUFFER
          SX7    TBUF
          RJ     SREAD       READ DUMMY EOLN
          SA7    OUTPUT+2    IN
          SA7    A7+B1       OUT; HENCE OUTPUT BUFFER IS EMPTY
          BX7    X7-X7
          EQ     INSTART
 TESTFIL  SPACE  4,18
** TESTFIL  CHECKS WHETHER A LOCAL FILE EXISTS OR NOT.   NO REGISTERS
*  ARE PRESERVED.   ON ENTRY X6 = THE ADDRESS OF THE FET OF THE FILE.
*  ON EXIT, X6 CONTAINS THE FILE STATUS: X6 = 0 IF NO FILE WAS FOUND;
*  X6 > 0 IF A FILE WAS FOUND.
 TESTFIL  SPACE  3,10
 TESTFIL  PS
          SA6    UPDAT       SAVE FET ADDRESS
          STATUS X6
          SA2    UPDAT
          SA1    X2          GET FET + 0
          MX0    42
          BX6    X0*X1       X6 := FILE NAME
          SX5    B1+B1
          SX5    X5+B1       X5 := 3 = BINARY FET FLAG
          BX6    X6+X5
          SA6    A1          RESTORE FET TO NORMAL
          MX0    48
          BX6    -X0*X1
          AX6    1           X6 CONTAINS DESIRED STATUS
          EQ     TESTFIL
 WWRITE   TITLE  PRIMARY OUTPUT ROUTINES
**     PRIMARY OUTPUT ROUTINES
*
*  WWRITE WRITES ONE WORD TO A FILE.   IF THIS FILLS THE FILE BUFFER,
*  WWRITE FLUSHES IT.  THE WORD TO BE WRITTEN IN IN X7; X7 STILL CON-
*  TAINS THIS WORD UPON EXIT FROM THIS ROUTINE.
 WWRITE   SPACE  3,10
 WWRITE   PS
          SA7    B6+B7
          SB6    B6+B1
          MI     B6,WWRITE
          SA7    REGIST      REGIST CONTAINS X7
          MX0    42
          SX2    B2
          SX4    B3
          SX6    B4
          SX7    B5
          BX2    -X0*X2      REMOVE SIGN EXTENSIONS FROM B REGISTERS
          BX4    -X0*X4
          BX6    -X0*X6
          BX7    -X0*X7
          LX6    18
          LX7    18
          BX6    X6+X2
          BX7    X7+X4
          SA6    A7+B1       REGIST + 1 CONTAINS B4, B2
          SA7    A6+B1       REGIST + 2 CONTAINS B5, B3
          BX7    X3
          BX6    X5
          SA7    A7+B1       REGIST + 3 CONTAINS X3
          SA6    A7+B1       REGIST + 4 CONTAINS X5
          SA2    OUTFI       X2 = FET ADDRESS
          SA1    X2+B1
          BX6    -X0*X1      X6 = START OF BUFFER
          SX7    B7
          SA7    A1+B1       IN
          SA6    A7+B1       OUT
          WRITE  X2,R
          SA2    OUTFI       X2 := FET ADDRESS
          MX0    42
          SA1    X2+B1
          SA3    A1+B1       IN
          SA4    A3+B1       OUT
          SA5    A4+B1
          BX6    -X0*X1      FIRST
          BX5    -X0*X5      LIMIT
          SA6    A4          SAVE FIRST AS OUT
          SB7    X5          END OF BUFFER
          SB7    B7-B1
          SB6    X6
          IX5    X4-X3
          PL     X5,*+3      X5 > 0 IF THE BUFFER WAS EMPTIED
          SA1    X4          OTHERWISE GET NEXT WORD IN BUFFER
          BX7    X1
          SA7    B6          AND TRANSFER IT TO START OF BUFFER
          SX4    X4+B1       UPDATING SOURCE ADDRESS
          SB6    B6+B1       AND DESTINATION ADDRESS
          SX5    X5+B1       AND WORD COUNT (WHICH SHOULD BECOME 0)
          MI     X5,*-1      THIS SHOULD NEVER HAPPEN, BUT ...
          SB6    B6-B7
          SA4    REGIST      X4 = (X7)
          SA1    A4+B1       X1 = (B4, B2)
          SA2    A1+B1       X2 = (B5, B3)
          SA3    A2+B1       X3 = (X3)
          SA5    A3+B1       X5 = (X5)
          BX7    X4
          SB2    X1
          SB3    X2
          LX1    42
          LX2    42
          SB4    X1
          SB5    X2
          EQ     WWRITE
 SWRITE   SPACE  4,16
** SWRITE  WRITES  ONE  6-BIT CHARACTER FROM X5 TO THE CURRENT OUTPUT
*  FILE.
 SWRITE   SPACE  3,10
          LX7    6
          BX7    X7+X5       ADD CHAR TO OUTPUT WORD
          SB5    B5+B1
          MI     B5,*+1      B5 < 0 IF THE WORD IS NOT YET FULL
          RJ     WWRITE
 SWRITE   PS
          MI     B5,SWRITE-2 B5 < 0 WHEN THE WORD IS NOT FULL
          SB5    -9          THERE WILL BE 9 MORE CHARACTERS
          BX7    X5          AFTER THIS ONE
          EQ     SWRITE
 SLINE    SPACE  4,17
** SLINE WRITES AN END-OF-LINE ON AN ASCII OR DISPLAY CODE FILE, ADD-
*  ING A BLANK CHARACTER TO EMPTY LINES  AND TO LINES ENDING WITH ANY
*  CHARACTER WHOSE LAST SIX BITS ARE ZERO.
 SLINE    SPACE  3,10
          LX7    6           LOOP TO ADD ZEROS
          SB5    B5+B1
          MI     B5,*
          RJ     WWRITE      AND WRITE THE WORD
 SLINE    PS
          MX0    54
          BX4    -X0*X7      TEST THE LAST CHAR WRITTEN
          NZ     X4,*+5      IF IT <> 0 THEN JUST ADD EOLN;
          SX4    45          OTHERWISE ADD A BLANK
          MI     B5,*+2      B5 < 0 IF THE BLANK FITS IN THIS WORD
          BX7    X4          THE BLANK IS THE ONLY CHARACTER
          LX7    54          ADD NINE ZEROS
          EQ     SLINE-1     AND WRITE THE WORD
          LX7    6
          BX7    X7+X4       ADD THE BLANK
          SB5    B5+B1
          MI     B5,*+1      B5 < 0 IF BLANK DOES NOT FILL THIS WORD
          RJ     WWRITE
          PL     B5,*+2      B5 >= 0 IF X7 CONTAINS NO CHARACTERS
          LX7    6
          SB5    B5+B1
          MI     B5,SLINE-2  B5 < 0 IF END-OF-LINE FITS IN THIS WORD
          RJ     WWRITE
          BX7    X7-X7       WRITE A WORD OF ZEROS
          EQ     SLINE-1
 OSAVE    SPACE  4,18
** OSAVE INTERRUPTS WRITING TO A FILE AND SAVES 4 OUTPUT REGISTERS IN
*  THE FET AND ITS EXTENSION.  AFTER FLUSHING THE WORD BEING WRITTEN,
*  CALL THIS ROUTINE TO PREPARE TO CLOSE A FILE.  X6 = 0 ON EXIT.
 OSAVE    SPACE  3,11
 OSAVE    PS
          SA1    OUTFI       GET FET ADDRESS
          SX6    B6+B7
          SB6    B1+B1
          SB7    -B6
          SA6    X1+B6       IN
          SX6    B5
          SA6    X1+B7       WORD SHIFT
          SA7    A6+B1       OUTPUT WORD
          BX6    X6-X6
          EQ     OSAVE
 OREST    SPACE  4,17
** OREST PREPARES TO RESUME WRITING TO A FILE BY RESTORING THE OUTPUT
*  REGISTERS  SAVED BY OSAVE.   ON ENTRY X7 CONTAINS THE FET ADDRESS.
*  ON EXIT, X6 IS GUARANTEED NOT TO BE ZERO.
 OREST    SPACE  3,10
 OREST    PS
          SA7    OUTFI       SAVE FET ADDRESS AT OUTFI
          SB6    B1+B1
          SB7    -B6
          SA1    X7+B7       SHIFT COUNT
          SA2    A1+B1       WORD BEING WRITTEN
          SB5    X1
          SA1    X7+B6       IN
          BX7    X2
          SA4    A1+B6
          MX0    42
          BX4    -X0*X4      ADDRESS OF END OF BUFFER
          SB7    X4
          IX4    X1-X4       OFFSET
          SB6    X4+B1
          SB7    B7-B1
          SX6    B1          ENSURE THAT X6 <> 0
          EQ     OREST
 OUTSTRT  SPACE  4,17
** OUTSTRT  PREPARES TO WRITE ON THE FILE OUTPUT; IT ASSUMES THERE IS
*  NO TEXT ALREADY WRITTEN TO THIS FILE.
 OUTSTRT  SPACE  3,11
 OUTSTRT  PS
          SB7    WBUF-2      END OF OUTPUT BUFFER
          SB6    1-TBUFL     SIZE OF OUTPUT BUFFER
          SX7    OUTPUT
          SA7    OUTFI
          SX6    B6+B7
          SA6    OUTPUT+2    IN
          SA6    A6+B1       OUT
          BX7    X7-X7       NO CHARACTERS WRITTEN
          SB5    B0
          EQ     OUTSTRT
 NREAD    TITLE  SECONDARY INPUT: TRANSLATION AND UTILITIES
**     SECONDARY INPUT: TRANSLATION AND UTILITIES
*
*  NREAD READS A NUMBER FROM TERMINAL INPUT.  IT IS USED WITH THE SET
*  COMMAND AND THE OPTIONS DELAY, PACKET-LENGTH, AND RETRY.  ON EXIT,
*  B5 SHOWS THAT AN END-OF-LINE WAS READ (0) OR A NUMBER (1) OR INPUT
*  OF SOME OTHER KIND (-1); THE NUMBER IS IN X7.
 NREAD    SPACE  3,10
          SB5    -B1         ERROR
 NREAD    PS
          BX7    X7-X7
          SB5    B0
          RJ     SREAD       GET A CHAR
          MI     X5,NREAD    X5 < 0 AT EOLN
          SX4    X5-45       TEST FOR BLANK
          ZR     X4,*-2      IGNORE LEADING BLANKS
 +        SX5    X5-1R0
          MI     X5,NREAD-1  ALPHABETIC INPUT
          SX4    X5-10
          PL     X4,NREAD-1  NON-DIGIT
          SB5    B1          SET DATA FLAG; SOMETHING WAS READ
          LX4    B1,X7       X4 := X7 * 2
          LX7    3           X7 := X7 * 8
          IX7    X7+X4
          IX7    X7+X5
          RJ     SREAD       GET NEXT CHAR
          MI     X5,NREAD    EOLN
          SX4    X5-45       TEST FOR BLANK
          NZ     X4,NREAD+4  NO BLANK
          EQ     NREAD       STOP AT BLANK
 DREAD    SPACE  4,15
** DREAD  READS FROM A DISPLAY CODE FILE BUT PRODUCES AN ASCII VALUE.
 DREAD    SPACE  3,10
 DREAD    PS
          RJ     SREAD
          MI     X5,DREAD    EOLN
          NZ     X5,*+2
          IFEQ   1R:,0
          SX5    58          COLON
          ELSE   2
          SX5    B1
          LX5    5           BLANK
          EQ     DREAD
          SX5    X5-27       TEST ALPHABETIC
          PL     X5,*+2      X5 > 0 UNLESS ALPHABETIC
          SX5    X5+91
          EQ     DREAD
          SX5    X5-10       TEST FOR DIGITS
          PL     X5,*+2      X5 > 0 FOR SYMBOLS WHICH ARE NOT DIGITS
          SX5    X5+58
          EQ     DREAD
          SA5    X5+DITAB    USE TABLE TO CONVERT
          EQ     DREAD
 AREAD    SPACE  4,15
** AREAD READS FROM A 6/12 ASCII FILE AND YIELDS STANDARD ASCII CODE.
 AREAD    SPACE  3,10
          RJ     SREAD
          MI     X5,AREAD    IGNORE @ + EOLN
          SX4    X5-8
          PL     X4,AREAD1-1 WHEN X4 > 0, @ + X4 IS UNPRINTABLE
          SA5    X5+ATTAB
 AREAD    PS
          RJ     SREAD       GET NEXT CHAR
          MI     X5,AREAD    X5 < 0 AT EOLN, EOR, EOF
          SX4    X5-62       TEST FOR UP-ARROW
          ZR     X4,AREAD1   PROCESS THEM AT AREAD1
          SX4    X4+B1
          SX4    X4+B1       TEST FOR @
          ZR     X4,AREAD-3  TEST @ ELSEWHERE
          NZ     X5,*+2
          IFEQ   1R:,0
          SX5    58          COLON
          ELSE   2
          SX5    B1
          LX5    5           BLANK SPACE
          EQ     AREAD
          SX5    X5-27       TEST FOR UPPER CASE LETTERS
          PL     X5,*+2
          SX5    X5+91       CONVERT LETTERS
          EQ     AREAD
          SX5    X5-10       TEST FOR DIGITS
          PL     X5,*+2
          SX5    X5+58       CONVERT DIGITS
          EQ     AREAD
          SA5    X5+DITAB    CONVERT OTHER SYMBOLS
          EQ     AREAD
          SX5    B1
          LX5    5           BLANK
          EQ     AREAD
 AREAD1   RJ     SREAD       GET NEXT CHAR
          MI     X5,AREAD    IGNORE ^ + EOLN
          ZR     X5,AREAD1-1 UNDEFINED COMBINATION
          SX5    X5-32
          PL     X5,AREAD    UNPRINTABLE CHARACTER
          SX5    X5+128
          EQ     AREAD
 EREAD    SPACE  4,15
** EREAD READS ASCII CODE FROM AN ASCII8 FILE.
 EREAD    SPACE  3,10
          RJ     SREAD       GET NEXT CHAR
 EREAD    PS
          RJ     SREAD       GET NEXT CHAR
          MI     X5,EREAD    EOLN
          ZR     X5,EREAD-1
          MX0    58
          BX4    X0*X5       TEST FOR LEGITIMATE ASCII8 CHAR
          ZR     X4,*+3      X4 = 0 IF OK
          PL     B2,EREAD-1  GET EOLN NEXT
          RJ     SREAD
          SX5    B1
          LX5    5           BLANK
          EQ     EREAD
          MX0    59
          BX5    -X0*X5      MASK OFF EIGHTH BIT
          ZR     X5,EREAD-1
          PL     B2,*+2      ASSUME THERE SHOULD HAVE BEEN A BLANK
          RJ     SREAD
          SX5    X5+64       RESTORE MISSING BIT
          EQ     EREAD
          LX5    6           X5 := 64
          EQ     EREAD
 SETCHAR  SPACE  4,16
** SETCHAR IS USED BY SET WITH OPTIONS BIT-PREFIX, QUOTE-CHAR AND RE-
*  PEAT-CHAR.
 SETCHAR  SPACE  3,10
          MX7    58          RETURN ERROR VALUE
 SETCHAR  PS
          MI     X5,*-1      END-OF-LINE
          RJ     AREAD
          SX4    X5-32
          MI     X4,*-3      X4 < 0 FOR UNPRINTABLE CHARACTERS
          ZR     X4,*-2      X4 - 0 FOR BLANK SPACE
          MI     B2,*-4      B2 < 0 WHEN MORE INPUT FOLLOWS
          SX4    X5-63       PREPARE FOR LEGITIMACY TEST
          MI     X4,*+3      CONSIDER VALUES < 63 ELSEWHERE
          SX4    X5-96
          MI     X4,*-6      X4 < 0 FOR '?' AND CTRL-POSSIBLES
          MX0    53
          BX4    -X0-X5
          ZR     X4,*-7      X4 = 0 FOR DEL
          BX7    X5
          EQ     SETCHAR
 SETCTRL  SPACE  4,15
** SETCTRL IS USED TO SET ESCAPE AND PACKET-MARKER.
 SETCTRL  SPACE  3,10
          MX7    40
 SETCTRL  PS
          MI     X5,*-1      END-OF-LINE
          RJ     AREAD
          SX4    X5-32
          MI     X4,*-3      LITERAL CONTROL CHARACTERS NOT ALLOWED
          ZR     X4,*-2      LEADING BLANKS IGNORED
          MI     B2,*-4      TWO CHARACTERS NOT ALLOWED
          SX7    X5-64
          MI     X7,*-4      CHARS LESS THAN 64 NOT ALLOWED
          SX5    X7-32
          MI     X5,*+3      NEITHER ARE CHARS GREATER THAN 126
          ZR     X5,*-7
          BX7    X5
          SX5    X5-27       EXCEPT FOR LOWER CASE LETTERS
          PL     X5,*-8
          SB5    X7
          SX5    B1
          SA4    ILLEGIT     TEST FOR CHARS WITH SPECIAL MEANING
          LX5    B5,X5
          BX5    X4*X5
          ZR     X5,SETCTRL  X5 = 0 IF THE CHARACTER READ IS GOOD
          EQ     SETCTRL-1
 AWRITE   TITLE  SECONDARY OUTPUT: TRANSLATION AND UTILITIES
**     SECONDARY OUTPUT: TRANSLATION AND UTILITIES
*
*  AWRITE WRITES AN ASCII CODE TO A 6/12 FILE.
 AWRITE   SPACE  3,10
          RJ     SWRITE
 AWRITE   PS
          MX0    53
          BX5    -X0*X5      MASK OFF ANY EIGHTH BITS SET
          SX4    X5-13
          NZ     X4,*+2      TEST FOR CARRIAGE RETURN
          RJ     SLINE       IN WHICH CASE, WRITE END-OF-LINE
          EQ     AWRITE
          SX5    X5-32
          PL     X5,*+2      IF X5 < 0 THE CHAR IS NOT PRINTABLE
          SX5    X5+91       AND NEEDS A CODE AFTER UP-ARROW
          EQ     AWRITE1
          SX5    X5-1
          PL     X5,*+2      X5 >= 0 IF CHAR IS NOT BLANK
          SX5    45
          EQ     AWRITE-1
          SX4    X5-15       X4 IS < 0 FOR SOME NONALPHANUMERIC
          IFEQ   1R:,0
          MI     X4,AWRITE1-1
          ELSE   1
          MI     X4,AWRITE1-4
          SX4    X4-10
          PL     X4,*+2      X4 < 0 FOR DIGITS
          SX5    X5+12       WHICH WE CONVERT TO DISPLAY CODE
          EQ     AWRITE-1
          IFEQ   1R:,0,1
          ZR     X4,AWRITE1-3  COLON
          SX5    X5-10
          SX4    X5-22
          PL     X4,*+4      X4 < 0 FOR SOME NONALPHANUMERIC
          SX4    X4+B1
          MI     X4,AWRITE1-1  X4 = 0 FOR AT SYMBOL
          SX5    60
          RJ     SWRITE
          SX5    B1
          EQ     AWRITE-1
          SX4    X4-26
          PL     X4,*+2      X4 < 0 FOR UPPER CASE LETTERS
          SX5    X4+27
          EQ     AWRITE-1
          SX5    X5-26
          SX4    X5-28
          PL     X4,AWRITE1  X4 > 0 FOR CHARACTERS WITH UP-ARROW
          SX4    X4+B1
          MI     X4,*+3      X4 = 0 FOR GRAVE ACCENT
          SX5    60
          RJ     SWRITE
          SX5    7
          EQ     AWRITE-1
          SX4    X4+B1
          SX4    X4+B1
          NZ     X4,AWRITE1-1  X4 = 0 FOR UP-ARROW SYMBOL
          SX5    60
          RJ     SWRITE
          SX5    B1+B1
          EQ     AWRITE-1
          IFNE   1R:,0,2
          SX4    X5-5
          NZ     X4,*+3      X4 = 0 FOR PERCENT SYMBOL
          SX5    60
          RJ     SWRITE
          SX5    B1
          LX5    2
          EQ     AWRITE-1
          SA5    X5+ASCTAB   LOOK UP VALUE IN TABLE
          EQ     AWRITE-1
 AWRITE1  MI     B5,*+2      B5 < 0 IF X7 IS NOT YET FULL
          SX7    X5+3941
          SB5    -8          EIGHT CHARACTERS TO GO IN X7
          EQ     AWRITE
          SX4    62          ADD UP-ARROW TO X7
          LX7    6
          BX7    X7+X4
          SB5    B5+B1
          SX5    X5-27       CONVERT X5 TO HOLD APPROPRIATE CODE
          MI     B5,AWRITE-1 B5 < 0 IF X7 IS NOT YET FULL
          RJ     WWRITE
          BX7    X5
          SB5    -9          NINE CHARS TO GO IN X7
          EQ     AWRITE
 ELINE    SPACE  4,17
** ELINE   WRITES AN END-OF-LINE ON AN ASCII8 FILE.   IT ADDS A BLANK
*  SPACE TO EMPTY LINES  AND TO LINES ENDING WITH ANY CHARACTER WHOSE
*  LAST SIX BITS ARE ZERO (NUL AND AT-SYMBOL).
 ELINE    SPACE  3,10
          LX7    12          FILL WORD WITH ZEROS
          SB5    B5+B1
          MI     B5,*
          RJ     WWRITE      THEN WRITE IT
 ELINE    PS
          MX0    54
          BX4    -X0*X7
          NZ     X4,*+5      IF X4 = 0 A BLANK MUST BE ADDED
          SX4    B1
          LX4    53          X4 CONTAINS LEFT JUSTIFIED ASCII BLANK
          MI     B5,*+2      B5 < 0 IF THIS WORD IS NOT FULL
          BX7    X4
          EQ     ELINE-1
          BX7    X7+X4       ADD THE BLANK TO X7
          LX7    12
          SB5    B5+B1
          MI     B5,ELINE-2  B5 < 0 IF EOLN FITS IN THIS WORD
          RJ     WWRITE
          MI     B5,ELINE-2
          BX7    X7-X7       OTHERWISE WRITE A WORD OF ZEROS
          EQ     ELINE-1
 ZWRITE   SPACE  4,16
** ZWRITE COPIES A (DISPLAY OR 6/12 CODE) TEXT WHICH IS TERMINATED BY
*  SIX ZERO BITS.  ON ENTRY B3 MUST CONTAIN THE ADDRESS OF THE TEXT.
 ZWRITE   SPACE  3,10
 ZWRITE   PS
          SA3    B3          GET 1ST WORD OF TEXT
          SB3    B3+B1
          SB2    -10         SHIFT COUNT = 10
          MX0    54
          LX3    6
          BX5    -X0*X3      X5 := NEXT CHAR OF TEXT
          SB2    B2+B1
          ZR     X5,ZWRITE   X5 = 0 WHEN THE TEXT IS FINISHED
          RJ     SWRITE
          MI     B2,*-2      B2 < 0 WHEN THE NEXT CHAR IS IN X3
          EQ     *-3         OTHERWISE GET THE NEXT WORD
 NWRITE   SPACE  4,17
** NWRITE  CONVERTS A NUMBER TO DISPLAY CODE AND WRITES IT TO A FILE.
*  ON INPUT THE NUMBER MUST BE IN X3 AND THE FILE PARAMETERS IN OUTFI
*  AND THE REGISTERS B5, B6, B7, AND X7.
 NWRITE   SPACE  3,10
          MX0    54
          LX3    6
          BX5    -X0*X3      GET NEXT CHARACTER
          BX3    X3-X5       AND REMOVE IT FROM X3
          RJ     SWRITE
          NZ     X3,*-2
          RJ     SLINE       WRITE END-OF-LINE
 NWRITE   PS
          SA0    B2          SAVE B2 (USED BY NCONCV)
          BX5    X5-X5       AND MAKE X5 := 0
          RJ     NCONV       CONVERT THE NUMBER TO DISPLAY CODE
          SB2    A0          RESTORE B2
          BX3    X5
          EQ     NWRITE-3
 XWRITE   SPACE  4,12
** XWRITE WRITES A SPECIFIED NUMBER OF BLANKS TO A FILE.  ON ENTRY B2
*  MUST CONTAIN 1 LESS THAN THE NUMBER OF BLANKS DESIRED.
 XWRITE   SPACE  3,6
          RJ     SWRITE      WRITE ONE BLANK
          SB2    B2-B1       DECREMENT COUNT
          PL     B2,*-1      UNTIL DONE
 XWRITE   PS
          SX5    45          DISPLAY CODE BLANK
          EQ     XWRITE-2
 ZLINE    SPACE  4,10
** ZLINE  WRITES AN END-OF-LINE,  THEN THE ZERO-TERMINATED TEXT WHOSE
*  ADDRESS IS IN B3 ON ENTRY.
 ZLINE    SPACE  3,4
 ZLINE    PS
          RJ     SLINE
          RJ     ZWRITE
          EQ     ZLINE
 NZLINE   SPACE  4,10
** NZLINE WRITES THE NUMBER CONTAINED IN X3, THEN AN END-OF-LINE, AND
*  THEN THE TEXT WHOSE ADDRESS IS CONTAINED IN B3 ON ENTRY.
 NZLINE   SPACE  3,4
 NZLINE   PS
          RJ     NWRITE      THIS WRITES BOTH THE NUMBER AND THE EOLN
          RJ     ZWRITE      PRINT THE TEXT
          EQ     NZLINE
 BCTRLW   SPACE  4,18
** BCTRLW IS DESIGNED TO REPORT THAT SOMETHING IS OR BECOMES  CTRL-X,
*  WHERE 'X' IS AN ASCII CODE LETTER.  FIRST IT WRITES THE TEXT WHOSE
*  ADDRESS IS IN B3, THEN 14 SPACES, THEN THE TEXT 'CTRL-',  THEN THE
*  LETTER WHOSE ADDRESS IS IN B4.
 BCTRLW   SPACE  3,10
          SX5    X5+64       CONVERT TO PRINTABLE CHARACTER
          RJ     AWRITE
 BCTRLW   PS
          RJ     ZWRITE      PRINT THE TEXT
          SB2    13
          RJ     XWRITE      WRITE BLANKS
          SB3    CTRLHYP
          RJ     ZWRITE      WRITE 'CTRL-'
          SA5    B4
          EQ     BCTRLW-1
 WSTATS   SPACE  4,16
** WSTATS  WRITES TRANSFER STATISTICS REQUIRED BY THE STATUS COMMAND;
*  IT ALSO RECORDS PACKET TRAFFIC IN THE LOG AT END-OF-FILE.
 WSTATS   SPACE  3,10
 WSTATS   PS
          SB3    TRANSFM+4
          RJ     ZLINE
          SB2    9
          RJ     XWRITE
          SA3    PSENT       NUMBER OF PACKETS SENT
          RJ     NZLINE
          SB2    5
          RJ     XWRITE
          SA3    PRECD       NUMBER OF PACKETS RECEIVED
          RJ     NZLINE
          SB2    10
          RJ     XWRITE
          SA3    PKERRS      NUMBER OF INPUT ERRORS
          RJ     NZLINE
          SB2    10
          RJ     XWRITE
          SA3    RETRYT      NUMBER OF RETRIES
          RJ     NWRITE
          RJ     SLINE
          EQ     WSTATS
 WFILTYP  SPACE  4,16
** WFILTYP  WRITES THE NAME OF THE CURRENT FILE TYPE AND END-OF-LINE.
*  THE NAME OF THE FILE TYPE FOLLOWS A BLANK SPACE.
 WFILTYP  SPACE  3,10
          SB3    X4+FTLIST+4
          RJ     ZWRITE      WRITE NAME OF FILE TYPE
          RJ     SLINE       WRITE EOLN
 WFILTYP  PS
          SX5    45
          RJ     SWRITE      WRITE BLANK
          SA4    FILETYP+1
          MX0    58
          BX0    -X0*X4
          ZR     X0,*+1
          SX4    X4+B1
          LX4    2
          AX4    1
          EQ     *-6
 LOGLIN   SPACE  4,18
** LOGLIN  STARTS A NEW SECTION OF THE LOG.  IT DOES NOT PRESERVE ANY
*  REGISTER CONTENTS EXISTING AT ENTRY.  IT WRITES AN EOLN IF THE LOG
*  DID NOT HAVE ONE AFTER THE LAST LINE, THE TIME, AND A SPACE.   THE
*  OUTPUT REGISTERS ARE SET UP ON EXIT FOR WRITING TO THE LOG.
 LOGLIN   SPACE  3,10
 LOGLIN   PS
          CLOCK  TIMWORD
          SX7    ZZZKLOG
          RJ     OREST       PREPARE TO WRITE ON LOG
          MI     B5,*+1      OREST RETURNS WITH X6 <> 0
          MX0    48
          BX6    -X0*X7
          ZR     X6,*+1      X6 = 0 AFTER AN END-OF-LINE
          RJ     SLINE       OTHERWISE WRITE ONE
          SA3    TIMWORD
          SB5    -9
          BX7    X3
          RJ     WWRITE      WRITE THE TIME
          SX7    55B         AND A BLANK SPACE
          EQ     LOGLIN
 LOGSET   SPACE  4,13
** LOGSET  STARTS TO LOG A SET COMMAND; IT STARTS A NEW LOG ENTRY AND
*  WRITES THE WORD 'SET' FOLLOWED BY A BLANK SPACE.
 LOGSET   SPACE  3,7
 LOGSET   PS
          RJ     LOGLIN      SET UP LOG FOR WRITING
          SB3    CMDLIST+9   SET
          RJ     ZWRITE
          SX5    45          BLANK
          RJ     SWRITE
          EQ     LOGSET
 UNIQUE   SPACE  4,17
** UNIQUE ENSURES THAT NO FILE HAS A GIVEN NAME (IN X6 ON ENTRY);  IF
*  THERE IS SUCH A FILE, THE NAME IS REPLACED BY ANOTHER.    ANY NAME
*  CHANGES ARE LOGGED.  THE PROCESS CREATES A FILE ENVIRONMENT TABLE.
 UNIQUE   SPACE  3,10
 UNIQUE   PS
          SX6    3           BINARY FILE CODE (ALL FILES ARE BINARY)
          SA1    DUMMY+1
          SA2    A1+B1
          BX6    X6+X3       FILE NAME + TYPE
          SX5    WBUF        ADDRESS OF BUFFER ('IN' AND 'OUT')
          BX7    X1
          SA6    FILE
          SA7    A6+B1
          BX7    X5
          SA7    A7+B1
          SA7    A7+B1
          BX7    X2
          SA7    A7+B1       LAST (5TH) WORD OF FET
          SX5    3RZZZ
          LX5    42
          BX5    X5-X6       TEST FOR AN ILLEGAL FILE NAME
          AX5    42
          ZR     X5,*+2      X5 = 0 IF THE NAME BEGINS WITH ZZZ
          SX6    FILE
          RJ     TESTFIL     TEST FOR EXISTENCE OF FILE
          ZR     X6,*+3      X6 IS 0 IF THE FILE DOES NOT EXIST
          RJ     DEFFILE     OTHERWISE CREATE A NEW FILE NAME
          SA6    FILE
          SA2    A3
          SX6    X2+B1       AND INCREMENT THE DEFAULT FILE NUMBER
          SA6    A2
          EQ     *-3
          SA1    FILE
          SA2    FILNAM
          BX2    X2-X1       HAS THE NAME BEEN CHANGED?
          AX2    18
          ZR     X2,UNIQUE   X2 = 0 IF THE NAME HAS NOT BEEN CHANGED
          BX6    X1
          SA6    A2
          RJ     LOGLIN
          SB3    FNCHGM      NAME OF FILE CHANGED TO
          RJ     ZWRITE
          SB3    FILE
          RJ     ZWRITE      FILENAME
          RJ     OSAVE
          EQ     UNIQUE
 MAINPRG  TITLE  MAINPRG -- MAIN COMMAND PROCESSOR
** THE MAIN COMMAND PROCESSOR, MAINPRG, HAS TWO ENTRY POINTS: MAINPRG
*  ITSELF IS USED WHEN THE OUTPUT BUFFER CONTAINS DATA AND THE OUTPUT
*  REGISTERS ARE SET;  MAINPRG-1 IS USED WHEN NEITHER OF THESE CONDI-
*  TIONS IS TRUE.
 MAINPRG  SPACE  3,10
          RJ     OUTSTRT
 MAINPRG  SB3    KPROMPT
          RJ     ZWRITE      WRITE THE CYBER KERMIT PROMPT
          LX7    12
          SX6    B1          AND PREVENT CARRIAGE RETURN
          BX7    X7+X6
          SB5    B5+B1
          SB5    B5+B1
          RJ     SLINE
          RJ     OSAVE       UPDATE OUTPUT FET FOR AUTOMATIC FLUSHING
          SB7    COMTAB      PREPARE TO READ ONE OF THE MAIN COMMANDS
          RJ     INSTART     AND FILL THE INPUT BUFFER
 CREAD    SPACE  4,22
** CREAD UNITES THE TWO COMMAND PROCESSORS.  ONE READS TERMINAL INPUT
*  AND ONE READS COMMANDS SENT IN PACKETS; KMODE (ARE WE A SERVER) IS
*  THE DISTINGUISHING FLAG.  BOTH PROCESSORS KEEP THE INPUT REGISTERS
*  FOR GETTING DATA FROM THEIR SOURCE.  ON ENTRY B7 HOLDS THE ADDRESS
*  OF THE WORD BEFORE THE FIRST ACCEPTABLE COMMAND IN A TABLE.  AMBI-
*  GUOUS COMMANDS REQUIRE AN ENTRY FOR AN AMBIGUOUS STRING; OTHERWISE
*  THE FIRST WILL BE CHOSEN.  COMMANDS MAY HAVE AT MOST NINE LETTERS.
*  SELECTING A COMMAND CAUSES A JUMP TO A LOCATION IN COMSEL.
 CREAD    SPACE  3,10
 CREAD    SB6    B7+COMDIFF  WHERE TO GO
          SB5    -9          MAX CHARS TESTED IN A COMMAND
          BX7    X7-X7
          SA1    KMODE       ARE WE A SERVER
          ZR     X1,CREAD1   IF NOT, READ
          EQ     CREAD3
 CREAD5   SX4    X5-32       TEST FOR BLANK
          NZ     X4,*+2
          NZ     X7,CREAD1+3  A BLANK TERMINATES A COMMAND
          EQ     CREAD3      UNLESS NOTHING WAS READ
          SX4    X5-45       TEST FOR HYPHEN
          NZ     X4,*+2
          NZ     X7,CREAD3   A HYPHEN IS IGNORED
          JP     B6          UNLESS NOTHING WAS READ
          SX4    X5-44       TEST FOR COMMAS
          ZR     X4,CREAD1+2  COMMA, LIKE EOLN, ALWAYS TERMINATES
          SX4    X5-58       TEST FOR DIGITS
          MI     X4,*+6
          SX5    X5-64
          SX4    X5-27
          MI     X4,*+1
          SX5    X5-32       CHANGE LOWER CASE TO UPPER CASE
          MI     X5,*+2
          ZR     X5,*+2
          SX4    X5-27       TEST FOR LETTERS
          MI     X4,*+4
          JP     B6
          SX4    X4+10
          MI     X4,*-1
          SX5    X5-21       CONVERT DIGITS
 +        PL     B5,CREAD3   IGNORE CHARS BEYOND 9
          LX7    6
          BX7    X7+X5
          SB5    B5+B1
 CREAD3   RJ     UNPACK      GET THE NEXT CHARACTER FROM THE PACKET
          MX0    54
          PL     X5,CREAD5
          NZ     X7,CREAD1+3
          JP     B6
 CREAD4   SX4    X5-45       TEST FOR BLANK
          NZ     X4,*+2
          NZ     X7,CREAD1+3  A BLANK TERMINATES A COMMAND
          EQ     CREAD1      PROVIDED SOMETHING WAS READ
          SX4    X5-1R-      TEST FOR A HYPHEN
          NZ     X4,*+2
          NZ     X7,CREAD1   IGNORE HYPHENS IN A COMMAND
          JP     B6          BUT DO NOT ALLOW ONE BEFORE IT
          SX4    X5-1R,      TEST FOR A COMMA
          ZR     X4,CREAD1+2  COMMA, LIKE EOLN, ALWAYS TERMINATES
          SX4    X5-1R^      TEST FOR UP-ARROW
          NZ     X4,*+4
          RJ     SREAD
          SX4    X5-27       TEST FOR ALPHABETIC
          MI     X4,*+3      ERROR UNLESS ALPHABETIC
          JP     B6
          SX4    X5-37       TEST FOR ALPHANUMERIC
          PL     X4,*-1      ERROR IF NOT
          PL     B5,CREAD1   IGNORE LETTERS BEYOND 9
          LX7    6
          BX7    X7+X5       ADD THE LETTER TO THE WORD
          SB5    B5+B1
 CREAD1   RJ     SREAD       READ THE NEXT SIX-BIT CHARACTER
          MX0    54
          PL     X5,CREAD4   NOT EOLN
          NZ     X7,*+1      X7 = 0 IF NO COMMAND WAS READ
          JP     B6
          LX7    6
          SB5    B5+B1
          LE     B5,B0,*     LEFT-JUSTIFY COMMAND IN X7
          SA1    B5+B7       GET WORD FROM TABLE
          ZR     X1,CREAD1-4  X1 = 0 WHEN NO COMMAND HAS MATCHED
          BX6    X7          MAKE AN EXTRA COPY OF THE COMMAND
          LX6    6
          BX4    -X0*X6      GET NEXT CHAR FROM COMMAND
          NZ     X4,*+2      IF THERE IS NONE, MATCH IS FOUND
          SB6    B6+B5
          JP     B6
          LX1    6
          BX2    -X0*X1      GET NEXT CHAR FROM TABLE
          BX2    X2-X4       AND COMPARE IT WITH X4
          ZR     X2,*-3      KEEP GOING IF THEY MATCH
          SB5    B5+B1       OTHERWISE TRY THE NEXT TABLE ENTRY
          EQ     *-5
 LOGPACK  TITLE  PACKET HANDLING ROUTINES
** LOGPACK IS USED BY THE DEBUG FACILITY TO LOG PACKET DATA.  B4 CON-
*  TAINS ON ENTRY THE ADDRESS OF THE FIRST WORD IN THE PACKET  (AFTER
*  THE PACKET SYNC-MARKER).  THE END OF THE DATA IS MARKED BY A NEGA-
*  TIVE CHARACTER.
 LOGPACK  SPACE  3,10
          RJ     AWRITE      WRITE THE CHARACTER IN THE LOG
          SB4    B4+B1
          SA5    B4          AND GET THE NEXT CHARACTER
          PL     X5,*-1
          SB3    EOPMSG      MARK POSITION OF END-OF-PACKET
          RJ     ZWRITE
          SB4    B4-B1
          RJ     SLINE
          SX6    -B1
          SA6    B4          CANCEL CHECKSUM CHARACTER
          RJ     SLINE
          RJ     OSAVE
 LOGPACK  PS
          SA5    B4
          PL     X5,*-7      X5 <= 0 WHEN NO DATA FOLLOWS SYNCM
          SB3    NOTHIGM
          RJ     ZWRITE
          SB4    B4+B1
          EQ     LOGPACK-3
 SENDPACK SPACE  4,18                                               X
** SENDPACK IS USED TO SEND A PACKET.   IT SETS UP OUTPUT, WRITES ANY
*  PADDING CHARACTERS REQUIRED BY THE PROTOCOL,  SENDS A SYNC MARKER,
*  COMPUTES AND SENDS A CHECKSUM CHARACTER, SENDS ANY REQUIRED TERMI-
*  NATION CHARACTER, AND LOGS THE PACKET IF DEBUG IS SET ON.
 SENDPACK SPACE  3,10
 SENDPACK PS
          SA4    NPAD        WRITE PADDING CHARACTERS?
          RJ     OUTSTRT
          ZR     X4,*+3      X4 = 0 IF THERE ARE NO PAD CHARACTERS
          SA3    A4+B1
          SB2    X4          USE B2 TO COUNT THEN
          BX5    X3
          RJ     AWRITE      WRITE A PAD CHARACTER
          SB2    B2-B1
          NZ     B2,*-1      B2 <> 0 IF WE NEED MORE PAD CHARS
          SA5    SYNCM
          RJ     AWRITE      WRITE THE PACKET SYNCHRONISATION MARKER
          SA5    CBUF
          SB4    X5-32
          SB3    B1-B4
          SB2    X5
          SB4    A5+B4
          RJ     AWRITE      WRITE THE FIRST CHARACTER
          SA5    B3+B4       GET A CHARACTER
          SB2    X5+B2       UPDATE THE CKECKSUM
          RJ     AWRITE      WRITE THE CHARACTER
          SB3    B3+B1       INCREMENT THE OFFSET
          MI     B3,*-1
          MX0    52          COMPUTE THE CHECKSUM
          SX5    B2
          BX5    -X0*X5
          BX4    X5
          AX4    6
          IX6    X5+X4
          MX1    54
          BX6    -X1*X6
          SX4    B1
          LX4    5
          IX6    X6+X4       AND THE CHECKSUM CHARACTER
          SA6    B7
          BX5    X6
          SA6    B4
          SX6    -B1
          SA6    A6+B1       ENSURE THAT BUFFER CONTENTS END WITH -1
          RJ     AWRITE      WRITE THE CHECKSUM
          SA1    PSENT
          SX6    X1+B1
          SA6    A1          INCREMENT COUNT OF PACKETS SENT
          SA5    EOLN
          MI     X5,*+2
          RJ     AWRITE      SEND HIS EOLN IF NECESSARY
          RJ     SLINE
          SA3    DEBUGW
          RJ     OSAVE
          ZR     X3,SENDPACK  X3 = 0 IF THE PACKET NEED NOT BE LOGGED
          RJ     LOGLIN
          SB3    PACKNUM-1   WRITE 'SEND PACKET NUMBER'
          RJ     ZWRITE
          SB4    CBUF
          SA3    B4+B1
          SX3    X3-32
          RJ     NWRITE      WRITE PACKET NUMBER
          SB2    10
          RJ     XWRITE
          RJ     LOGPACK     COPY PACKET
          EQ     SENDPACK
 ACKIT    SPACE  4,15
** ACKIT SENDS ACKNOWLEDGEMENT FOR A PACKET RECEIVED.
 ACKIT    SPACE  3,10
          SA7    CBUF
          SA1    CURN        ACKNOWLEDGEMENT HAS CURRENT PACK NUMBER
          SX7    X1+32
          SX6    89          Y = ACK
          SA7    A7+B1
          SA6    A7+B1
          RJ     SENDPACK
 ACKIT    PS
          SX7    35          PACKET = 3 WORDS LONG
          EQ     ACKIT-3
 TERMIN   SPACE  4,16
** TERMIN SENDS ACK FOR LAST PACKET RECEIVED,  THEN WRITES IN THE LOG
*  THE TEXT WHOSE ADDRESS IS IN X6 ON ENTRY.
 TERMIN   SPACE  3,10
 TERMIN   SA6    UPDAT       STORE TERMINATING MESSAGE
          RJ     ACKIT
          SA1    RETRYT      UPDATE TOTAL RETRY COUNT
          SA2    A1+B1
          IX6    X1+X2
          SA6    A1
          BX7    X7-X7
          SA7    CURN        SET PACKET NUMBER TO 0
          SA7    A2
          RJ     LOGLIN      WRITE IN LOG
          SA3    UPDAT       AFTER RECOVERING ADDRESS OF MESSAGE
          SB3    X3
          RJ     ZWRITE      WRITE END-OF-LINE
 TERMIN1  RJ     OSAVE       AND SAVE PLACE IN OUTPUT FILE
          SA1    FILETYP+1
          BX6    X1          RESTORE FILE TYPE (NEEDED ONLY RARELY)
          SA6    A1-B1
          SA1    KMODE
          NZ     X1,RECCOM2  IF X1 <> 0, YOU ARE A SERVER
          SX7    OUTPUT      OTHERWISE PREPARE TO WRITE ON OUTPUT
          RJ     OREST       (CAN'T USE MAINPRG-1 IF ACK IS SENT)
          EQ     MAINPRG
 MYPARM   SPACE  4,18
** MYPARM SENDS A PACKET CONTAINING THE CYBER KERMIT (MY) PARAMETERS.
*  ON ENTRY X7 CONTAINS THE TYPE OF PARAMETER (SEND-INIT OR ACK), AND
*  X0 MUST = 32.   ON EXIT A7 CONTAINS THE ADDRESS BEFORE THAT OF THE
*  REPEAT PREFIX IN THE OUTGOING PACKET.
 MYPARM   SPACE  3,10
 MYPARM   PS
          SX6    44          LENGTH OF MY PACKET
          SA6    CBUF
          SA1    PLENGTH     MAXIMUM LENGTH I WANT TO RECEIVE
          BX6    X0
          SA6    A6+B1       SEQUENCE NUMBER
          SA7    A6+B1       YES OR SEND
          IX7    X0+X1
          SA1    TIMEOUT
          SA7    A7+B1       MY MAXL
          IX7    X0+X1
          SA7    A7+B1       REQUESTED TIMEOUT LIMIT
          SA6    A7+B1       NUMBER OF PAD CHARS
          LX6    1
          SA6    A6+B1       DEFAULT PAD CHARACTER
          SX6    45
          SA6    A6+B1       END-OF-PACKET IS END-OF-LINE
          SA1    QUOTEC
          SA2    BITPREF
          BX6    X1
          BX7    X2
          SA6    A6+B1       MY QCTL
          SA7    A6+B1       MY QBIN
          SX7    49
          SA7    A7+B1       DEFAULT CHECKSUM TYPE
          EQ     MYPARM
 YOURPAR  SPACE  4,16
** YOURPAR PROCESSES THE MICRO KERMIT'S (YOUR) PARAMETERS.   ON ENTRY
*  X0 MUST BE 32.  ON EXIT X2 CONTAINS THE VALUE OF YOUR REPEAT-CHAR.
 YOURPAR  SPACE  3,10
          SA7    QBIN
 YOURPAR  PS
          SA1    CBUF+96     HOW LONG IS YOUR PACKET
          IX1    X1-X0
          SB6    X1
          SX7    -B1
          SB7    -10
          SA7    A1+B6
          SA7    A7+B1
          SB7    B7+B1
          MI     B7,*        ENSURE WE DON'T GET BAD DATA
          SA1    CBUF+99     CHAR (HIS MAXL)
          IX1    X0-X1
          BX7    -X1
          MI     X1,*+1
          SX7    80          DEFAULT PACKET LENGTH
          SA7    SLENGTH
          SA0    A1+B1       IGNORE HIS TIME
          SA2    A0+B1       CHAR (HIS NPAD)
          IX3    X0-X2
          LX7    B1,X0       X7 := 64
          SA2    A2+B1       CTRL (HIS PADC)
          BX7    X7-X2
          BX6    -X3
          MI     X1,*+1
          BX6    X6-X6       DEFAULT NUMBER OF PAD CHARS
          IX2    X0-X2
          MI     X2,*+1
          BX7    X7-X7       DEFAULT PAD CHAR
          SA6    NPAD        AMOUNT OF PADDING
          SA7    A6+B1       CONTENT OF PADDING
          SA2    A2+B1       CHAR (HIS EOLN)
          IX2    X0-X2
          BX7    -X2
          SX5    13          DEFAULT EOLN
          SA1    A2+B1       HIS QCTL
          MI     X2,*+1
          BX7    X5
          BX5    X5-X7
          NZ     X5,*+1
          MX7    44
          SA7    A7+B1       HIS EOLN
          BX6    X1
          IX5    X0-X1
          SA1    A1+B1       HIS QBIN
          MI     X5,*+1
          SX6    35          DEFAULT QCTL
          SA6    QCTL
          BX7    X1
          SA0    A1+B1       IGNORE HIS CHECKSUM TYPE
          SA2    A0+B1       HIS RPCH
          BX6    X2
          SX3    X7-89       TEST FOR AFFIRMATION
          NZ     X3,*+1
          SX7    38          DEFAULT QBIN
          IX1    X0-X1
          MI     X1,*+1
          MX7    49          SET QBIN TO NO BIT-PREFIX
          SX3    X7-78       CHECK FOR REFUSAL
          ZR     X3,*-1      IF SO, USE DEFAULT
          PL     X7,YOURPAR-1
          SA3    FILETYP+1
          ZR     X3,YOURPAR-1
          MX1    58          X1 := -3
          IX1    X1+X3
          PL     X1,YOURPAR-1
          SX6    BINERM      BINARY FILES MUST USE BIT-PREFIXING
 SENDERR  SPACE  4,16
** SENDERR TERMINATES A PROCESS BY SENDING AN ERROR PACKET CONTAINING
*  THE MESSAGE WHOSE ADDRESS IS IN X6 ON ENTRY.
 SENDERR  SPACE  3,10
 SENDERR  SA6    UPDAT
          SX7    69          ERROR MESSAGE
          SA4    SLENGTH
          SB7    X4+CBUF-5   LIMIT OF PACKET SIZE (PLUS SAFE MARGIN)
          SA7    CBUF+2
          SB6    A7-B7
          SB6    B6+B1
          SB5    B1
          SB3    X6
          SB2    B0
          BX7    X7-X7
          SA7    CURN
          RJ     PREAD       GET 1ST CHAR OF ERROR MESSAGE
          BX7    X5
          RJ     PACKTEX     PUT REST OF MESSAGE INTO PACKET
          SX5    B1
          LX5    5
          RJ     PUTVAL      INCLUDING LAST CHAR (UNLESS BLANK)
          SX6    B1
          SX7    B6+B7
          SX7    X7+32-CBUF  1ST CHAR OF PACKET
          LX6    5           X6 := 32
          SA7    CBUF
          SA6    A7+B1       SEQUENCE
          RJ     SENDPACK
          EQ     TERMIN+1
 RETRINC  SPACE  4,14
** RETRINC INCREMENTS THE RETRY COUNT AND ABORTS IF TOO MANY OCCUR.
 RETRINC  SPACE  3,9
 RETRINC  PS
          SA2    RETRYC      CURRENT RETRIES
          SA1    A2+B1       MAXIMUM ALLOWED RETRIES
          SX6    X2+B1
          SA6    A2
          IX2    X2-X1
          MI     X2,RETRINC  X2 < 0 UNTIL THE LIMIT IS REACHED
          SX6    RETRYM
          EQ     SENDERR     IN THAT CASE, ABORT
 INTTEST  SPACE  4,14
** INTTEST  TESTS (PACKET) TERMINAL INPUT FOR THE CYBER KERMIT INTER-
*  RUPT SEQUENCE; IT SHOULD BE CALLED ONLY IF THE CHAR (IN X5) < 32.
 INTTEST  SPACE  3,8
 INTTEST  PS
          SA4    ESCAPEC
          BX6    X4-X5
          NZ     X6,INTTEST  X6 <> 0 IF THE INPUT CHAR IS NOT ESCAPEC
          SA6    KMODE
          SX6    INTERM
          SA6    UPDAT
          EQ     TERMIN+1
 GETPACK  SPACE  4,21
** GETPACK READS AND CHECKS OUT A PACKET 'INTERNALLY',  THAT IS, WITH
*  NO ATTEMPT TO VERIFY THAT THIS PARTICULAR PACKET IS APPROPRIATE AT
*  THIS POINT IN THE PROTOCOL.   IF A PUTATIVE PACKET STARTS WITH THE
*  SYNC MARKER,  CONTAINS THE NUMBER OF CHARACTERS  CODED IN ITS NEXT
*  ELEMENT,  HAS TYPE AND SEQUENCE CODES IN THE CORRECT  RANGES,  ALL
*  INTERNAL CHARACTERS PRINTABLE, AND THE CORRECT CHECKSUM, THEN X1 =
*  0 ON RETURN; OTHERWISE X1 <> 0.
 GETPACK  SPACE  3,10
 NORECP   SA1    DEBUGW
          ZR     X1,*+4      X1 = 0 IF DEBUG IS NOT ON
          SX7    -B1
          SA7    B6+B7       TERMINATE THE FAILURE FOR LOGGING
          RJ     LOGLIN
          SB3    RECEIVM     'RECEIVED'
          RJ     ZWRITE
          SB4    CBUF+96
          RJ     LOGPACK     PRINT WHAT WAS RECEIVED
          SA1    CBUF+96
          MI     X1,*+2      INCREMENT ERROR COUNT ONLY IF DATA READ
          SA1    PKERRS
          SX6    X1+B1
          SA6    A1
          RJ     RETRINC     INCREMENT RETRY COUNT
 GETPACK  PS
          SB6    CBUF+96
          RJ     INSTART     READ SOMETHING
          SX6    -B1         ENSURE END OF BUFFER IS FLAGGED
          SA6    B6
          SA4    SYNCM       GET SYNC MARKER
          BX7    X4
          SB7    B0
          SB5    CBUF+64
          RJ     AREAD       GET NEXT ASCII CHAR INPUT
          MI     X5,NORECP   X5 < 0 AT END-OF-INPUT
          BX4    X5-X7       IS IT A SYNC MARKER
          ZR     X4,*+2      X4 = 0 IF IT IS A SYNC MARKER
          RJ     INTTEST     IF NOT, IS IT ESCAPE
          EQ     *-3
          RJ     AREAD       GET LENGTH OF PACKET
          SX4    X5-32
          PL     X4,*+3      X4 > 0 WHEN CHARACTER IS PRINTABLE
 GETPCK1  MI     X5,NORECP   X5 < 0 AT END-OF-INTPUT
          RJ     INTTEST     IS IT AN INTERRUPT
          EQ     NORECP      IF NOT, NO PACKET RECEIVED
          MX0    53
          BX0    -X0-X5      TEST FOR DEL
          ZR     X0,NORECP   X0 = 0 WHEN 'DEL' IS READ
          BX7    X5
          SA7    B6
          SB7    X5+B5       ADDRESS OF LAST CHAR
          SB6    B6-B7
          SB6    B6+B1       OFFSET
          SX4    B6+B1
          PL     X4,NORECP   NOT LONG ENOUGH FOR A PACKET
          SB5    X5          START CHECKSUM
          RJ     AREAD       GET SEQUENCE NUMBER
          SX4    X5-32
          MI     X4,GETPCK1  INTERRUPT OR ERROR
          SX4    X5-96       TEST FOR LEGITIMATE SEQUENCE NUMBER
          PL     X4,NORECP   (IN THE REANGE 32 - 95)
          BX7    X5
          SA7    B6+B7
          SB6    B6+B1
          SB5    X5+B5       ADD TO CHECKSUM
          RJ     AREAD       GET PACKET TYPE
          SX4    X5-65
          MI     X4,GETPCK1  ACCORDING TO THE PROTOCOL,
          SX4    X4-26       PACKET TYPES MUST BE
          PL     X4,NORECP   IN THE RANGE 65 -- 90
          BX7    X5
          SA7    B6+B7
          SB6    B6+B1
          SB5    X5+B5
          PL     B6,*+4      TIME FOR CHECKSUM
          RJ     AREAD       GET NEXT CHARACTER IN PACKET
          SX4    X5-32
          MI     X4,GETPCK1  IT MUST BE PRINTABLE
          MX0    53
          BX0    -X0-X5      TEST FOR DEL
          NZ     X0,*-3
          EQ     NORECP
          RJ     AREAD       GET CHECKSUM
          MX0    52          AND COMPUTE CHECKSUM OF DATA RECEIVED
          SX7    B5
          BX7    -X0*X7
          BX4    X7
          AX4    6
          IX7    X7+X4
          MX1    54
          BX7    -X1*X7
          SX7    X7+32
          BX4    X5-X7
          BX7    X5
          SA1    DEBUGW
          NZ     X1,*+4      X1 <> 0 IF DEBUGGING IS TO BE DONE
          MX6    57
          SA6    B7
          NZ     X4,GETPACK-2  THERE WAS AN ERROR IN THE CHECKSUM
          SA2    PRECD       THERE WAS NO ERROR; SUCCESS IS OURS!
          SX6    X2+B1
          SA6    A2
          EQ     GETPACK     (NOTE THAT X1 IS ALREADY = 0)
          MX6    57
          SA7    B7
          SA6    A7+B1
          NZ     X4,GETPCK2  X4 <> 0 IF THERE WAS A CHECKSUM ERROR
          RJ     LOGLIN
          SB3    RECEIVM
          RJ     ZWRITE      'RECEIVED'
          SB3    PACKNUM
          RJ     ZWRITE      'PACKET NUMBER'
          SB4    CBUF+96
          SA3    B4+B1
          SX3    X3-32
          RJ     NWRITE      WRITE PACKET NUMBER
          SB2    10
          RJ     XWRITE
          RJ     LOGPACK
          BX1    X1-X1       RETURN ZERO
          EQ     *-10        UPDATE RECEIVED COUNT BEFORE LEAVING
 GETPCK2  RJ     LOGLIN
          SB3    CKERRM      REPORT CHECKSUM ERROR
          RJ     ZWRITE
          RJ     SLINE
          SB2    10
          RJ     XWRITE
          EQ     GETPACK-5   AND RECORD WHAT WAS RECEIVED
 REQUESP  SPACE  4,25
** REQUESP IS SLIGHTLY MORE SOPHISTICATED THAN GETPACK.  IF NO PACKET
*  WAS RECEIVED, IT RETRIES.  THEN FOR PACKETS OF TYPE C-G-I-K-R-S IT
*  RETURNS (WITHOUT CHECKING THE PACKET'S SEQUENCE NUMBER) WITH X1 <>
*  0.   FOR E-PACKETS  (ALSO WITHOUT CHECKING THE SEQUENCE NUMBER) IT
*  TERMINATES THE CURRENT PROCESS  (WITHOUT RETURNING)  AFTER LOGGING
*  THE ERROR MESSAGE.  IT CONSIDERS ALL OTHER PACKETS LEGITIMATE WHEN
*  THEY ARE IN PROPER SEQUENCE;  IT DOES NOT RETURN AFTER RECEIVING A
*  B-PACKET,  AND IT RETURNS WITH X1 = 0 FOR D-F-Z AND OTHER PACKETS.
*  AFTER RECEIVING A PACKET WITH AN INCORRECT SEQUENCE NUMBER, WE NAK
*  THE EXPECTED PACKET AND TRY AGAIN.  REQUESP RETURNS WITH A2 = CBUF
*  + 98, X2 = PACKET TYPE, AND X0 = 32.
 REQUESP  SPACE  3,10
 RECERR   SA6    UPDAT       SAVE ERROR MESSAGE
          EQ     REQUSP1
 REQUESP  PS
          RJ     GETPACK     READ A PACKET
          SX0    B1
          LX0    5           X0 := 32
          NZ     X1,REQUSP2+1  X1 <> 0 IF NO PACKET WAS RECEIVED
          SA1    PTYPES
          SA2    CBUF+98     GET PACKET TYPE
          SB2    X2-69
          LX3    B2,X0
          BX1    X1*X3       TEST FOR THE RESERVED PACKET TYPES
          NZ     X1,REQUSP2-2  (C, E, G, I, K, R, S)
          SA3    CURN        IF NOT RESERVED, THEN TEST:
          SA1    A2-B1       GET SEQUENCE NUMBER AS CODED
          IX1    X1-X0
          BX1    X1-X3       TEST FOR CORRECT SEQUENCE NUMBER
          NZ     X1,REQUSP2  IF INCORRECT NAK AND TRY AGAIN
          SX3    X2-66       TEST FOR BREAK
          NZ     X3,REQUESP  IF NOT BREAK, RETURN (WITH X1 = 0)
          SX6    BREAKM      IF BREAK, REPORT IT
          SA6    UPDAT
          RJ     ACKIT       ACKNOWLEDGE RECEIPT OF PACKET
 REQUSP1  SA2    RETRYT
          SA1    A2+B1       UPDATE RETRY COUNTS
          IX6    X2+X1
          BX7    X7-X7
          SA6    A2
          SA7    A1          UPDATE ERROR COUNTS
          RJ     LOGLIN      SET UP LOG FOR WRITING
          SA1    UPDAT
          SB4    CBUF+99
          SB3    X1
          RJ     ZWRITE      REPORT CAUSE OF TERMINATION
          BX3    X3-X3
          SB2    B1
          RJ     UNPACK
          EQ     *+2
          RJ     AWRITE      AND RECORD ANY MESSAGES RECEIVED
          RJ     UNPACK
          SX4    X5-32
          PL     X4,*-2      UNTIL X4 < 0 AT END-OF-PACKET
          EQ     TERMIN1
          SX4    X2-69       TEST FOR ERROR PACKET
          NZ     X4,REQUESP  OTHERWISE RETURN (WITH X1 <> 0)
          SX6    ERRORM
          EQ     RECERR
 REQUSP2  RJ     RETRINC     TEST NUMBER OF FAILURES
          SA1    CURN
          SX7    35
          SX6    78          NO = NAK
          SA7    CBUF
          IX7    X0+X1
          SA7    A7+B1
          SA6    A7+B1
          RJ     SENDPACK    SEND NAK OF EXPECTED PACKET
          EQ     REQUESP+1   AND TRY AGAIN
 SENDWAC  SPACE  4,17
** SENDWAC  SENDS A PACKET AND INSISTS ON ACKNOWLEDGEMENT.  ON ENTRY,
*  X2 CONTAINS THE TYPE OF PACKET IN ASCII, AND B6 + B7 = THE ADDRESS
*  OF THE CHECKSUM CHARACTER IN THE BUFFER.  ON EXIT, A1 = CBUF + 98.
          SPACE  3,10
 SENDWAC  PS
          SA7    XSTORE      XSTORE CONTAINS X7
          BX7    X3
          BX6    X5
          SA7    A7+B1       XSTORE + 1 CONTAINS X3
          SA6    A7+B1       XSTORE + 2 CONTAINS X5
          SX4    B2
          SX5    B3
          SX6    B4
          SX7    B5
          MX0    42
          BX4    -X0*X4      MASK OFF ALL BUT 18 BITS
          BX5    -X0*X5
          BX6    -X0*X6
          BX7    -X0*X7
          LX6    18
          LX7    18
          BX6    X6+X4
          BX7    X7+X5
          SA6    A6+B1       XSTORE + 3 CONTAINS B4, B2
          SA7    A6+B1       XSTORE + 4 CONTAINS B5, B3
          SA1    INFI
          BX7    X1
          SA7    A7+B1       XSTORE + 5 CONTAINS ADDR OF FILE FET
          SA3    RETRYT
          SA4    A3+B1
          IX6    X3+X4
          BX7    X7-X7
          SA6    A3
          SA7    A4          UPDATE RETRY COUNT FOR NEW PACKET
          SA1    CURN
          SX7    X1+32       PACKET NUMBER
          SA7    CBUF+1
          BX7    X2
          SX6    B6+B7       ADDRESS OF CHECKSUM
          SX6    X6+32-CBUF
          SA6    A7-B1       1ST WORD OF PACKET
          SA7    A7+B1       PACKET TYPE
          EQ     SENDWA1+1
 SENDWA3  SX3    X1-78       NO
          ZR     X3,*+3
          SA3    X1-69       TEST FOR ERROR PACKET
          NZ     X3,FATALE   ANY OTHER KIND IS A DISASTER
          SX6    ERRORM
          EQ     RECERR
          SA3    A1-B1       CHECK NUMBER OF RECEIVED PACKET
          SX4    X3-32
          BX5    X2-X4
          ZR     X5,SENDWA1  X5 = 0 WHEN THE NUMBER IS CORRECT
          MX0    54
          SX6    X2+B1
          BX6    -X0*X6
          BX5    X4-X6
          ZR     X5,SENDWA2  X5 = 0 WHEN YOU NAK THE SUCCESSOR
 FATALE   SX6    KDATERM
          EQ     SENDERR     ABORT WITH ERROR MESSAGE
 SENDWA1  RJ     RETRINC     INCREMENT RETRY COUNT
          RJ     SENDPACK    (RE)SEND
          RJ     GETPACK     ASK FOR ACKNOWLEDGEMENT
          NZ     X1,*-2      REPEAT IF NOTHING RECEIVED
          SA1    CBUF+98     GET TYPE OF PACKET RECEIVED
          SA2    CURN
          SX3    X1-89       Y = ACK
          NZ     X3,SENDWA3  X3 <> 0 IF THIS WAS NOT AN ACK
          SA3    A1-B1       GET SEQUENCE NUMBER RECEIVED
          SX6    X2+B1
          SX4    X3-32
          BX5    X4-X2       DID WE RECEIVE ACK OF PACKET SENT
          MX0    54
          ZR     X5,SENDWA2  YES
          SX4    X4+B1
          BX4    -X0*X4
          BX5    X2-X4       OR ACK OF PREVIOUS PACKET
          ZR     X5,SENDWA1  IF SO REPEAT
          EQ     FATALE      OTHERWISE ABORT
 SENDWA2  BX6    -X0*X6      (MAKE 64 = 0)
          SA6    A2          UPDATE CURRENT PACKET NUMBER CURN
          SA3    RETRYT
          SA4    A3+B1
          IX6    X3+X4
          BX7    X7-X7
          SA6    A3          RESTART ERROR COUNT
          SA3    SLENGTH
          SB7    X3+CBUF-5
          SB6    CBUF+3      PREPARE TO SEND A PACKET
          SB6    B6-B7
          SA7    A4
          SA2    XSTORE      AND RESTORE ALL INPUT REGISTERS
          BX7    X2
          SA3    A2+B1
          SA5    A3+B1
          SA2    A5+B1
          SA4    A2+B1
          SB2    X2
          SB3    X4
          LX2    42
          LX4    42
          SB4    X2
          SA2    A4+B1       GET FORMER CONTENTS OF INFI
          BX6    X2
          SA6    INFI
          SB5    X4
          EQ     SENDWAC
 PTVWAC   SPACE  4,16
** PTVWAC STORES A VALUE IN A PACKET,  SENDING THE PACKET AND GETTING
*  IT ACKNOWLEDGED WHEN THE PACKET IS FULL.
 PTVWAC   SPACE  3,10
 PTVWAC   PS
          RJ     PUTVAL
          MI     B6,PTVWAC   B6 < 0 IF THE PACKET IS NOT YET FULL
          SX2    68          D = DATA
          RJ     SENDWAC     SEND AND GET ACK
          SX4    X1-89       Y = ACK
          NZ     X4,PTVWAC1  IGNORE NAK PACKETS
          SA1    A1+B1       GET 1ST DATA WORD
          MI     X4,PTVWAC1  IGNORE ACKS WITH NO DATA
          SX4    X4+B1       X = ABANDON
          SX1    X4-2        Z = ABANDON
          ZR     X4,PUTEOF1  WE ARE HERE INSTRUCTED TO ABORT SENDING
          ZR     X1,PUTEOF1  THE FILE
 PTVWAC1  BX4    X5-X7       TEST THAT REPEATED CHARACTER DOESN'T
          ZR     X4,PTVWAC   OVERFLOW INTO NEXT PACKET (WHEN X4 <> 0)
          EQ     PTVWAC+1    NOT YET DONE
 PZWRITE  SPACE  4,15
** PZWRITE TRANSFERS A ZERO-TERMINATED MESSAGE TO A PACKET.  ON ENTRY
*  THE ADDRESS OF THE MESSAGE SHOULD BE IN B3.
 PZWRITE  SPACE  3,9
          RJ     PTVWAC
          RJ     PREAD
          NZ     X5,*-2      X5 <> 0 BEFORE THE TEXT TERMINATES
          SX5    B1
          LX5    5           X5 := ASCII BLANK
          RJ     PTVWAC      ENSURE LAST CHAR IS STORED
 PZWRITE  PS
          SB2    B0          FLAG NEED TO FETCH NEXT WORD OF TEXT
          EQ     *-4
 PLINE    SPACE  4,15
** PLINE STORES A PROTOCOL END-OF-LINE IN A PACKET AFTER FLUSHING THE
*  OUTPUT REGISTER X7.
 PLINE    SPACE  3,9
 PLINE    PS
          SX5    B1
          LX5    5           X5 := BLANK
          RJ     PTVWAC      THIS DOES NOT PUT THE BLANK BUT THE
          SX7    13          PREVIOUS CHARACTER (UNLESS IT WAS BLANK)
          SX5    10          THEN ADD THE CR/LF SEQUENCE REQUIRED
          SB5    B1
          RJ     PTVWAC
          EQ     PLINE
 PZLINE   SPACE  4,10
** PZLINE PUTS INTO A PACKET AN END-OF-LINE  FOLLOWED BY A TEXT WHOSE
*  ADDRESS IS IN B3 ON ENTRY.
 PZLINE   SPACE  3,4
 PZLINE   PS
          RJ     PLINE
          RJ     PZWRITE
          EQ     PZLINE
 PNWRITE  SPACE  4,17
** PNWRITE CONVERTS A  (BINARY)  NUMBER TO ASCII AND STORES IT IN THE
*  OUTGOING PACKET, SENDING THE PACKET WHEN IT IS FULL, IF NECESSARY.
*  THE NUMBER MUST BE IN X3 ON ENTRY.
 PNWRITE  SPACE  3,10
          MX0    54
          LX3    6
          BX5    -X0*X3      GET THE NEXT DIGIT
          BX3    X3-X5       AND REMOVE IT FROM X3
          SX5    X5+21       CONVERT IT TO ASCII
          RJ     PTVWAC      STORE IT
          NZ     X3,*-2      AND REPEAT UNTIL X3 IS EMPTY
          RJ     PLINE       THEN PUT END-OF-LINE
 PNWRITE  PS
          SA0    B2          SAVE CONTENTS OF B2
          BX5    X5-X5
          RJ     NCONV       AND CALL NCONV
          SB2    A0
          BX3    X5          PUT THE RESULT IN X3
          EQ     *-5         AND CONVERT IT
 SENDINIT TITLE  MORE SPECIALISED PACKET HANDLERS
** SENDINIT  PERFORMS NEGOTIATIONS AT THE START OF A FILE TRANSFER IF
*  I AM SENDING A FILE AND YOU ARE RECEIVING ONE.
 SENDINIT SPACE  3,10
          SA6    A1-B1       SAVE REPETC
          SA7    CURN        AND NEW PACKET NUMBER
          SB2    B0
 SENDINIT PS
          SX0    B1
          LX0    5           X0 := 32
          RJ     MYPARM      SEND MY PARAMETERS
          SA1    REPETC
          BX7    X1
          SA7    A7+B1       AND THE REPEAT PREFIX
          EQ     *+3
          SX1    X2-69       TEST FOR ERROR TYPE
          SX6    ERRORM
          ZR     X1,RECERR   X1 = 0 IF AN ERROR PACKET IS RECEIVED
          RJ     RETRINC     OTHERWISE INCREMENT RETRIES
          RJ     SENDPACK    SEND MY PARAMETERS
          RJ     GETPACK     AND TRY TO GET YOURS
          NZ     X1,*-2      X1 MUST EQUAL 0
          SA2    CBUF+98
          SX1    X2-89       Y = ACK MUST BE THE TYPE OF PACKET REC'D
          NZ     X1,*-5
          SA1    A2-B1       SEQUENCE
          SX0    B1
          LX0    5           X0 := 5
          BX1    X1-X0       SEQUENCE MUST BE 0
          NZ     X1,*-6
          RJ     YOURPAR     PROCESS YOUR PARAMETERS
          SA1    REPETC
          BX1    X2-X1       DOES HE ACCEPT REPETITION
          SX7    B1
          ZR     X1,SENDINIT-1
          MX6    50          IF NOT, CHOOSE A SAFE NEGATIVE NUMBER
          EQ     SENDINIT-1
 NONEXT   SPACE  4,13
** NONEXT REPORTS THAT A FILE DOES NOT EXIST.
 NONEXT   SPACE  3,8
 NONEXT   SX6    NONEXTM
 +        SA3    KMODE       ARE YOU A SERVER
          NZ     X3,SENDERR  IF SO, SEND AN ERROR PACKET
          SB3    X6          OTHERWISE
          RJ     OUTSTRT     PREPARE TO WRITE ON OUTPUT
          RJ     ZLINE
          RJ     SLINE
          EQ     MAINPRG     AND START OVER
 SENDSUB  SPACE  4,19
** SENDSUB PREPARES TO SEND DATA TO ANOTHER KERMIT; WHEN IT IS CALLED
*  IT EXPECTS ZZZKLOG TO BE SET UP FOR WRITING  AND B3 TO CONTAIN THE
*  ADDRESS OF 'SEND' OR 'TYPE'.  AFTER LOGGING THE FILE NAME IT MAKES
*  AN FET AND TESTS FOR THE FILE'S EXISTENCE.   IF IT EXISTS, WE SEND
*  A SEND-INITIATION PACKET, PROCESS THE REPLY, AND OPEN THE FILE.
 SENDSUB  SPACE  3,10
          BX6    X4
          SA6    A4+B1       STORE THE FILE NAME IN 'LAST FILE' ADDR
          RJ     ISAVE       AND SAVE ITS REGISTERS FOR REST OF INIT
 SENDSUB  PS
          RJ     ZWRITE      WRITE CALLING COMMAND
          SX5    45          A BLANK SPACE
          RJ     SWRITE
          SB3    FILNAM      AND FILE NAME ON COMMAND OR IN R-PACKET
          RJ     ZWRITE
          RJ     OSAVE
          SA3    FILNAM
          SX6    3           ALL KERMIT FET'S ARE BINARY
          SA1    DUMMY+1
          SA2    A1+B1
          BX6    X6+X3       ADD TYPE CODE TO FILE NAME
          SX5    WBUF
          SA6    FILE        CREATE A NEW FET
          BX7    X1
          SA7    A6+B1
          BX7    X5
          SA7    A7+B1
          SA7    A7+B1
          BX7    X2
          SX5    3RZZZ       TEST FOR ILLEGAL FILE NAMES
          SA7    A7+B1
          LX5    42
          BX5    X5-X6
          AX5    42
          ZR     X5,NONEXT   X5 = 0 IF FILE NAME BEGINS WITH 'ZZZ'
          SX6    A6          PUT ADDRESS OF FET INTO X6
          RJ     TESTFIL
          ZR     X6,NONEXT   X6 = 0 IF THE FILE DOES NOT EXIST
          REWIND FILE,R
          BX7    X7-X7
          SA7    FILE-2      CLEAR ANY SAVED SHIFT & CHARS FROM FET
          SA7    A7+B1
          SA7    CURN        PACKET NUMBER WILL BE 0
          SA7    PSENT       NO PACKETS SEND
          SA7    A7+B1       NONE RECEIVED
          SA7    A7+B1       NO ERRORS
          SA7    A7+B1
          SA7    A7+B1       AND NO RETRIES
          SX7    83          SEND-INITIATION PACKET
          RJ     SENDINIT
          SX7    FILE
          SA7    INFI
          BX2    X7
          BX3    X3-X3
          RJ     FREAD       FILL THE FILE BUFFER
          SA4    FILNAM
          MI     B3,SENDSUB-1  B3 < 0 IF THE FILE CONTAINS DATA
 SENCOM3  SX6    NONEXTM     OTHERWISE REPORT NONEXISTENCE
          EQ     SENDERR
 INFOSUB  SPACE  4,19
** INFOSUB PREPARES TO TYPE ON THE REMOTE SCREEN AS A RESULT OF A RE-
*  MOTE TYPE COMMAND OR A REMOTE REQUEST FOR INFORMATION.   ON ENTRY,
*  X1 CONTAINS THE NAME OF THE FILE BEING TYPED AND A1 THE ADDRESS OF
*  THE NAME.   AFTER INITIAL NEGOTIATIONS AN X-PACKET IS SENT INSTEAD
*  OF THE USUAL FILE HEADER.
 INFOSUB  SPACE  3,10
 INFOSUB  PS
          BX6    X1
          SA6    FILNAM
          SB3    A1
          RJ     ZWRITE      LOG THE KIND OF INFORMATION
          RJ     OSAVE
          BX7    X7-X7
          SA7    PSENT       CLEAR ALL TRANSFER COUNTS
          SA7    A7+B1
          SA7    A7+B1
          SA7    A7+B1
          SA7    A7+B1
          SA7    FILETYP     TO AVOID PROBLEMS DURING SENDINIT
          SA7    CURN
          SX7    83          S = SEND-INITIATION
          RJ     SENDINIT
          SB7    CBUF+3
          SX2    88          X = TYPE ON SCREEN
          SB6    B0
          RJ     SENDWAC     SEND X-PACKET
          SA4    SLENGTH
          SB7    X4+CBUF-5   AND PREPARE TO SEND NEXT PACKET
          SB6    CBUF+3
          SB6    B6-B7
          SB5    B1
          SX7    B1
          LX7    5           X7 := 32
          EQ     INFOSUB
 LWRITE   TITLE  SOME UTILITY SUBROUTINES FOR COMMAND PROCESSING
** LWRITE PRINTS THE COMPRESSED LIST WHOSE ADDRESS IS IN B3 ON ENTRY.
*  THE FORMAT OF SUCH A LIST CONSISTS OF A SERIES OF ASCII TEXTS WITH
*  SIX ZERO BITS TERMINATING EACH TEXT, FOLLOWED BY A CODE SPECIFYING
*  THE ACTION TO BE TAKEN: 0 = START A NEW LINE; 1 = END OF LIST; 2 -
*  63 = WRITE 2 - 63 BLANKS.  THE ZERO BITS AND THE CODE MUST FALL IN
*  THE SAME WORD, AND THE NEXT SECTION OF TEXT MUST BEING IN THE FOL-
*  LOWING WORD.
 LWRITE   SPACE  3,10
 LWRITE   RJ     OUTSTRT     SET UP OUTPUT REGISTERS
          RJ     SLINE       SKIP A LINE
          SX7    45          AND START WITH A BLANK
          SB5    -9
          RJ     ZWRITE      PRINT HEADER
          LX3    6
          BX5    -X0*X3      GET NEXT CHAR AFTER COLON
          ZR     X5,*-3      IF IT'S 0, THEN WRITELN
          SB2    X5
          NE     B1,B2,*+3   COLON-A MEANS END-OF-LIST
          RJ     SLINE
          EQ     MAINPRG
          SB2    B2-B1
          RJ     XWRITE      WRITE BLANKS
          EQ     LWRITE+3
 SETDBG   SPACE  4,17
** SETDBG SETS DEBUGGING ON OR OFF.   ON ENTRY X7 CONTAINS THE CHOSEN
*  OPTION.  FIRST WE TEST FOR A HELP REQUEST, AND IF THERE IS NONE WE
*  SET DEBUG AND LOG THE FACT.
 SETDBG   SPACE  3,10
          RJ     SREAD
 SETDBG   MI     X5,*+3      SET IT AT END OF LINE
          SX4    X5-45       TEST FOR BLANK
          ZR     X4,*-2      X4 = 0 IF A BLANK WAS READ
          SX5    X7+6        OTHERWISE HELP IS REQUESTED
          EQ     GETHELP
          SA7    DEBUGW      SAVE OPTION
          RJ     LOGSET
          SB3    SETLIST+10  'DEBUG'
          RJ     ZWRITE
          SX5    45
          RJ     SWRITE      WRITE BLANK SPACE
          SA5    DEBUGW
          SB3    X5+KNAME+2  'OFF' OR 'ON'
          RJ     ZWRITE
          EQ     TERMIN1     SAVE PLACE IN LOG
 SETFILE  SPACE  4,15
** SETFILE SETS THE FILE TYPE; X7 = THE OPTION ON ENTRY.
 SETFILE  SPACE  3,10
 SETFILE  SA1    KMODE
          ZR     X1,SETFIL1  X1 = 0 IF WE ARE IN COMMAND MODE
          EQ     *+2
          RJ     UNPACK
          MI     X5,SETFIL1+3  AT THIS POINT WE REACH END-OF-PACKET
          SX4    X5-32       BLANK
          NZ     X4,SETFIL1+1  IF X4 <> 0 HELP IS REQUESTED
          EQ     *-2
          RJ     SREAD
 SETFIL1  MI     X5,*+3      END OF LINE
          SX4    X5-45
          ZR     X4,*-2      BLANK
          SX5    X7+B1
          EQ     GETHELP
          SA7    FILETYP+1   SAVE OPTION
          SA1    KMODE
          ZR     X1,*+1
          RJ     ACKIT       IN SERVER MODE WE MUST SEND ACK IF OK
          RJ     LOGSET      READY TO WRITE LOG
          SB3    SETLIST+6   'FILE-TYPE'
          RJ     ZWRITE
          RJ     WFILTYP     WRITE NAME OF FILE-TYPE
          EQ     TERMIN1
 SETBIT   SPACE  4,15
** SETBIT SETS THE BIT-PREFIX.  THE DEFAULT VALUE IS THE AMPERSAND.
 SETBIT   SPACE  3,10
          SX5    13
          EQ     GETHELP
 SETBIT   SX7    38
          RJ     SETCHAR
          MI     X7,*-2      IF X7 < 0 THERE WAS A REQUEST FOR HELP
          SA1    QUOTEC
          SA2    REPETC
          BX1    X1-X7       THE BIT-PREFIX MUST BE DISTINCT FROM THE
          BX2    X2-X7       QUOTE AND REPEAT PREFIXES
          ZR     X1,*-4
          ZR     X2,*-4
          SA7    BITPREF     IF SO, SAVE IT
          RJ     LOGSET
          SB3    SETLIST+4
          RJ     ZWRITE
          SA3    BITPREF
 CHAREND  SX5    45          WRITE A BLANK SPACE
          RJ     SWRITE
          BX5    X3
          RJ     AWRITE      AND THEN THE CHARACTER
          EQ     TERMIN1
 SETQUOT  SPACE  4,15
** SETQUOT SETS THE QUOTE PREFIX.
 SETQUOT  SPACE  3,10
          SX5    14
          EQ     GETHELP
 SETQUOT  SX7    35
          RJ     SETCHAR
          MI     X7,*-2      X7 = 0 IF HELP IS REQUESTED
          SA1    BITPREF
          SA2    REPETC
          BX1    X1-X7       THE THREE PREFIXES MUST BE DISTINCT
          BX2    X2-X7
          ZR     X1,*-4
          ZR     X2,*-4
          SA7    QUOTEC      IF SO, SAVE AND LOG THE SET COMMAND
          RJ     LOGSET
          SB3    SETLIST+8
          RJ     ZWRITE
          SA3    QUOTEC
          EQ     CHAREND
 SETREP   SPACE  4,15
** SETREP SETS THE REPEAT PREFIX.
 SETREP   SPACE  3,10
          SX5    15
          EQ     GETHELP
 SETREP   SX7    126
          RJ     SETCHAR
          MI     X7,*-2      X7 < 0 IF HELP IS REQUESTED
          SA1    BITPREF
          SA2    QUOTEC
          BX1    X1-X7       THE THREE PREFIXES MUST BE DISTINCT
          BX2    X2-X7
          ZR     X1,*-4
          ZR     X2,*-4
          SA7    REPETC      IF SO, SAVE AND LOG THE SET COMMAND
          RJ     LOGSET
          SB3    SETLIST+13
          RJ     ZWRITE
          SA3    REPETC
          EQ     CHAREND
 SETESCA  SPACE  4,15
** SETESCA SETS THE ESCAPE CHARACTER.
 SETESCA  SPACE  3,10
          SX5    17
          EQ     GETHELP
 SETESCA  SX7    DEFESCA     DEFAULT ESCAPE CHAR
          RJ     SETCTRL
          MI     X7,*-2      ERRORS REQUIRE HELP
          SA1    SYNCM
          BX1    X1-X7
          ZR     X1,*-3      ESCAPE MAY NOT BE THE SAME AS SYNC
          SA7    ESCAPEC
          RJ     LOGSET
          SB3    SETLIST+20  ESCAPE
          SB4    ESCAPEC
 CTRLREP  RJ     ZWRITE      WRITE THE TERM BEING SET
          SX5    45          A BLANK SPACE
          RJ     SWRITE
          SB3    CTRLHYP     'CTRL-'
          RJ     ZWRITE
          SA4    B4
          SX5    X4+64
          RJ     AWRITE      AND THE SYMBOL YOU MUST PRESS WITH CTRL
          EQ     TERMIN1
 SETMARK  SPACE  4,15
** SETMARK SETS THE PACKET SYNC MARKER.
 SETMARK  SPACE  3,10
          SX5    18
          EQ     GETHELP
 SETMARK  SX7    B1          DEFAULT PACKET SYNC MARKER
          RJ     SETCTRL
          MI     X7,*-2      ERRORS REQUIRE HELP
          SA1    ESCAPEC
          BX1    X1-X7
          ZR     X1,*-3      SYNC MAY NOT BE THE SAME AS ESCAPE
          SA7    SYNCM
          RJ     LOGSET
          SB3    SETLIST+11  MARKER
          SB4    SYNCM
          EQ     CTRLREP
 SETDELA  SPACE  4,15
** SETDELA SETS THE DELAY TO BE REQUESTED FROM ANOTHER KERMIT.
 SETDELA  SPACE  3,10
          SX7    DEFTIME     DEFAULT DELAY IS 20 SECONDS
          EQ     *+6
 SETDELA  RJ     NREAD       READ THE AMOUNT
          ZR     B5,*-2      SET THE DEFAULT VALUE
          PL     B5,*+2      SET THE VALUE READ
          SX5    16
          EQ     GETHELP
          SX4    X7-5        5 SECONDS IS MINIMUM
          MI     X4,*-1
          SX4    X7-95       94 SECONDS IS MAXIMUM
          PL     X4,*-2
          SA7    TIMEOUT     STORE THE VALUE
          RJ     LOGSET
          SB3    SETLIST+15  DELAY
          SB4    TIMEOUT
 SETNUM   RJ     ZWRITE      WHAT IS BEING SET
          SX5    45
          RJ     SWRITE      A BLANK SPACE
          SA3    B4
          RJ     NWRITE      THE NUMBER TO WHICH IT IS SET
          RJ     OSAVE
          EQ     MAINPRG-1
 SETPACL  SPACE  4,15
** SETPACL SETS THE MAXIMUM PACKET LENGTH TO REQUEST.
 SETPACL  SPACE  3,10
          SX7    DEFPLEN     DEFAULT IS 94
          EQ     *+6
 SETPACL  RJ     NREAD
          ZR     B5,*-2
          PL     B5,*+2
          SX5    19
          EQ     GETHELP
          SX4    X7-40       40 IS MINIMUM
          MI     X4,*-1
          SX4    X7-95       94 IS MAXIMUM
          PL     X4,*-2
          SA7    PLENGTH
          RJ     LOGSET
          SB3    SETLIST+16  PACKET LENGTH
          SB4    PLENGTH
          EQ     SETNUM
 SETTRY   SPACE  4,15
** SETTRY SETS THE LIMIT ON THE NUMBER OF RETRIES PER PACKET.
 SETTRY   SPACE  3,10
          SX7    DEFRETR     DEFAULT LIMIT IS 5
          EQ     *+6
 SETTRY   RJ     NREAD
          ZR     B5,*-2
          PL     B5,*+2
          SX5    20
          EQ     GETHELP
          SX4    X7-3        3 IS MINIMUM
          MI     X4,*-1
          SX4    X7-31       30 IS MAXIMUM
          PL     X4,*-2
          SA7    RETRYN
          RJ     LOGSET
          SB3    SETLIST+19  RETRY
          SB4    RETRYN
          EQ     SETNUM
 SENDCOM  TITLE  SENDING A FILE
** SENDCOM HANDLES SENDING A FILE TO ANOTHER KERMIT.   SENDCOM IS THE
*  ENTRY POINT FOR THE SEND COMMAND,  SENDSER FOR A (REMOTE) GET COM-
*  MAND, AND SENCOM2 FOR REMOTE LISTING (TYPE) AND HELP.
 SENDCOM  SPACE  3,10
 SENDCOM  BX7    X7-X7       COMMAND-MODE ENTRY POINT
          MI     X5,*+5      END-OF-LINE MEANS GET HELP
          SB5    -7
          EQ     *+2
          RJ     AREAD
          RJ     MAKEFN
          MI     B5,*-2      CONSTRUCT A FILE NAME
          NZ     X7,*+4      AND PREPARE TO SEND IT
          SX5    8
          EQ     GETHELP     UNLESS THERE ISN'T ANY NAME
 SENDSER  RJ     UNPCFIL     ENTRY POINT FOR R PACKET
          ZR     X7,NONEXT
 +        SA7    FILNAM
          RJ     LOGLIN
          SB3    CMDLIST+11  'SEND'
          RJ     SENDSUB
          SA5    SLENGTH
          SB7    X5+CBUF-5
          SB6    CBUF+3
          SB6    B6-B7
          SB5    B1
          SB3    FILNAM
          RJ     PREAD
          BX7    X5
          RJ     PACKTEX
          SX5    B1
          LX5    5
          RJ     PUTVAL
          SX2    70          F = FILE HEADER
          RJ     SENDWAC
 SENCOM2  SA4    SLENGTH
          SB7    X4+CBUF-5
          SB6    CBUF+3
          SB6    B6-B7
          SB5    B1
          SA1    FILE-2
          RJ     IREST
          SA1    FILETYP
          ZR     X1,SENAS    ASCII TEXT
          MX0    58          X0 := -3
          IX0    X0+X1
          MI     X0,SENBI
          ZR     X0,SENNO
 
          SB2    B0          SEND AN ASCII8 FILE
          RJ     EREAD
          RJ     EREAD
          MI     X5,*+6
          BX7    X5
          EQ     *+2
          RJ     PTVWAC
          RJ     EREAD
          PL     X5,*-2
          SX5    B1
          LX5    5
          RJ     PTVWAC
          GT     B2,B0,PUTEOF
          SX7    13
          SX5    10
          SB5    B1
          EQ     *-6
 
 SENNO    SB2    B0          SEND A DISPLAY CODE FILE
          RJ     DREAD
          RJ     DREAD
          MI     X5,*+6
          BX7    X5
          EQ     *+2
          RJ     PTVWAC
          RJ     DREAD
          PL     X5,*-2
          SX5    B1
          LX5    5
          RJ     PTVWAC
          GT     B2,B0,PUTEOF
          SX7    13
          SX5    10
          SB5    B1
          EQ     *-6
 
 SENAS    SB2    B0          SEND AN ASCII 6/12 FILE
          RJ     AREAD
          RJ     AREAD
          MI     X5,*+6
          BX7    X5
          EQ     *+2
          RJ     PTVWAC
          RJ     AREAD
          PL     X5,*-2
          SX5    B1
          LX5    5
          RJ     PTVWAC
          GT     B2,B0,PUTEOF
          SX7    13
          SX5    10
          SB5    B1
          EQ     *-6
 
 SENKE    SB3    B3-B1       SEND A 'KERMIT'-FORMAT BINARY
          SB2    B0
          RJ     KREAD
          MI     X5,SENCOM3
          BX7    X5
          SB5    B1
          EQ     *+2
          RJ     PTVWAC
          RJ     KREAD
          PL     X5,*-2
          EQ     PUTEOF-2
 
 SENBI    SX7    X0+B1       SEND A BINARY FILE
          RJ     WREAD
          NZ     X1,SENCOM3
          ZR     X7,SENKE
          BX3    X6
          LX3    8
          SB2    -13
          MX0    52
          BX7    -X0*X3
          LX3    4
          EQ     *+2
          RJ     PTVWAC
          RJ     BREAD
          PL     X5,*-2
          SX5    B1+B1
          BX5    X5-X7
          RJ     PTVWAC
 
 PUTEOF   SA1    FILETOT     SEND AN END-OF-FILE PACKET
          SX6    X1+B1
          SA6    A1
          SB3    CBUF+3
          SB4    B6+B7
          EQ     B3,B4,PUTEOF1
          SX2    68          D = DATA
          RJ     SENDWAC
 PUTEOF1  SB7    CBUF+3
          SX2    90          Z = EOF
          SX4    X1-78       N = NAK
          SA1    A1+B1       GET DATA WORD
          SB6    B0
          ZR     X4,*+4
          SX4    X1-90       TEST Z
          ZR     X4,*+1
          SX4    X4+B1
          SX4    X4+B1       TEST X
          NZ     X4,*+2
          SX6    68          D = DISCARD
          SA6    B7
          SB6    B1
 +        RJ     SENDWAC
          SB7    CBUF+3
          SX2    66          B = EOT
          SB6    B0
          RJ     SENDWAC
          RJ     LOGLIN
          SB3    EOFM
          RJ     ZWRITE
          SA1    FILNAM
          BX6    X6-X6       CANCEL CURRENT NAME AND PACKET NUMBER
          SA6    A1
          SA6    CURN
          BX6    X1
          SA6    A1+B1
          SB3    A6
          RJ     ZWRITE
          RJ     SLINE
          RJ     WSTATS
          EQ     TERMIN1
 GENERIC  TITLE  RECEIVE FILES AND CODED COMMANDS
** GENERIC, FINICOM, TYPECOM, AND REMCOM  DEAL WITH COMMANDS RECEIVED
*  FROM THE LOCAL KERMIT IN PACKETS.
 FINICOM  SPACE  3,10
 FINICOM  BX7    X7-X7       PROCESS FINISH COMMAND
          SA7    KMODE
          SX6    FINISHM
          EQ     TERMIN
 GENERIC  SPACE  4,10
 GENERIC  SB2    B1
          SB4    A2+B1       B4 := CBUF+99
          RJ     UNPACK      A DUMMY OPERATION
          RJ     UNPACK
          SX4    X5-70       TEST FOR F = FINISH
          ZR     X4,FINICOM
          SX4    X5-81       TEST FOR Q = STATUS QUERY
          ZR     X5,STATUSP
          SX4    X5-72       TEST FOR H = GET HELP
          ZR     X4,SERVHLP
          SX4    X5-76       TEST FOR L = LOGOUT
          ZR     X4,*+4
          SX7    X5-84       TEST FOR T = TYPE
          SB5    -7
          ZR     X7,TYPECOM+1
          SX6    NOTIMP      OTHERWISE SEND A 'NOT IMPLEMENTED' MSG
          EQ     SENDERR
          RJ     ACKIT
          WRITER OUTPUT
          SX7    LOGOUTM
          EQ     FINIS+3
 TYPECOM  SPACE  4,10
 TYPECOM  BX7    X7-X7       TYPE A LOCAL FILE ON THE OTHER KERMIT'S
          EQ     *+2         SCREEN
          RJ     UNPACK      IGNORE ENCODED FIELD LENGTH
          SA1    FILETYP+1
          ZR     X1,*+3
          MX2    58
          IX2    X1+X2
          PL     X2,*+2
          SX6    TYPERM
          EQ     SENDERR
          RJ     UNPACK
          RJ     MAKEFN
          MI     B5,*-2
          NZ     X7,*+2
          SX5    21
          EQ     GETHELP
          SA7    FILNAM
          RJ     LOGLIN
          SB3    TYPEM
          RJ     SENDSUB
          SB7    CBUF+3
          SX2    88          X = TYPE ON SCREEN
          SB6    B0
          RJ     SENDWAC
          EQ     SENCOM2
 REMCOM   SPACE  4,10
 REMCOM   SB2    B1          PROCESS A REMOTE COMMAND
          SB4    A2+B1       B4 := CBUF + 99
          RJ     UNPACK      GET DUMMY CONTENTS OF X3
          SB7    SERVTAB
          EQ     CREAD
 SERVCOM  SPACE  4,15
** SERVCOM IS THE ENTRY POINT FOR THE SERVER COMMAND.
 SERVCOM  SPACE  3,10
          RJ     SREAD
 SERVCOM  MI     X5,*+3
          SX4    X5-45
          ZR     X4,*-2
          SX5    10
          EQ     GETHELP
          SX6    B1          SET SERVER MODE
          SA6    KMODE
          BX6    X6-X6
          SA6    CURN
          RJ     LOGLIN
          SB3    CMDLIST+14
          RJ     ZWRITE
          RJ     OSAVE
          SA6    FILNAM
          EQ     RECCOM2
 RECVCOM  SPACE  4,15
** RECVCOM IS THE ENTRY POINT FOR THE RECEIVE COMMAND.
 RECVCOM  SPACE  3,10
 RECVCOM  BX7    X7-X7
          MI     X5,*+6
          SB5    -7
          EQ     *+2
          RJ     AREAD
          RJ     MAKEFN
          MI     B5,*-2
          NZ     X7,*+2
          SX5    9
          EQ     GETHELP
          SA7    FILNAM
          RJ     LOGLIN
          SB3    CMDLIST+7   'RECEIVE'
          RJ     ZWRITE
          SX5    45
          RJ     SWRITE
          SB3    FILNAM
          RJ     ZWRITE
          RJ     OSAVE
          SA3    FILNAM
          ZR     X3,*+2
          RJ     UNIQUE
          BX7    X7-X7
          SA7    FILE-2
          SA7    A7+B1
          SA7    PSENT
          SA7    A7+B1       PRECD
          SA7    A7+B1       PKERRS
          SA7    A7+B1       RETRYT
          SA7    A7+B1       RETRYC
          SA7    CURN
          SA7    RPCH
          EQ     RECCOM2
 RECCOM1  SPACE  4,10
 RECCOM1  SX3    X2-82       ENTRY FOR RECEIVING R-PACKET
          ZR     X3,SENDSER
          SX3    X2-71       GENERIC COMMAND
          ZR     X3,GENERIC
          SX3    X2-67       'HOST' COMMAND
          ZR     X3,REMCOM
          SX3    X2-75       KERMIT COMMAND
          ZR     X3,REMCOM
          SX3    X2-73       INITIALISE PACKET
          ZR     X3,*+2      WILL BE FOLLOWED BY 0, NOT 1
          SX6    B1
          SA6    CURN
          RJ     YOURPAR     GET YOUR PARAMETERS
          IX2    X0-X2       ARE YOU USING REPEAT COUNTS
          MI     X2,*+1
          MX6    46
          BX7    X6
          PL     X6,*+1
          BX7    X0
          SA7    CBUF+11
          SX7    89          YES = ACK
          SA6    A6+B1
          RJ     MYPARM
          RJ     SENDPACK
 RECCOM2  RJ     REQUESP
          NZ     X1,RECCOM1  PROCESS INITIALISATION COMMANDS
          SX4    X2-70       IS IT A FILE HEADER
          NZ     X4,FATALE   IF NOT, IT IS A FATAL ERROR
          SA1    RPCH
          ZR     X1,REQUSP2  THIS SHOULD BE IMPOSSIBLE; WHO KNOWS
          SA1    FILNAM
          NZ     X1,RECCOM3  THE FILE HAS A NAME ALREADY
          RJ     UNPCFIL
          SA7    FILNAM
          NZ     X7,*+3      DO NOT USE THE PACKET NAME IF THERE WAS
          RJ     DEFFILE       ONE ON THE COMMAND LINE
          BX7    X6
          SA2    A3
          SX6    X2+B1
          SA6    A2
          BX3    X7
          RJ     UNIQUE      ENSURE THERE IS NO SUCH FILE YET
 
 RECCOM3  RJ     LOGLIN      START TO RECEIVE A FILE
          SB3    OPENFM
          RJ     ZWRITE
          SB2    B1
          BX3    X3-X3
          SB4    CBUF+99
          RJ     UNPACK
          EQ     *+2
          RJ     AWRITE      RECORD THE FILE'S NAME IN THE LOG
          RJ     UNPACK
          PL     X5,*-2
          RJ     OSAVE
          SA1    FILNAM
          BX6    X1
          SA6    A1+B1       RECORD THIS FILE AS LAST TRANSFERRED
          EQ     *+2
 
 RECCOM4  RJ     OSAVE       START OF MAIN RECEIVE LOOP
          SX7    89          ACKNOWLEDGE
          SA1    RETRYT      RESTART RETRY COUNT
          SA2    A1+B1
          IX6    X1+X2
          SA6    A1
          BX6    X6-X6
          SA6    A2
          SA1    CURN
          SX6    X1+B1       INCREMENT PACKET NUMBER
          MX0    54
          BX6    -X0*X6      PROVIDED IT'S LESS THAN 63
          SA6    A1
          SX6    35
          SA6    CBUF
          SX6    X1+32       NUMBER OF PREVIOUS PACKET
          SA6    A6+B1
          SA7    A6+B1       TYPE OF PACKET (ACK OR NAK)
          RJ     SENDPACK
          RJ     REQUESP
          NZ     X1,FATALE   WE CANNOT GET A COMMAND PACKET HERE
          SX4    X2-90       Z IS END-OF-FILE
          ZR     X4,RECEOF
          SX4    X2-68       TEST FOR DATA
          NZ     X4,RECCOM4+1
          SX7    FILE
          SB4    CBUF+99
          RJ     OREST
          SB2    B1
          BX3    X3-X3
          RJ     UNPACK
          SA1    FILETYP
          ZR     X1,RECAS
          MX2    58          X2 := -3
          IX1    X1+X2
          MI     X1,*+2
          ZR     X1,RECNO
          EQ     RECEI
          SX1    X1+B1
          MI     X1,RECBI
          EQ     RECKE
* RECEIVE ASCII8 FILES
          MX0    53
          BX5    -X0*X5
          MI     B5,*+3
          SB5    -4
          BX7    X5
          EQ     RECEI
          LX7    12
          SB5    B5+B1
          BX7    X7+X5
          MI     B5,*+1
          RJ     WWRITE
 RECEI    RJ     UNPACK
          MI     X5,RECCOM4
          SX4    X5-10
          ZR     X4,*-2
          SX4    X5-13
          NZ     X4,*-8
          RJ     ELINE
          EQ     *-4
* RECEIVE ASCII FILES
          RJ     AWRITE
 RECAS    RJ     UNPACK
          MI     X5,RECCOM4
          SX4    X5-10
          ZR     X4,*-2
          SX4    X5-13
          NZ     X4,*-4
          RJ     SLINE
          EQ     RECAS
* RECEIVE BINARY FILES
          MI     B5,*+2
          SB5    -13
          BX7    X5
          EQ     RECBI
          SB5    B5+B1
          MI     B5,*+4
          BX4    X5
          AX4    4
          MX0    56
          BX4    -X0*X4
          BX5    -X0*X5
          LX7    4
          BX7    X7+X4
          RJ     WWRITE
          SB5    -14
          EQ     *-4
          SB5    B5+B1
          LX7    8
          BX7    X7+X5
          MI     B5,*+1
          RJ     WWRITE
 RECBI    RJ     UNPACK
          PL     X5,*-9
          EQ     RECCOM4
* RECEIVE KERMIT-FORMAT BINARY FILES
          MI     B5,*+2
          SB5    -6
          BX7    X5
          EQ     *+3
          SB5    B5+B1
          LX7    8
          BX7    X7+X5
          MI     B5,*+1
          RJ     WWRITE
 RECKE    RJ     UNPACK
          PL     X5,*-5
          EQ     RECCOM4
* RECEIVE DISPLAY CODE FILES
          SX4    X5-15
          PL     X4,*+2      X4 < 0 FOR CERTAIN SYMBOLS
          SA5    X5+ASCTAB
          EQ     RECNO-1
          SX4    X4-10
          PL     X4,*+2      X4 < 0 FOR DIGITS
          SX5    X5+12
          EQ     RECNO-1     DIGITS
          SX5    X5-10
          SX4    X5-22
          MI     X4,*-4      X4 < 0 FOR CERTAIN SYMBOLS
          SX4    X4-26
          MI     X4,*+4      X4 < 0 FOR UPPER CASE LETTERS
          SX5    X5-26
          SX4    X5-28
          MI     X4,*-6      X4 < 0 FOR CERTAIN SYMBOLS
          SX4    X4-26
          MI     X4,*+2      X4 < 0 FOR LOWER CASE LETTERS
          SA5    X5+ASCTAB-26
          EQ     RECNO-1
          SX5    X4+27       LETTERS
          EQ     RECNO-1
          MX0    53
          BX5    -X0*X5      SHAVE OFF EIGHTH BIT IF NECESSARY
          SX5    X5-33
          PL     X5,*-12     X5 >= 0 IF PRINTABLE
          SX5    45          BLANK
          RJ     SWRITE
 RECNO    RJ     UNPACK
          MI     X5,RECCOM4
          SX4    X5-10
          ZR     X4,*-2
          SX4    X5-13
          NZ     X4,*-6
          RJ     SLINE
          EQ     RECNO
*
 RECEOF   SA2    A2+B1       CONTENTS OF DATA FIELD
          SX2    X2-68       IS IT A DISCARD
          ZR     X2,RECEOF2
          SA3    FILETYP
          SX7    FILE
          SA1    FILETOT
          SX6    X1+B1
          SA6    A1
          RJ     OREST
          ZR     X3,RECEOFA
          MX0    58          X0 := -3
          IX3    X0+X3
          PL     X3,RECEOFA
          PL     B5,RECEOF1  BINARY FILE ENDS AT A WORD BOUNDARY
          SX3    X3+B1
          ZR     X3,*+6
          NZ     X7,*+2      IF X7 CONTAINS DATA, FILL WITH ZEROS
          SB4    B5+14
          ZR     B4,RECEOF1
 +        LX7    4
          SB5    B5+B1
          MI     B5,*
          RJ     WWRITE      WRITE LAST WORD OF FILE
          EQ     RECEOF1-1
          SX3    -B5
          LX7    4
 +        LX7    8
          SB5    B5+B1
          MI     B5,*
          BX7    X7+X3
          LX7    56
          EQ     *-4
 RECEOFA  MI     B5,*+1
          MX0    48
          BX6    -X0*X7      HAVE WE HAD AN EOLN
          ZR     X6,RECEOF1
          ZR     X3,*+3      SIX BIT FILE CODES HAVE X3 = 0 HERE
          RJ     ELINE
          EQ     *+2
          RJ     SLINE
          RJ     OSAVE
 RECEOF1  WRITER FILE
          EQ     RECEOF3
 RECEOF2  RETURN FILE
 RECEOF3  RJ     LOGLIN
          SB3    EOFM
          RJ     ZWRITE
          SB3    FILE
          RJ     ZWRITE
          SA3    CBUF+99
          RJ     SLINE
          SX3    X3-68       TEST FOR DISCARD INSTRUCTION
          NZ     X3,*+4
          SB2    9
          RJ     XWRITE
          SB3    DISCARM
          RJ     ZWRITE
          RJ     SLINE
          RJ     WSTATS
          RJ     OSAVE
          SA1    CURN
          SX7    X1+B1
          MX0    54
          BX7    -X0*X7
          SA7    A1
          SX6    X1+32
          BX7    X7-X7
          SA7    FILNAM
          SX7    35
          SA7    CBUF
          SX7    89          Y = ACK
          SA6    A7+B1
          SA7    A6+B1
          EQ     RECCOM2-1
 SHOWP    TITLE  INFORMATION ROUTINES
** SHOWP EXECUTES A REMOTE SHOW COMMAND.
 SHOWP    SPACE  3,10
 SHOWP    RJ     LOGLIN
          SA1    CMDLIST+12  SHOW
          RJ     INFOSUB
          SB3    SETLIST+4   BIT-PREFIX
          RJ     PZLINE
          SB5    10
          SA5    BITPREF
          RJ     PTVWAC
          SB3    BLOCKM
          RJ     PZLINE
          SB3    SETLIST+10  DEBUG
          RJ     PZLINE
          SB5    15
          SA5    DEBUGW
          SB3    X5+KNAME+2
          RJ     PZWRITE
          SB3    DEFAULM
          RJ     PZLINE
          SB5    B5-B1
          RJ     DEFFILE     DEFAULT FILE NAME
          SA6    UPDAT
          SB3    A6
          RJ     PZWRITE
          SB3    SETLIST+15  DELAY
          RJ     PZLINE
          SB5    15
          SA3    TIMEOUT
          RJ     PNWRITE
          SB3    SETLIST+20  ESCAPE
          RJ     PZWRITE
          SB5    14
          SB3    CTRLHYP
          RJ     PZWRITE
          SA5    ESCAPEC
          SX7    X5+64
          SB3    SETLIST+6   FILE TYPE
          RJ     PZLINE
          SA4    FILETYP+1
          MX0    58
          BX0    -X0*X4
          ZR     X0,*+1
          SX4    X4+B1
          LX4    2
          AX4    1
          SB3    X4+FTLIST+4
          SB5    11
          RJ     PZWRITE
          RJ     PLINE
          SB3    SETLIST+11  SYNC MARKER
          RJ     PZWRITE
          SB5    14
          SB3    CTRLHYP
          RJ     PZWRITE
          SA5    SYNCM
          SX7    X5+64
          SB3    SETLIST+16  PACKET LENGTH
          RJ     PZLINE
          SB5    7
          SA3    PLENGTH
          RJ     PNWRITE
          SB3    PAREVEN
          RJ     PZWRITE
          SB3    SETLIST+8   QUOTE CHARACTER
          RJ     PZLINE
          SB5    10
          SA5    QUOTEC
          RJ     PTVWAC
          SB3    SETLIST+13  REPEAT CHARACTER
          RJ     PZLINE
          SB5    9
          SA5    REPETC
          RJ     PTVWAC
          SB3    SETLIST+19  RETRY LIMIT
          RJ     PZLINE
          SB5    15
          SA3    RETRYN
 SHSTEND  RJ     PNWRITE
          RJ     PLINE
          SX5    B1
          LX5    5
          RJ     PTVWAC
          EQ     PUTEOF
 STATUSP  SPACE  4,15
** STATUSP EXECUTES A REMOTE STATUS COMMAND.
 STATUSP  SPACE  3,10
 STATUSP  RJ     LOGLIN
          SA1    CMDLIST+16
          SA2    SETTAB-1
          BX1    X2
          RJ     INFOSUB
          SB3    TRANSFM
          RJ     PZLINE
          SB5    5
          SA3    FILETOT     FILES TRANSFERRED
          RJ     PNWRITE
          SB3    LASTFM
          RJ     PZWRITE
          SB3    FILNAM+1
          SB5    12
          RJ     PZWRITE     NAME OF LAST FILE TRANSFERRED
          SB3    TRANSFM+4
          RJ     PZLINE
          SB5    10
          SA3    PSENT       PACKETS SENT
          RJ     PNWRITE
          RJ     PZWRITE
          SB5    6
          SA3    PRECD       PACKETS RECEIVED
          RJ     PNWRITE
          RJ     PZWRITE
          SB5    11
          SA3    PKERRS      ERRORS IN RECEIVED DATA
          RJ     PNWRITE
          RJ     PZWRITE
          SB5    11
          SA3    RETRYT      TOTAL RETRIES
          EQ     SHSTEND
 SHOWVAL  SPACE  4,15
** SHOWVAL DISPLAYS THE VALUES OF KERMIT VARIABLES.
 SHOWVAL  SPACE  3,10
 SHOWVAL  SX7    OUTPUT      PREPARE TO WRITE OUTPUT
          RJ     OREST
          SB3    SETLIST+4
          RJ     ZLINE
          SB2    9
          RJ     XWRITE
          SA5    BITPREF     BIT-PREFIX
          RJ     AWRITE
          SB3    BLOCKM      CHECKSUM TYPE
          RJ     ZLINE
          SB3    SETLIST+10
          RJ     ZLINE
          SB2    14
          RJ     XWRITE
          SA5    DEBUGW
          SB3    X5+KNAME+2
          RJ     ZWRITE      DEBUG
          SB3    DEFAULM
          RJ     ZLINE
          RJ     DEFFILE     CURRENT DEFAULT FILE NAME
          SA6    UPDAT
          SB3    A6
          RJ     ZWRITE
          SB3    SETLIST+15  DELAY
          RJ     ZLINE
          SB2    14
          RJ     XWRITE
          SA3    TIMEOUT
          RJ     NWRITE
          SB3    SETLIST+20  ESCAPE
          SB4    ESCAPEC
          RJ     BCTRLW
          SB3    SETLIST+6   FILE TYPE
          RJ     ZLINE
          SB2    9
          RJ     XWRITE
          RJ     WFILTYP
          SB3    SETLIST+11  SYNC MARKER
          SB4    SYNCM
          RJ     BCTRLW
          SB3    SETLIST+16  PACKET LENGTH
          RJ     ZLINE
          SB2    6
          RJ     XWRITE
          SA3    PLENGTH
          RJ     NWRITE
          SB3    PAREVEN     PARITY
          RJ     ZWRITE
          SB3    SETLIST+8   QUOTE CHARACTER
          RJ     ZLINE
          SB2    9
          RJ     XWRITE
          SA5    QUOTEC
          RJ     AWRITE
          SB3    SETLIST+13  REPEAT CHARACTER
          RJ     ZLINE
          SB2    8
          RJ     XWRITE
          SA5    REPETC
          RJ     AWRITE
          SB3    SETLIST+19  RETRY
          RJ     ZLINE
          SB2    14
          RJ     XWRITE
          SA3    RETRYN
          RJ     NWRITE
          RJ     SLINE
          EQ     MAINPRG
 STATUSV  SPACE  4,15
** STATUSV DISPLAYS THE CURRENT TRANSFER STATISTICS.
 STATUSV  SPACE  3,10
 STATUSV  SX7    OUTPUT
          RJ     OREST       PREPARE TO WRITE ON OUTPUT
          SB3    TRANSFM
          RJ     ZLINE
          SB2    4
          RJ     XWRITE
          SA3    FILETOT     NUMBER OF FILES TRANSFERRED
          RJ     NWRITE
          SB3    LASTFM      NAME OF LAST FILE TRANSFERRED
          RJ     ZWRITE
          SB2    11
          RJ     XWRITE
          SB3    FILNAM+1
          RJ     ZWRITE
          RJ     WSTATS
          EQ     MAINPRG
 GETHELP  SPACE  4,16
** GETHELP OBTAINS LONG HELP MESSAGES FROM THE FILE ZZZKHLP, A MULTI-
*  RECORD FILE.
 GETHELP  SPACE  3,10
 GETHELP  SA4    HELPLOC
          SX6    X5+B1
          SA6    A4          SAVE THE NEXT POSITION IN ZZZKHLP
          SX6    ZZZKHLP
          SA6    INFI
          NZ     X4,GETHLP1
          REWIND ZZZKHLP     HERE THE FILE  HAS NOT YET BEEN USED
          SA5    HELPLOC
          SX4    B1+B1
 GETHLP1  IX1    X5-X4       COMPUTE RELATIVE LOCATION
          PL     X1,GETHLP2  IF X1 >= 0, WE MOVE FORWARD
          BX1    -X1         OTHERWISE WE MOVE BACK
          SKIPB  ZZZKHLP,X1,R
          EQ     GETHLP3
 GETHLP2  ZR     X1,GETHLP3
          SKIPF  ZZZKHLP,X1,R
 GETHLP3  SA1    KMODE
          NZ     X1,GETHLP4  X1 <> 0 IN SERVER MODE
          SX2    ZZZKHLP
          RJ     FREAD       FILL READ BUFFER
          RJ     OUTSTRT
          EQ     *+2
          BX7    X6
          RJ     WWRITE
          RJ     WREAD
          ZR     X1,*-2
          EQ     MAINPRG
 GETHLP4  RJ     LOGLIN      IN SERVER MODE, SEND HELP IN PACKETS
          SA1    HELPM
          RJ     INFOSUB
          SX6    ZZZKHLP
          SA6    INFI
          BX2    X6
          RJ     FREAD
          EQ     SENAS
 KERMIT   TITLE  INITIALISATION
 KERMIT   SB1    1
          OPEN   INPUT,READNR,R
          OPEN   OUTPUT,WRITENR,R
          SX6    ZZZKHLP
          RJ     TESTFIL
          ZR     X6,DEBACL-2
          SX6    ZZZKLOG
          RJ     TESTFIL     DOES THE LOG FILE EXIST
          NZ     X6,KERMIT1  IF SO, WRITE ON END OF IT
          SX6    1R1         IF NOT, START WITH TOP-OF-PAGE
          SA6    A6-B1
          EQ     KERMIT2
 KERMIT1  SKIPEI X2,R
 KERMIT2  SETFS  ZZZKLOG,NAD
          SX6    ZZZKDAT
          RJ     TESTFIL     WAS THERE A PUSH COMMAND
          ZR     X6,KERMIT3
          REWIND ZZZKDAT,R
          READ   ZZZKDAT,R
          SA2    ZZZKDAT+3   GET ADDR OF START OF DATA
          SX3    X2+12
          SA1    A2-B1       GET ADDR AFTER END OF DATA
          BX3    X3-X1
          NZ     X3,DEBACLD  X3 <> 0 IF FILE NOT PROPER LENGTH
          SA1    X2          BITPREFIX
          SA2    A1+B1       DEBUG
          SA3    A2+B1       DEFAULT FILE
          SA4    A3+B1       ESCAPE CHAR
          BX6    X1
          SA6    BITPREF
          BX6    X2
          BX7    X3
          SA6    DEBUGW
          SA7    A6+B1       DEFAULF
          BX7    X4
          SA7    A7+B1       ESCAPEC
          SA1    A4+B1       FILE TYPE
          SA2    A1+B1       SYNC MARKER
          SA3    A2+B1       PACKET LENGTH
          BX7    X1
          SA7    FILETYP+1
          SA4    A3+B1       QUOTE CHARACTER
          BX7    X2
          BX6    X3
          SA7    A7+B1       SYNCM
          SA6    A7+B1       PLENGTH
          BX6    X4
          SA6    QUOTEC
          SA1    A4+B1       REPEAT PREFIX
          SA2    A1+B1       TIMEOUT
          SA3    A2+B1       NUMBER OF FILES TRANSFERRED
          SA4    A3+B1       RETRY LIMIT
          BX6    X1
          BX7    X2
          SA6    REPETC
          SA7    A6+B1       TIMEOUT
          BX6    X4
          SA6    RETRYN
          BX7    X3
          SA7    A7+B1       FILETOT
          RETURN ZZZKDAT
 KERMIT3  SA2    INPUT+1
          SA1    OUTPUT+1
          LX2    1
          LX3    B1,X1
          PL     X2,DEBACL-1 INPUT IS NOT FROM A TERMINAL
          PL     X3,DEBACL-1 OUTPUT IS NOT TO A TERMINAL
          SX2    B1
          LX2    36          FLUSH BIT
          BX7    X1+X2
          SA7    A1          SET FLUSH BIT IN OUTPUT
          SA3    ZZZKLOG+1
          BX7    X2+X3
          SA7    A3          SET FLUSH BIT IN LOG FILE
          SA1    DUMMY+4
          BX6    X1
          SA6    DUMMY+2
          PROMPT OFF
          CSET   ASCII
          SETTL  77777B      SET TIME LIMIT TO MAXIMUM
          SETLOF LOFS        THESE FILES WILL BE FLUSHED
          DATE   UPDAT
          RJ     LOGLIN      START LOG FILE
          SB3    KNAME
          RJ     ZWRITE
          SB2    5
          RJ     XWRITE
          SB3    UPDAT
          RJ     ZWRITE
          RJ     OSAVE
          SA3    TPARAMS     SET PARITY AND PAGE CHARACTERISTICS
          RJ     OUTSTRT     SET UP OUTPUT FOR WRITING
          BX7    X3
          SA7    B6+B7
          SB6    B6+B1
          SA3    A3+B1
          BX7    X3
          SA7    B6+B7
          SB6    B6+B1
          EQ     MAINPRG
 COMSEL   TITLE  START TO PROCESS EACH COMMAND
 FILEASK  ZR     X1,COMSEL-1  X1 = 0 WHEN WE ARE IN COMMAND MODE
          SX5    23          OTHERWISE SEND A HELP MESSAGE
          EQ     GETHELP
          SB3    FTLIST      ASK ABOUT FILES
          EQ     LWRITE
 COMSEL   SB3    OFFLIST     ASK FOR HELP WITH SET DEBUG
          EQ     LWRITE
 COMDIFF  EQU    COMSEL-KNAME
          SB3    OFFLIST     AMBIGUOUS 'O'
          EQ     LWRITE
          BX7    X7-X7       OFF = 0
          EQ     SETDBG
          SX7    B1          ON = 1
          EQ     SETDBG
          SB3    CMDLIST     LIST COMMANDS
          EQ     LWRITE
          SX7    CMDLIST+6   EXIT
          EQ     FINIS
          SX7    CMDLIST+10  PUSH
          EQ     PUSHIT
          SX7    CMDLIST+13  QUIT
          EQ     FINIS
          EQ     RECVCOM     RECEIVE
          SB3    CMDLIST     AMBIGUOUS 'SE'
          EQ     LWRITE
          EQ     SENDCOM     SEND
          EQ     SERVCOM     SERVER
          SB7    SETTAB      SET
          EQ     CREAD
          EQ     SHOWVAL     SHOW
          EQ     STATUSV     STATUS
          SB3    SETLIST     ASK ABOUT SET
          EQ     LWRITE
          EQ     SETBIT      BIT-PREFIX
          SB3    SETLIST     AMBIGUOUS 'DE'
          EQ     LWRITE
          SB7    KNAME       DEBUG
          EQ     CREAD
          EQ     SETDELA     DELAY
          EQ     SETESCA     ESCAPE
          SB7    FTYPES      FILE-TYPE
          EQ     CREAD
          EQ     SETMARK     MARKER
          EQ     SETPACL     PACKET-LENGTH
          EQ     SETQUOT     QUOTE-CHAR
          SB3    SETLIST     AMBIGUOUS 'RE'
          EQ     LWRITE
          EQ     SETREP      REPEAT-CHAR
          EQ     SETTRY      RETRY
          SA1    KMODE       ASK ABOUT FILES
          EQ     FILEASK
          BX7    X7-X7       ASCII
          EQ     SETFILE
          SX7    B1          ASCII8
          LX7    2
          EQ     SETFILE
          SX7    B1          BINARY
          EQ     SETFILE
          MX7    58          DISPLAY CODE
          BX7    -X7
          EQ     SETFILE
          MX7    58          DIS64
          BX7    -X7
          EQ     SETFILE
          SX7    B1          EIGHT
          LX7    2
          EQ     SETFILE
          SX7    B1+B1       KERMIT
          EQ     SETFILE
          MX7    58          NORMAL
          BX7    -X7
          EQ     SETFILE
          SX7    B1          8
          LX7    2
          EQ     SETFILE
 SERVHLP  SX5    22          GET HELP WITH SERVER COMMANDS
          EQ     GETHELP
          SX5    22          AMBIGUOUS S
          EQ     GETHELP
          SB7    FTYPES      SET-FILE-TYPE
          EQ     CREAD
          EQ     SHOWP       SHOW
          EQ     STATUSP     STATUS
          SB5    -7          TYPE
          EQ     TYPECOM
 PUSHIT   TITLE  PROGRAM TERMINATION
** PUSHIT TERMINATES EXECUTION AFTER SAVING VARIABLES.
 PUSHIT   SPACE  3,10
          RJ     SREAD
 PUSHIT   MI     X5,*+3      TEST FOR END-OF-LINE
          SX4    X5-45
          ZR     X4,*-2      IGNORE BLANKS
          SX5    12
          EQ     GETHELP
          SA7    UPDAT
          EVICT  ZZZKDAT     GET RID OF ANYTHING ELSE ON FILE
          SX6    WBUF
          SA6    ZZZKDAT+3   START OF DATA
          SA3    BITPREF
          BX7    X3
          SA7    X6          BIT PREFIX
          SA3    DEBUGW
          BX7    X3
          SA7    A7+B1       DEBUG SETTING
          SA3    A3+B1       DEFAULF
          BX7    X3
          SA7    A7+B1       DEFAULT FILE NUMBER
          SA3    A3+B1       ESCAPEC
          BX7    X3
          SA7    A7+B1       ESCAPE CHARACTER
          SA3    FILETYP+1
          BX7    X3
          SA7    A7+B1       FILE TYPE
          SA3    A3+B1       SYNCM
          BX7    X3
          SA7    A7+B1       PACKET SYNCHRONISATION MARKER
          SA3    A3+B1       PLENGTH
          BX7    X3
          SA7    A7+B1       PACKET LENGTH TO REQUEST
          SA3    QUOTEC
          BX7    X3
          SA7    A7+B1       QUOTE CHARACTER
          SA3    REPETC
          BX7    X3
          SA7    A7+B1       REPEAT PREFIX
          SA3    A3+B1       TIMEOUT
          BX7    X3
          SA7    A7+B1       TIMEOUT TO REQUEST
          SA3    A3+B1       FILETOT
          BX7    X3
          SA7    A7+B1       NUMBER OF FILES TRANSFERRED
          SA3    RETRYN
          BX7    X3
          SA7    A7+B1       NUMBER OF RETRIES PERMITTED
          SX6    A7+B1
          SA6    A6-B1       ADDRESS AFTER END OF DATA
          WRITER ZZZKDAT
          SETFS  ZZZKDAT,NAD
          EQ     FINIS1
 FINIS    SPACE  4,15
** FINIS TERMINATES EXECUTION WITHOUT SAVING VARIABLES.
 FINIS    SPACE  3,10
          RJ     SREAD
 FINIS    MI     X5,*+3
          SX4    X5-45
          ZR     X4,*-2
          SX5    11
          EQ     GETHELP
          SA7    UPDAT
          RETURN ZZZKDAT
 FINIS1   RJ     LOGLIN
          SA2    UPDAT
          SB3    X2
          RJ     ZWRITE
          RJ     SLINE
          RJ     OSAVE
          WRITER ZZZKLOG
          ENDRUN
          SPACE  4,6
 OPL      XTEXT  COMCSYS
 OPL      XTEXT  COMCCIO
 OPL      XTEXT  COMCLFM
 OPL      XTEXT  COMCCPM
          XREF   A
          END    KERMIT
