Split up files.
[pdp10-muddle.git] / sumex / fopen.mcr352
diff --git a/sumex/fopen.mcr352 b/sumex/fopen.mcr352
new file mode 100644 (file)
index 0000000..7f0e38f
--- /dev/null
@@ -0,0 +1,3957 @@
+TITLE OPEN - CHANNEL OPENER FOR MUDDLE\r
+\r
+RELOCATABLE\r
+\r
+;C. REEVE  MARCH 1973\r
+\r
+.INSRT MUDDLE >\r
+\r
+SYSQ\r
+\r
+IFE ITS,[\r
+IF1,   .INSRT MUDSYS;STENEX >\r
+]\r
+;THIS PROGRAM HAS ENTRIES:  FOPEN, FCLOSE, RENAME, READB, PRINTB, FILECOPY, READSTRING,\r
+;                          PRINTSTRING, NETSTATE, NETACC, NETS, AND ACCESS.\r
+\r
+;THESE SUBROUTINES HANDLE I/O STREAMS FOR THE MUDDLE SYSTEM.\r
+\r
+;      FOPEN   - OPENS A FILE FOR EITHER READING OR WRITING.  IT TAKES\r
+;              FIVE OPTINAL ARGUMENTS AS FOLLOWS:\r
+\r
+;              FOPEN (<DIR>,<FILE NAME1>,<FILE NAME2>,<DEVICE>,<SYSTEM NAME>)\r
+;\r
+;              <DIR> - DIRECTION EITHER READ (INPUT) OR PRINT (OUPUT). DEFAULT IS READ\r
+\r
+;              <FILE NAME1> - FIRST FILE NAME.  DEFAULT INPUT OR OUTPUT.\r
+\r
+;              <FILE NAME2> - SECOND FILE NAME.  DEFAULT MUDDLE.\r
+\r
+;              <DEVICE> - DEVICE FROM WHICH TO OPEN.  DEFAULT IS DSK.\r
+\r
+;              <SNAME> - SYSTEM (DIRECTORY) NAME. DEFAULT UNAME.\r
+\r
+;      FOPEN   RETURNS AN OBJECT OF TYPE CHANNEL IF IT SUCCEEDS OTHERWISE NIL\r
+\r
+\r
+;      FCLOSE  - CLOSES A FILE.  TAKES A CHANNEL OBJECT AS ITS ARGUMENT.  IT ALSO TAKES\r
+;      ACCESS  - DOES A .ACCESS ON A CHARACTER BASIS FOR CHARACTER FILES\r
+\r
+\r
+; A CHANNEL OBJECT IS A VECTOR CONTAINIG THE FOLLOWING INFORMATION\r
+\r
+;      CHANNO  ;ITS I/O CHANNEL NUMBER.  0 MEANS NOT A REAL CHANNEL.\r
+;      DIRECT  ;DIRECTION (EITHER READ OR PRINT)\r
+;      NAME1   ;FIRST NAME OF FILE AS OPENED.\r
+;      NAME2   ;SECOND NAME OF FILE\r
+;      DEVICE  ;DEVICE UPON WHICH THE CHANNEL IS OPEN\r
+;      SNAME   ;DIRECTORY NAME\r
+;      RNAME1  ;REAL FIRST NAME (AS RETURNED BY READING CHANNEL STATUS)\r
+;      RNAME2  ;REAL SECOND NAME\r
+;      RDEVIC  ;REAL DEVICE\r
+;      RSNAME  ;SYSTEM OR DIRECTORY NAME\r
+;      STATUS  ;VARIOUS STATUS BITS\r
+;      IOINS   ;INSTRUCTION EXECUTED TO INPUT OR OUTPUT ONE CHARACTER\r
+;      ACCESS  ;ACCESS POINTER FOR RAND ACCESS (OR USED FOR DISPLAY INFO)\r
+;      RADX    ;RADIX FOR CHANNELS NUMBER CONVERSION\r
+\r
+;      *** THE FOLLOWING FIELDS FOR OUTPUT ONLY ***\r
+;      LINLN   ;LENGTH OF A LINE IN CHARACTERS FOR THIS DEVICE\r
+;      CHRPOS  ;CURRENT POSITION ON CURRENT LINE\r
+;      PAGLN   ;LENGTH OF A PAGE\r
+;      LINPOS  ;CURRENT LINE BEING WRITTEN ON\r
+\r
+;      *** THE FOLLOWING FILEDS FOR INPUT ONLY ***\r
+;      EOFCND  ;GETS EVALUATED  ON EOF\r
+;      LSTCH   ;BACKUP CHARACTER\r
+;      WAITNS  ;FOR TTY INPUT, BECOMES A .SLEEP WHEN WAITING\r
+;      EXBUFR  ;FOR TTY INPUT, CONTAINS A WAITING BUFFER LIST\r
+;      BUFSTR  ;A CHARACTER STRING USED AS BUFFER FOR NON-TTY DEVICES\r
+\r
+; THIS DEFINES THE LENGTH OF THE NON-TTY BUFFER\r
+BUFLNT==100\r
+\r
+;THIS DEFINES BLOCK MODE BIT FOR OPENING\r
+BLOCKM==2              ;DEFINED IN THE LEFT HALF\r
+IMAGEM==4\r
+\r
+\f\r
+;THIS IRP DEFINES THE FIELDS AT ASSEMBLY TIME\r
+\r
+       CHANLNT==4                      ;INITIAL CHANNEL LENGTH\r
+\r
+; BUILD A PROTOTYPE CHANNEL AND DEFINE FILEDS\r
+BUFRIN==-1     ;SPECIAL HACK SO LOSERS WON'T SEE TTY BUFFER\r
+SCRPTO==-3     ;SPECIAL HACK FOR SCRIPT CHANNELS\r
+PROCHN:\r
+\r
+IRP A,,[[CHANNO,FIX],[DIRECT,CHSTR]\r
+[NAME1,CHSTR],[NAME2,CHSTR],[DEVICE,CHSTR],[SNAME,CHSTR]\r
+[RNAME1,CHSTR],[RNAME2,CHSTR],[RDEVIC,CHSTR],[RSNAME,CHSTR]\r
+[STATUS,FIX],[IOINS,FIX],[LINLN,FIX],[CHRPOS,FIX],[PAGLN,FIX],[LINPOS,FIX]\r
+[ACCESS,FIX],[RADX,FIX],[BUFSTR,CHSTR]]\r
+\r
+       IRP     B,C,[A]\r
+               B==CHANLNT-3\r
+               T!C,,0\r
+               0\r
+               .ISTOP\r
+               TERMIN\r
+       CHANLNT==CHANLNT+2\r
+TERMIN\r
+\r
+\r
+; EQUIVALANCES FOR CHANNELS\r
+\r
+EOFCND==LINLN\r
+LSTCH==CHRPOS\r
+WAITNS==PAGLN\r
+EXBUFR==LINPOS\r
+DISINF==BUFSTR ;DISPLAY INFO\r
+INTFCN==BUFSTR ;FUNCTION (OR SUBR, OR RSUBR) TO BE APPLIED FOR INTERNAL CHNLS\r
+\r
+\r
+;DEFINE VARIABLES ASSOCIATED WITH TTY BUFFERS\r
+\r
+IRP A,,[IOIN2,ECHO,CHRCNT,ERASCH,KILLCH,BRKCH,ESCAP,SYSCHR,BRFCHR,BRFCH2,BYTPTR]\r
+A==.IRPCNT\r
+TERMIN\r
+\r
+EXTBFR==BYTPTR+1+<100./5>      ;LENGTH OF ADD'L BUFFER\r
+\r
+\r
+\r
+\r
+.GLOBAL IPNAME,MOPEN,MCLOSE,MIOT,ILOOKU,6TOCHS,ICLOS,OCLOS,RGPARS,RGPRS\r
+.GLOBAL OPNCHN,CHMAK,READC,TYO,SYSCHR,BRFCHR,LSTCH,BRFCH2,EXTBFR\r
+.GLOBAL CHRWRD,STRTO6,TTYBLK,WAITNS,EXBUFR,TTICHN,TTOCHN,GETCHR\r
+.GLOBAL CHANNO,STATUS,LINPOS,PAGLN,CHRPOS,LINLN,IOINS,ACCESS\r
+.GLOBAL DIRECT,DISINF,RADX,EOFCND,BUFSTR,MODE1,MODE2,GCHACK,GMTYO\r
+.GLOBAL T.CHAN,NAME1,BFCLOS,DOIOTI,DOIOTO,DOACCS,NOTTY,BYTDOP,TNXIN\r
+.GLOBAL DISOPN,DISROP,DISCLS,DCHAR,DISLNL,DISPGL,INSTAT,MTYO\r
+.GLOBAL ECHO,ERASCH,KILLCH,BRKCH,BYTPTR,SYSCHR,CHRCNT,ESCAP,N.CHNS\r
+.GLOBAL REOPN,QUITTE,CHNL0,CHNL1,BUFRIN,IOIN2,IFALSE,GFALS,IDVAL\r
+.GLOBAL BADCHN,WRONGD,CHNCLS,GSNAME,GIBLOK,APLQ,NAPT,ICONS,INCONS,IBLOCK,IDVAL1\r
+.GLOBAL GRB,GWB,R1CHAR,W1CHAR,BFCLS1,TTYOP2,MPOPJ,COMPER,R1C,W1C,WXCT,RXCT\r
+.GLOBAL TMTNXS,TNXSTR,RDEVIC\r
+\r
+\f\r
+.VECT.==40000\r
+\r
+; PAIR MOVING MACRO\r
+\r
+DEFINE PMOVEM A,B\r
+       MOVE    0,A\r
+       MOVEM   0,B\r
+       MOVE    0,A+1\r
+       MOVEM   0,B+1\r
+       TERMIN\r
+\r
+; DEFINITIONS OF THE OFFSETS INTO THE TP STACK FOR OPEN\r
+\r
+T.SPDL==0              ; SAVES P STACK BASE\r
+T.DIR==2               ; CONTAINS DIRECTION AND MODE\r
+T.NM1==4               ; NAME 1 OF FILE\r
+T.NM2==6               ; NAME 2 OF FILE\r
+T.DEV==10              ; DEVICE NAME\r
+T.SNM==12              ; SNAME\r
+T.XT==14               ; EXTRA CRUFT IF NECESSARY\r
+T.CHAN==16             ; CHANNEL AS GENERATED\r
+\r
+; OFFSETS FROM PSTACK BASE (USED FOR OPENS, .RCHST AND .FDELES)\r
+\r
+S.DIR==0               ; CODE FOR DIRECTION 0-IN, 1-OUT, 2-BIN, 3-BOUT,4-DISPLAY\r
+IFN ITS,[\r
+S.DEV==1               ; SIXBIT DEVICE RIGHT JUSTIFIED\r
+S.NM1==2               ; SIXBIT NAME1\r
+S.NM2==3               ; SIXBIT NAME2\r
+S.SNM==4               ; SIXBIT SNAME\r
+S.X1==5                        ; TEMPS\r
+S.X2==6\r
+S.X3==7\r
+]\r
+\r
+IFE ITS,[\r
+S.DEV==1\r
+S.X1==2\r
+S.X2==3\r
+S.X3==4\r
+]\r
+\r
+\r
+; FLAGS SPECIFYING STATE OF THE WORLD AT VARIOUS TIMES\r
+\r
+NOSTOR==400000         ; ON MEANS DONT BUILD NEW STRINGS\r
+MSTNET==200000         ; ON MEANS ONLY THE "NET" DEVICE CAN WIN\r
+SNSET==100000          ; FLAG, SNAME SUPPLIED\r
+DVSET==040000          ; FLAG, DEV SUPPLIED\r
+N2SET==020000          ; FLAG, NAME2 SET\r
+N1SET==010000          ; FLAG, NAME1 SET\r
+\r
+RMT [EXPUNGE N1SET,N2SET,DVSET,SNSET,MSTNET,NOSTOR\r
+]\r
+\r
+\r
+; TABLE OF LEGAL MODES\r
+\r
+MODES: IRP A,,[READ,PRINT,READB,PRINTB,DISPLAY]\r
+       SIXBIT /A/\r
+       TERMIN\r
+NMODES==.-MODES\r
+\r
+; TABLE OF KNOWN DEVICES AND A POINTER TO THEIR OPENERS\r
+\r
+IFN ITS,[\r
+\r
+DEVS:  IRP A,,[DSK,TPL,SYS,COM,TTY,USR,STY,[ST ],NET,DIS,E&S,INT,PTP,PTR\r
+[P  ],[DK ],[UT ],[T  ],NUL,[AI ]\r
+[ML ],[DM ],[AR ],ARC]B,,[ODSK,ODSK,ODSK,ODSK,OTTY,OUSR,OSTY,OSTY,ONET,ODIS,ODIS\r
+OINT,OPTP,OPTP,ODSK,ODSK,OUTN,OTTY,ONUL,ODSK,ODSK,ODSK,ODSK,ODSK]\r
+       B,,(SIXBIT /A/)\r
+       TERMIN\r
+]\r
+IFE ITS,[\r
+DEVS:  IRP A,,[DSK,TTY,INT,NET]B,,[ODSK,OTTY,OINT,ONET]\r
+       B,,(SIXBIT /A/)\r
+       TERMIN\r
+]\r
+NDEVS==.-DEVS\r
+\r
+\r
+\f\r
+;SUBROUTINE TO DO OPENING BEGINS HERE\r
+\r
+MFUNCTION NFOPEN,SUBR,[OPEN-NR]\r
+\r
+       JRST    FOPEN1\r
+\r
+MFUNCTION FOPEN,SUBR,[OPEN]\r
+\r
+FOPEN1:        ENTRY\r
+       PUSHJ   P,MAKCHN        ;MAKE THE CHANNEL\r
+       PUSHJ   P,OPNCH ;NOW OPEN IT\r
+       JRST    FINIS\r
+\r
+; SUBR TO JUST CREATE A CHANNEL\r
+\r
+MFUNCTION CHANNEL,SUBR\r
+\r
+       ENTRY\r
+       PUSHJ   P,MAKCHN\r
+       MOVSI   A,TCHAN\r
+       JRST    FINIS\r
+\r
+\r
+\f\r
+\r
+; THIS ROUTINE PARSES ARGUMENTS TO FOPEN ETC. AND BUILDS A CHANNEL BUT DOESN'T OPEN IT\r
+\r
+MAKCHN:        PUSH    TP,$TPDL\r
+       PUSH    TP,P            ; POINT AT CURRENT STACK BASE\r
+       PUSH    TP,$TCHSTR\r
+       PUSH    TP,CHQUOTE READ\r
+       MOVEI   E,10            ; SLOTS OF TP NEEDED\r
+       PUSH    TP,[0]\r
+       SOJG    E,.-1\r
+       MOVEI   E,0\r
+       EXCH    E,(P)           ; GET RET ADDR IN E\r
+IFE ITS,       PUSH    P,[0]\r
+IRP ATM,,[DEV,NM1,NM2,SNM]MDF,,[DSK,INPUT,>,[ ]]TMDF,,[DSK,INPUT,MUD,[ ]]\r
+       MOVE    B,IMQUOTE ATM\r
+IFN ITS,       PUSH    P,E\r
+       PUSHJ   P,IDVAL1\r
+       GETYP   0,A\r
+       CAIN    0,TCHSTR\r
+       JRST    MAK!ATM\r
+\r
+       MOVE    A,$TCHSTR\r
+IFN ITS,       MOVE    B,CHQUOTE MDF\r
+IFE ITS,       MOVE    B,CHQUOTE TMDF\r
+MAK!ATM:\r
+       MOVEM   A,T.!ATM(TB)\r
+       MOVEM   B,T.!ATM+1(TB)\r
+IFN ITS,[\r
+       POP     P,E\r
+       PUSHJ   P,STRTO6        ; RESULT LEFT ON P STACK AS DESIRED\r
+]\r
+       TERMIN\r
+       PUSH    TP,[0]          ; PUSH SLOTS\r
+       PUSH    TP,[0]\r
+\r
+       PUSH    P,[0]           ; EXT SLOTS\r
+       PUSH    P,[0]\r
+       PUSH    P,[0]\r
+       PUSH    P,E             ; PUSH RETURN ADDRESS\r
+       MOVEI   A,0\r
+\r
+       JUMPGE  AB,MAKCH0       ; NO ARGS, ALREADY DONE\r
+       GETYP   0,(AB)          ; 1ST ARG MUST BE A STRING\r
+       CAIE    0,TCHSTR\r
+       JRST    WTYP1\r
+       MOVE    A,(AB)          ; GET ARG\r
+       MOVE    B,1(AB)\r
+       PUSHJ   P,CHMODE        ; CHECK OUT OPEN MODE\r
+\r
+       PMOVEM  (AB),T.DIR(TB)  ; SAVE MODE NAME IN TEMPS\r
+       ADD     AB,[2,,2]       ; BUMP PAST DIRECTION\r
+       MOVEI   A,0\r
+       JUMPGE  AB,MAKCH0       ; CHECK NAME1 BASED ON JUST MODE\r
+\r
+       MOVEI   0,0             ; FLAGS PRESET\r
+       PUSHJ   P,RGPARS        ; PARSE THE STRING(S)\r
+       JRST    TMA\r
+\r
+; ARGUMENTS PARSED, DO FINAL CHECKS AND BUILD CHANNEL\r
+\r
+MAKCH0:\r
+IFN ITS,[\r
+       MOVE    C,T.SPDL+1(TB)\r
+       HLRZS   D,S.DEV(C)      ; GET DEV\r
+]\r
+IFE ITS,[\r
+       MOVE    A,T.DEV(TB)\r
+       MOVE    B,T.DEV+1(TB)\r
+       PUSHJ   P,STRTO6\r
+       POP     P,D\r
+       HLRZS   D\r
+       MOVE    C,T.SPDL+1(TB)\r
+       MOVEM   D,S.DEV(C)\r
+]\r
+       CAIE    D,(SIXBIT /INT/); INTERNAL?\r
+       JRST    CHNET           ; NO, MAYBE NET\r
+       SKIPN   T.XT+1(TB)      ; WAS FCN SUPPLIED?\r
+       JRST    TFA\r
+\r
+; FALLS TROUGH IF SKIP\r
+\r
+\f\r
+\r
+; NOW BUILD THE CHANNEL\r
+\r
+ARGSOK:        MOVEI   A,CHANLNT       ; GET LENGTH\r
+       PUSHJ   P,GIBLOK        ; GET A BLOCK OF STUFF\r
+       ADD     B,[4,,4]        ; HIDE THE TTY BUFFER SLOT\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,B\r
+       HRLI    C,PROCHN        ; POINT TO PROTOTYPE\r
+       HRRI    C,(B)           ; AND NEW ONE\r
+       BLT     C,CHANLN-5(B)   ; CLOBBER\r
+       MOVSI   C,TLIST         ; TO GIVE HIM A CLEAN LIST OF SCRIPT CHANS\r
+       MOVEM   C,SCRPTO-1(B)\r
+\r
+; NOW BLT IN STUFF FROM THE STACK\r
+\r
+       MOVSI   C,T.DIR(TB)     ; DIRECTION\r
+       HRRI    C,DIRECT-1(B)\r
+       BLT     C,SNAME(B)\r
+       MOVEI   C,RNAME1-1(B)   ; NOW "REAL" SLOTS\r
+       HRLI    C,T.NM1(TB)\r
+       BLT     C,RSNAME(B)\r
+       POPJ    P,\r
+\r
+; HERE TO VALIDIFY ARGUMENTS FOR A NET OPEN\r
+\r
+CHNET: CAIE    D,(SIXBIT /NET/)        ; IS IT NET\r
+IFN ITS,       JRST    MAKCH1\r
+IFE ITS,[\r
+       JRST    ARGSOK\r
+]\r
+       MOVSI   D,TFIX          ; FOR TYPES\r
+       MOVEI   B,T.NM1(TB)     ; MAKE SURE ALL ARE FIXED\r
+       PUSHJ   P,CHFIX\r
+       MOVEI   B,T.NM2(TB)\r
+       PUSHJ   P,CHFIX\r
+       MOVEI   B,T.SNM(TB)\r
+       LSH     A,-1            ; SKIP DEV FLAG\r
+       PUSHJ   P,CHFIX\r
+       JRST    ARGSOK\r
+\r
+MAKCH1:        TRNN    A,MSTNET        ; CANT HAVE SEEN A FIX\r
+       JRST    ARGSOK\r
+       JRST    WRONGT\r
+\r
+IFN ITS,[\r
+CHFIX: TRNE    A,N1SET         ; SKIP IF NOT SPECIFIED\r
+       JRST    CHFIX1\r
+]\r
+       SETOM   1(B)            ; SET TO -1\r
+       SETOM   S.NM1(C)\r
+       MOVEM   D,(B)           ; CORRECT TYPE\r
+IFE ITS,CHFIX:\r
+       GETYP   0,(B)\r
+       CAIE    0,TFIX\r
+       JRST    PARSQ\r
+CHFIX1:        ADDI    C,1             ; POINT TO NEXT FIELD\r
+       LSH     A,-1            ; AND NEXT FLAG\r
+       POPJ    P,\r
+PARSQ: CAIE    0,TCHSTR\r
+       JRST    WRONGT\r
+IFE ITS,       POPJ    P,\r
+IFN ITS,[\r
+       PUSH    P,A\r
+       PUSH    P,C\r
+       PUSH    TP,(B)\r
+       PUSH    TP,1(B)\r
+       SUBI    B,(TB)\r
+       PUSH    P,B\r
+       MCALL   1,PARSE\r
+       GETYP   0,A\r
+       CAIE    0,TFIX\r
+       JRST    WRONGT\r
+       POP     P,C\r
+       ADDI    C,(TB)\r
+       MOVEM   A,(C)\r
+       MOVEM   B,1(C)\r
+       POP     P,C\r
+       POP     P,A\r
+       POPJ    P,\r
+]\r
+\f\r
+\r
+; SUBROUTINE TO CHECK VALIDITY OF MODE AND SAVE A CODE\r
+\r
+CHMODE:        PUSHJ   P,CHMOD         ; DO IT\r
+       MOVE    C,T.SPDL+1(TB)\r
+       HRRZM   A,S.DIR(C)\r
+       POPJ    P,\r
+\r
+CHMOD: PUSHJ   P,STRTO6        ; TO SIXBIT\r
+       POP     P,B             ; VALUE ENDSUP ON STACK, RESTORE IT\r
+\r
+       CAME    B,[SIXBIT /PRINTO/]     ; KLUDGE TO MAKE PRINTO AS PRINTB\r
+       JRST    .+3\r
+       MOVEI   A,3             ; CODE FOR PRINTB\r
+       POPJ    P,\r
+\r
+       MOVSI   A,-NMODES       ; SCAN TO SEE IF LEGAL MODE\r
+       CAME    B,MODES(A)\r
+       AOBJN   A,.-1\r
+       JUMPGE  A,WRONGD        ; ILLEGAL MODE NAME\r
+       POPJ    P,\r
+\f\r
+IFN ITS,[\r
+; RGPARS -- PARSE THE STRINGS COMPRISING FILE NAMES INTO STANDARD ITS GOODIES\r
+\r
+RGPRS: MOVEI   0,NOSTOR        ; DONT STORE STRINGS IF ENTER HERE\r
+\r
+RGPARS:        HRLM    0,(P)           ; LH IS FLAGS FOR THIS PROG\r
+       MOVSI   E,-4            ; FIELDS TO FILL\r
+\r
+RPARGL:        GETYP   0,(AB)          ; GET TYPE\r
+       CAIE    0,TCHSTR        ; STRING?\r
+       JRST    ARGCLB          ; NO, JUST CLOBBER IT IN RAW\r
+       JUMPGE  E,CPOPJ         ; DON'T DO ANY MORE\r
+       PUSH    TP,(AB)         ; GET AN ARG\r
+       PUSH    TP,1(AB)\r
+\r
+FPARS: PUSH    TP,-1(TP)       ; ANOTHER COPY\r
+       PUSH    TP,-1(TP)\r
+       PUSHJ   P,FLSSP         ; NO LEADING SPACES\r
+       MOVEI   A,0             ; WILL HOLD SIXBIT\r
+       MOVEI   B,6             ; CHARS PER 6BIT WORD\r
+       MOVE    C,[440600,,A]   ; BYTE POINTER INTO A\r
+\r
+FPARSL:        HRRZ    0,-1(TP)        ; GET COUNT\r
+       JUMPE   0,PARSD         ; DONE\r
+       SOS     -1(TP)          ; COUNT\r
+       ILDB    0,(TP)          ; CHAR TO 0\r
+\r
+       CAIE    0,"\11            ; FILE NAME QUOTE?\r
+       JRST    NOCNTQ\r
+       HRRZ    0,-1(TP)\r
+       JUMPE   0,PARSD\r
+       SOS     -1(TP)\r
+       ILDB    0,(TP)          ; USE THIS\r
+       JRST    GOTCNQ\r
+\r
+NOCNTQ:        CAIG    0,40            ; SPACE?\r
+       JRST    NDFLD           ; YES, TERMINATE THIS FIELD\r
+       CAIN    0,":            ; DEVICE ENDED?\r
+       JRST    GOTDEV\r
+       CAIN    0,";            ; SNAME ENDED\r
+       JRST    GOTSNM\r
+\r
+GOTCNQ:        PUSHJ   P,A0TO6         ; CONVERT TO 6BIT AND CHECK\r
+\r
+       JUMPE   B,FPARSL        ; IGNORE IF AREADY HAVE 6\r
+       IDPB    0,C\r
+       SOJA    B,FPARSL\r
+\r
+; HERE IF SPACE ENCOUNTERED\r
+\r
+NDFLD: MOVEI   D,(E)           ; COPY GOODIE\r
+       PUSHJ   P,FLSSP         ; FLUSH REDUNDANT SPACES\r
+       JUMPE   0,PARSD         ; NO CHARS LEFT\r
+\r
+NFL0:  PUSH    P,A             ; SAVE SIXBIT WORD\r
+       PUSHJ   P,6TOCHS        ; CONVERT TO STRING\r
+       HRRZ    0,-1(TP)        ; RESTORE CHAR COUNT\r
+\r
+NFL2:  MOVEI   C,(D)           ; COPY REL PNTR\r
+       SKIPGE  -1(P)           ; SKIP IF STRINGS TO BE STORED\r
+       JRST    NFL3\r
+       ASH     D,1             ; TIMES 2\r
+       ADDI    D,T.NM1(TB)\r
+       MOVEM   A,(D)           ; STORE\r
+       MOVEM   B,1(D)\r
+NFL3:  MOVSI   A,N1SET         ; FLAG IT\r
+       LSH     A,(C)\r
+       IORM    A,-1(P)         ; AND CLOBBER\r
+       MOVE    D,T.SPDL+1(TB)  ; GET P BASE\r
+       POP     P,@SIXTBL(C)    ; AND STORE SIXBIT OF IT\r
+\r
+       POP     TP,-2(TP)       ; MAKE NEW STRING POINTER\r
+       POP     TP,-2(TP)\r
+       JUMPE   0,.+3           ; SKIP IF NO MORE CHARS\r
+       AOBJN   E,FPARS         ; MORE TO PARSE?\r
+CPOPJ: POPJ    P,              ; RETURN, ALL DONE\r
+\r
+       SUB     TP,[2,,2]       ; FLUSH OLD STRING\r
+       ADD     E,[1,,1]\r
+       ADD     AB,[2,,2]       ; BUMP ARG\r
+       JUMPL   AB,RPARGL       ; AND GO ON\r
+CPOPJ1:        AOS     A,(P)           ; PREPARE TO WIN\r
+       HLRZS   A\r
+       POPJ    P,\r
+\r
+\f\r
+\r
+; HERE IF STRING HAS ENDED\r
+\r
+PARSD: PUSH    P,A             ; SAVE 6 BIT\r
+       MOVE    A,-3(TP)        ; CAN USE ARG STRING\r
+       MOVE    B,-2(TP)\r
+       MOVEI   D,(E)\r
+       JRST    NFL2            ; AND CONTINUE\r
+\r
+; HERE IF JUST READ DEV\r
+\r
+GOTDEV:        MOVEI   D,2             ; CODE FOR DEVICE\r
+       JRST    GOTFLD          ; GOT A FIELD\r
+\r
+; HERE IF  JUST READ SNAME\r
+\r
+GOTSNM:        MOVEI   D,3\r
+GOTFLD:        PUSHJ   P,FLSSP\r
+       SOJA    E,NFL0\r
+\r
+\r
+; HERE FOR NON STRING ARG ENCOUNTERED\r
+\r
+ARGCLB:        SKIPGE  (P)             ; IF NOT STORING, CONSIDER THIS THE END\r
+\r
+       POPJ    P,\r
+       MOVE    C,T.SPDL+1(TB)  ; GET P-BASE\r
+       HLRZ    A,S.DEV(C)      ; GET DEVICE\r
+       CAIE    A,(SIXBIT /INT/)        ; IS IT THE INTERNAL DEVICE\r
+       JRST    TRYNET          ; NO, COUD BE NET\r
+       MOVE    A,0             ; OFFNEDING TYPE TO A\r
+       PUSHJ   P,APLQ          ; IS IT APPLICABLE\r
+       JRST    NAPT            ; NO, LOSE\r
+       PMOVEM  (AB),T.XT(TB)\r
+       ADD     AB,[2,,2]       ; MUST BE LAST ARG\r
+       JUMPL   AB,TMA\r
+       JRST    CPOPJ1          ; ELSE SUCCESSFUL RETURN\r
+TRYNET:        CAIE    0,TFIX          ; FOR NET DEV, ARGS MUST BE FIX\r
+       JRST    WRONGT          ; TREAT AS WRONG TYPE\r
+       MOVSI   A,MSTNET        ; BETTER BE NET EVENTUALLY\r
+       IORM    A,(P)           ; STORE FLAGS\r
+       MOVSI   A,TFIX\r
+       MOVE    B,1(AB)         ; GET NUMBER\r
+       MOVEI   0,(E)           ; MAKE SURE NOT DEVICE\r
+       CAIN    0,2\r
+       JRST    WRONGT\r
+       PUSH    P,B             ; SAVE NUMBER\r
+       MOVEI   D,(E)           ; SET FOR TABLE OFFSETS\r
+       MOVEI   0,0\r
+       ADD     TP,[4,,4]\r
+       JRST    NFL2            ; GO CLOBBER IT AWAY\r
+]\r
+\f\r
+\r
+; ROUTINE TO FLUSH LEADING SPACES FROM A FIELD\r
+\r
+FLSSP: HRRZ    0,-1(TP)        ; GET CHR COUNNT\r
+       JUMPE   0,CPOPJ         ; FINISHED STRING\r
+FLSS1: MOVE    B,(TP)          ; GET BYTR\r
+       ILDB    C,B             ; GETCHAR\r
+       CAILE   C,40\r
+       JRST    FLSS2\r
+       MOVEM   B,(TP)          ; UPDATE BYTE POINTER\r
+       SOJN    0,FLSS1\r
+\r
+FLSS2: HRRM    0,-1(TP)        ; UPDATE STRING\r
+       POPJ    P,\r
+\r
+IFN ITS,[\r
+;TABLE FOR STFUFFING SIXBITS AWAY\r
+\r
+SIXTBL:        S.NM1(D)\r
+       S.NM2(D)\r
+       S.DEV(D)\r
+       S.SNM(D)\r
+       S.X1(D)\r
+]\r
+\r
+RDTBL: RDEVIC(B)\r
+       RNAME1(B)\r
+       RNAME2(B)\r
+       RSNAME(B)\r
+\r
+\r
+\f\r
+IFE ITS,[\r
+\r
+; TENEX VERSION OF FILE NAME PARSER (ONLY ACCEPT ARGS IN SINGLE STRING)\r
+\r
+RGPRS: MOVEI   0,NOSTOR\r
+\r
+RGPARS:        HRLM    0,(P)           ; SAVE FOR STORE CHECKING\r
+       CAMGE   AB,[-7,,]       ; MULTI-STRING CASE POSSIBLE?\r
+       JRST    TN.MLT          ; YES, GO PROCESS\r
+RGPRSS:        GETYP   0,(AB)          ; CHECK ARG TYPE\r
+       CAIE    0,TCHSTR\r
+       JRST    WRONGT          ; FOR NOW ONLY STRING ARGS WIN\r
+       PUSH    TP,(AB)\r
+       PUSH    TP,1(AB)\r
+       PUSHJ   P,FLSSP         ; FLUSH LEADING SPACES\r
+       PUSHJ   P,RGPRS1\r
+       ADD     AB,[2,,2]\r
+CHKLST:        JUMPGE  AB,CPOPJ1\r
+       SKIPGE  (P)             ; IF FROM OPEN, ALLOW ONE MORE\r
+       POPJ    P,\r
+       PMOVEM  (AB),T.XT(TB)\r
+       ADD     AB,[2,,2]\r
+       JUMPL   AB,TMA\r
+CPOPJ1:        AOS     (P)\r
+       POPJ    P,\r
+\r
+RGPRS1:        PUSH    P,[0]           ; ALLOW A DEVICE SPEC\r
+TN.SNM:        MOVE    A,(TP)\r
+       HRRZ    0,-1(TP)\r
+       JUMPE   0,RPDONE\r
+       ILDB    A,A\r
+       CAIE    A,"<            ; START "DIRECTORY" ?\r
+       JRST    TN.N1           ; NO LOOK FOR NAME1\r
+       SETOM   (P)             ; DEV NOT ALLOWED\r
+       IBP     (TP)            ; SKIP CHAR\r
+       SOS     -1(TP)\r
+       PUSHJ   P,TN.CNT        ; COUNT CHARS TO ">"\r
+       JUMPE   B,ILLNAM        ; RAN OUT\r
+       CAIE    A,">            ; SKIP IF WINS\r
+       JRST    ILLNAM\r
+       PUSHJ   P,TN.CPS        ; COPY TO NEW STRING\r
+       MOVEM   A,T.SNM(TB)\r
+       MOVEM   B,T.SNM+1(TB)\r
+\r
+TN.N1: PUSHJ   P,TN.CNT\r
+       JUMPE   B,RPDONE\r
+       CAIE    A,":            ; GOT A DEVICE\r
+       JRST    TN.N11\r
+       SKIPE   (P)\r
+       JRST    ILLNAM\r
+       SETOM   (P)\r
+       PUSHJ   P,TN.CPS\r
+       MOVEM   A,T.DEV(TB)\r
+       MOVEM   B,T.DEV+1(TB)\r
+       JRST    TN.SNM          ; NOW LOOK FOR SNAME\r
+\r
+TN.N11:        CAIE    A,">\r
+       CAIN    A,"<\r
+       JRST    ILLNAM\r
+       MOVEM   A,(P)           ; SAVE END CHAR\r
+       PUSHJ   P,TN.CPS        ; GEN STRING\r
+       MOVEM   A,T.NM1(TB)\r
+       MOVEM   B,T.NM1+1(TB)\r
+\r
+TN.N2: SKIPN   A,(P)           ; GET CHAR BACK\r
+       JRST    RPDONE\r
+       CAIN    A,";            ; START VERSION?\r
+       JRST    .+3\r
+       CAIE    A,".            ; START NAME2?\r
+       JRST    ILLNAM          ; I GIVE UP!!!\r
+       HRRZ    B,-1(TP)        ; GET RMAINS OF STRING\r
+       PUSHJ   P,TN.CPS        ; AND COPY IT\r
+       MOVEM   A,T.NM2(TB)\r
+       MOVEM   B,T.NM2+1(TB)\r
+RPDONE:        SUB     P,[1,,1]        ; FLUSH TEMP\r
+       SUB     TP,[2,,2]\r
+CPOPJ: POPJ    P,\r
+\r
+TN.CNT:        HRRZ    0,-1(TP)        ; CHAR COUNT\r
+       MOVE    C,(TP)          ; BPTR\r
+       MOVEI   B,0             ; INIT COUNT TO 0\r
+\r
+TN.CN1:        MOVEI   A,0             ; IN CASE RUN OUT\r
+       SOJL    0,CPOPJ         ; RUN OUT?\r
+       ILDB    A,C             ; TRY ONE\r
+       CAIE    A,"\16            ; TNEX FILE QUOTE?\r
+       JRST    TN.CN2\r
+       SOJL    0,CPOPJ\r
+       IBP     C               ; SKIP QUOTED CHAT\r
+       ADDI    B,2\r
+       JRST    TN.CN1\r
+\r
+TN.CN2:        CAIE    A,"<\r
+       CAIN    A,">\r
+       POPJ    P,\r
+\r
+       CAIE    A,".\r
+       CAIN    A,";\r
+       POPJ    P,\r
+       CAIN    A,":\r
+       POPJ    P,\r
+       AOJA    B,TN.CN1\r
+\r
+TN.CPS:        PUSH    P,B             ; # OF CHARS\r
+       MOVEI   A,4(B)          ; ADD 4 TO B IN A\r
+       IDIVI   A,5\r
+       PUSHJ   P,IBLOCK        ; GET BLOCK OF WORDS FOR STRING\r
+\r
+       POP     P,C             ; CHAR COUNT BACK\r
+       HRLI    B,440700\r
+       MOVSI   A,TCHSTR\r
+       HRRI    A,(C)           ; CHAR STRING\r
+       MOVE    D,B             ; COPY BYTER\r
+\r
+       JUMPE   C,CPOPJ\r
+       ILDB    0,(TP)          ; GET CHAR\r
+       IDPB    0,D             ; AND STROE\r
+       SOJG    C,.-2\r
+\r
+       MOVNI   C,(A)           ; - LENGTH TO C\r
+       ADDB    C,-1(TP)        ; DECREMENT WORDS COUNT\r
+       TRNN    C,-1            ; SKIP IF EMPTY\r
+       POPJ    P,\r
+       IBP     (TP)\r
+       SOS     -1(TP)          ; ELSE FLUSH TERMINATOR\r
+       POPJ    P,\r
+\r
+ILLNAM:        PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE ILLEGAL-TENEX-FILE-NAME\r
+       JRST    CALER1\r
+\r
+TN.MLT:        MOVEI   A,(AB)\r
+       HRLI    A,-10\r
+\r
+TN.ML1:        GETYP   0,(A)\r
+       CAIE    0,TFIX\r
+       CAIN    0,TCHSTR\r
+       JRST    .+2\r
+       JRST    RGPRSS          ; ASSUME SINGLE STRING \r
+       ADD     A,[2,,2]\r
+       JUMPL   A,TN.ML1\r
+\r
+       MOVEI   A,T.NM1(TB)\r
+       HRLI    A,(AB)\r
+       BLT     A,T.SNM+1(TB)   ; BLT 'EM IN\r
+       ADD     AB,[10,,10]     ; SKIP THESE GUYS\r
+       JRST    CHKLST\r
+\r
+]\r
+\f\r
+\r
+; ROUTINE TO OPEN A CHANNEL FOR ANY DEVICE.  NAMES ARE ASSUMED TO ALREADY\r
+; BE ON BOTH TP STACK AND P STACK\r
+\r
+OPNCH: MOVE    C,T.SPDL+1(TB)  ; GET PDL BASE\r
+       HRRZ    A,S.DIR(C)\r
+       ANDI    A,1             ; JUST WANT I AND O\r
+       HRLM    A,S.DEV(C)\r
+;      .TRANS  S.DEV(C)        ; UNDO ANY TRANSLATIONS\r
+;      JRST    TRLOST          ; COMPLAIN\r
+\r
+       HRRZ    A,S.DEV(C)      ; GET SIXBIT DEVICE CODE\r
+       MOVEI   E,(A)           ; COPY TO E\r
+       ANDI    E,777700        ; WITHOUT LAST\r
+       MOVEI   D,(E)           ; AND D\r
+       ANDI    D,770000        ; WITH JUST LETTER\r
+       MOVSI   B,-NDEVS        ; AOBJN COUNTER\r
+\r
+DEVLP: HRRZ    0,DEVS(B)       ; GET ONE\r
+       CAIN    0,(A)           ; FULL DEV?\r
+       JRST    DISPA\r
+       CAIN    0,(D)           ; ONE LETTER\r
+       JRST    CH2DIG\r
+       CAIN    0,(E)           ; 2 LTTERS\r
+       JRST    CH1DIG\r
+NXTDEV:        AOBJN   B,DEVLP         ; LOOP THRU\r
+\r
+IFN ITS,[\r
+OUSR:  HRRZ    A,S.DIR(C)      ; BLOCK OR UNIT?\r
+       TRNE    A,2             ; SKIP IF UNIT\r
+       JRST    ODSK\r
+       PUSHJ   P,OPEN1         ; OPEN IT\r
+       PUSHJ   P,FIXREA        ; AND READCHST IT\r
+       MOVE    B,T.CHAN+1(TB)  ; RESTORE CHANNEL\r
+       MOVE    0,[PUSHJ P,DOIOT]       ; GET AN IOINS\r
+       MOVEM   0,IOINS(B)\r
+       MOVE    C,T.SPDL+1(TB)\r
+       HRRZ    A,S.DIR(C)\r
+       TRNN    A,1\r
+       JRST    EOFMAK\r
+       MOVEI   0,80.\r
+       MOVEM   0,LINLN(B)\r
+       JRST    OPNWIN\r
+\r
+OSTY:  HLRZ    A,S.DEV(C)\r
+       IORI    A,10            ; THE DONT LOSE BIT (DONT HANG ON INPUT DO ON OUTPUT)\r
+       HRLM    A,S.DEV(C)\r
+       JRST    OUSR\r
+]\r
+IFE ITS,[\r
+       PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE NO-SUCH-DEVICE?\r
+       JRST    CALER1\r
+]\r
+\r
+; MAKE SURE DIGITS EXIST\r
+\r
+CH2DIG:        LDB     0,[60600,,A]\r
+       CAIG    0,'9            ; CHECK DIGITNESS\r
+       CAIGE   0,'0\r
+       JRST    NXTDEV          ; LOSER\r
+\r
+CH1DIG:        LDB     0,[600,,A]      ; LAST CHAR\r
+       CAIG    0,'9\r
+       CAIGE   0,'0\r
+       JRST    NXTDEV\r
+\r
+; HERE TO DISPATCH IF SUCCESSFUL\r
+\r
+DISPA: HLRZ    B,DEVS(B)\r
+IFN ITS,[\r
+       HRRZ    A,S.DIR(C)      ; GET DIR OF OPEN\r
+       CAIN    A,5             ; IS IT DISPLAY\r
+       CAIN    B,ODIS          ; BETTER BE OPENING DISPLAY\r
+       JRST    (B)             ; GO TO HANDLER\r
+       JRST    WRONGD\r
+]\r
+IFE ITS,       JRST    (B)\r
+\r
+\f\r
+IFN ITS,[\r
+\r
+; DISK DEVICE OPNER COME HERE\r
+\r
+ODSK:  MOVE    A,S.SNM(C)      ; GET SNAME\r
+       .SUSET  [.SSNAM,,A]     ; CLOBBER IT\r
+       PUSHJ   P,OPEN0         ; DO REAL LIVE OPEN\r
+]\r
+IFE ITS,[\r
+\r
+; TENEX DISK FILE OPENER\r
+\r
+ODSK:  MOVE    B,T.CHAN+1(TB)  ; GET CHANNEL\r
+       PUSHJ   P,STSTK         ; EXPAND STRING ONTO STACK (E POINTS TO OLD P)\r
+       MOVE    A,DIRECT-1(B)\r
+       MOVE    B,DIRECT(B)\r
+       PUSHJ   P,STRTO6        ; GET DIR NAME\r
+       POP     P,C\r
+       MOVE    D,T.SPDL+1(TB)\r
+       HRRZ    D,S.DIR(D)\r
+       CAMN    C,[SIXBIT /PRINTO/]\r
+       IORI    D,100           ; TURN ON BIT TO SAY USE OLD FILE\r
+       MOVSI   A,101           ; START SETTING UP BITS EXTRA BIT FOR MSB\r
+       TRNE    D,1             ; SKIP IF INPUT\r
+       TRNE    D,100           ; WITE OVER?\r
+       TLOA    A,100000        ; FORCE NEW VERSION\r
+       TLO     A,400000        ; FORCE OLD\r
+       HRROI   B,1(E)          ; POIT TO STRING\r
+       GTJFN\r
+       TDZA    0,0             ; SAVE FACT OF NO SKIP\r
+       MOVEI   0,1             ; INDICATE SKIPPED\r
+       MOVE    P,E             ; RESTORE PSTACK\r
+       JUMPE   0,GTJLOS        ; FIND OUT WHAT HAPPENED\r
+\r
+       MOVE    B,T.CHAN+1(TB)  ; GET CHANNEL\r
+       HRRZM   A,CHANNO(B)     ; SAVE IT\r
+       ANDI    A,-1            ; READ Y TO DO OPEN\r
+       MOVSI   B,440000        ; USE 36. BIT BYES\r
+       HRRI    B,200000        ; ASSUME READ\r
+       TRNE    D,1             ; SKIP IF READ\r
+       HRRI    B,300000        ; WRITE BIT\r
+       HRRZ    0,FSAV(TB)              ; SEE IF REF DATE HACK\r
+       CAIN    0,NFOPEN\r
+       TRO     B,400           ; SET DON'T MUNG REF DATE BIT\r
+       OPENF\r
+       JRST    OPFLOS\r
+       MOVEI   0,C.OPN+C.READ\r
+       TRNE    D,1             ; SKIP FOR READ\r
+       MOVEI   0,C.OPN+C.PRIN\r
+       MOVE    B,T.CHAN+1(TB)\r
+       HRRM    0,-4(B)         ; MUNG THOSE BITS\r
+       ASH     A,1             ; POINT TO SLOT\r
+       ADDI    A,CHNL0(TVP)    ; TO REAL SLOT\r
+       MOVEM   B,1(A)          ; SAVE CHANNEL\r
+       PUSHJ   P,TMTNXS        ; GET STRING FROM TENEX\r
+       MOVE    B,CHANNO(B)     ; JFN TO A\r
+       HRROI   A,1(E)          ; BASE OF STRING\r
+       MOVE    C,[111111,,140001]      ; WEIRD CONTROL BITS\r
+       JFNS                    ; GET STRING\r
+       MOVEI   B,1(E)          ; POINT TO START OF STRING\r
+       SUBM    P,E             ; RELATIVIZE E\r
+       PUSHJ   P,TNXSTR        ; MAKE INTO A STRING\r
+       SUB     P,E             ; BACK TO NORMAL\r
+       PUSH    TP,A\r
+       PUSH    TP,B\r
+       PUSHJ   P,RGPRS1        ; PARSE INTO FIELDS\r
+       MOVE    B,T.CHAN+1(TB)\r
+       MOVEI   C,RNAME1-1(B)\r
+       HRLI    C,T.NM1(TB)\r
+       BLT     C,RSNAME(B)\r
+       JRST    OPBASC\r
+OPFLOS:        MOVEI   C,(A)           ; SAVE ERROR CODE\r
+       MOVE    B,T.CHAN+1(TB)\r
+       HRRZ    A,CHANNO(B)     ; JFN BACK TO A\r
+       RLJFN                   ; TRY TO RELEASE IT\r
+       JFCL\r
+       MOVEI   A,(C)           ; ERROR CODE BACK TO A\r
+\r
+GTJLOS:        PUSHJ   P,TGFALS        ; GET A FALSE WITH REASON\r
+       JRST    OPNRET\r
+\r
+STSTK: PUSH    TP,$TCHAN\r
+       PUSH    TP,B\r
+       MOVEI   A,4+5           ; COUNT CHARS NEEDED (NEED LAST 0 BYTE)\r
+       MOVE    B,(TP)\r
+       ADD     A,RDEVIC-1(B)\r
+       ADD     A,RNAME1-1(B)\r
+       ADD     A,RNAME2-1(B)\r
+       ADD     A,RSNAME-1(B)\r
+       ANDI    A,-1            ; TO 18 BITS\r
+       IDIVI   A,5             ; TO WORDS NEEDED\r
+       POP     P,C             ; SAVE RET ADDR\r
+       MOVE    E,P             ; SAVE POINTER\r
+       PUSH    P,[0]           ; ALOCATE SLOTS\r
+       SOJG    A,.-1\r
+       PUSH    P,C             ; RET ADDR BACK\r
+       INTGO                   ; IN CASE OVERFLEW\r
+       MOVE    B,(TP)          ; IN CASE GC'D\r
+       MOVE    D,[440700,,1(E)]        ; BYTE POINTER TO IT\r
+       MOVEI   A,RDEVIC-1(B)\r
+       PUSHJ   P,MOVSTR        ; FLUSH IT ON\r
+       MOVEI   A,":\r
+       IDPB    A,D\r
+       HRRZ    A,RSNAME-1(B)   ; ANY SNAME AT ALL?\r
+       JUMPE   A,ST.NM1        ; NOPE, CANT HACK WITH IT\r
+       MOVEI   A,"<\r
+       IDPB    A,D\r
+       MOVEI   A,RSNAME-1(B)\r
+       PUSHJ   P,MOVSTR        ; SNAME UP\r
+       MOVEI   A,">\r
+       IDPB    A,D\r
+       MOVEI   A,RNAME1-1(B)\r
+       PUSHJ   P,MOVSTR\r
+       MOVEI   A,".\r
+       IDPB    A,D\r
+ST.NM1:        MOVEI   A,RNAME2-1(B)\r
+       PUSHJ   P,MOVSTR\r
+       SUB     TP,[2,,2]\r
+       POPJ    P,\r
+\r
+MOVSTR:        HRRZ    0,(A)           ; CHAR COUNT\r
+       MOVE    A,1(A)          ; BYTE POINTER\r
+       SOJL    0,CPOPJ\r
+       ILDB    C,A             ; GET CHAR\r
+       IDPB    C,D             ; MUNG IT UP\r
+       JRST    .-3\r
+\r
+; MAKE A TENEX ERROR MESSAGE STRING\r
+\r
+TGFALS:        PUSH    P,A             ; SAVE ERROR CODE\r
+       PUSHJ   P,TMTNXS        ; STRING ON STACK\r
+       HRROI   A,1(E)          ; POINT TO SPACE\r
+       MOVE    B,(E)           ; ERROR CODE\r
+       HRLI    B,400000        ; FOR ME\r
+       MOVSI   C,-100.         ; MAX CHARS\r
+       ERSTR                   ; GET TENEX STRING\r
+       JRST    TGFLS1\r
+       JRST    TGFLS1\r
+\r
+       MOVEI   B,1(E)          ; A AND B BOUND STRING\r
+       SUBM    P,E             ; RELATIVIZE E\r
+       PUSHJ   P,TNXSTR        ; BUILD STRING\r
+       SUB     P,E             ; P BACK TO NORMAL\r
+TGFLS2:        SUB     P,[1,,1]        ; FLUSH ERROR CODE SLOT\r
+       MOVE    C,A\r
+       MOVE    D,B\r
+       PUSHJ   P,INCONS        ; BUILD LIST\r
+       MOVSI   A,TFALSE        ; MAKE IT FALSE\r
+       POPJ    P,\r
+\r
+TGFLS1:        MOVE    P,E             ; RESET STACK\r
+       MOVE    A,$TCHSTR\r
+       MOVE    B,CHQUOTE UNKNOWN PROBLEM IN I/O\r
+       JRST    TGFLS2\r
+\r
+]\r
+; OTHER BUFFERED DEVICES JOIN HERE\r
+\r
+OPDSK1:\r
+IFN ITS,[\r
+       PUSHJ   P,FIXREA        ; STORE THE "REAL" NAMES INTO THE CHANNEL\r
+]\r
+OPBASC:        MOVE    C,T.SPDL+1(TB)  ; C WAS CLOBBERED, GET IT BACK\r
+       HRRZ    A,S.DIR(C)      ; FIND OUT IF OPEN IS ASCII OR WORD\r
+       TRZN    A,2             ; SKIP IF BINARY\r
+       PUSHJ   P,OPASCI        ; DO IT FOR ASCII\r
+\r
+; NOW SET UP IO INSTRUCTION FOR CHANNEL\r
+\r
+MAKION:        MOVE    B,T.CHAN+1(TB)\r
+       MOVEI   C,GETCHR\r
+       JUMPE   A,MAKIO1        ; JUMP IF INPUT\r
+       MOVEI   C,PUTCHR        ; ELSE GET INPUT\r
+       MOVEI   0,80.           ; DEFAULT LINE LNTH\r
+       MOVEM   0,LINLN(B)\r
+       MOVSI   0,TFIX\r
+       MOVEM   0,LINLN-1(B)\r
+MAKIO1:\r
+       HRLI    C,(PUSHJ P,)\r
+       MOVEM   C,IOINS(B)      ; STORE IT\r
+       JUMPN   A,OPNWIN        ; GET AN EOF FORM FOR INPUT CHANNEL\r
+\r
+; HERE TO CONS UP <ERROR END-OF-FILE>\r
+\r
+EOFMAK:        MOVSI   C,TATOM\r
+       MOVE    D,EQUOTE END-OF-FILE\r
+       PUSHJ   P,INCONS\r
+       MOVEI   E,(B)\r
+       MOVSI   C,TATOM\r
+       MOVE    D,IMQUOTE ERROR\r
+       PUSHJ   P,ICONS\r
+       MOVE    D,T.CHAN+1(TB)  ; RESTORE CHANNEL\r
+       MOVSI   0,TFORM\r
+       MOVEM   0,EOFCND-1(D)\r
+       MOVEM   B,EOFCND(D)\r
+\r
+OPNWIN:        MOVEI   0,10.           ; SET UP RADIX\r
+       MOVSI   A,TCHAN         ; OPEN SUCCEEDED, RET CHANNEL\r
+       MOVE    B,T.CHAN+1(TB)\r
+       MOVEM   0,RADX(B)\r
+\r
+OPNRET:        MOVE    C,(P)           ; RET ADDR\r
+       SUB     P,[S.X3+2,,S.X3+2]\r
+       SUB     TP,[T.CHAN+2,,T.CHAN+2]\r
+       JRST    (C)\r
+\f\r
+\r
+; HERE TO CREATE CHARACTER BUFFERS FOR ASCII I/O\r
+\r
+OPASCI:        PUSH    P,A             ; CONTAINS MODE, SAVE IT\r
+       MOVEI   A,BUFLNT        ; GET SIZE  OF BUFFER\r
+       PUSHJ   P,IBLOCK        ; GET STORAGE\r
+       MOVSI   0,TWORD+.VECT.  ; SET UTYPE\r
+       MOVEM   0,BUFLNT(B)     ; AND STORE\r
+       MOVSI   A,TCHSTR\r
+       SKIPE   (P)             ; SKIP IF INPUT\r
+       JRST    OPASCO\r
+       MOVEI   D,BUFLNT(B)     ; REST BYTE POINTER\r
+OPASCA:        HRLI    D,440700\r
+       MOVE    B,T.CHAN+1(TB)  ; GET CHANNEL BACK\r
+       MOVEI   0,C.BUF\r
+       IORM    0,-4(B)         ; TURN ON BUFFER BIT\r
+       MOVEM   A,BUFSTR-1(B)\r
+       MOVEM   D,BUFSTR(B)     ; CLOBBER\r
+       POP     P,A\r
+       POPJ    P,\r
+\r
+OPASCO:        HRROI   C,777776\r
+       MOVEM   C,(B)           ; -1 THE BUFFER (LEAVE OFF LOW BIT)\r
+       MOVSI   C,(B)\r
+       HRRI    C,1(B)          ; BUILD BLT POINTER\r
+       BLT     C,BUFLNT-1(B)   ; ZAP\r
+       MOVEI   D,(B)           ; START MAKING STRING POINTER\r
+       HRRI    A,BUFLNT*5      ; SET UP CHAR COUNT\r
+       JRST    OPASCA\r
+\f\r
+\r
+; OPEN NON FILE ORIENTED DEVICES (NUL, PTR, PTP ETC.)\r
+\r
+ONUL:\r
+OPTP:\r
+OPTR:  PUSHJ   P,OPEN0         ; SET UP MODE AND OPEN\r
+       SETZM   S.NM1(C)        ; CLOBBER UNINTERESTING FIELDS\r
+       SETZM   S.NM2(C)\r
+       SETZM   S.SNM(C)\r
+       JRST    OPDSK1\r
+\r
+; OPEN DEVICES THAT IGNORE SNAME\r
+\r
+OUTN:  PUSHJ   P,OPEN0\r
+       SETZM   S.SNM(C)\r
+       JRST    OPDSK1\r
+\r
+; OPEN THE DISPLAY DEVICE\r
+\r
+ODIS:  MOVEI   B,T.DIR(TB)     ; GET CHANNEL\r
+       PUSHJ   P,CHRWRD        ; TO ASCII\r
+       JFCL\r
+       MOVE    E,B             ; DIR TO E\r
+       MOVE    B,T.CHAN+1(TB)  ; CHANNEL\r
+       MOVE    0,[PUSHJ P,DCHAR]       ; IOINS\r
+       CAIN    A,1\r
+       MOVEM   0,IOINS(B)\r
+       PUSHJ   P,DISOPN\r
+       JRST    DISLOS          ; LOSER\r
+\r
+       MOVE    D,T.CHAN+1(TB)  ; GET CHANNEL\r
+       MOVEI   0,C.OPN+C.PRIN\r
+       HRRM    0,-4(D)\r
+       MOVEM   A,DISINF-1(D)   ; AND STORE\r
+       MOVEM   B,DISINF(D)\r
+       SETZM   CHANNO(D)       ; NO REAL CHANNEL\r
+       MOVEI   0,DISLNL\r
+       MOVEM   0,LINLN(D)\r
+       MOVEI   0,DISPGL\r
+       MOVEM   0,PAGLN(D)\r
+       MOVEI   0,10.           ; SET RADIX\r
+       MOVEM   0,RADX(D)\r
+       JRST    SAVCHN          ; ADD TO CHANNEL LIST\r
+\f\r
+\r
+; INTERNAL CHANNEL OPENER\r
+\r
+OINT:  HRRZ    A,S.DIR(C)      ; CHECK DIR\r
+       CAIL    A,2             ; READ/PRINT?\r
+       JRST    WRONGD          ; NO, LOSE\r
+\r
+       MOVE    0,INTINS(A)     ; GET INS\r
+       MOVE    D,T.CHAN+1(TB)  ; AND CHANNEL\r
+       MOVEM   0,IOINS(D)      ; AND CLOBBER\r
+       MOVEI   0,C.OPN+C.READ\r
+       TRNE    A,1\r
+       MOVEI   0,C.OPN+C.PRIN\r
+       HRRM    0,-4(D)\r
+       SETOM   STATUS(D)       ; MAKE SURE NOT AA TTY\r
+       PMOVEM  T.XT(TB),INTFCN-1(D)\r
+\r
+; HERE TO SAVE PSEUDO CHANNELS\r
+\r
+SAVCHN:        HRRZ    E,CHNL0+1(TVP)  ; POINT TO CURRENT LIST\r
+       MOVSI   C,TCHAN\r
+       PUSHJ   P,ICONS         ; CONS IT ON\r
+       HRRZM   B,CHNL0+1(TVP)\r
+       JRST    OPNWIN\r
+\r
+; INT DEVICE I/O INS\r
+\r
+INTINS:        PUSHJ   P,GTINTC\r
+       PUSHJ   P,PTINTC\r
+\f\r
+\r
+; HERE TO OPEN THE NET DEVICE (I.E. THE ARPA NET)\r
+\r
+IFN ITS,[\r
+ONET:  HRRZ    A,S.DIR(C)      ; DIRECTION CODE\r
+       CAILE   A,1             ; ASCII ?\r
+       IORI    A,4             ; TURN ON IMAGE BIT\r
+       SKIPGE  S.NM1(C)        ; NAME1 I.E. LOCAL HOST GIVEN\r
+       IORI    A,10            ; NO, WE WILL LET ITS GIVE US ONE\r
+       SKIPGE  S.NM2(C)        ; NORMAL OR "LISTEN"\r
+       IORI    A,20            ; TURN ON LISTEN BIT\r
+       MOVEI   0,7             ; DEFAULT BYTE SIZE\r
+       TRNE    A,2             ; UNLESS\r
+       MOVEI   0,36.           ; IMAGE WHICH IS 36\r
+       SKIPN   T.XT(TB)        ; BYTE SIZE GIVEN?\r
+       MOVEM   0,S.X1(C)       ; NO, STORE DEFAULT\r
+       SKIPG   D,S.X1(C)       ; BYTE SIZE REASONABLE?\r
+       JRST    RBYTSZ          ; NO <0, COMPLAIN\r
+       TRNE    A,2             ; SKIP TO CHECK ASCII\r
+       JRST    ONET2           ; CHECK IMAGE\r
+       CAIN    D,7             ; 7-BIT WINS\r
+       JRST    ONET1\r
+       CAIE    D,44            ; 36-BIT INDICATES BLOCK ASCII MODE\r
+       JRST    .+3\r
+       IORI    A,2             ; SET BLOCK FLAG\r
+       JRST    ONET1\r
+       IORI    A,40            ; USE 8-BIT MODE\r
+       CAIN    D,10            ; IS IT RIGHT\r
+       JRST    ONET1           ; YES\r
+]\r
+\r
+RBYTSZ:        PUSH    TP,$TATOM       ; CALL ERROR\r
+       PUSH    TP,EQUOTE BYTE-SIZE-BAD\r
+       JRST    CALER1\r
+\r
+IFN ITS,[\r
+ONET2: CAILE   D,36.           ; IMAGE SIZE REASONABLE?\r
+       JRST    RBYTSZ          ; NO\r
+       CAIN    D,36.           ; NORMAL\r
+       JRST    ONET1           ; YES, DONT SET FIELD\r
+\r
+       ASH     D,9.            ; POSITION FOR FIELD\r
+       IORI    A,40(D)         ; SET IT AND ITS BIT\r
+\r
+ONET1: HRLM    A,S.DEV(C)      ; CLOBBER OPEN BLOCK\r
+       MOVE    E,A             ; SAVE BLOCK MODE INFO\r
+       PUSHJ   P,OPEN1         ; DO THE OPEN\r
+       PUSH    P,E\r
+\r
+; CLOBBER REAL SLOTS FOR THE OPEN\r
+\r
+       MOVEI   A,3             ; GET STATE VECTOR\r
+       PUSHJ   P,IBLOCK\r
+       MOVSI   A,TUVEC\r
+       MOVE    D,T.CHAN+1(TB)\r
+       MOVEM   A,BUFRIN-1(D)\r
+       MOVEM   B,BUFRIN(D)\r
+       MOVSI   A,TFIX+.VECT.   ; SET U TYPE\r
+       MOVEM   A,3(B)\r
+       MOVE    C,T.SPDL+1(TB)\r
+       MOVE    B,T.CHAN+1(TB)\r
+\r
+       PUSHJ   P,INETST                ; GET STATE\r
+\r
+       POP     P,A             ; IS THIS BLOCK MODE\r
+       MOVEI   0,80.           ; POSSIBLE LINE LENGTH\r
+       TRNE    A,1             ; SKIP IF INPUT\r
+       MOVEM   0,LINLN(B)\r
+       TRNN    A,2             ; BLOCK MODE?\r
+       JRST    .+3\r
+       TRNN    A,4             ; ASCII MODE?\r
+       JRST    OPBASC  ; GO SETUP BLOCK ASCII\r
+       MOVE    0,[PUSHJ P,DOIOT]\r
+       MOVEM   0,IOINS(B)\r
+\r
+       JRST    OPNWIN\r
+\r
+; INTERNAL ROUTINE TO GET THE CURRENT STATE OF THE NETWROK CHANNEL\r
+\r
+INETST:        MOVE    A,S.NM1(C)\r
+       MOVEM   A,RNAME1(B)\r
+       MOVE    A,S.NM2(C)\r
+       MOVEM   A,RNAME2(B)\r
+       LDB     A,[1100,,S.SNM(C)]\r
+       MOVEM   A,RSNAME(B)\r
+\r
+       MOVE    E,BUFRIN(B)             ; GET STATE BLOCK\r
+INTST1:        HRRE    0,S.X1(C)\r
+       MOVEM   0,(E)\r
+       ADDI    C,1\r
+       AOBJN   E,INTST1\r
+\r
+       POPJ    P,\r
+\f\r
+\r
+; ACCEPT A CONNECTION\r
+\r
+MFUNCTION NETACC,SUBR\r
+\r
+       PUSHJ   P,ARGNET        ; CHECK THAT ARG IS AN OPEN NET CHANNEL\r
+       MOVE    A,CHANNO(B)     ; GET CHANNEL\r
+       LSH     A,23.           ; TO AC FIELD\r
+       IOR     A,[.NETACC]\r
+       XCT     A\r
+       JRST    IFALSE          ; RETURN FALSE\r
+NETRET:        MOVE    A,(AB)\r
+       MOVE    B,1(AB)\r
+       JRST    FINIS\r
+\r
+; FORCE SYSTEM NETWORK BUFFERS TO BE SENT\r
+\r
+MFUNCTION NETS,SUBR\r
+\r
+       PUSHJ   P,ARGNET\r
+       CAME    A,MODES+1\r
+       CAMN    A,MODES+3\r
+       SKIPA   A,CHANNO(B)     ; GET CHANNEL\r
+       JRST    WRONGD\r
+       LSH     A,23.\r
+       IOR     A,[.NETS]\r
+       XCT     A\r
+       JRST    NETRET\r
+\r
+; SUBR TO RETURN UPDATED NET STATE\r
+\r
+MFUNCTION NETSTATE,SUBR\r
+\r
+       PUSHJ   P,ARGNET        ; IS IT A NET CHANNEL\r
+       PUSHJ   P,INSTAT\r
+       JRST    FINIS\r
+\r
+; INTERNAL NETSTATE ROUTINE\r
+\r
+INSTAT:        MOVE    C,P             ; GET PDL BASE\r
+       MOVEI   0,S.X3          ; # OF SLOTS NEEDED\r
+       PUSH    P,[0]\r
+       SOJN    0,.-1\r
+\r
+       MOVEI   D,S.DEV(C)              ; SETUP FOR .RCHST\r
+       HRL     D,CHANNO(B)\r
+       .RCHST  D,              ; GET THE GOODS\r
+\r
+       PUSHJ   P,INETST        ; INTO VECTOR\r
+       SUB     P,[S.X3,,S.X3]\r
+       MOVE    B,BUFRIN(B)\r
+       MOVSI   A,TUVEC\r
+       POPJ    P,\r
+]\r
+; INTERNAL ROUTINE TO CHECK FOR CORRECT CHANNEL TYPE\r
+\r
+ARGNET:        ENTRY   1\r
+       GETYP   0,(AB)\r
+       CAIE    0,TCHAN\r
+       JRST    WTYP1\r
+       MOVE    B,1(AB)         ; GET CHANNEL\r
+       SKIPN   CHANNO(B)       ; OPEN?\r
+       JRST    CHNCLS\r
+       MOVE    A,RDEVIC-1(B)   ; GET DEV NAME\r
+       MOVE    B,RDEVIC(B)\r
+       PUSHJ   P,STRTO6\r
+       POP     P,A\r
+       CAME    A,[SIXBIT /NET   /]\r
+       JRST    NOTNET\r
+       MOVE    B,1(AB)\r
+       MOVE    A,DIRECT-1(B)   ; CHECK FOR A READ SOCKET\r
+       MOVE    B,DIRECT(B)\r
+       PUSHJ   P,STRTO6\r
+       MOVE    B,1(AB)         ; RESTORE CHANNEL\r
+       POP     P,A\r
+       POPJ    P,\r
+\f\r
+IFE ITS,[\r
+\r
+; TENEX NETWRK OPENING CODE\r
+\r
+ONET:  MOVE    B,T.CHAN+1(TB)  ; GET CHANNEL\r
+       MOVSI   C,100700\r
+       HRRI    C,1(P)\r
+       MOVE    E,P\r
+       PUSH    P,[ASCII /NET:/]        ; FOR STRINGS\r
+       GETYP   0,RNAME1-1(B)   ; CHECK TYPE\r
+       CAIE    0,TFIX          ; SKIP IF # SUPPLIED\r
+       JRST    ONET1\r
+       MOVE    0,RNAME1(B)     ; GET IT\r
+       PUSHJ   P,FIXSTK\r
+       JFCL\r
+       JRST    ONET2\r
+ONET1: CAIE    0,TCHSTR\r
+       JRST    WRONGT\r
+       HRRZ    0,RNAME1-1(B)\r
+       MOVE    B,RNAME1(B)\r
+       JUMPE   0,ONET2\r
+       ILDB    A,B\r
+       JSP     D,ONETCH\r
+       SOJA    0,.-3\r
+ONET2: MOVEI   A,".\r
+       JSP     D,ONETCH\r
+       MOVE    B,T.CHAN+1(TB)\r
+       GETYP   0,RNAME2-1(B)\r
+       CAIE    0,TFIX\r
+       JRST    ONET3\r
+       GETYP   0,RSNAME-1(B)\r
+       CAIE    0,TFIX\r
+       JRST    WRONGT\r
+       MOVE    0,RSNAME(B)\r
+       PUSHJ   P,FIXSTK\r
+       JRST    ONET4\r
+       MOVE    B,T.CHAN+1(TB)\r
+       MOVEI   A,"-\r
+       JSP     D,ONETCH\r
+       MOVE    0,RNAME2(B)\r
+       PUSHJ   P,FIXSTK\r
+       JRST    WRONGT\r
+       JRST    ONET4\r
+ONET3: CAIE    0,TCHSTR\r
+       JRST    WRONGT\r
+       HRRZ    0,RNAME2-1(B)\r
+       MOVE    B,RNAME2(B)\r
+       JUMPE   0,ONET4\r
+       ILDB    A,B\r
+       JSP     D,ONETCH\r
+       SOJA    0,.-3\r
+\r
+ONET4:\r
+ONET5: MOVE    B,T.CHAN+1(TB)\r
+       GETYP   0,RNAME2-1(B)\r
+       CAIN    0,TCHSTR\r
+       JRST    ONET6\r
+       MOVEI   A,";\r
+       JSP     D,ONETCH\r
+       MOVEI   A,"T\r
+       JSP     D,ONETCH\r
+ONET6: MOVSI   A,1\r
+       HRROI   B,1(E)          ; STRING POINTER\r
+       GTJFN                   ; GET THE G.D JFN\r
+       TDZA    0,0             ; REMEMBER FAILURE\r
+       MOVEI   0,1\r
+       MOVE    P,E             ; RESTORE P\r
+       JUMPE   0,GTJLOS        ; CONS UP ERROR STRING\r
+\r
+       MOVE    B,T.CHAN+1(TB)\r
+       HRRZM   A,CHANNO(B)     ; SAVE THE JFN\r
+\r
+       MOVE    C,T.SPDL+1(TB)\r
+       MOVE    D,S.DIR(C)\r
+       MOVEI   B,10\r
+       TRNE    D,2\r
+       MOVEI   B,36.\r
+       SKIPE   T.XT(TB)\r
+       MOVE    B,T.XT+1(TB)\r
+       JUMPL   B,RBYTSZ\r
+       CAILE   B,36.\r
+       JRST    RBYTSZ\r
+       ROT     B,-6\r
+       TLO     B,3400\r
+       HRRI    B,200000\r
+       TRNE    D,1             ; SKIP FOR INPUT\r
+       HRRI    B,100000\r
+       ANDI    A,-1            ; ISOLATE JFCN\r
+       OPENF\r
+       JRST    OPFLOS          ; REPORT ERROR\r
+       MOVE    B,T.CHAN+1(TB)\r
+       ASH     A,1             ; POINT TO SLOT\r
+       ADDI    A,CHNL0(TVP)    ; TO REAL SLOT\r
+       MOVEM   B,1(A)          ; SAVE CHANNEL\r
+       MOVE    A,CHANNO(B)\r
+       CVSKT                   ; GET ABS SOCKET #\r
+       FATAL NETWORK BITES THE BAG!\r
+       MOVE    D,B\r
+       MOVE    B,T.CHAN+1(TB)\r
+       MOVEM   D,RNAME1(B)\r
+       MOVSI   0,TFIX\r
+       MOVEM   0,RNAME1-1(B)\r
+\r
+       MOVSI   0,TFIX\r
+       MOVEM   0,RNAME2-1(B)\r
+       MOVEM   0,RSNAME-1(B)\r
+       MOVE    C,T.SPDL+1(TB)\r
+       MOVE    C,S.DIR(C)\r
+       MOVE    0,[PUSHJ P,DONETO]\r
+       TRNN    C,1             ; SKIP FOR OUTPUT\r
+       MOVE    0,[PUSHJ P,DONETI]\r
+       MOVEM   0,IOINS(B)\r
+       MOVEI   0,80.           ; LINELENGTH\r
+       TRNE    C,1             ; SKIP FOR INPUT\r
+       MOVEM   0,LINLN(B)\r
+       MOVEI   A,3             ; GET STATE UVECTOR\r
+       PUSHJ   P,IBLOCK\r
+       MOVSI   0,TFIX+.VECT.\r
+       MOVEM   0,3(B)\r
+       MOVE    C,B\r
+       MOVE    B,T.CHAN+1(TB)\r
+       MOVEM   C,BUFRIN(B)\r
+       MOVSI   0,TUVEC\r
+       MOVEM   0,BUFRIN-1(B)\r
+       MOVE    A,CHANNO(B)     ; GET JFN\r
+       GDSTS                   ; GET STATE\r
+       MOVE    E,T.CHAN+1(TB)\r
+       MOVEM   D,RNAME2(E)\r
+       MOVEM   C,RSNAME(E)\r
+       MOVE    C,BUFRIN(E)\r
+       MOVEM   B,(C)           ; INITIAL STATE STORED\r
+       MOVE    B,E\r
+       JRST    OPNWIN\r
+\r
+; DOIOT FOR TENEX NETWRK\r
+\r
+DONETO:        PUSH    P,0\r
+       MOVE    0,[BOUT]\r
+       JRST    .+3\r
+\r
+DONETI:        PUSH    P,0\r
+       MOVE    0,[BIN]\r
+       PUSH    P,0\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,B\r
+       MOVEI   0,(A)           ; POSSIBLE OUTPUT CHAR TO 0\r
+       MOVE    A,CHANNO(B)\r
+       MOVE    B,0\r
+       ENABLE\r
+       XCT     (P)\r
+       DISABLE\r
+       MOVEI   A,(B)           ; RET CHAR IN A\r
+       MOVE    B,(TP)\r
+       MOVE    0,-1(P)\r
+       SUB     P,[2,,2]\r
+       SUB     TP,[2,,2]\r
+       POPJ    P,\r
+       \r
+NETPRS:        MOVEI   D,0\r
+       HRRZ    0,(C)\r
+       MOVE    C,1(C)\r
+\r
+ONETL: ILDB    A,C\r
+       CAIN    A,"#\r
+       POPJ    P,\r
+       SUBI    A,60\r
+       ASH     D,3\r
+       IORI    D,(A)\r
+       SOJG    0,ONETL\r
+       AOS     (P)\r
+       POPJ    P,\r
+\r
+FIXSTK:        CAMN    0,[-1]\r
+       POPJ    P,\r
+       JFFO    0,FIXS3         ; PUT OCTAL DIGITS INTO STIRNG\r
+       MOVEI   A,"0\r
+       POP     P,D\r
+       AOJA    D,ONETCH\r
+FIXS3: IDIVI   A,3\r
+       MOVEI   B,12.\r
+       SUBI    B,(A)\r
+       HRLM    B,(P)\r
+       IMULI   A,3\r
+       LSH     0,(A)\r
+       POP     P,B\r
+FIXS2: MOVEI   A,0\r
+       ROTC    0,3             ; NEXT DIGIT\r
+       ADDI    A,60\r
+       JSP     D,ONETCH\r
+       SUB     B,[1,,0]\r
+       TLNN    B,-1\r
+       JRST    1(B)\r
+       JRST    FIXS2\r
+\r
+ONETCH:        IDPB    A,C\r
+       TLNE    C,760000        ; SKIP IF NEW WORD\r
+       JRST    (D)\r
+       PUSH    P,[0]\r
+       JRST    (D)\r
+\r
+INSTAT:        MOVE    E,B\r
+       MOVE    A,CHANNO(E)\r
+       GDSTS\r
+       LSH     B,-32.\r
+       MOVEM   D,RNAME2(E)     ; UPDATE FOREIGN SOCHKET\r
+       MOVEM   C,RSNAME(E)     ; AND HOST\r
+       MOVE    C,BUFRIN(E)\r
+       XCT     ITSTRN(B)       ; XLATE TO LOOK MORE LIKE ITS\r
+       MOVEM   B,(C)           ; STORE STATE\r
+       MOVE    B,E\r
+       POPJ    P,\r
+\r
+ITSTRN: MOVEI   B,0\r
+        JRST    NLOSS\r
+        JRST    NLOSS\r
+        MOVEI   B,1\r
+        MOVEI   B,2\r
+        JRST    NLOSS\r
+        MOVEI   B,4\r
+        PUSHJ   P,NOPND\r
+        MOVEI   B,0\r
+        JRST    NLOSS\r
+        JRST    NLOSS\r
+        PUSHJ   P,NCLSD\r
+        MOVEI   B,0\r
+        JRST    NLOSS\r
+       MOVEI   B,0\r
+\r
+NLOSS: FATAL ILLEGAL NETWORK STATE\r
+\r
+NOPND: MOVE    B,DIRECT(E)     ; SEE IF READ OR PRINT\r
+       ILDB    B,B             ; GET 1ST CHAR\r
+       CAIE    B,"R            ; SKIP FOR READ\r
+       JRST    NOPNDW\r
+       SIBE            ; SEE IF INPUT EXISTS\r
+       JRST    .+3\r
+       MOVEI   B,5\r
+       POPJ    P,\r
+       MOVEM   B,2(C)          ; STORE BYTES IN STATE VECTOR\r
+       MOVEI   B,11            ; RETURN DATA PRESENT STATE\r
+       POPJ    P,\r
+\r
+NOPNDW:        SOBE                    ; SEE IF OUTPUT PRESENT\r
+       JRST    .+3\r
+       MOVEI   B,5\r
+       POPJ    P,\r
+\r
+       MOVEI   B,6\r
+       POPJ    P,\r
+\r
+NCLSD: MOVE    B,DIRECT(E)\r
+       ILDB    B,B\r
+       CAIE    B,"R\r
+       JRST    RET0\r
+       SIBE\r
+       JRST    .+2\r
+       JRST    RET0\r
+       MOVEI   B,10\r
+       POPJ    P,\r
+\r
+RET0:  MOVEI   B,0\r
+       POPJ    P,\r
+\r
+\r
+MFUNCTION NETSTATE,SUBR\r
+\r
+       PUSHJ   P,ARGNET\r
+       PUSHJ   P,INSTAT\r
+       MOVE    B,BUFRIN(B)\r
+       MOVSI   A,TUVEC\r
+       JRST    FINIS\r
+\r
+MFUNCTION NETS,SUBR\r
+\r
+       PUSHJ   P,ARGNET\r
+       CAME    A,MODES+1       ; PRINT OR PRINTB?\r
+       CAMN    A,MODES+3\r
+       SKIPA   A,CHANNO(B)\r
+       JRST    WRONGD\r
+       MOVEI   B,21\r
+       MTOPR\r
+NETRET:        MOVE    B,1(AB)\r
+       MOVSI   A,TCHAN\r
+       JRST    FINIS\r
+\r
+MFUNCTION NETACC,SUBR\r
+\r
+       PUSHJ   P,ARGNET\r
+       MOVE    A,CHANNO(B)\r
+       MOVEI   B,20\r
+       MTOPR\r
+       JRST    NETRET\r
+\r
+]\r
+\f\r
+; HERE TO OPEN TELETYPE DEVICES\r
+\r
+OTTY:  HRRZ    A,S.DIR(C)      ; GET DIR CODE\r
+       TRNE    A,2             ; SKIP IF NOT READB/PRINTB\r
+       JRST    WRONGD          ; CANT DO THAT\r
+\r
+IFN ITS,[\r
+       MOVE    A,S.NM1(C)      ; CHECK FOR A DIR\r
+       MOVE    0,S.NM2(C)\r
+       CAMN    A,[SIXBIT /.FILE./]\r
+       CAME    0,[SIXBIT /(DIR)/]\r
+       SKIPA   E,[-15.*2,,]\r
+       JRST    OUTN            ; DO IT THAT WAY\r
+\r
+       HRRZ    A,S.DIR(C)      ; CHECK DIR\r
+       TRNE    A,1\r
+       JRST    TTYLP2\r
+       HRRI    E,CHNL1(TVP)\r
+       PUSH    P,S.DEV(C)      ; SAVE THE SIXBIT DEV NAME\r
+       HRLZS   (P)             ; POSTITION DEVICE NAME\r
+\r
+TTYLP: SKIPN   D,1(E)          ; CHANNEL OPEN?\r
+       JRST    TTYLP1          ; NO, GO TO NEXT\r
+       MOVE    A,RDEVIC-1(D)           ; GET DEV NAME\r
+       MOVE    B,RDEVIC(D)\r
+       PUSHJ   P,STRTO6        ; TO 6 BIT\r
+       POP     P,A             ; GET RESULT\r
+       CAMN    A,(P)           ; SAME?\r
+       JRST    SAMTYQ          ; COULD BE THE SAME\r
+TTYLP1:        ADD     E,[2,,2]\r
+       JUMPL   E,TTYLP\r
+       SUB     P,[1,,1]        ; THIS ONE MUST BE UNIQUE\r
+TTYLP2:        MOVE    C,T.SPDL+1(TB)  ; POINT TO P BASE\r
+       HRRZ    A,S.DIR(C)      ; GET DIR OF OPEN\r
+       SKIPE   A               ; IF OUTPUT,\r
+       IORI    A,20            ; THEN USE DISPLAY MODE\r
+       HRLM    A,S.DEV(C)      ; STORE IN OPEN BLOCK\r
+       PUSHJ   P,OPEN2         ; OPEN THE TTY\r
+       HRLZ    A,S.DEV(C)      ; GET DEVICE NAME\r
+       PUSHJ   P,6TOCHS        ; TO A STRING\r
+       MOVE    D,T.CHAN+1(TB)  ; POINT TO CHANNEL\r
+       MOVEM   A,RDEVIC-1(D)\r
+       MOVEM   B,RDEVIC(D)\r
+       MOVE    C,T.SPDL+1(TB)  ; RESTORE PDL BASE\r
+       MOVE    B,D             ; CHANNEL TO B\r
+       HRRZ    0,S.DIR(C)      ; AND DIR\r
+       JUMPE   0,TTYSPC\r
+TTY1:  DOTCAL  TTYGET,[CHANNO(B),[2000,,0],[2000,,A],[2000,,D]]\r
+       FATAL .CALL FAILURE\r
+       DOTCAL  TTYSET,[CHANNO(B),MODE1,MODE2,D]\r
+       FATAL .CALL FAILURE\r
+       MOVE    A,[PUSHJ P,GMTYO]\r
+       MOVEM   A,IOINS(B)\r
+       DOTCAL  RSSIZE,[CHANNO(B),[2000,,A],[2000,,D]]\r
+       FATAL .CALL FAILURE\r
+       MOVEM   D,LINLN(B)\r
+       MOVEM   A,PAGLN(B)\r
+       JRST    OPNWIN\r
+\r
+; MAKE AN IOT\r
+\r
+IOTMAK:        HRLZ    A,CHANNO(B)     ; GET CHANNEL\r
+       ROT     A,5\r
+       IOR     A,[.IOT A]      ; BUILD IOT\r
+       MOVEM   A,IOINS(B)      ; AND STORE IT\r
+       POPJ    P,\r
+\f\r
+\r
+; HERE IF POSSIBLY OPENING AN ALREADY OPEN TTY\r
+\r
+SAMTYQ:        MOVE    D,1(E)          ; RESTORE CURRENT CHANNEL\r
+       MOVE    A,DIRECT-1(D)   ; GET DIR\r
+       MOVE    B,DIRECT(D)\r
+       PUSHJ   P,STRTO6\r
+       POP     P,A             ; GET SIXBIT\r
+       MOVE    C,T.SPDL+1(TB)\r
+       HRRZ    C,S.DIR(C)\r
+       CAME    A,MODES(C)      ; SKIP IF DIFFERENT DIRECTION\r
+       JRST    TTYLP1\r
+\r
+; HERE IF A RE-OPEN ON A TTY\r
+\r
+       HRRZ    0,FSAV(TB)      ; IS IT FROM A FOPEN\r
+       CAIN    0,FOPEN\r
+       JRST    RETOLD          ; RET OLD CHANNEL\r
+\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,1(E)         ; PUSH OLD CHANNEL\r
+       PUSH    TP,$TFIX\r
+       PUSH    TP,T.CHAN+1(TB)\r
+       MOVE    A,[PUSHJ P,CHNFIX]\r
+       PUSHJ   P,GCHACK\r
+       SUB     TP,[4,,4]\r
+       \r
+RETOLD:        MOVE    B,1(E)          ; GET CHANNEL\r
+       AOS     CHANNO-1(B)     ; AOS REF COUNT\r
+       MOVSI   A,TCHAN\r
+       SUB     P,[1,,1]        ; CLEAN UP STACK\r
+       JRST    OPNRET          ; AND LEAVE\r
+\r
+\r
+; ROUTINE TO PASS TO GCHACK TO FIX UP CHANNEL POINTER\r
+\r
+CHNFIX:        CAIN    C,TCHAN\r
+       CAME    D,(TP)\r
+       POPJ    P,\r
+       MOVE    D,-2(TP)        ; GET REPLACEMENT\r
+       SKIPE   B\r
+       MOVEM   D,1(B)          ; CLOBBER IT AWAY\r
+       POPJ    P,\r
+]\f\r
+\r
+IFE ITS,[\r
+       MOVE    C,T.SPDL+1(TB)  ; POINT TO P BASE\r
+       HRRZ    0,S.DIR(C)      ; 0/ 0 FOR READ 0/ 1 FOR PRINT\r
+       MOVE    A,[PUSHJ P,MTYO]\r
+       MOVE    B,T.CHAN+1(TB)\r
+       MOVEM   A,IOINS(B)\r
+       MOVEI   A,100           ; PRIM INPUT JFN\r
+       JUMPN   0,TNXTY1\r
+       MOVEI   E,C.OPN+C.READ\r
+       HRRM    E,-4(B)\r
+       MOVEM   B,CHNL0+2*100+1(TVP)\r
+       JRST    TNXTY2\r
+TNXTY1:        MOVEM   B,CHNL0+2*101+1(TVP)\r
+       MOVEI   A,101           ; PRIM OUTPUT JFN\r
+       MOVEI   E,C.OPN+C.PRIN\r
+       HRRM    E,-4(B)\r
+TNXTY2:        MOVEM   A,CHANNO(B)\r
+       JUMPN   0,OPNWIN\r
+]\r
+; SETUP FUNNY BUFFER FOR TTY INPUT DEVICES\r
+\r
+TTYSPC:        MOVEI   A,EXTBFR        ; GET EXTRA BUFFER\r
+       PUSHJ   P,IBLOCK        ; GET BLOCK\r
+       MOVE    D,T.CHAN+1(TB)  ;RESTORE CHANNEL POINTER\r
+IFN ITS,[\r
+       MOVE    A,CHANNO(D)\r
+       LSH     A,23.\r
+       IOR     A,[.IOT A]\r
+       MOVEM   A,IOIN2(B)\r
+]\r
+IFE ITS,[\r
+       MOVE    A,[PBIN]\r
+       MOVEM   A,IOIN2(B)\r
+]\r
+       MOVSI   A,TLIST\r
+       MOVEM   A,EXBUFR-1(D)   ; FOR WAITING TTY BUFFERS\r
+       SETZM   EXBUFR(D)       ; NIL LIST\r
+       MOVEM   B,BUFRIN(D)     ;STORE IN CHANNEL\r
+       MOVSI   A,TUVEC         ;MAKE SURE TYPE IS UNIFORM VECTOR\r
+       MOVEM   A,BUFRIN-1(D)\r
+IFN ITS,       MOVEI   A,177           ;SET ERASER TO RUBOUT\r
+IFE ITS,       MOVEI   A,1             ; TRY ^A FOR TENEX\r
+       MOVEM   A,ERASCH(B)\r
+       SETZM   KILLCH(B)       ;NO KILL CHARACTER NEEDED\r
+       MOVEI   A,33            ;BREAKCHR TO C.R.\r
+       MOVEM   A,BRKCH(B)\r
+       MOVEI   A,"\            ;ESCAPER TO \\r
+       MOVEM   A,ESCAP(B)\r
+       MOVE    A,[010700,,BYTPTR(E)]   ;RELATIVE BYTE POINTER\r
+       MOVEM   A,BYTPTR(B)\r
+       MOVEI   A,14            ;BARF BACK CHARACTER FF\r
+       MOVEM   A,BRFCHR(B)\r
+       MOVEI   A,^D\r
+       MOVEM   A,BRFCH2(B)\r
+\r
+; SETUP DEFAULT TTY INTERRUPT HANDLER\r
+\r
+       PUSH    TP,$TATOM\r
+       PUSH    TP,MQUOTE CHAR,CHAR,INTRUP\r
+       PUSH    TP,$TFIX\r
+       PUSH    TP,[10]         ; PRIORITY OF CHAR INT\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,D\r
+       MCALL   3,EVENT         ; 1ST MAKE AN EVENT EXIST\r
+       PUSH    TP,A\r
+       PUSH    TP,B\r
+       PUSH    TP,$TSUBR\r
+       PUSH    TP,[QUITTER]    ; DEFAULT HANDLER IS QUITTER\r
+       MCALL   2,HANDLER\r
+\r
+; BUILD A NULL STRING\r
+\r
+       MOVEI   A,0\r
+       PUSHJ   P,IBLOCK                ; USE A BLOCK\r
+       MOVE    D,T.CHAN+1(TB)\r
+       MOVEI   0,C.BUF\r
+       IORM    0,-4(D)\r
+       HRLI    B,440700\r
+       MOVSI   A,TCHSTR\r
+       MOVEM   A,BUFSTR-1(D)\r
+       MOVEM   B,BUFSTR(D)\r
+       MOVEI   A,0\r
+       MOVE    B,D             ; CHANNEL TO B\r
+       JRST    MAKION\r
+\f\r
+\r
+; ROUTINE TO OPEN ITS CHANNEL WITHOUT .RCHST\r
+\r
+OPEN2: MOVEI   A,S.DEV(C)      ; POINT TO OPEN BLOCK\r
+       PUSHJ   P,MOPEN         ; OPEN THE FILE\r
+       JRST    OPNLOS\r
+       MOVE    B,T.CHAN+1(TB)  ; GET CHANNEL BACK\r
+       MOVEM   A,CHANNO(B)     ; SAVE THE CHANNEL\r
+       JRST    OPEN3\r
+\r
+; FIX UP MODE AND FALL INTO OPEN\r
+\r
+OPEN0: HRRZ    A,S.DIR(C)              ; GET DIR\r
+       TRNE    A,2             ; SKIP IF NOT BLOCK\r
+       IORI    A,4             ; TURN ON IMAGE\r
+       IORI    A,2             ; AND BLOCK\r
+\r
+       PUSH    P,A\r
+       PUSH    TP,$TPDL\r
+       PUSH    TP,C            ; SAVE CRUFT TO CHECK FOR PRINTO, HA HA\r
+       MOVE    B,T.CHAN+1(TB)\r
+       MOVE    A,DIRECT-1(B)\r
+       MOVE    B,DIRECT(B)     ; THIS KLUDGE THE MESS OF NDR\r
+       PUSHJ   P,STRTO6\r
+       MOVE    C,(TP)\r
+       POP     P,D             ; THE SIXBIT FOR KLUDGE\r
+       POP     P,A             ; GET BACK THE RANDOM BITS\r
+       SUB     TP,[2,,2]\r
+       CAME    D,[SIXBIT /PRINTO/]\r
+       JRST    OPEN9           ; WELL NOT THIS TIME\r
+       IORI    A,100000        ; WRITEOVER BIT\r
+\r
+       HRRZ    0,FSAV(TB)\r
+       CAIN    0,NFOPEN\r
+       IOR     A,4             ; DON'T CHANGE REF DATE\r
+OPEN9: HRLM    A,S.DEV(C)      ; AND STORE IT\r
+\r
+; ROUTINE TO ATTEMPT TO OPEN A REAL ITS CHANNEL\r
+\r
+OPEN1: MOVEI   A,S.DEV(C)      ; POINT TO OPEN BLOCK\r
+       PUSHJ   P,MOPEN\r
+       JRST    OPNLOS\r
+       MOVE    B,T.CHAN+1(TB)  ; GET CHANNEL BACK\r
+       MOVEM   A,CHANNO(B)     ; CLOBBER INTO CHANNEL\r
+       MOVSI   A,(A)           ; SET UP READ CHAN STATUS\r
+       HRRI    A,S.DEV(C)\r
+       .RCHST  A,              ; GET THE GOODS\r
+\r
+; NOW CLOBBER THE TVP SLOT FOR THIS CHANNEL\r
+\r
+OPEN3: MOVE    A,S.DIR(C)\r
+       MOVEI   0,C.OPN+C.READ\r
+       TRNE    A,1\r
+       MOVEI   0,C.OPN+C.PRIN\r
+       TRNE    A,2\r
+       TRO     0,C.BIN\r
+       HRRM    0,-4(B)\r
+       MOVE    A,CHANNO(B)     ; GET CHANNEL #\r
+       ASH     A,1\r
+       ADDI    A,CHNL0(TVP)    ; POINT TO SLOT\r
+       MOVEM   B,1(A)          ; NOT: TYPE ALREADY SETUP\r
+\r
+; NOW GET STATUS WORD\r
+\r
+DOSTAT:        HRLZ    A,CHANNO(B)     ; NOW GET STATUS WORD\r
+       ROT     A,5\r
+       IOR     A,[.STATUS STATUS(B)]   ; GET INS\r
+       XCT     A               ; AND DO IT\r
+       POPJ    P,\r
+\f\r
+\r
+; HERE IF OPEN FAILS (CHANNEL IS IN A)\r
+\r
+OPNLOS:        JUMPL   A,NOCHAN        ; ALL CHANNELS ARE IN USE\r
+       LSH     A,23.           ; DO A .STATUS\r
+       IOR     A,[.STATUS A]\r
+       XCT     A               ; STATUS TO A\r
+       PUSHJ   P,GFALS         ; GET A FALSE WITH A MESSAGE\r
+       SUB     P,[1,,1]        ; EXTRA RET ADDR FLUSHED\r
+       JRST    OPNRET          ; AND RETURN\r
+\r
+; ROUTINE TO CONS UP FALSE WITH REASON\r
+\r
+GFALS: PUSH    P,[SIXBIT /   ERR/]     ; SET UP OPEN TO ERR DEV\r
+       PUSH    P,[3]           ; SAY ITS FOR CHANNEL\r
+       PUSH    P,A\r
+       .OPEN   0,-2(P)         ; USE CHANNEL 0 FOR THIS\r
+       FATAL CAN'T OPEN ERROR DEVICE\r
+       SUB     P,[3,,3]        ; DONT WANT OPEN BLOCK NOW\r
+       MOVEI   A,0             ; PREPARE TO BUILD STRING ON STACK\r
+EL1:   PUSH    P,[0]           ; WHERE IT WILL GO\r
+       MOVSI   B,(<440700,,(P)>)       ; BYTE POINTER TO TOP OF STACK\r
+EL2:   .IOT    0,0             ; GET A CHAR\r
+       JUMPL   0,EL3           ; JUMP ON -1,,3\r
+       CAIN    0,3             ; EOF?\r
+       JRST    EL3             ; YES, MAKE STRING\r
+       CAIN    0,14            ; IGNORE FORM FEEDS\r
+       JRST    EL2             ; IGNORE FF\r
+       CAIE    0,15            ; IGNORE CR & LF\r
+       CAIN    0,12\r
+       JRST    EL2\r
+       IDPB    0,B             ; STUFF IT\r
+       TLNE    B,760000        ; SIP IF WORD FULL\r
+       AOJA    A,EL2\r
+       AOJA    A,EL1           ; COUNT WORD AND GO\r
+\r
+EL3:   SKIPN   (P)             ; ANY CHARS AT END?\r
+       SUB     P,[1,,1]        ; FLUSH XTRA\r
+       PUSH    P,A             ; PUT UP COUNT\r
+       .CLOSE  0,              ; CLOSE THE ERR DEVICE\r
+       PUSHJ   P,CHMAK         ; MAKE STRING\r
+       MOVE    C,A\r
+       MOVE    D,B             ; COPY STRING\r
+       PUSHJ   P,INCONS        ; CONS TO NIL\r
+       MOVSI   A,TFALSE        ; MAKEIT A FALSE\r
+       POPJ    P,\r
+\f\r
+\r
+; ROUTINE TO FILL IN THE "REAL" SLOTS FOR THE CHANNEL\r
+\r
+FIXREA:        HRLZS   S.DEV(C)        ; KILL MODE BITS\r
+       MOVE    D,[-4,,S.DEV]\r
+\r
+FIXRE1:        MOVEI   A,(D)           ; COPY REL POINTER\r
+       ADD     A,T.SPDL+1(TB)  ; POINT TO SLOT\r
+       SKIPN   A,(A)           ; SKIP IF GOODIE THERE\r
+       JRST    FIXRE2\r
+       PUSHJ   P,6TOCHS        ; MAKE INOT A STRING\r
+       MOVE    C,RDTBL-S.DEV(D); GET OFFSET\r
+       ADD     C,T.CHAN+1(TB)\r
+       MOVEM   A,-1(C)\r
+       MOVEM   B,(C)\r
+FIXRE2:        AOBJN   D,FIXRE1\r
+       POPJ    P,\r
+\r
+DOOPN: PUSH    P,A\r
+       HRLZ    A,CHANNO(B)     ; GET CHANNEL\r
+       ASH     A,5\r
+       HRR     A,(P)           ; POINT\r
+       TLO     A,(.OPEN)\r
+       XCT     A\r
+       SKIPA\r
+       AOS     -1(P)\r
+       POP     P,A\r
+       POPJ    P,\r
+\f\r
+;THIS ROUTINE CONVERTS MUDDLE CHARACTER STRINGS TO SIXBIT FILE NAMES\r
+STRTO6:        PUSH    TP,A\r
+       PUSH    TP,B\r
+       PUSH    P,E             ;SAVE USEFUL FROB\r
+       MOVEI   E,(A)           ; CHAR COUNT TO E\r
+       GETYP   A,A\r
+       CAIE    A,TCHSTR                ; IS IT ONE WORD?\r
+       JRST    WRONGT          ;NO\r
+CHREAD:        MOVEI   A,0             ;INITIALIZE OUTPUT WORD\r
+       MOVE    D,[440600,,A]   ;AND BYTE POINTER TO IT\r
+NEXCHR:        SOJL    E,SIXDON\r
+       ILDB    0,B             ; GET NEXT CHAR\r
+       JUMPE   0,SIXDON        ;IF NULL, WE ARE FINISHED\r
+       PUSHJ   P,A0TO6         ; CONVERT TO SIXBIT\r
+       IDPB    0,D             ;DEPOSIT INTO SIX BIT\r
+       TRNN    A,77            ;IS OUTPUT FULL\r
+       JRST    NEXCHR          ; NO, GET NEXT\r
+SIXDON:        SUB     TP,[2,,2]       ;FIX UP TP\r
+       POP     P,E\r
+       EXCH    A,(P)           ;LEAVE RESULT ON P-STACK\r
+       JRST    (A)             ;NOW RETURN\r
+\r
+\r
+;SUBROUTINE TO CONVERT SIXBIT TO ATOM\r
+\r
+6TOCHS:        PUSH    P,E\r
+       PUSH    P,D\r
+       MOVEI   B,0             ;MAX NUMBER OF CHARACTERS\r
+       PUSH    P,[0]           ;STRING WILL GO ON P SATCK\r
+       JUMPE   A,GETATM        ; EMPTY, LEAVE\r
+       MOVEI   E,-1(P)         ;WILL BE BYTE POINTER\r
+       HRLI    E,10700         ;SET IT UP\r
+       PUSH    P,[0]           ;SECOND POSSIBLE WORD\r
+       MOVE    D,[440600,,A]   ;INPUT BYTE POINTER\r
+6LOOP: ILDB    0,D             ;START CHAR GOBBLING\r
+       ADDI    0,40            ;CHANGET TOASCII\r
+       IDPB    0,E             ;AND STORE IT\r
+       TLNN    D,770000        ; SKIP IF NOT DONE\r
+       JRST    6LOOP1\r
+       TDNN    A,MSKS(B)       ; CHECK IF JUST SPACES LEFT\r
+       AOJA    B,GETATM        ; YES, DONE\r
+       AOJA    B,6LOOP         ;KEEP LOOKING\r
+6LOOP1:        PUSH    P,[6]           ;IF ARRIVE HERE, STRING IS 2 WORDS\r
+       JRST    .+2\r
+GETATM:        MOVEM   B,(P)           ;SET STRING LENGTH=1\r
+       PUSHJ   P,CHMAK         ;MAKE A MUDDLE STRING\r
+       POP     P,D\r
+       POP     P,E\r
+       POPJ    P,\r
+\r
+MSKS:  7777,,-1\r
+       77,,-1\r
+       ,,-1\r
+       7777\r
+       77\r
+\r
+\r
+; CONVERT ONE CHAR\r
+\r
+A0TO6: CAIL    0,141           ;IF IT IS GREATER OR EQUAL TO LOWER A\r
+       CAILE   0,172           ;BUT LESS THAN OR EQUAL TO LOWER Z\r
+       JRST    .+2             ;THEN\r
+       SUBI    0,40            ;CONVERT TO UPPER CASE\r
+       SUBI    0,40            ;NOW TO SIX BIT\r
+       JUMPL   0,BAD6          ;CHECK FOR A WINNER\r
+       CAILE   0,77\r
+       JRST    BAD6\r
+       POPJ    P,\r
+\f\r
+; SUBR TO DELETE AND RENAME FILES\r
+\r
+MFUNCTION RENAME,SUBR\r
+\r
+       ENTRY\r
+\r
+       JUMPGE  AB,TFA\r
+       PUSH    TP,$TPDL\r
+       PUSH    TP,P            ; SAVE P-STACK BASE\r
+       GETYP   0,(AB)          ; GET 1ST ARG TYPE\r
+IFN ITS,[\r
+       CAIN    0,TCHAN         ; CHANNEL?\r
+       JRST    CHNRNM          ; MUST BE RENAME WHILE OPEN FOR WRITING\r
+]\r
+IFE ITS,[\r
+       PUSH    P,[100000,,0]\r
+       PUSH    P,[377777,,377777]\r
+]\r
+       MOVSI   E,-4            ; 4 THINGS TO PUSH\r
+RNMALP:        MOVE    B,@RNMTBL(E)\r
+       PUSH    P,E\r
+       PUSHJ   P,IDVAL1\r
+       POP     P,E\r
+       GETYP   0,A\r
+       CAIE    0,TCHSTR        ; SKIP IF WINS\r
+       JRST    RNMLP1\r
+\r
+IFN ITS,       PUSHJ   P,STRTO6        ; CONVERT TO SIXBIT\r
+IFE ITS,       PUSH    P,B             ; PUSH BYTE POINTER\r
+       JRST    .+2\r
+\r
+RNMLP1:        PUSH    P,RNSTBL(E)     ; USE DEFAULT\r
+       AOBJN   E,RNMALP\r
+\r
+IFN ITS,[\r
+       PUSHJ   P,RGPRS         ; PARSE THE ARGS\r
+       JRST    RNM1            ; COULD BE A RENAME\r
+\r
+; HERE TO DELETE A FILE\r
+\r
+DELFIL:        MOVEI   A,0             ; SETUP FDELE\r
+       EXCH    A,(P)           ; AND GET SNAME\r
+       .SUSET  [.SSNAM,,A]\r
+       HLRZS   -3(P)           ; FIXUP DEVICE\r
+       .FDELE  -3(P)           ; DO IT TO IT\r
+       JRST    FDLST           ; ANALYSE ERROR\r
+\r
+FDLWON:        MOVSI   A,TATOM\r
+       MOVE    B,MQUOTE T\r
+       JRST    FINIS\r
+]\r
+IFE ITS,[\r
+       MOVE    A,(TP)          ; GET BASE OF PDL\r
+       MOVEI   A,1(A)          ; POINT TO CRAP\r
+       MOVE    B,1(AB)         ; STRING POINTER\r
+       PUSH    P,[0]\r
+       PUSH    P,[0]\r
+       PUSH    P,[0]\r
+       GTJFN                   ; GET A JFN\r
+       JRST    TDLLOS          ; LOST\r
+       ADD     AB,[2,,2]       ; PAST ARG\r
+       JUMPL   AB,RNM1         ; GO TRY FOR RENAME\r
+       MOVE    P,(TP)          ; RESTORE P STACK\r
+       MOVEI   C,(A)           ; FOR RELEASE\r
+       DELF                    ; ATTEMPT DELETE\r
+       JRST    DELLOS          ; LOSER\r
+       RLJFN                   ; MAKE SURE FLUSHED\r
+       JFCL\r
+\r
+FDLWON:        MOVSI   A,TATOM\r
+       MOVE    B,MQUOTE T\r
+       JRST    FINIS\r
+\r
+RNMLOS:        PUSH    P,A\r
+       MOVEI   A,(B)\r
+       RLJFN\r
+       JFCL\r
+DELLO1:        MOVEI   A,(C)\r
+       RLJFN\r
+       JFCL\r
+       POP     P,A             ; ERR NUMBER BACK\r
+TDLLOS:        PUSHJ   P,TGFALS        ; GET FALSE WITH REASON\r
+       JRST    FINIS\r
+\r
+DELLOS:        PUSH    P,A             ; SAVE ERROR\r
+       JRST    DELLO1\r
+]\r
+\r
+;TABLE OF REANMAE DEFAULTS\r
+IFN ITS,[\r
+RNMTBL:        IMQUOTE DEV\r
+       IMQUOTE NM1\r
+       IMQUOTE NM2\r
+       IMQUOTE SNM\r
+\r
+RNSTBL:        SIXBIT /DSK   _MUDS_>           /\r
+]\r
+IFE ITS,[\r
+RNMTBL:        IMQUOTE DEV\r
+       IMQUOTE SNM\r
+       IMQUOTE NM1\r
+       IMQUOTE NM2\r
+\r
+RNSTBL:        -1,,[ASCIZ /DSK/]\r
+       0\r
+       -1,,[ASCIZ /_MUDS_/]\r
+       -1,,[ASCIZ /MUD/]\r
+]\r
+; HERE TO DO A RENAME\r
+\r
+RNM1:  JUMPGE  AB,TMA          ; IF ARGS EXHAUSTED, MUST BE TOO MUCH STRING\r
+       GETYP   0,(AB)\r
+       MOVE    C,1(AB)         ; GET ARG\r
+       CAIN    0,TATOM         ; IS IT "TO"\r
+       CAME    C,MQUOTE TO\r
+       JRST    WRONGT          ; NO, LOSE\r
+       ADD     AB,[2,,2]       ; BUMP PAST "TO"\r
+       JUMPGE  AB,TFA\r
+IFN ITS,[\r
+       MOVEM   P,T.SPDL+1(TB)  ; SAVE NEW P-BASE\r
+\r
+       MOVEI   0,4             ; FOUR DEFAULTS\r
+       PUSH    P,-3(P)         ; DEFAULT DEVICE IS CURRENT\r
+       SOJN    0,.-1\r
+\r
+       PUSHJ   P,RGPRS         ; PARSE THE NEXT STRING\r
+       JRST    TMA\r
+\r
+       HLRZS   A,-7(P)         ; FIX AND GET DEV1\r
+       HLRZS   B,-3(P)         ; SAME FOR DEV2\r
+       CAIE    A,(B)           ; SAME?\r
+       JRST    DEVDIF\r
+\r
+       POP     P,A             ; GET SNAME 2\r
+       CAME    A,(P)-3         ; SNAME 1\r
+       JRST    DEVDIF\r
+       .SUSET  [.SSNAM,,A]\r
+       POP     P,-2(P)         ; MOVE NAMES DOWN\r
+       POP     P,-2(P)\r
+       .FDELE  -4(P)           ; TRY THE RENAME\r
+       JRST    FDLST\r
+       JRST    FDLWON\r
+\r
+; HERE FOR RENAME WHILE OPEN FOR WRITING\r
+\r
+CHNRNM:        ADD     AB,[2,,2]       ; NEXT ARG\r
+       JUMPGE  AB,TFA\r
+       MOVE    B,-1(AB)        ; GET CHANNEL\r
+       SKIPN   CHANNO(B)       ; SKIP IF OPEN\r
+       JRST    BADCHN\r
+       MOVE    A,DIRECT-1(B)   ; CHECK DIRECTION\r
+       MOVE    B,DIRECT(B)\r
+       PUSHJ   P,STRTO6        ; TO 6 BIT\r
+       POP     P,A\r
+       CAME    A,[SIXBIT /PRINT/]\r
+       CAMN    A,[SIXBIT /PRINTB/]\r
+       JRST    CHNRN1\r
+       CAME    A,[SIXBIT /PRINTO/]\r
+       JRST    WRONGD\r
+\r
+; SET UP .FDELE BLOCK\r
+\r
+CHNRN1:        PUSH    P,[0]\r
+       PUSH    P,[0]\r
+       MOVEM   P,T.SPDL+1(TB)\r
+       PUSH    P,[0]\r
+       PUSH    P,[SIXBIT /_MUDL_/]\r
+       PUSH    P,[SIXBIT />/]\r
+       PUSH    P,[0]\r
+\r
+       PUSHJ   P,RGPRS         ; PARSE THESE\r
+       JRST    TMA\r
+\r
+       SUB     P,[1,,1]        ; SNAME/DEV IGNORED\r
+       MOVE    AB,ABSAV(TB)    ; GET ORIG ARG POINTER\r
+       MOVE    B,1(AB)\r
+       MOVE    A,CHANNO(B)     ; ITS CHANNEL #\r
+       MOVEM   A,-2(P)\r
+       .FDELE  -4(P)\r
+       JRST    FDLST\r
+       MOVEI   A,-4(P)         ; SET UP FOR RDCHST\r
+       HRL     A,CHANNO(B)\r
+       .RCHST  A,\r
+       MOVE    A,-3(P)         ; UPDATE CHANNEL\r
+       PUSHJ   P,6TOCHS        ; GET A STRING\r
+       MOVE    C,1(AB)\r
+       MOVEM   A,RNAME1-1(C)\r
+       MOVEM   B,RNAME1(C)\r
+       MOVE    A,-2(P)\r
+       PUSHJ   P,6TOCHS\r
+       MOVE    C,1(AB)\r
+       MOVEM   A,RNAME2-1(C)\r
+       MOVEM   B,RNAME2(C)\r
+       MOVE    B,1(AB)\r
+       MOVSI   A,TCHAN\b\r
+       JRST    FINIS\r
+]\r
+IFE ITS,[\r
+       PUSH    P,A\r
+       MOVE    A,(TP)          ; PBASE BACK\r
+       PUSH    A,[400000,,0]\r
+       MOVEI   A,(A)\r
+       MOVE    B,1(AB)\r
+       GTJFN\r
+       JRST    TDLLOS\r
+       POP     P,B\r
+       EXCH    A,B\r
+       MOVEI   C,(A)           ; FOR RELEASE ATTEMPT\r
+       RNAMF\r
+       JRST    RNMLOS\r
+       MOVEI   A,(B)\r
+       RLJFN                   ; FLUSH JFN\r
+       JFCL\r
+       MOVEI   A,(C)           ; MAKE SURR OTHER IS FLUSHED\r
+       RLJFN\r
+       JFCL\r
+       JRST    FDLWON\r
+]\r
+; HERE FOR LOSING .FDELE\r
+\r
+FDLST: .STATUS 0,A             ; GET STATUS\r
+       PUSHJ   P,GFALS         ; ANALYZE IT\r
+       JRST    FINIS\r
+\r
+; SOME .FDELE ERRORS\r
+\r
+DEVDIF:        PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE DEVICE-OR-SNAME-DIFFERS\r
+       JRST    CALER1\r
+\r
+\f; HERE TO RESET A READ CHANNEL\r
+\r
+MFUNCTION FRESET,SUBR,RESET\r
+\r
+       ENTRY   1\r
+       GETYP   A,(AB)\r
+       CAIE    A,TCHAN\r
+       JRST    WTYP1\r
+       MOVE    B,1(AB)         ;GET CHANNEL\r
+       SKIPN   IOINS(B)                ; OPEN?\r
+       JRST    REOPE1          ; NO, IGNORE CHECKS\r
+IFN ITS,[\r
+       MOVE    A,STATUS(B)     ;GET STATUS\r
+       ANDI    A,77\r
+       JUMPE   A,REOPE1        ;IF IT CLOSED, JUST REOPEN IT, MAYBE?\r
+       CAILE   A,2             ;SKIPS IF TTY FLAVOR\r
+       JRST    REOPEN\r
+]\r
+IFE ITS,[\r
+       MOVE    A,CHANNO(B)\r
+       CAIE    A,100           ; TTY-IN\r
+       CAIN    A,101           ; TTY-OUT\r
+       JRST    .+2\r
+       JRST    REOPEN\r
+]\r
+       CAME    B,TTICHN+1(TVP)\r
+       CAMN    B,TTOCHN+1(TVP)\r
+       JRST    REATTY\r
+REATT1:        MOVEI   B,DIRECT-1(B)   ;POINT TO DIRECTION\r
+       PUSHJ   P,CHRWRD        ;CONVERT TO A WORD\r
+       JFCL\r
+       CAME    B,[ASCII /READ/]\r
+       JRST    TTYOPN\r
+       MOVE    B,1(AB)         ;RESTORE CHANNEL\r
+       PUSHJ   P,RRESET"       ;DO REAL RESET\r
+       JRST    TTYOPN\r
+\r
+REOPEN:        PUSH    TP,(AB)         ;FIRST CLOSE IT\r
+       PUSH    TP,(AB)+1\r
+       MCALL   1,FCLOSE\r
+       MOVE    B,1(AB)         ;RESTORE CHANNEL\r
+\r
+; SET UP TEMPS FOR OPNCH\r
+\r
+REOPE1:        PUSH    P,[0]           ; WILL HOLD DIR CODE\r
+       PUSH    TP,$TPDL\r
+       PUSH    TP,P\r
+       IRP A,,[DIRECT,RNAME1,RNAME2,RDEVIC,RSNAME,ACCESS]\r
+       PUSH    TP,A-1(B)\r
+       PUSH    TP,A(B)\r
+       TERMIN\r
+\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,1(AB)\r
+\r
+       MOVE    A,T.DIR(TB)\r
+       MOVE    B,T.DIR+1(TB)   ; GET DIRECTION\r
+       PUSHJ   P,CHMOD ; CHECK THE MODE\r
+       MOVEM   A,(P)           ; AND STORE IT\r
+\r
+; NOW SET UP OPEN BLOCK IN SIXBIT\r
+IFN ITS,[\r
+       MOVSI   E,-4            ; AOBN PNTR\r
+FRESE2:        MOVE    B,T.CHAN+1(TB)\r
+       MOVEI   A,@RDTBL(E)     ; GET ITEM POINTER\r
+       GETYP   0,-1(A)         ; GET ITS TYPE\r
+       CAIE    0,TCHSTR\r
+       JRST    FRESE1\r
+       MOVE    B,(A)           ; GET STRING\r
+       MOVE    A,-1(A)\r
+       PUSHJ   P,STRTO6\r
+FRESE3:        AOBJN   E,FRESE2\r
+       HLRZS   -3(P)           ; FIX DEVICE SPEC\r
+]\r
+IFE ITS,[\r
+       MOVE    B,T.CHAN+1(TB)\r
+       MOVE    A,RDEVIC-1(B)\r
+       MOVE    B,RDEVIC(B)\r
+       PUSHJ   P,STRTO6                ; RESULT ON STACK\r
+       HLRZS   (P)\r
+]\r
+\r
+       PUSH    P,[0]           ; PUSH UP SOME DUMMIES\r
+       PUSH    P,[0]\r
+       PUSH    P,[0]\r
+       PUSHJ   P,OPNCH         ; ATTEMPT TO DO THEOPEN\r
+       GETYP   0,A\r
+       CAIE    0,TCHAN\r
+       JRST    FINIS           ; LEAVE IF FALSE OR WHATEVER\r
+\r
+DRESET:        MOVE    A,(AB)\r
+       MOVE    B,1(AB)\r
+       SETZM   CHRPOS(B)       ;INITIALIZE THESE PARAMETERS\r
+       SETZM   LINPOS(B)\r
+       SETZM   ACCESS(B)\r
+       JRST    FINIS\r
+\r
+TTYOPN:        MOVE    B,1(AB)\r
+       CAME    B,TTOCHN+1(TVP)\r
+       CAMN    B,TTICHN+1(TVP)\r
+       PUSHJ   P,TTYOP2\r
+       PUSHJ   P,DOSTAT\r
+       DOTCAL  RSSIZE,[CHANNO(B),[2000,,C],[2000,,D]]\r
+       FATAL .CALL FAILURE\r
+       MOVEM   C,PAGLN(B)\r
+       MOVEM   D,LINLN(B)\r
+       JRST    DRESET\r
+\r
+IFN ITS,[\r
+FRESE1:        CAIE    0,TFIX\r
+       JRST    BADCHN\r
+       PUSH    P,(A)\r
+       JRST    FRESE3\r
+]\r
+\r
+; INTERFACE TO REOPEN CLOSED CHANNELS\r
+\r
+OPNCHN:        PUSH    TP,$TCHAN\r
+       PUSH    TP,B\r
+       MCALL   1,FRESET\r
+       POPJ    P,\r
+\r
+REATTY:        PUSHJ   P,TTYOP2\r
+       SKIPE   NOTTY\r
+       JRST    DRESET\r
+       MOVE    B,1(AB)\r
+       JRST    REATT1\r
+\f\r
+; FUNCTION TO LIST ALL CHANNELS\r
+\r
+MFUNCTION CHANLIST,SUBR\r
+\r
+       ENTRY   0\r
+\r
+       MOVEI   A,N.CHNS-1      ;MAX # OF REAL CHANNELS\r
+       MOVEI   C,0\r
+       MOVEI   B,CHNL1(TVP)    ;POINT TO FIRST REAL CHANNEL\r
+\r
+CHNLP: SKIPN   1(B)            ;OPEN?\r
+       JRST    NXTCHN          ;NO, SKIP\r
+       HRRZ    E,(B)           ; ABOUT TO FLUSH?\r
+       JUMPN   E,NXTCHN        ; YES, FORGET IT\r
+       MOVE    D,1(B)          ; GET CHANNEL\r
+       HRRZ    E,CHANNO-1(D)   ; GET REF COUNT\r
+       PUSH    TP,(B)\r
+       PUSH    TP,1(B)\r
+       ADDI    C,1             ;COUNT WINNERS\r
+       SOJGE   E,.-3           ; COUNT THEM\r
+NXTCHN:        ADDI    B,2\r
+       SOJN    A,CHNLP\r
+\r
+       SKIPN   B,CHNL0(TVP)+1  ;NOW HACK LIST OF PSUEDO CHANNELS\r
+       JRST    MAKLST\r
+CHNLS: PUSH    TP,(B)\r
+       PUSH    TP,(B)+1\r
+       ADDI    C,1\r
+       HRRZ    B,(B)\r
+       JUMPN   B,CHNLS\r
+\r
+MAKLST:        ACALL   C,LIST\r
+       JRST    FINIS\r
+\r
+\f; ROUTINE TO RESTORE A CLOSED CHANNEL TO ITS PREVIOUS STATE\r
+\r
+\r
+REOPN: PUSH    TP,$TCHAN\r
+       PUSH    TP,B\r
+       SKIPN   CHANNO(B)       ; ONLY REAL CHANNELS\r
+       JRST    PSUEDO\r
+\r
+IFN ITS,[\r
+       MOVSI   E,-4            ; SET UP POINTER FOR NAMES\r
+\r
+GETOPB:        MOVE    B,(TP)          ; GET CHANNEL\r
+       MOVEI   A,@RDTBL(E)     ; GET POINTER\r
+       MOVE    B,(A)           ; NOW STRING\r
+       MOVE    A,-1(A)\r
+       PUSHJ   P,STRTO6        ; LEAVES SIXBIT ON STACK\r
+       AOBJN   E,GETOPB\r
+]\r
+IFE ITS,[\r
+       MOVE    A,RDEVIC-1(B)\r
+       MOVE    B,RDEVIC(B)\r
+       PUSHJ   P,STRTO6        ; GET DEV NAME IN SIXBIT\r
+]\r
+       MOVE    B,(TP)          ; RESTORE CHANNEL\r
+       MOVE    A,DIRECT-1(B)\r
+       MOVE    B,DIRECT(B)\r
+       PUSHJ   P,CHMOD ; CHECK FOR A VALID MODE\r
+\r
+IFN ITS,       HLRZS   E,-3(P)         ; GET DEVICE IN PROPER PLACE\r
+IFE ITS,       HLRZS   E,(P)\r
+       MOVE    B,(TP)          ; RESTORE CHANNEL\r
+       CAIN    E,(SIXBIT /DSK/)\r
+       JRST    DISKH           ; DISK WINS IMMEIDATELY\r
+       CAIN    E,(SIXBIT /TTY/)        ; NO NEED TO RE-OPEN THE TTY\r
+       JRST    REOPD1\r
+IFN ITS,[\r
+       ANDI    E,777700        ; COULD BE "UTn"\r
+       MOVE    D,CHANNO(B)     ; GET CHANNEL\r
+       ASH     D,1\r
+       ADDI    D,CHNL0(TVP)    ; DON'T SEEM TO BE OPEN\r
+       SETZM   1(D)\r
+       SETZM   CHANNO(B)\r
+       CAIN    E,(SIXBIT /UT /)\r
+       JRST    REOPD           ; CURRENTLY, CANT RESTORE UTAPE CHANNLES\r
+       CAIN    E,(SIXBIT /AI /)\r
+       JRST    REOPD           ; CURRENTLY CANT RESTORE AI CHANNELS\r
+       CAIN    E,(SIXBIT /ML /)\r
+       JRST    REOPD           ; CURRENTLY CANT RESTORE ML CHANNELS\r
+       CAIN    E,(SIXBIT /DM /)\r
+       JRST    REOPD           ; CURRENTLY CANT RESTORE DM CHANNELS\r
+]\r
+       PUSH    TP,$TCHAN       ; TRY TO RESET IT \r
+       PUSH    TP,B\r
+       MCALL   1,FRESET\r
+\r
+IFN ITS,[\r
+REOPD1:        AOS     -4(P)\r
+REOPD: SUB     P,[4,,4]\r
+]\r
+IFE ITS,[\r
+REOPD1:        AOS     -1(P)\r
+REOPD: SUB     P,[1,,1]\r
+]\r
+REOPD0:        SUB     TP,[2,,2]\r
+       POPJ    P,\r
+\r
+IFN ITS,[\r
+DISKH: MOVE    C,(P)           ; SNAME\r
+       .SUSET  [.SSNAM,,C]\r
+]\r
+IFE ITS,[\r
+DISKH: MOVEM   A,(P)           ; SAVE MODE WORD\r
+       PUSHJ   P,STSTK         ; STRING TO STACK\r
+       MOVE    A,(E)           ; RESTORE MODE WORD\r
+       PUSH    TP,$TPDL\r
+       PUSH    TP,E            ; SAVE PDL BASE\r
+       MOVE    B,-2(TP)        ; CHANNEL BACK TO B\r
+]\r
+       MOVE    C,ACCESS(B)     ; GET CHANNELS ACCESS\r
+       TRNN    A,2             ; SKIP IF NOT ASCII CHANNEL\r
+       JRST    DISKH1\r
+       HRRZ    D,ACCESS-1(B)   ; IF PARTIAL WORD OUT\r
+       IMULI   C,5             ; TO CHAR ACCESS\r
+       JUMPE   D,DISKH1        ; NO SWEAT\r
+       ADDI    C,(D)\r
+       SUBI    C,5\r
+DISKH1:        HRRZ    D,BUFSTR-1(B)   ; ANY CHARS IN MUDDLE BUFFER\r
+       JUMPE   D,DISKH2\r
+       PUSH    P,A\r
+       PUSH    P,C\r
+       MOVEI   C,BUFSTR-1(B)\r
+       PUSHJ   P,BYTDOP        ; FIND LENGTH OF WHOLE BUFFER\r
+       HLRZ    D,(A)           ; LENGTH + 2 TO D\r
+       SUBI    D,2\r
+       IMULI   D,5             ; TO CHARS\r
+       POP     P,C\r
+       POP     P,A\r
+DISKH2:        SUBI    C,(D)           ; UPDATE CHAR ACCESS\r
+       IDIVI   C,5             ; BACK TO WORD ACCESS\r
+       IORI    A,6             ; BLOCK IMAGE\r
+IFN ITS,[\r
+       TRNE    A,1\r
+       IORI    A,100000        ; WRITE OVER BIT\r
+       HRLM    A,-3(P)\r
+       MOVEI   A,-3(P)\r
+       PUSHJ   P,DOOPN\r
+       JRST    REOPD\r
+       MOVE    A,C             ; ACCESS TO A\r
+       PUSHJ   P,GETFLN        ; CHECK LENGTH\r
+       CAIGE   0,(A)           ; CHECK BOUNDS\r
+       JRST    .+3             ; COMPLAIN\r
+       PUSHJ   P,DOACCS        ; AND ACESS\r
+       JRST    REOPD1          ; SUCCESS\r
+\r
+       MOVE    A,CHANNO(B)     ; CLOSE THE G.D. CHANNEL\r
+       PUSHJ   P,MCLOSE\r
+       JRST    REOPD\r
+\r
+DOACCS:        PUSH    P,A\r
+       HRLZ    A,CHANNO(B)\r
+       ASH     A,5\r
+       IOR     A,[.ACCESS (P)]\r
+       XCT     A\r
+       POP     P,A\r
+       POPJ    P,\r
+\r
+DOIOTO:\r
+DOIOTI:\r
+DOIOT:\r
+       PUSH    P,0\r
+       MOVSI   0,TCHAN\r
+       MOVEM   0,BSTO(PVP)     ; IN CASE OF INTERRUPT\r
+       ENABLE\r
+       HRLZ    0,CHANNO(B)\r
+       ASH     0,5\r
+       IOR     0,[.IOT A]\r
+       XCT     0\r
+       DISABLE\r
+       SETZM   BSTO(PVP)\r
+       POP     P,0\r
+       POPJ    P,\r
+\r
+GETFLN:        MOVE    0,CHANNO(B)     ; GET CHANNEL\r
+       .CALL   FILBLK          ; READ LNTH\r
+       .VALUE\r
+       POPJ    P,\r
+\r
+FILBLK:        SETZ\r
+       SIXBIT /FILLEN/\r
+       0\r
+       402000,,0       ; STUFF RESULT IN 0\r
+]\r
+IFE ITS,[\r
+\r
+       HRROI   B,1(E)          ; TENEX STRING POINTER\r
+       MOVEI   A,1(P)          ; A POINT TO BLOCK OF INFO\r
+       PUSH    P,[100400,,0]   ; FORCE JFN REUSE AND ONLY ACCEPT EXISTING FILE\r
+       PUSH    P,[377777,,377777]      ; NO I/O FOR CORRECTIONS ETC.\r
+       REPEAT  6,PUSH P,[0]            ; OTHER SLOTS\r
+       MOVE    D,-2(TP)        ; CHANNEL BACK\r
+       PUSH    P,CHANNO(D)     ; AND DESIRED JFN\r
+       GTJFN                   ; GO GET IT\r
+       JRST    RGTJL           ; COMPLAIN\r
+       MOVE    P,(TP)          ; RESTORE P\r
+       MOVE    A,(P)           ; MODE WORD BACK\r
+       MOVE    B,[440000,,200000]      ; FLAG BITS\r
+       TRNE    A,1             ; SKIP FOR INPUT\r
+       TRC     B,300000        ; CHANGE TO WRITE\r
+       MOVE    A,CHANNO(D)     ; GET JFN\r
+       OPENF\r
+       JRST    ROPFLS\r
+       MOVE    E,C             ; LENGTH TO E\r
+       SIZEF                   ; GET CURRENT LENGTH\r
+       JRST    ROPFLS\r
+       CAMGE   B,E             ; STILL A WINNER\r
+       JRST    ROPFLS\r
+       MOVE    A,-2(TP)        ; CHANNEL\r
+       MOVE    A,CHANNO(A)     ; JFN\r
+       MOVE    B,C\r
+       SFPTR\r
+       JRST    ROPFLS\r
+       SUB     TP,[2,,2]       ; FLUSH PDL POINTER\r
+       JRST    REOPD1\r
+\r
+ROPFLS:        MOVE    A,-2(TP)\r
+       MOVE    A,CHANNO(A)\r
+       CLOSF                   ; ATTEMPT TO CLOSE\r
+       JFCL                    ; IGNORE FAILURE\r
+       SKIPA\r
+\r
+RGTJL: MOVE    P,(TP)\r
+       SUB     TP,[2,,2]\r
+       JRST    REOPD\r
+\r
+DOACCS:        PUSH    P,B\r
+       EXCH    A,B\r
+       MOVE    A,CHANNO(A)\r
+       SFPTR\r
+       JRST    ACCFAI\r
+       POP     P,B\r
+       POPJ    P,\r
+]\r
+PSUEDO:        AOS     (P)             ; ASSUME SUCCESS FOR NOW\r
+       MOVEI   B,RDEVIC-1(B)   ; SEE WHAT DEVICE IS\r
+       PUSHJ   P,CHRWRD\r
+       JFCL\r
+       CAME    B,[ASCII /E&S/] ; DISPLAY ?\r
+       CAMN    B,[ASCII /DIS/]\r
+       SKIPA   B,(TP)          ; YES, REGOBBLE CHANNEL AND CONTINUE\r
+       JRST    REOPD0          ; NO, RETURN HAPPY\r
+       PUSHJ   P,DISROP\r
+       SOS     (P)             ; DISPLAY DID NOT REOPEN, UNDO ASSUMPTION OF SUCCESS\r
+       JRST    REOPD0\r
+\r
+\f;THIS PROGRAM CLOSES THE SPECIFIED CHANNEL\r
+\r
+MFUNCTION FCLOSE,SUBR,[CLOSE]\r
+\r
+       ENTRY   1               ;ONLY ONE ARG\r
+       GETYP   A,(AB)          ;CHECK ARGS\r
+       CAIE    A,TCHAN         ;IS IT A CHANNEL\r
+       JRST    WTYP1\r
+       MOVE    B,1(AB)         ;PICK UP THE CHANNEL\r
+       HRRZ    A,CHANNO-1(B)   ; GET REF COUNT\r
+       SOJGE   A,CFIN5         ;  NOT READY TO REALLY CLOSE\r
+       CAME    B,TTICHN+1(TVP) ; CHECK FOR TTY\r
+       CAMN    B,TTOCHN+1(TVP)\r
+       JRST    CLSTTY\r
+       MOVE    A,[JRST CHNCLS]\r
+       MOVEM   A,IOINS(B)      ;CLOBBER THE IO INS\r
+       MOVE    A,RDEVIC-1(B)   ;GET THE NAME OF THE DEVICE\r
+       MOVE    B,RDEVIC(B)\r
+       PUSHJ   P,STRTO6\r
+       HLRZS   A,(P)\r
+       MOVE    B,1(AB)         ; RESTORE CHANNEL\r
+       CAIE    A,(SIXBIT /E&S/)\r
+       CAIN    A,(SIXBIT /DIS/)\r
+       PUSHJ   P,DISCLS\r
+       MOVE    B,1(AB)         ; IN CASE CLOBBERED BY DISCLS\r
+       SKIPN   A,CHANNO(B)     ;ANY REAL CHANNEL?\r
+       JRST    REMOV           ; NO, EITHER  CLOSED OR PSEUDO CHANNEL\r
+\r
+       MOVE    A,DIRECT-1(B)   ; POINT TO DIRECTION\r
+       MOVE    B,DIRECT(B)\r
+       PUSHJ   P,STRTO6        ; CONVERT TO WORD\r
+       POP     P,A\r
+       LDB     E,[140600,,(P)] ; FIRST CHAR OD DEV NAME\r
+       CAIE    E,'T            ; SKIP IF TTY\r
+       JRST    CFIN4\r
+       CAME    A,[SIXBIT /READ/]       ; SKIP IF WINNER\r
+       JRST    CFIN1\r
+IFN ITS,[\r
+       MOVE    B,1(AB)         ; IN ITS CHECK STATUS\r
+       LDB     A,[600,,STATUS(B)]\r
+       CAILE   A,2\r
+       JRST    CFIN1\r
+]\r
+       PUSH    TP,$TCHSTR\r
+       PUSH    TP,CHQUOTE CHAR\r
+       PUSH    TP,(AB)\r
+       PUSH    TP,1(AB)\r
+       MCALL   2,OFF           ; TURN OFF INTERRUPT\r
+CFIN1: MOVE    B,1(AB)\r
+       MOVE    A,CHANNO(B)\r
+IFN ITS,[\r
+       PUSHJ   P,MCLOSE\r
+]\r
+IFE ITS,[\r
+       TLZ     A,400000        ; FOR JFN RELEASE\r
+       CLOSF                   ; CLOSE THE FILE AND RELEASE THE JFN\r
+       JFCL\r
+       MOVE    A,CHANNO(B)\r
+]\r
+CFIN:  LSH     A,1\r
+       ADDI    A,CHNL0+1(TVP)  ;POINT TO THIS CHANNELS LSOT\r
+       SETZM   CHANNO(B)\r
+       SETZM   (A)             ;AND CLOBBER IT\r
+       HLLZS   BUFSTR-1(B)\r
+       SETZM   BUFSTR(B)\r
+       HLLZS   ACCESS-1(B)\r
+CFIN2: HLLZS   -4(B)\r
+       MOVSI   A,TCHAN         ;RETURN THE CHANNEL\r
+       JRST    FINIS\r
+\r
+CLSTTY:        PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE ATTEMPT-TO-CLOSE-TTY-CHANNEL\r
+       JRST    CALER1\r
+\r
+\r
+REMOV: MOVEI   D,CHNL0(TVP)+1  ;ATTEMPT TO REMOVE FROM PSUEDO CHANNEL LIST\r
+REMOV0:        SKIPN   C,D             ;FOUND ON LIST ?\r
+       JRST    CFIN2           ;NO, JUST IGNORE THIS CLOSED CHANNEL\r
+       HRRZ    D,(C)           ;GET POINTER TO NEXT\r
+       CAME    B,(D)+1         ;FOUND ?\r
+       JRST    REMOV0\r
+       HRRZ    D,(D)           ;YES, SPLICE IT OUT\r
+       HRRM    D,(C)\r
+       JRST    CFIN2\r
+\r
+\r
+; CLOSE UP ANY LEFTOVER BUFFERS\r
+\r
+CFIN4: CAME    A,[SIXBIT /PRINTO/]\r
+       CAMN    A,[SIXBIT /PRINTB/]\r
+       JRST    .+3\r
+       CAME    A,[SIXBIT /PRINT/]\r
+       JRST    CFIN1\r
+       MOVE    B,1(AB)         ; GET CHANNEL\r
+       GETYP   0,BUFSTR-1(B)   ; IS THERE AN OUTPUT BUFFER\r
+       SKIPN   BUFSTR(B)\r
+       JRST    CFIN1\r
+       CAIE    0,TCHSTR\r
+       JRST    CFINX1\r
+IFE ITS,       PUSH    P,A             ; SAVE MODE\r
+       PUSHJ   P,BFCLOS\r
+IFE ITS,[\r
+       POP     P,A             ; RESTORE MODE\r
+       MOVE    0,RDEVIC(B)\r
+       ILDB    0,0\r
+       CAIN    0,"D\r
+       CAME    A,[SIXBIT /PRINT/]\r
+       JRST    CFINX1\r
+       MOVE    A,CHANNO(B)     ; GET JFN\r
+       TLO     A,400000        ; BIT MEANS DONT RELEASE JFN\r
+       CLOSF                   ; CLOSE THE FILE\r
+       FATAL   CLOSF LOST?\r
+       MOVE    E,B             ; SAVE CHANNEL\r
+       MOVE    A,CHANNO(B)\r
+       HRLI    A,11\r
+       MOVSI   B,7700          ; MASK\r
+       MOVSI   C,700           ; MAKE NEW SIZE 7\r
+       CHFDB\r
+       HRLI    A,12\r
+       SETOM   B\r
+       MOVE    C,ACCESS(E)     ; LENGTH IN CHARS\r
+       CHFDB\r
+]\r
+       HLLZS   BUFSTR-1(B)\r
+       SETZM   BUFSTR(B)\r
+CFINX1:        HLLZS   ACCESS-1(B)\r
+       JRST    CFIN1\r
+\r
+CFIN5: HRRM    A,CHANNO-1(B)\r
+       JRST    CFIN2\r
+\f;SUBR TO DO .ACCESS ON A READ CHANNEL\r
+;FORM: <ACCESS  CHANNEL FIX-NUMBER>\r
+;POSITIONS CHANNEL AT CHARACTER POSN FIX-NUMBER\r
+;H. BRODIE 7/26/72\r
+\r
+MFUNCTION MACCESS,SUBR,[ACCESS]\r
+       ENTRY   2       ;ARGS: CHANNEL AND FIX-NUMBER\r
+\r
+;CHECK ARGUMENT TYPES\r
+       GETYP   A,(AB)\r
+       CAIE    A,TCHAN         ;FIRST ARG SHOULD BE CHANNEL\r
+       JRST    WTYP1\r
+       GETYP   A,2(AB)         ;TYPE OF SECOND\r
+       CAIE    A,TFIX          ;SHOULD BE FIX\r
+       JRST    WTYP2\r
+\r
+;CHECK DIRECTION OF CHANNEL\r
+       MOVE    B,1(AB)         ;B GETS PNTR TO CHANNEL\r
+       MOVEI   B,DIRECT-1(B)   ;GET DIRECTION OF CHANNEL\r
+       PUSHJ   P,CHRWRD        ;GRAB THE CHAR STRNG\r
+       JFCL\r
+       CAME    B,[<ASCII /PRINT/>+1]\r
+       JRST    MACCA\r
+       PUSH    P,[2]           ;ACCESS ON PRINTB CHANNEL\r
+       MOVE    B,1(AB)\r
+       SKIPE   BUFSTR(B)       ;SEE IF WE MUST FLUSH PART BUFFER\r
+       PUSHJ   P,BFCLS1\r
+       JRST    MACC\r
+MACCA: PUSH    P,[0]           ; READ RATHER THAN READB INDICATOR\r
+       CAMN    B,[ASCIZ /READ/]\r
+       JRST    .+4\r
+       CAME    B,[ASCIZ /READB/]       ; READB CHANNEL?\r
+       JRST    WRONGD\r
+       AOS     (P)                     ; SET INDICATOR FOR BINARY MODE\r
+\r
+;CHECK THAT THE CHANNEL IS OPEN\r
+MACC:  MOVE    B,1(AB)         ;GET BACK PTR TO CHANNEL\r
+       SKIPN   CHANNO(B)       ;CLOSED CHANNELS HAVE CHANNO ZEROED OUT\r
+       JRST    CHNCLS  ;IF CHNL CLOSED => ERROR\r
+\r
+;COMPUTE ACCESS PNTR TO ACCESS WORD CHAR IS IN\r
+;REMAINDER IS NUMBER OF TIMES TO INCR BYTE POINTER\r
+ADEVOK:        SKIPGE  C,3(AB)         ;GET CHAR POSN...ALL NEGS = -5\r
+       MOVNI   C,-5\r
+;BUT .ACCESS -1 ISN'T IMPLEMENTED ON ITS YET, SO TELL HIM\r
+       JUMPGE  C,MACC1\r
+       PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE NEGATIVE-ACCESS-NOT-ON-ITS\r
+       JRST    CALER1\r
+MACC1: SKIPN   (P)\r
+       IDIVI   C,5\r
+\r
+;SETUP THE .ACCESS\r
+       MOVE    B,1(AB)         ;GET BACK PTR TO CHANNEL\r
+       MOVE    A,CHANNO(B)     ;A GETS REAL CHANNEL NUMBER\r
+IFN ITS,[\r
+       ROT     A,23.           ;SET UP IN AC FIELD\r
+       IOR     A,[.ACCESS 0,C] ;C CONTAINS PLACE TO ACCESS TO\r
+\r
+;DO IT TO IT!\r
+       XCT     A\r
+]\r
+IFE ITS,[\r
+       MOVE    B,C\r
+       SFPTR                   ; DO IT IN TENEX\r
+       JRST    ACCFAI\r
+       MOVE    B,1(AB)         ; RESTORE CHANNEL\r
+]\r
+       POP     P,E             ; CHECK FOR READB MODE\r
+       CAIN    E,2\r
+       JRST    DONADV          ; PRINTB CHANNEL\r
+       SKIPE   BUFSTR(B)       ; IS THERE A READ BUFFER TO FLUSH\r
+       JRST    .+3\r
+       SETZM   LSTCH(B)        ; CLEAR OUT POSSIBLE EOF INDICATOR\r
+       JRST    DONADV\r
+\r
+;NOW FORCE GETCHR TO DO A .IOT FIRST THING\r
+       MOVEI   C,BUFSTR-1(B)   ; FIND END OF STRING\r
+       PUSHJ   P,BYTDOP"\r
+       SUBI    A,2             ; LAST REAL WORD\r
+       HRLI    A,010700\r
+       MOVEM   A,BUFSTR(B)\r
+       HLLZS   BUFSTR-1(B)     ; CLOBBER CHAR COUNT\r
+       MOVEM   A,BUFSTR(B)\r
+       SETZM   LSTCH(B)        ;CLOBBER READ'S HIDDEN CHARACTER\r
+\r
+;NOW DO THE APPROPRIATE NUM OF BYTE ADVANCEMENTS\r
+       JUMPLE  D,DONADV\r
+ADVPTR:        PUSHJ   P,GETCHR\r
+       MOVE    B,1(AB)         ;RESTORE IN CASE CLOBBERED\r
+       SOJG    D,ADVPTR\r
+\r
+DONADV:        MOVE    C,3(AB)         ;FIXUP ACCESS SLOT IN CHNL\r
+       MOVEM   C,ACCESS(B)\r
+       MOVE    A,$TCHAN        ;TYPE OF RESULT = "CHANNEL"\r
+       JRST    FINIS           ;DONE...B CONTAINS CHANNEL\r
+\r
+IFE ITS,[\r
+ACCFAI:        PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE ACCESS-FAILURE\r
+       JRST    CALER1\r
+]\r
+\r
+\r
+;WRONG TYPE OF DEVICE ERROR\r
+WRDEV: PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE NON-DSK-DEVICE\r
+       JRST    CALER1\r
+\f\r
+; BINARY READ AND PRINT ROUTINES\r
+\r
+MFUNCTION PRINTB,SUBR\r
+\r
+       ENTRY   2\r
+\r
+PBFL:  PUSH    P,.             ; PUSH NON-ZERONESS\r
+       JRST    BINI1\r
+\r
+MFUNCTION READB,SUBR\r
+\r
+       ENTRY\r
+\r
+       PUSH    P,[0]\r
+       HLRZ    0,AB\r
+       CAIG    0,-3\r
+       CAIG    0,-7\r
+       JRST    WNA\r
+\r
+BINI1: GETYP   0,(AB)          ; SHOULD BE UVEC OR STORE\r
+       CAIN    0,TUVEC\r
+       JRST    BINI2\r
+       CAIE    0,TSTORAGE\r
+       JRST    WTYP1           ; ELSE LOSE\r
+BINI2: MOVE    B,1(AB)         ; GET IT\r
+       HLRE    C,B\r
+       SUBI    B,(C)           ; POINT TO DOPE\r
+       GETYP   A,(B)\r
+       PUSHJ   P,SAT"          ; GET ITS ST.ALOC.TYPE\r
+       CAIE    A,S1WORD\r
+       JRST    WTYP1\r
+       GETYP   0,2(AB)\r
+       CAIE    0,TCHAN         ; BETTER BE A CHANNEL\r
+       JRST    WTYP2\r
+       MOVE    B,3(AB)         ; GET IT\r
+       MOVEI   B,DIRECT-1(B)   ; GET DIRECTION OF\r
+       PUSHJ   P,CHRWRD        ; INTO 1 WORD\r
+       JFCL\r
+       MOVNI   E,1\r
+       CAMN    B,[ASCII /READB/]\r
+       MOVEI   E,0\r
+       CAMN    B,[<ASCII /PRINT/>+1]\r
+       MOVE    E,PBFL\r
+       JUMPL   E,WRONGD                ; LOSER\r
+       CAME    E,(P)           ; CHECK WINNGE\r
+       JRST    WRONGD\r
+       MOVE    B,3(AB)         ; GET CHANNEL BACK\r
+       SKIPN   A,IOINS(B)      ; OPEN?\r
+       PUSHJ   P,OPENIT                ; LOSE\r
+       CAMN    A,[JRST CHNCLS]\r
+       JRST    CHNCLS          ; LOSE, CLOSED\r
+       JUMPN   E,BUFOU1        ; JUMP FOR OUTPUT\r
+       CAML    AB,[-5,,]       ; SKIP IF EOF GIVEN\r
+       JRST    BINI5\r
+       MOVE    0,4(AB)\r
+       MOVEM   0,EOFCND-1(B)\r
+       MOVE    0,5(AB)\r
+       MOVEM   0,EOFCND(B)\r
+BINI5: SKIPE   LSTCH(B)        ; INDICATES IF EOF HIT\r
+       JRST    BINEOF\r
+       MOVE    A,1(AB)         ; GET VECTOR\r
+       PUSHJ   P,PGBIOI        ; READ IT\r
+       HLRE    C,A             ; GET COUNT DONE\r
+       HLRE    D,1(AB) ; AND FULL COUNT\r
+       SUB     C,D             ; C=> TOTAL READ\r
+       ADDM    C,ACCESS(B)\r
+       JUMPGE  A,BINIOK        ; NOT EOF YET\r
+       SETOM   LSTCH(B)\r
+BINIOK:        MOVE    B,C\r
+       MOVSI   A,TFIX          ; RETURN AMOUNT ACTUALLY READ\r
+       JRST    FINIS\r
+\r
+BUFOU1:        SKIPE   BUFSTR(B)       ; ANY BUFFERS AROUND?\r
+       PUSHJ   P,BFCLS1        ; GET RID OF SAME\r
+       MOVE    A,1(AB)\r
+       PUSHJ   P,PGBIOO\r
+       HLRE    C,1(AB)\r
+       MOVNS   C\r
+       addm    c,ACCESS(B)\r
+       MOVE    A,(AB)          ; RET VECTOR ETC.\r
+       MOVE    B,1(AB)\r
+       JRST    FINIS\r
+\r
+\r
+BINEOF:        PUSH    TP,EOFCND-1(B)\r
+       PUSH    TP,EOFCND(B)\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,B\r
+       MCALL   1,FCLOSE        ; CLOSE THE LOSER\r
+       MCALL   1,EVAL\r
+       JRST    FINIS\r
+\r
+OPENIT:        PUSH    P,E\r
+       PUSHJ   P,OPNCHN        ;TRY TO OPEN THE LOSER\r
+       JUMPE   B,CHNCLS        ;FAIL\r
+       POP     P,E\r
+       POPJ    P,\r
+\f; THESE SUBROUTINES BY NDR 9/16/73 TO FACILITATE THE\r
+; TYPES OF IO NECESSARY TO MAKE MORE EFFICIENT USE OF\r
+; THE NETWORK AND DO RELATED FILE TRANSFER TYPE OF JOBS.\r
+\r
+R1CHAR:        SKIPN   A,LSTCH(B)              ; CHAR READING ROUTINE FOR FCOPY\r
+       PUSHJ   P,RXCT\r
+       MOVEM   A,LSTCH(B)\r
+       JUMPL   A,.+2                   ; IN CASE OF -1 ON STY\r
+       TRZN    A,400000                ; EXCL HACKER\r
+       JRST    .+4\r
+       MOVEM   A,LSTCH(B)              ; SAVE DE-EXCLED CHAR\r
+       MOVEI   A,"!\r
+       JRST    .+2\r
+       SETZM   LSTCH(B)\r
+       PUSH    P,C\r
+       HRRZ    C,DIRECT-1(B)\r
+       CAIE    C,5                     ; IF DIRECTION IS 5 LONG THEN READB\r
+       JRST    R1CH1\r
+       AOS     C,ACCESS-1(B)\r
+       CAMN    C,[TFIX,,1]\r
+       AOS     ACCESS(B)               ; EVERY FIFTY INCREMENT\r
+       CAMN    C,[TFIX,,5]\r
+       HLLZS   ACCESS-1(B)\r
+       JRST    .+2\r
+R1CH1: AOS     ACCESS(B)\r
+       POP     P,C\r
+       POPJ    P,\r
+\r
+W1CHAR:        CAIE    A,15            ; CHAR WRITING ROUTINE, TEST FOR CR\r
+       JRST    .+3\r
+       SETOM   CHRPOS(B)\r
+       AOSA    LINPOS(B)\r
+       CAIE    A,12                    ; TEST FOR LF\r
+       AOS     CHRPOS(B)               ; IF NOT LF AOS CHARACTE5R POSITION\r
+       CAIE    A,14                    ; TEST FOR FORM FEED\r
+       JRST    .+3\r
+       SETZM   CHRPOS(B)               ; IF FORM FEED ZERO CHARACTER POSITION\r
+       SETZM   LINPOS(B)               ; AND LINE POSITION\r
+       CAIE    A,11                    ; IS THIS A TAB?\r
+       JRST    .+6\r
+       MOVE    C,CHRPOS(B)\r
+       ADDI    C,7\r
+       IDIVI   C,8.\r
+       IMULI   C,8.                    ; FIX UP CHAR POS FOR TAB\r
+       MOVEM   C,CHRPOS(B)             ; AND SAVE\r
+       PUSH    P,C\r
+       HRRZ    C,DIRECT-1(B)\r
+       CAIE    C,6                     ; SIX LONG MUST BE PRINTB\r
+       JRST    W1CH1\r
+       AOS     C,ACCESS-1(B)\r
+       CAMN    C,[TFIX,,1]\r
+       AOS     ACCESS(B)\r
+       CAMN    C,[TFIX,,5]\r
+       HLLZS   ACCESS-1(B)\r
+       JRST    .+2\r
+W1CH1: AOS     ACCESS(B)\r
+       PUSHJ   P,WXCT\r
+       POP     P,C\r
+       POPJ    P,\r
+\r
+R1C:   SUBM    M,(P)                   ;LITTLE ENTRY FOR COMPILED STUFF\r
+       PUSH    TP,$TCHAN               ;SAVE THE CHANNEL TO BLESS IT\r
+       PUSH    TP,B\r
+       MOVEI   B,DIRECT-1(B)\r
+       PUSHJ   P,CHRWRD\r
+       JFCL\r
+       CAME    B,[ASCIZ /READ/]\r
+       CAMN    B,[ASCII /READB/]\r
+       JRST    .+2\r
+       JRST    BADCHN\r
+       POP     TP,B\r
+       POP     TP,(TP)\r
+       SKIPN   IOINS(B)                ; IS THE CHANNEL OPEN\r
+       PUSHJ   P,OPENIT                ; NO, GO DO IT\r
+       PUSHJ   P,GRB                   ; MAKE SURE WE HAVE A READ BUFFER\r
+       PUSHJ   P,R1CHAR                ; AND GET HIM A CHARACTER\r
+       JRST    MPOPJ                   ; THATS ALL FOLKS\r
+\r
+W1C:   SUBM    M,(P)\r
+       PUSHJ   P,W1CI\r
+       JRST    MPOPJ\r
+\r
+W1CI:  PUSH    TP,$TCHAN\r
+       PUSH    TP,B\r
+       PUSH    P,A                     ; ASSEMBLER ENTRY TO OUTPUT 1 CHAR\r
+       MOVEI   B,DIRECT-1(B)\r
+       PUSHJ   P,CHRWRD                ; INTERNAL CALL TO W1CHAR\r
+       JFCL\r
+       CAME    B,[ASCII /PRINT/]\r
+       CAMN    B,[<ASCII /PRINT/>+1]\r
+       JRST    .+2\r
+       JRST    BADCHN\r
+       POP     TP,B\r
+       POP     TP,(TP)\r
+       SKIPN   IOINS(B)                ; MAKE SURE THAT IT IS OPEN\r
+       PUSHJ   P,OPENIT\r
+       PUSHJ   P,GWB\r
+       POP     P,A                     ; GET THE CHAR TO DO\r
+       JRST    W1CHAR\r
+\r
+; ROUTINES TO REPLACE XCT IOINS(B) FOR INPUT AND OUTPUT\r
+; THEY DO THE XCT THEN CHECK OUT POSSIBLE SCRIPTAGE--BLECH.\r
+\r
+\r
+WXCT:  PUSH    P,A                     ; SAVE THE CHAR TO WRITE\r
+       PUSH    TP,$TCHAN               ; AND SAVE THE CHANNEL TOO\r
+       PUSH    TP,B\r
+       XCT     IOINS(B)                ; DO THE REAL ONE\r
+       JRST    DOSCPT                  ; AND CHECK OUT SCRIPTAGE\r
+\r
+RXCT:  PUSH    TP,$TCHAN\r
+       PUSH    TP,B                    ; DO IT FOR READS, SAVE THE CHAN\r
+       XCT     IOINS(B)                ; READ IT\r
+       PUSH    P,A                     ; AND SAVE THE CHAR AROUND\r
+       JRST    DOSCPT                  ; AND CHECK OUT SCRIPTAGE\r
+\r
+DOSCPT:        MOVE    B,(TP)                  ;CHECK FOR SCRIPTAGE\r
+       SKIPN   SCRPTO(B)               ; IF ZERO FORGET IT\r
+       JRST    SCPTDN                  ; THATS ALL THERE IS TO IT\r
+       PUSH    P,C                     ; SAVE AN ACCUMULATOR FOR CLEANLINESS\r
+       GETYP   C,SCRPTO-1(B)           ; IS IT A LIST\r
+       CAIE    C,TLIST\r
+       JRST    BADCHN\r
+       PUSH    TP,$TLIST\r
+       PUSH    TP,[0]          ; SAVE A SLOT FOR THE LIST\r
+       MOVE    C,SCRPTO(B)             ; GET THE LIST OF SCRIPT CHANNELS\r
+SCPT1: GETYP   B,(C)                   ; GET THE TYPE OF THIS SCRIPT CHAN\r
+       CAIE    B,TCHAN\r
+       JRST    BADCHN                  ; IF IT ISN'T A CHANNEL, COMPLAIN\r
+       HRRZ    B,(C)                   ; GET THE REST OF THE LIST IN B\r
+       MOVEM   B,(TP)                  ; AND STORE ON STACK\r
+       MOVE    B,1(C)                  ; GET THE CHANNEL IN B\r
+       MOVE    A,-1(P)                 ; AND THE CHARACTER IN A\r
+       PUSHJ   P,W1CI          ; GO TO INTERNAL W1C, IT BLESSES GOODIES\r
+       SKIPE   C,(TP)                  ; GET THE REST OF LIST OF CHANS\r
+       JRST    SCPT1                   ; AND CYCLE THROUGH\r
+       SUB     TP,[2,,2]               ; CLEAN OFF THE LIST OF CHANS\r
+       POP     P,C                     ; AND RESTORE ACCUMULATOR C\r
+SCPTDN:        POP     P,A                     ; RESTORE THE CHARACTER\r
+       POP     TP,B                    ; AND THE ORIGINAL CHANNEL\r
+       POP     TP,(TP)\r
+       POPJ    P,                      ; AND THATS ALL\r
+\r
+\r
+; SUBROUTINE TO COPY FROM INCHAN TO OUTCHAN UNTIL EOF HIT\r
+; ON THE INPUT CHANNEL\r
+; CALL IS <FILECOPY IN OUT> WHERE DEFAULTS ARE INCHAN AND OUTCHAN\r
+\r
+       MFUNCTION       FCOPY,SUBR,[FILECOPY]\r
+\r
+       ENTRY\r
+       HLRE    0,AB\r
+       CAMGE   0,[-4]\r
+       JRST    WNA                     ; TAKES FROM 0 TO 2 ARGS\r
+\r
+       JUMPE   0,.+4                   ; NO FIRST ARG?\r
+       PUSH    TP,(AB)\r
+       PUSH    TP,1(AB)                ; SAVE IN CHAN\r
+       JRST    .+6\r
+       MOVE    A,$TATOM\r
+       MOVE    B,IMQUOTE INCHAN\r
+       PUSHJ   P,IDVAL\r
+       PUSH    TP,A\r
+       PUSH    TP,B\r
+       HLRE    0,AB                    ; CHECK FOR SECOND ARG\r
+       CAML    0,[-2]                  ; WAS THERE MORE THAN ONE ARG?\r
+       JRST    .+4\r
+       PUSH    TP,2(AB)                ; SAVE SECOND ARG\r
+       PUSH    TP,3(AB)\r
+       JRST    .+6\r
+       MOVE    A,$TATOM                ; LOOK UP OUTCHAN AS DEFAULT\r
+       MOVE    B,IMQUOTE OUTCHAN\r
+       PUSHJ   P,IDVAL\r
+       PUSH    TP,A\r
+       PUSH    TP,B                    ; AND SAVE IT\r
+\r
+       MOVE    A,-3(TP)\r
+       MOVE    B,-2(TP)                ; INPUT CHANNEL\r
+       MOVEI   0,0                             ; INDICATE INPUT\r
+       PUSHJ   P,CHKCHN                ; CHECK FOR GOOD CHANNEL\r
+       MOVE    A,-1(TP)\r
+       MOVE    B,(TP)                  ; GET OUT CHAN\r
+       MOVEI   0,1                     ; INDICATE OUT CHAN\r
+       PUSHJ   P,CHKCHN                ; CHECK FOR GOOD OUT CHAN\r
+\r
+       PUSH    P,[0]                   ; COUNT OF CHARS OUTPUT\r
+\r
+       MOVE    B,-2(TP)\r
+       PUSHJ   P,GRB                   ; MAKE SURE WE HAVE READ BUFF\r
+       MOVE    B,(TP)\r
+       PUSHJ   P,GWB                   ; MAKE SURE WE HAVE WRITE BUFF\r
+\r
+FCLOOP:        MOVE    B,-2(TP)\r
+       PUSHJ   P,R1CHAR                ; GET A CHAR\r
+       JUMPL   A,FCDON                 ; IF A NEG NUMBER WE GOT EOF\r
+       MOVE    B,(TP)                  ; GET OUT CHAN\r
+       PUSHJ   P,W1CHAR                ; SPIT IT OUT\r
+       AOS     (P)                     ; INCREMENT COUNT\r
+       JRST    FCLOOP\r
+\r
+FCDON: SUB     TP,[2,,2]               ; POP OFF OUTCHAN\r
+       MCALL   1,FCLOSE                ; CLOSE INCHAN\r
+       MOVE    A,$TFIX\r
+       POP     P,B                     ; GET CHAR COUNT TO RETURN\r
+       JRST FINIS\r
+\r
+CHKCHN:        PUSH    P,0                     ; CHECK FOR GOOD TASTING CHANNEL\r
+       PUSH    TP,A\r
+       PUSH    TP,B\r
+       GETYP   C,A\r
+       CAIE    C,TCHAN\r
+       JRST    CHKBDC                  ; GO COMPLAIN IN RIGHT WAY\r
+       MOVEI   B,DIRECT-1(B)\r
+       PUSHJ   P,CHRWRD\r
+       JRST    CHKBDC\r
+       MOVE    C,(P)                   ; GET CHAN DIRECT\r
+       CAMN    B,CHKT(C)\r
+       JRST    .+4\r
+       ADDI    C,2                     ; TEST FOR READB OR PRINTB ALSO\r
+       CAME    B,CHKT(C)               ; TEST FOR CORRECT DIRECT\r
+       JRST    CHKBDC\r
+       MOVE    B,(TP)\r
+       SKIPN   IOINS(B)                ; MAKE SURE IT IS OPEN\r
+       PUSHJ   P,OPENIT                ; IF ZERO IOINS GO OPEN IT\r
+       SUB     TP,[2,,2]\r
+       POP     P,                      ; CLEAN UP STACKS\r
+       POPJ    P,\r
+\r
+CHKT:  ASCIZ /READ/\r
+       ASCII /PRINT/\r
+       ASCII /READB/\r
+       <ASCII /PRINT/>+1\r
+\r
+CHKBDC:        POP     P,E\r
+       MOVNI   D,2\r
+       IMULI   D,1(E)\r
+       HLRE    0,AB\r
+       CAMLE   0,D                     ; SEE IF THIS WAS HIS ARG OF DEFAULT\r
+       JRST    BADCHN\r
+       JUMPE   E,WTYP1\r
+       JRST    WTYP2\r
+\r
+\f; FUNCTIONS READSTRING AND PRINTSTRING WORK LIKE READB AND PRINTB,\r
+; THAT IS THEY READ INTO AND OUT OF STRINGS.  IN ADDITION BOTH ACCEPT\r
+; AN ADDITIONAL ARGUMENT WHICH IS THE NUMBER OF CHARS TO READ OR PRINT, IF\r
+; IT IS DESIRED FOR THIS TO BE DIFFERENT THAN THE LENGTH OF THE STRING.\r
+\r
+; FORMAT IS <READSTRING .STRING .INCHANNEL .EOFCOND .MAXCHARS>\r
+; AND BOTH SUBRS RETURN THE NUMBER OF CHARS READ OR WRITTEN\r
+\r
+; FORMAT FOR PRINTSTRING IS <PRINTSTRING .STRING .OUTCHANNEL .MAXCHARS>\r
+\r
+; THESE WERE CODED 9/16/73 BY NEAL D. RYAN\r
+\r
+       MFUNCTION       RSTRNG,SUBR,READSTRING\r
+\r
+       ENTRY\r
+       PUSH    P,[0]           ; FLAG TO INDICATE READING\r
+       HLRE    0,AB\r
+       CAMG    0,[-1]\r
+       CAMG    0,[-9]\r
+       JRST    WNA             ; CHECK THAT IT HAS FROM 1 TO 4 ARGS\r
+       JRST    STRIO1\r
+\r
+       MFUNCTION       PSTRNG,SUBR,PRINTSTRING\r
+\r
+       ENTRY\r
+       PUSH    P,[1]           ; FLAG TO INDICATE WRITING\r
+       HLRE    0,AB\r
+       CAMG    0,[-1]\r
+       CAMG    0,[-7]\r
+       JRST    WNA             ; CHECK THAT IT HAS FROM 1 TO 3 ARGS\r
+\r
+STRIO1:        PUSH    TP,[0]          ; SAVE SLOT ON STACK\r
+       PUSH    TP,[0]\r
+       GETYP   0,(AB)\r
+       CAIE    0,TCHSTR                ; MAKE SURE WE GOT STRING\r
+       JRST    WTYP1\r
+       HRRZ    0,(AB)          ; CHECK FOR EMPTY STRING\r
+       SKIPN   (P)\r
+       JUMPE   0,MTSTRN\r
+       HLRE    0,AB\r
+       CAML    0,[-2]          ; WAS A CHANNEL GIVEN\r
+       JRST    STRIO2\r
+       GETYP   0,2(AB)\r
+       CAIE    0,TCHAN\r
+       JRST    WTYP2           ; SECOND ARG NOT CHANNEL\r
+       MOVE    B,3(AB)\r
+       MOVEI   B,DIRECT-1(B)\r
+       PUSHJ   P,CHRWRD\r
+       JFCL\r
+       MOVNI   E,1             ; CHECKING FOR GOOD DIRECTION\r
+       CAMN    B,[ASCII /READ/]\r
+       MOVEI   E,0\r
+       CAMN    B,[ASCII /PRINT/]\r
+       MOVEI   E,1\r
+       CAMN    B,[<ASCII /PRINT/>+1]\r
+       MOVEI   E,1\r
+       CAMN    B,[ASCII /READB/]\r
+       MOVEI   E,0\r
+       CAME    E,(P)\r
+       JRST    WRONGD          ; MAKE SURE CHANNEL IS OPEN IN RIGHT MODE\r
+       PUSH    TP,2(AB)\r
+       PUSH    TP,3(AB)        ; PUSH ON CHANNEL\r
+       JRST    STRIO3\r
+STRIO2:        MOVE    B,IMQUOTE INCHAN\r
+       MOVSI   A,TCHAN\r
+       SKIPE   (P)\r
+       MOVE    B,IMQUOTE OUTCHAN\r
+       PUSHJ   P,IDVAL\r
+       TLZ     A,TYPMSK#777777\r
+       CAME    A,$TCHAN\r
+       JRST    BADCHN          ; MAKE SURE WE GOT A GOOD DEFAULT CHANNEL\r
+       PUSH    TP,A\r
+       PUSH    TP,B\r
+STRIO3:        MOVE    B,(TP)          ; GET CHANNEL\r
+       SKIPN   E,IOINS(B)              ; MAKE SURE HE IS OPEN\r
+       PUSHJ   P,OPENIT                ; IF NOT GO OPEN\r
+       CAMN    E,[JRST CHNCLS]\r
+       JRST    CHNCLS          ; CHECK TO SEE THAT CHANNEL ISNT ALREADY CLOSED\r
+STRIO4:        HLRE    0,AB\r
+       CAML    0,[-4]\r
+       JRST    STRIO5          ; NO COUNT TO WORRY ABOUT\r
+       GETYP   0,4(AB)\r
+       MOVE    E,4(AB)\r
+       MOVE    C,5(AB)\r
+       CAIE    0,TCHSTR\r
+       CAIN    0,TFIX          ; BETTER BE A FIXED NUMBER\r
+       JRST    .+2\r
+       JRST    WTYP3\r
+       HRRZ    D,(AB)          ; GET ACTUAL STRING LENGTH\r
+       CAIN    0,TFIX\r
+       JRST    .+7\r
+       SKIPE   (P)     ; TEST FOR WRITING\r
+       JRST    .-7             ; IF WRITING WE GOT TROUBLE\r
+       PUSH    P,D             ; ACTUAL STRING LENGTH\r
+       MOVEM   E,(TB)  ; STUFF HIS FUNNY DELIM STRING\r
+       MOVEM   C,1(TB)\r
+       JRST    STRIO7\r
+       CAML    D,C             ; MAKE SURE THE STRING IS LONG ENOUGH\r
+       JRST    .+4             ; WIN\r
+       PUSH    TP,$TATOM       ; LOSAGE, COUNT TOO GREAT\r
+       PUSH    TP,EQUOTE COUNT-GREATER-THAN-STRING-SIZE\r
+       JRST    CALER1\r
+       PUSH    P,C     ; PUSH ON MAX COUNT\r
+       JRST    STRIO7\r
+STRIO5:\r
+STRIO6:        HRRZ    C,(AB)  ; GET CHAR COUNT\r
+       PUSH    P,C             ; AND PUSH IT ON STACK AS NO MAX COUNT GIVEN\r
+STRIO7:        HLRE    0,AB\r
+       CAML    0,[-6]\r
+       JRST    .+6\r
+       MOVE    B,(TP)          ; GET THE CHANNEL\r
+       MOVE    0,6(AB)\r
+       MOVEM   0,EOFCND-1(B)   ; STUFF IN SLOT IN CHAN\r
+       MOVE    0,7(AB)\r
+       MOVEM   0,EOFCND(B)\r
+       PUSH    TP,(AB)         ; PUSH ON STRING\r
+       PUSH    TP,1(AB)\r
+       PUSH    P,[0]           ; PUSH ON CURRENT COUNT OF CHARS DONE\r
+       MOVE    0,-2(P)         ; GET READ OR WRITE FLAG\r
+       JUMPN   0,OUTLOP        ; GO WRITE STUFF\r
+\r
+       MOVE    B,-2(TP)        ; GET CHANNEL\r
+       PUSHJ   P,GRB           ; MAKE SURE WE HAVE BUFF\r
+       SKIPGE  A,LSTCH(B)      ; CHECK FOR EOF ALREADY READ PREVIOUSLY\r
+       JRST    SRDOEF          ; GO DOES HIS EOF HACKING\r
+INLOP: INTGO\r
+       MOVE    B,-2(TP)        ; GET CHANNEL\r
+       MOVE    C,-1(P)         ; MAX COUNT\r
+       CAMG    C,(P)           ; COMPARE WITH COUNT DONE\r
+       JRST    STREOF          ; WE HAVE FINISHED\r
+       PUSHJ   P,R1CHAR        ; GET A CHAR\r
+       JUMPL   A,INEOF         ; EOF HIT\r
+       MOVE    C,1(TB)\r
+       HRRZ    E,(TB)          ; DO WE HAVE A STRING TO WORRY US?\r
+       SOJL    E,INLNT         ; GO FINISH STUFFING\r
+       ILDB    D,C\r
+       CAME    D,A\r
+       JRST    .-3\r
+       JRST    INEOF\r
+INLNT: IDPB    A,(TP)          ; STUFF IN STRING\r
+       SOS     -1(TP)          ; DECREMENT STRING COUNT\r
+       AOS     (P)             ; INCREMENT CHAR COUNT\r
+       JRST    INLOP\r
+\r
+INEOF: SKIPE   C,LSTCH(B)      ; IS THIS AN ! AND IS THERE A CHAR THERE\r
+       JRST    .+3             ; YES\r
+       MOVEM   A,LSTCH(B)      ; NO SAVE THE CHAR\r
+       JRST    .+3\r
+       ADDI    C,400000\r
+       MOVEM   C,LSTCH(B)\r
+       HRRZ    C,DIRECT-1(B)   ; GET THE TYPE OF CHAN\r
+       CAIN    C,5             ; IS IT READB?\r
+       JRST    .+3\r
+       SOS     ACCESS(B)       ; FIX UP ACCESS FOR READ CHANNEL\r
+       JRST    STREOF          ; AND THATS IT\r
+       HRRZ    C,ACCESS-1(B)   ; FOR A READB ITS WORSE\r
+       MOVEI   D,5\r
+       SKIPG   C\r
+       HRRM    D,ACCESS-1(B)   ; CHANGE A 0 TO A FIVE\r
+       SOS     C,ACCESS-1(B)\r
+       CAMN    C,[TFIX,,0]\r
+       SOS     ACCESS(B)       ; AND SOS THE WORD COUNT MAYBE\r
+       JRST    STREOF\r
+\r
+SRDOEF:        SETZM   LSTCH(B)        ; IN CASE OF -1, FLUSH IT\r
+       AOJE    A,INLOP         ; SKIP OVER -1 ON PTY'S\r
+       SUB     TP,[6,,6]\r
+       SUB     P,[3,,3]        ; POP JUNK OFF STACKS\r
+       PUSH    TP,EOFCND-1(B)\r
+       PUSH    TP,EOFCND(B)    ; WHAT WE NEED TO EVAL\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,B\r
+       MCALL   1,FCLOSE        ; CLOSE THE LOOSING CHANNEL\r
+       MCALL   1,EVAL          ; EVAL HIS EOF JUNK\r
+       JRST    FINIS\r
+\r
+OUTLOP:        MOVE    B,-2(TP)\r
+       PUSHJ   P,GWB           ; MAKE SURE WE HAVE BUFF\r
+OUTLP1:        INTGO\r
+       MOVE    B,-2(TP)\r
+       MOVE    C,-1(P)         ; MAX COUNT TO DO\r
+       CAMG    C,(P)           ; HAVE WE DONE ENOUGH\r
+       JRST    STREOF\r
+       ILDB    A,(TP)          ; GET THE CHAR\r
+       SOS     -1(TP)  ; SUBTRACT FROM STRING LENGTH\r
+       AOS     (P)             ; INC COUNT OF CHARS DONE\r
+       PUSHJ   P,W1CHAR        ; GO STUFF CHAR\r
+       JRST    OUTLP1\r
+\r
+STREOF:        MOVE    A,$TFIX\r
+       POP     P,B             ; RETURN THE LOOSER A COUNT OF WHAT WAS DONE\r
+       SUB     P,[2,,2]\r
+       SUB     TP,[6,,6]\r
+       JRST    FINIS\r
+\r
+\r
+GWB:   SKIPE   BUFSTR(B)\r
+       POPJ    P,\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,B            ; GET US A WRITE BUFFER ON PRINTB CHAN\r
+       MOVEI   A,BUFLNT\r
+       PUSHJ   P,IBLOCK\r
+       MOVSI   A,TWORD+.VECT.\r
+       MOVEM   A,BUFLNT(B)\r
+       SETOM   (B)\r
+       MOVEI   C,1(B)\r
+       HRLI    C,(B)\r
+       BLT     C,BUFLNT-1(B)\r
+       MOVE    C,B\r
+       HRLI    C,440700\r
+       MOVE    B,(TP)\r
+       MOVEI   0,C.BUF\r
+       IORM    0,-4(B)\r
+       MOVEM   C,BUFSTR(B)\r
+       MOVE    C,[TCHSTR,,BUFLNT*5]\r
+       MOVEM   C,BUFSTR-1(B)\r
+       SUB     TP,[2,,2]\r
+       POPJ    P,\r
+\r
+\r
+GRB:   SKIPE   BUFSTR(B)\r
+       POPJ    P,\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,B            ; GET US A READ BUFFER\r
+       MOVEI   A,BUFLNT\r
+       PUSHJ   P,IBLOCK\r
+       MOVEI   C,BUFLNT(B)\r
+       POP     TP,B\r
+       MOVEI   0,C.BUF\r
+       IORM    0,-4(B)\r
+       HRLI    C,440700\r
+       MOVEM   C,BUFSTR(B)\r
+       MOVSI   C,TCHSTR\r
+       MOVEM   C,BUFSTR-1(B)\r
+       SUB     TP,[1,,1]\r
+       POPJ    P,\r
+\r
+MTSTRN:        PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE EMPTY-STRING\r
+       JRST    CALER1\r
+\r
+\f; INPUT UNBUFFERING ROUTINE.  THIS DOES THE CHARACTER UNBUFFERING\r
+; FOR INPUT.  THE OPEN ROUTINE SETUPS A PUSHJ P, TO\r
+; THIS ROUTINE AS THE IOINS FOR A CHANNEL OPEN TO A NON-TTY DEVICE.\r
+\r
+; H. BRODIE 7/19/72\r
+\r
+; CALLING SEQ:\r
+;      PUSHJ   P,GETCHR\r
+;              B/ AOBJN PNTR TO CHANNEL VECTOR\r
+;              RETURNS NEXT CHARACTER IN AC A.\r
+;      ON ENCOUNTERING EITHER ^C OR NUL(^@) IT ASSUMES EOF AND\r
+;      TRANSMITS ONLY ^C ON SUCCESSIVE CALLS\r
+\r
+\r
+GETCHR:\r
+; FIRST GRAB THE BUFFER\r
+       GETYP   A,BUFSTR-1(B)   ; GET TYPE WORD\r
+       CAIN    A,TCHSTR        ; SKIPS IF NOT CHSTR (I.E. IF BAD BUFFER)\r
+       JRST    GTGBUF          ; IS GOOD BUFFER...SKIP ERROR RETURN\r
+BDCHAN:        PUSH    TP,$TATOM       ; ERROR RETURN\r
+       PUSH    TP,EQUOTE BAD-INPUT-BUFFER\r
+       JRST    CALER1\r
+\r
+; BUFFER WAS GOOD\r
+GTGBUF:        HRRZ    A,BUFSTR-1(B)   ; GET LENGTH OF STRING\r
+       SOJGE   A,GTGCHR        ; JUMP IF STILL MORE\r
+\r
+; HERE IF THE BUFFER WAS EXHAUSTED (BYTE PNTR POINTS INTO DOPE WDS)\r
+; GENERATE AN .IOT POINTER\r
+;FIRST SAVE C AND D AS I WILL CLOBBER THEM\r
+NEWBUF:        PUSH    P,C\r
+       PUSH    P,D\r
+IFN ITS,[\r
+       LDB     C,[600,,STATUS(B)]      ; GET TYPE\r
+       CAIG    C,2             ; SKIP IF NOT TTY\r
+]\r
+IFE ITS,[\r
+       SKIPE   BUFRIN(B)\r
+]\r
+       JRST    GETTTY          ; GET A TTY BUFFER\r
+\r
+       PUSHJ   P,PGBUFI        ; RE-FILL BUFFER\r
+\r
+       JUMPGE  A,BUFGOO                ;SKIPS IF IOT COMPLETED...FIX UP CHANNEL\r
+       MOVEI   C,1             ; MAKE SURE LAST EOF REALLY ENDS IT\r
+       ANDCAM  C,-1(A)\r
+       MOVSI   C,014000        ; GET A ^C\r
+       MOVEM   C,(A)           ;FAKE AN EOF\r
+\r
+; RESET THE BYTE POINTER IN THE CHANNEL.\r
+; BUILD ONE USING THE PTR TO BEG OF BUFFER SAVED IN D\r
+BUFGOO:        HRLI    D,440700        ; GENERATE VIRGIN LH\r
+\r
+       MOVEM   D,BUFSTR(B)     ; STASH IN THE BUFFER BYTE PNTR SLOT\r
+       MOVEI   A,BUFLNT*5-1\r
+BUFROK:        POP     P,D             ;RESTORE D\r
+       POP     P,C             ;RESTORE C\r
+\r
+\r
+; HERE IF THERE ARE CHARS IN BUFFER\r
+GTGCHR:        HRRM    A,BUFSTR-1(B)\r
+       ILDB    A,BUFSTR(B)     ; GET A CHAR FROM BUFFER\r
+IFE ITS,[\r
+       CAIN    A,32    ; TENEX EOF?\r
+       JRST    .+3\r
+]\r
+       CAIE    A,3             ; EOF?\r
+       POPJ    P,              ; AND RETURN\r
+IFN ITS,[\r
+       LDB     A,[600,,STATUS(B)]      ; CHECK FOR TTY\r
+       CAILE   A,2             ; SKIP IF TTY\r
+]\r
+IFE ITS,       SKIPN   BUFRIN(B)\r
+\r
+       JRST    .+3\r
+RETEO1:        HRRI    A,3\r
+       POPJ    P,\r
+\r
+       HRRZ    A,@BUFSTR(B)    ; SEE IF RSUBR START BIT IS ON\r
+       TRNN    A,1\r
+       MOVSI   A,-1\r
+       JRST    RETEO1\r
+\r
+IFN ITS,[\r
+PGBUFO:\r
+PGBUFI:\r
+]\r
+IFE ITS,[\r
+PGBUFO:        SKIPA   D,[SOUT]\r
+PGBUFI:        MOVE    D,[SIN]\r
+]\r
+       SKIPGE  A,BUFSTR(B)     ; POINT TO CURRENT BUFFER POSIT\r
+       SUBI    A,1             ; FOR 440700 AND 010700 START\r
+       SUBI    A,BUFLNT-1      ; CALCULATE PNTR TO BEG OF BUFFER\r
+       HRLI    A,-BUFLNT       ; IOT (AOBJN) PNTR IN A\r
+IFN ITS,[\r
+PGBIOO:\r
+PGBIOI:        MOVE    D,A             ; COPY FOR LATER\r
+       MOVSI   C,TUVEC         ; PREPARE TO HANDDLE INTS\r
+       MOVEM   C,DSTO(PVP)\r
+       MOVEM   C,ASTO(PVP)\r
+       MOVSI   C,TCHAN\r
+       MOVEM   C,BSTO(PVP)\r
+\r
+; BUILD .IOT INSTR\r
+       MOVE    C,CHANNO(B)     ; CHANNEL NUMBER IN C\r
+       ROT     C,23.           ; MOVE INTO AC FIELD\r
+       IOR     C,[.IOT 0,A]    ; IOR IN SKELETON .IOT\r
+\r
+; DO THE .IOT\r
+       ENABLE                  ; ALLOW INTS\r
+       XCT     C               ; EXECUTE THE .IOT INSTR\r
+       DISABLE\r
+       SETZM   BSTO(PVP)\r
+       SETZM   ASTO(PVP)\r
+       SETZM   DSTO(PVP)\r
+       POPJ    P,\r
+]\r
+\r
+IFE ITS,[\r
+PGBIOT:        PUSH    P,D\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,B\r
+       MOVEI   C,(A)           ; POINT TO BUFFER\r
+       HRLI    C,444400\r
+       MOVE    D,A             ; XTRA POINTER\r
+       MOVE    A,CHANNO(B)     ; FILE JFN\r
+       MOVE    B,C\r
+       HLRE    C,D             ; - COUNT TO C\r
+       XCT     (P)             ; DO IT TO IT\r
+       MOVEI   A,1(B)\r
+       MOVE    B,(TP)\r
+       SUB     TP,[2,,2]\r
+       SUB     P,[1,,1]\r
+       JUMPGE  C,CPOPJ         ; NO EOF YET\r
+       HRLI    A,(C)           ; LOOK LIKE AN AOBJN PNTR\r
+       POPJ    P,\r
+\r
+PGBIOO:        SKIPA   D,[SOUT]\r
+PGBIOI:        MOVE    D,[SIN]\r
+       JRST    PGBIOT\r
+DOIOTO:        PUSH    P,D\r
+       PUSH    P,C\r
+       PUSHJ   P,PGBIOO\r
+DOIOTE:        POP     P,C\r
+       POP     P,D\r
+       POPJ    P,\r
+DOIOTI:        PUSH    P,D\r
+       PUSH    P,C\r
+       PUSHJ   P,PGBIOI\r
+       JRST    DOIOTE\r
+]\r
+\f\r
+; OUTPUT BUFFERING ROUTINES SIMILAR TO INPUT BUFFERING ROUTINES OF PREV PAGE\r
+\r
+PUTCHR:        PUSH    P,A\r
+       GETYP   A,BUFSTR-1(B)   ; CHECK TYPE OF ARG\r
+       CAIE    A,TCHSTR        ; MUST BE STRING\r
+       JRST    BDCHAN\r
+\r
+       HRRZ    A,BUFSTR-1(B)   ; GET CHAR COUNT\r
+       JUMPE   A,REBUFF        ; PREV RESET BUFF, UNDO SAME\r
+\r
+PUTCH1:        POP     P,A             ; RESTORE CHAR\r
+       CAMN    A,[-1]          ; SPECIAL HACK?\r
+       JRST    PUTCH2          ; YES GO HANDLE\r
+       IDPB    A,BUFSTR(B)     ; STUFF IT\r
+PUTCH3:        SOS     A,BUFSTR-1(B)   ; COUNT DOWN STRING\r
+       TRNE    A,-1            ; SKIP IF FULL\r
+       POPJ    P,\r
+\r
+; HERE TO FLUSH OUT A BUFFER\r
+\r
+       PUSH    P,C\r
+       PUSH    P,D\r
+       PUSHJ   P,PGBUFO        ; SETUP AND DO IOT\r
+       HRLI    D,440700        ; POINT INTO BUFFER\r
+       MOVEM   D,BUFSTR(B)     ; STORE IT\r
+       MOVEI   A,BUFLNT*5      ; RESET  COUNT\r
+       HRRM    A,BUFSTR-1(B)\r
+       POP     P,D\r
+       POP     P,C\r
+       POPJ    P,\r
+\r
+;HERE TO DA ^C AND TURN ON MAGIC BIT\r
+\r
+PUTCH2:        MOVEI   A,3\r
+       IDPB    A,BUFSTR(B)     ; ZAP OUT THE ^C\r
+       MOVEI   A,1             ; GET BIT\r
+       IORM    A,@BUFSTR(B)    ; ON GOES THE BIT\r
+       JRST    PUTCH3\r
+\r
+; RESET A FUNNY BUF\r
+\r
+REBUFF:        MOVEI   A,BUFLNT*5              ; 1ST COUNT\r
+       HRRM    A,BUFSTR-1(B)\r
+       HRRZ    A,BUFSTR(B)             ; NOW POINTER\r
+       SUBI    A,BUFLNT\r
+       HRLI    A,440700\r
+       MOVEM   A,BUFSTR(B)             ; STORE BACK\r
+       JRST    PUTCH1\r
+\r
+\r
+; HERE TO FLUSH FINAL BUFFER\r
+\r
+BFCLOS: HLLZS  ACCESS-1(B)     ; CLEAR OUT KLUDGE PRINTB PART ACCESS COUNT\r
+       MOVE    C,B             ; THIS BUFFER FLUSHER THE WORK OF NDR\r
+       MOVEI   B,RDEVIC-1(B)   ; FIND OUT IF THIS IS NET\r
+       PUSHJ   P,CHRWRD\r
+       JFCL\r
+       TRZ     B,77777         ; LEAVE ONLY HIGH 3 CHARS\r
+       MOVEI   A,0             ; FLAG 0=NET 1=DSK\r
+       CAME    B,[ASCIZ /NET/] ; IS THIS NET?\r
+       AOS     A\r
+       PUSH    P,A             ; SAVE THE RESULT OF OUR TEST\r
+       MOVE    B,C             ; RESTORE CHANNEL IN B\r
+       JUMPN   A,BFCLNN        ; DONT HAVE TO CHECK NET STATE\r
+       PUSH    TP,$TCHAN\r
+       PUSH    TP,B            ; SAVE CHANNEL\r
+       PUSHJ   P,INSTAT        ; GET CURRENT NETWORK STATE\r
+       MOVE    A,(B)           ; GET FIRST ELEMENT OF STATE UVECTOR WHICH IS CUR STATE\r
+       POP     TP,B            ; RESTORE B\r
+       POP     TP,\r
+       CAIE    A,5             ; IS NET IN OPEN STATE?\r
+       CAIN    A,6             ; OR ELSE IS IT IN RFNM WAIT STATE\r
+       JRST    BFCLNN          ; IF SO TO THE IOT\r
+       POP     P,              ; ELSE FLUSH CRUFT AND DONT IOT\r
+       POPJ    P,              ; RETURN DOING NO IOT\r
+BFCLNN:        MOVEI   C,BUFLNT*5      ; NEW BUFFER FLUSHER BY NDR\r
+       HRRZ    D,BUFSTR-1(B)   ; SO THAT NET ALSO WORKS RIGHT\r
+       SUBI    C,(D)           ; GET NUMBER OF CHARS\r
+       IDIVI   C,5             ; NUMBER OF FULL WORDS AND REST\r
+       PUSH    P,D             ; SAVE NUMBER OF ODD CHARS\r
+       SKIPGE  A,BUFSTR(B)     ; GET CURRENT BUF POSITION\r
+       SUBI    A,1             ; FIX FOR 440700 BYTE POINTER\r
+       PUSH    P,(A)           ; SAVE THE ODD WORD OF BUFFER\r
+       MOVEI   D,BUFLNT\r
+       SUBI    D,(C)\r
+       SKIPE   -1(P)\r
+       SUBI    A,1\r
+       ADDI    D,1(A)          ; FIX UP FOR POSSIBLE ODD CHARS\r
+       PUSH    TP,$TUVEC\r
+       PUSH    TP,D            ; PUSH THE DOPE VECTOR ONTO THE STACK\r
+       JUMPE   C,BFCLSR        ; IN CASE THERE ARE NO FULL WORDS TO DO\r
+       HRL     A,C\r
+       MOVE    E,[A,,BUFLNT]\r
+       SUBI    E,(C)   ; FIX UP FOR BACKWARDS BLT\r
+       POP     A,@E            ; AMAZING GRACE\r
+       TLNE    A,-1\r
+       JRST    .-2\r
+       HRRO    A,D             ; SET UP AOBJN POINTER\r
+       SUBI    A,(C)\r
+       TLC     A,-1(C)\r
+       PUSHJ   P,PGBIOO        ; DO THE IOT OF ALL THE FULL WORDS\r
+BFCLSR:        HRRO    A,(TP)          ; GET IOT PTR FOR REST OF JUNK\r
+       SUBI    A,1             ; POINT TO WORD BEFORE DOPE WORDS\r
+       POP     P,0             ; GET BACK ODD WORD\r
+       POP     P,C             ; GET BACK ODD CHAR COUNT\r
+       POP     P,D             ; FLAG FOR NET OR DSK\r
+       JUMPE   C,BFCLSD        ; IF NO ODD CHARS FINISH UP\r
+       JUMPN   D,BFCDSK        ; GO FINISH OFF DSK\r
+       MOVEI   D,7\r
+       IMULI   D,(C)           ; FIND NO OF BITS TO SHIFT\r
+       LSH     0,-43(D)        ; SHIFT BITS TO RIGHT PLACE\r
+       MOVEM   0,(A)   ; STORE IN STRING\r
+       SUBI    C,5             ; HOW MANY CHAR POSITIONS TO SKIP\r
+       MOVNI   C,(C)           ; MAKE C POSITIVE\r
+       LSH     C,17\r
+       TLC     A,(C)           ; MUNG THE AOBJN POINTER TO KLUDGE\r
+       PUSHJ   P,PGBIOO        ; DO IOT OF ODD CHARS\r
+BFCLSD:        HRRZ    A,(TP)  ; GET PTR TO DOPE WORD\r
+       SUBI    A,BUFLNT\r
+       HRLI    A,440700        ; AOBJN POINTER TO FIRST OF BUFFER\r
+       MOVEM   A,BUFSTR(B)\r
+       MOVEI   A,BUFLNT*5\r
+       HRRM    A,BUFSTR-1(B)\r
+       SUB     TP,[2,,2]\r
+       POPJ    P,\r
+\r
+BFCDSK: MOVE   C,A             ; FOR FUNNY AOBJN PTR\r
+       HLL     C,BUFSTR(B)     ; POINT INTO WORD AFTER LAST CHAR\r
+       TRZ     0,1\r
+       MOVEM   0,(A)\r
+IFN ITS,       MOVEI   0,3             ; CONTROL C\r
+IFE ITS,       MOVEI   0,32            ; CNTL Z\r
+       IDPB    0,C\r
+       PUSHJ   P,PGBIOO\r
+       JRST    BFCLSD\r
+\r
+BFCLS1:        HRRZ    C,DIRECT-1(B)\r
+       MOVSI   0,(JFCL)\r
+       CAIE    C,6\r
+       MOVE    0,[AOS ACCESS(B)]\r
+       PUSH    P,0\r
+       HRRZ    C,BUFSTR-1(B)\r
+       IDIVI   C,5\r
+       JUMPE   D,BCLS11\r
+       MOVEI   A,40            ; PAD WITH SPACES\r
+       PUSHJ   P,PUTCHR\r
+       XCT     (P)             ; AOS ACCESS IF NECESSARY\r
+       SOJG    D,.-3           ; TO END OF WORD\r
+BCLS11:        POP     P,0\r
+       HLLZS   ACCESS-1(B)\r
+       HRRZ    C,BUFSTR-1(B)\r
+       CAIE    C,BUFLNT*5\r
+       PUSHJ   P,BFCLOS\r
+       POPJ    P,\r
+\r
+\f\r
+; HERE TO GET A TTY BUFFER\r
+\r
+GETTTY:        SKIPN   C,EXBUFR(B)     ; SKIP IF BUFFERS BACKED UP\r
+       JRST    TTYWAI\r
+       HRRZ    D,(C)           ; CDR THE LIST\r
+       GETYP   A,(C)           ; CHECK TYPE\r
+       CAIE    A,TDEFER        ; MUST BE DEFERRED\r
+       JRST    BDCHAN\r
+       MOVE    C,1(C)          ; GET DEFERRED GOODIE\r
+       GETYP   A,(C)           ; BETTER BE CHSTR\r
+       CAIE    A,TCHSTR\r
+       JRST    BDCHAN\r
+       MOVE    A,(C)           ; GET FULL TYPE WORD\r
+       MOVE    C,1(C)\r
+       MOVEM   D,EXBUFR(B)     ; STORE CDR'D LIST\r
+       MOVEM   A,BUFSTR-1(B)   ; MAKE CURRENT BUFFER\r
+       MOVEM   C,BUFSTR(B)\r
+       SOJA    A,BUFROK\r
+\r
+TTYWAI:        PUSHJ   P,TTYBLK        ; BLOCKED FOR TTY I/O\r
+       JRST    GETTTY          ; SHOULD ONLY RETURN HAPPILY\r
+\r
+\f;INTERNAL DEVICE READ ROUTINE.\r
+\r
+;FOR INTERNAL DEVICES THIS ROUTINE APPLIES THE GIVEN OBJECT,\r
+;CHECKS THAT THE RETURNED VALUE IS OF TYPE CHARACTER,\r
+;AND RETURNS THAT AS THE NEXT CHARACTER IN THE "FILE"\r
+\r
+;H. BRODIE 8/31/72\r
+\r
+GTINTC:        PUSH    TP,$TCHAN       ;SAVE THE CHANNEL...WE'LL CLOBBER B\r
+       PUSH    TP,B\r
+       PUSH    P,C     ;AND SAVE THE OTHER ACS\r
+       PUSH    P,D\r
+       PUSH    P,E\r
+       PUSH    P,0\r
+       PUSH    TP,INTFCN-1(B)\r
+       PUSH    TP,INTFCN(B)\r
+       MCALL   1,APPLY\r
+       GETYP   A,A\r
+       CAIE    A,TCHRS\r
+       JRST    BADRET\r
+       MOVE    A,B\r
+INTRET:        POP     P,0             ;RESTORE THE ACS\r
+       POP     P,E\r
+       POP     P,D\r
+       POP     P,C\r
+       POP     TP,B            ;RESTORE THE CHANNEL\r
+       SUB     TP,[1,,1]       ;FLUSH $TCHAN...WE DON'T NEED IT\r
+       POPJ    P,\r
+\r
+\r
+BADRET:        PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE INT-DEVICE-WRONG-TYPE-EVALUATION-RESULT\r
+       JRST    CALER1\r
+\r
+;INTERNAL DEVICE PRINT ROUTINE.\r
+\r
+;FOR INTERNAL DEVICES THIS ROUTINE APPLIES THE GIVEN OBJECT,(FUNCTION, SUBR, OR RSUBR)\r
+;TO THE CURRENT CHARACTER BEING "PRINTED".\r
+\r
+PTINTC:        PUSH    TP,$TCHAN       ;SAVE THE CHANNEL...WE'LL CLOBBER B\r
+       PUSH    TP,B\r
+       PUSH    P,C     ;AND SAVE THE OTHER ACS\r
+       PUSH    P,D\r
+       PUSH    P,E\r
+       PUSH    P,0\r
+       PUSH    TP,INTFCN-1(B)  ;PUSH TYPE OF GIVEN OBJ\r
+       PUSH    TP,INTFCN(B)    ;PUSH THE SUPPLIED FUNCTION (OR SUBR ETC.)\r
+       PUSH    TP,$TCHRS       ;PUSH THE TYPE "CHARACTER"\r
+       PUSH    TP,A            ;PUSH THE CHAR\r
+       MCALL   2,APPLY         ;APPLY THE FUNCTION TO THE CHAR\r
+       JRST    INTRET\r
+\r
+\r
+\f\r
+; ROUTINE TO FLUSH OUT A PRINT BUFFER\r
+\r
+MFUNCTION BUFOUT,SUBR\r
+\r
+       ENTRY   1\r
+\r
+       GETYP   0,(AB)\r
+       CAIE    0,TCHAN\r
+       JRST    WTYP1\r
+\r
+       MOVE    B,1(AB)\r
+       MOVEI   B,DIRECT-1(B)\r
+       PUSHJ   P,CHRWRD        ; GET DIR NAME\r
+       JFCL\r
+       CAMN    B,[ASCII /PRINT/]\r
+       JRST    .+3\r
+       CAME    B,[<ASCII /PRINT/>+1]\r
+       JRST    WRONGD\r
+       TRNE    B,1             ; SKIP IF PRINT\r
+       PUSH    P,[JFCL]\r
+       TRNN    B,1             ; SKIP IF PRINTB\r
+       PUSH    P,[AOS ACCESS(B)]\r
+       MOVE    B,1(AB)\r
+       GETYP   0,BUFSTR-1(B)\r
+       CAIN    0,TCHSTR\r
+       SKIPN   C,BUFSTR(B)             ; BYTE POINTER?\r
+       JRST    BFIN1\r
+       HRRZ    C,BUFSTR-1(B)   ; CHARS LEFT\r
+       IDIVI   C,5             ; MULTIPLE OF 5?\r
+       JUMPE   D,BFIN2         ; YUP NO EXTRAS\r
+\r
+       MOVEI   A,40            ; PAD WITH SPACES\r
+       PUSHJ   P,PUTCHR        ; OUT IT GOES\r
+       XCT     (P)             ; MAYBE BUMP ACCESS\r
+       SOJG    D,.-3           ; FILL\r
+\r
+BFIN2: PUSHJ   P,BFCLOS        ; WRITE OUT BUFFER\r
+BFIN1: MOVSI   A,TCHAN\r
+       JRST FINIS\r
+\r
+\r
+\r
+; FUNCTION TO GET THE FILE LENGTH OF A READ CHANNEL\r
+\r
+MFUNCTION FILLNT,SUBR,[FILE-LENGTH]\r
+       ENTRY   1\r
+\r
+       GETYP   0,(AB)\r
+       CAIE    0,TCHAN\r
+       JRST    WTYP1\r
+       MOVE    B,1(AB)\r
+       MOVEI   B,DIRECT-1(B)   ; GET CHANNEL TYPE\r
+       PUSHJ   P,CHRWRD\r
+       JFCL\r
+       CAME    B,[ASCIZ /READ/]\r
+       JRST    .+3\r
+       PUSH    P,[5]           ; MULTIPLICATIVE FACTOR FOR READ\r
+       JRST    .+4\r
+       CAME    B,[ASCII /READB/]\r
+       JRST    WRONGD\r
+       PUSH    P,[1]           ; MULTIPLICATIVE FACTOR FOR READ\r
+       MOVE    C,1(AB)\r
+IFN ITS,[\r
+       .CALL   FILL1\r
+       JRST    FILLOS          ; GIVE HIM A NICE FALSE\r
+]\r
+IFE ITS,[\r
+       MOVE    A,CHANNO(C)\r
+       SIZEF\r
+       JRST    FILLOS\r
+]\r
+       POP     P,C\r
+       IMUL    B,C\r
+       MOVE    A,$TFIX\r
+       JRST    FINIS\r
+\r
+IFN ITS,[\r
+FILL1: SETZ                    ; BLOCK FOR .CALL TO FILLEN\r
+       SIXBIT /FILLEN/\r
+       CHANNO  (C)\r
+       SETZM   B\r
+\r
+FILLOS:        MOVE    A,CHANNO(C)\r
+       PUSHJ   P,GFALS\r
+       JRST    FINIS\r
+]\r
+IFE ITS,[\r
+FILLOS:        PUSHJ   P,TGFALS\r
+       JRST    FINIS\r
+]\r
+\r
+\r
+\f;THREE GENERALLY USEFUL ERROR ROUTINES FOR I/O\r
+\r
+NOTNET:\r
+BADCHN:        PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE BAD-CHANNEL\r
+       JRST    CALER1\r
+\r
+WRONGD:        PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE WRONG-DIRECTION-CHANNEL\r
+       JRST    CALER1\r
+\r
+CHNCLS: PUSH   TP,$TATOM\r
+       PUSH    TP,EQUOTE CHANNEL-CLOSED\r
+       JRST    CALER1\r
+\r
+BAD6:  PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE NON-6-BIT-CHARACTER-IN-FILE-NAME\r
+       JRST    CALER1\r
+\r
+DISLOS:        MOVE    C,$TCHSTR\r
+       MOVE    D,CHQUOTE [DISPLAY NOT AVAILABLE]\r
+       PUSHJ   P,INCONS\r
+       MOVSI   A,TFALSE\r
+       JRST    OPNRET\r
+\r
+NOCHAN:        PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE ITS-CHANNELS-EXHAUSTED\r
+       JRST    CALER1\r
+\r
+MODE1: 232020,,202020\r
+MODE2: 232023,,332320\r
+\r
+END\r
+\r
+\f\r