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