1
0
mirror of https://github.com/PDP-10/its.git synced 2026-03-23 17:22:35 +00:00
Files
PDP-10.its/src/sysen2/mldev.105
2017-02-20 06:47:02 -08:00

1423 lines
38 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;-*-MIDAS-*-
TITLE BOJ JOB MLDEV, Uses MLSLV on other system
VERSIO==.FNAM2
ICPSOC==123 ;This is the Postel-approved number
A=1
B=2
C=3
D=4
E=5
T=6
TT=7
INT=10 ;FLAG FOR INTERRUPT, -1 INT HAPPENED
H=11
J=12
Q=13
W=14
P=15
IOP=16 ;AOBJN POINTER FOR I/O ROUTINES
U=17 ;CLOBBERED AT INTERRUPT LEVEL
CH==,,-1 ;BIT TYPEOUT MODE MASK FOR I/O CHANNEL NAMES.
CHBOJ==1
CHFILE==3
CHNETI==4
CHNETO==5
IOCEOF==8 ;IOCERROR CODE FOR EOF.
DEFINE SYSCAL NAME,ARGS
.CALL [ SETZ ? SIXBIT/NAME/ ? ARGS ((SETZ))]
TERMIN
LOC 42
JSR TSINT
LOC 77
SIXBIT /MLDEV/
RDEVN: BLOCK 4
ACCP: 0
DIRECTN:0
CRUNAM: 0
CRJNAM: 0
FILLEN: 0 ;FILE LENGTH, IN BYTES OF SIZE NOW OPEN IN,
;OR -1 => FILLEN, FILBLN AND FILBSZ NOT KNOWN.
BYTSIZ: 0 ;BYTE SIZE OPEN IN. IF WE CAN'T GET THIS FROM
;A FILLEN, WE GUESS AT IT FROM OPEN MODE.
FILBLN: 0 ;FILE LENGTH, IN BYTES OF SIZE WRITTEN IN.
FILBSZ: 0 ;BYTE SIZE FILE WRITTEN IN.
FILDTP: 0 ;-1 => WE KNOW THE CREATION DATE OF THIS FILE.
FILDAT: 0 ;FILE CREATION DATE (IF KNOWN).
PAT:
PATCH: BLOCK 100
PATCHE: -1
DEBUG: 0
;START HERE.
GO: MOVE P,[-LPDLL-1,,PDL-1]
.SUSET [.SMASK,,[%PIIOC+%PIILO+%PIMPV+%PIPDL]]
.OPEN CHBOJ,[27,,'BOJ]
.VALUE
SYSCAL RFNAME,[
1000,,CHBOJ
2000,,0
2000,,CRUNAM
2000,,CRJNAM]
JFCL
.CALL JBGT ;GET INFO FOR ICP
.VALUE
MOVE A,JBCOP
TLNE A,60000 ;IF HE ALREADY PCLSR'D, GIVE UP, SINCE HE WILL GIVE UP ON US
JRST DIE ;SINCE WE DID A JOBGET AND SAW THAT FACT.
ANDI A,-1 ;NOW .VALUE IF OPCODE IS .IOT - SHOULDN'T HAPPEN,
CAIN A,1 ;BUT DID DUE TO A BUG.
.VALUE
MOVEI A,HSTPAG
MOVEI B,CHFILE
PUSHJ P,NETWRK"HSTMAP
.VALUE
MOVE A,JBCDEV ;GET "DEVICE"
MOVEM A,RDEVN ;REMEMBER IT TO RETURN FOR .RCHST'S.
IRPS Y,,AI ML DM MC MX MD KL KS DB ES NO SJ UP
CAMN A,[SIXBIT /X!Y/]
MOVE A,[SIXBIT /Y/] ;ALLOW "XAI", ETC., FOR EXPERIMENTAL VERSIONS OF "AI", ETC.
CAMN A,[SIXBIT /DIR!Y/]
MOVE A,[SIXBIT /Y!DIR/]
TERMIN ;DEVICES SUCH AS "DIRML" ARE REALLY HANDLED AS "MLDIR".
;THAT'S BECAUSE IT'S FASTER THAT WAY. DIR DEVICE MUST READ BOTH
;IMAGE AND ASCII DIRECTORIES.
MOVEM A,JBCDEV
LDB A,[301400,,JBCDEV] ;MIGHT BE DMAR1, ETC.
IRP X,,[DM,AI,ML,MC,MX,MD,KL,KS,DB,ES,NO,SJ,UP]
CAIN A,(SIXBIT / X/) ;**** IF ANY NON 2-CHAR HOST NAME EVER EXISTS,
JRST GOTHST ;THIS BARFUCIOUS KLUDGE WILL HAVE TO BE FIXED UP.
TERMIN
MOVS A,JBCDEV
CAIN A,'XGP ;XGP THROUGH THE NET TO AI FROM ML/MC/DM
JRST [ MOVS A,[SIXBIT/AIXGP/]
MOVSM A,JBCDEV
MOVEI A,'AI
JRST GOTHST]
CAIN A,'GLP ;GOULD THROUGH THE NET TO MX
JRST [ MOVS A,[SIXBIT/MXGLP/]
MOVSM A,JBCDEV
MOVEI A,'MX
JRST GOTHST]
CAIN A,'DVR ;DVR THROUGH THE NET TO MC FROM AI/ML/DM
JRST [ MOVS A,[SIXBIT/MCDVR/]
MOVSM A,JBCDEV
MOVEI A,'MC
JRST GOTHST]
CAIN A,'DVS ;DVS THROUGH THE NET TO MC FROM ML/DM
JRST [ MOVS A,[SIXBIT/MCDVS/]
MOVSM A,JBCDEV
MOVEI A,'MC
JRST GOTHST]
CAIN A,'TPL ;TPL THROUGH THE NETWORK FOR MC
JRST [ MOVS A,[SIXBIT/MLTPL/]
MOVSM A,JBCDEV
LDB B,[000400,,JBCOP]
CAIN B,2
JRST TPLLK ;TRYING TO LINK ON TPL: LOSES
LDB B,[410100,,JBCOP] ;0 => INPUT 1 => OUTPUT
CAIN B,1 ;SKIP IF E.G. READING DIRECTORY
JSP A,[MOVSI B,(SIXBIT/>/) ;ALSO SKIP IF DELETING
MOVEM B,JBCFN1
.SUSET [.RUNAME,,JBCFN2]
JRST (A) ]
MOVEI A,'ML ;USE THE MATHLAB LINE PRINTER
JRST GOTHST ]
;HOST NOT RECOGNIZED
NSD: MOVSI A,%ENSDV
JRST NOGO2
;A CONTAINS SIXBIT HOST, RIGHT-JUSTIFIED
GOTHST: MOVE B,[440700,,BUF] ;Make ASCIZ host name
GOTHS1: LDB T,[360600,,A]
JUMPE T,GOTHS2
ADDI T,40
IDPB T,B
GOTHS2: LSH A,6
JUMPN A,GOTHS1
IDPB A,B
MOVEI A,BUF
PUSHJ P,NETWRK"HSTLOOK
.VALUE ;Host not in host table?
MOVEM A,HOSTN' ;Host number
MOVEM TT,NETWRK' ;Network number
PUSHJ P,NETWRK"HSTUNMAP ;Don't need host table any more
.VALUE
LDB A,[3000,,JBCDEV] ;Right-hand four characters
JUMPN A,.+2
MOVE A,[SIXBIT / DSK/]
LSH A,14
MOVEM A,JBCDEV
MOVEM A,FDEVN
SETOM JBGTN' ;FLAG INITIAL JOBGET DONE
MOVE A,NETWRK
CAMN A,[NW%CHS]
JRST CHAICP
CAMN A,[NW%ARP]
JRST TCPICP
.VALUE ;How did we get an unknown network?
CHAICP: MOVEI A,CHNETI
MOVE B,HOSTN
MOVEI C,[ASCIZ/MLDEV/]
MOVEI D,8
PUSHJ P,NETWRK"CHACON
JRST NOGO ;Can't connect
JRST ICP1
TCPICP: MOVEI A,CHNETI
MOVE B,HOSTN
MOVEI C,ICPSOC
PUSHJ P,NETWRK"TCPCON
JRST NOGO ;Can't connect
JRST ICP1
;HERE FOR VARIOUS ERRORS THAT WE DETECT BEFORE FINISHING THE CONNECTION.
TPLLK: SKIPA A,[%ELCDV,,]
NOGO: MOVSI A,%ENADV ;DEVICE NOT AVAILABLE.
NOGO2: MOVEM A,ERRCOD
MOVEI C,20.
NOGO1: .CALL JBGT
.VALUE ;JOBGET ON INITIAL IS NOT SUPPOSED TO FAIL.
MOVE A,JBCOP
TLNE A,60000 ;HE CLOSED US => WE CAN STOP NOW.
JRST REUSE
.CALL JBRT3 ;KEEP TRYING TO RETURN THIS ERROR, IN CASE HE PCLSR'S AND COMES BACK.
SOJG C,[MOVEI B,1 ? .SLEEP B, ? JRST NOGO1]
JRST REUSE
ICP1: SETZM INT
SETZM NTICIN
.SUSET [.SMSK2,,[1_CHBOJ+1_CHNETI]]
;COME HERE WHEN REUSED BY A SECOND CREATOR.
REUSE1: SETZM CALING ;WE'RE NOT AWAITING A REPLY FOR A .CALL
SETZM CALACK
SETZM RNMWOS ;OR A RENMWO
SETZM MLINKS ;OR A MLINK.
SETZM ACCACK ;OR A .ACCESS
SETZM ACCP ;WE ARE AT THE BEGINNING OF THE FILE.
SETZM RETOOU ;WE AREN'T INSIDE AN IOT
SETZM RETOIN
SETZM FILOPN ;NO FILE OPEN.
SETOM JBINT ;DO ONE JOBGET NOW IN CASE ALREADY CLEARED THE INTERRUPT.
JRST GOLOOP
;ANY CHANGES IN THIS SHOULD BE REPORTED TO INFO-MLDEV@AI AND
;UPDATED IN MLSLV ALSO. NEW VERSION MUST THEN BE UPDATED
;SIMULTANEOUSLY ON ALL ITS'S AND ON MULTICS.
;[This comment inoperative since NCP has been terminated]
;ICP IS TO SOCKET 197. IF DOING MOSTLY INPUT, 199. IF MOSTLY OUTPUT
;COMMAND FORMAT: TO SLAVE
;AOBJN POINTER (RH = COMMAND CODE)
;BLOCK OF ARGUMENTS
;COMMAND CODES:
COPENI==1 ;OPEN FOR INPUT
;ARG1: DEVICE
;ARG2: FN1
;ARG3: FN2
;ARG4: SNAME
;ARG5: OPEN MODE
COPENO==2 ;OPEN FOR OUTPUT
;ARG1: DEVICE
;ARG2: FN1
;ARG3: FN2
;ARG4: SNAME
;ARG5: OPEN MODE
CDATA==3 ;WRITE DATA (WD COUNT INCLUDES DATA WDS AND BYTE COUNT WD).
;# OF BYTES OF DATA
;DATA, PACKED ILDB-STYLE INTO AT MOST 200 WORDS.
CALLOC==4 ;READ ALLOCATE
;ARG: ALLOCATION IN BYTES
CICLOS==5 ;INPUT CLOSE
;ARG: IGNORED
COCLOS==6 ;OUTPUT CLOSE
;ARG: IGNORED
CFDELE==7 ;.FDELE (DELETE OR RENAME)
;ARG1: DEV
;ARG2: FN1
;ARG3: FN2
;ARG4: 0 OR NEW FN1
;ARG5: 0 OR NEW FN2
;ARG6: SNAME
CRNMWO==10 ;.FDELE (RENAME WHILE OPEN)
;ARG1: NEW FN1
;ARG2: NEW FN2
CNOOP=11 ;NOOP
;ARG: ECHOED BY THE NOOP REPLY
CACCES==12 ;ACCESS
;ARG1: TRANSACTION NUMBER.
;ARG2: ACCESS POINTER
;ARG3: NEW ALLOCATION
CSYSCL==13 ;RANDOM SYSTEM CALL. 11 (DECIMAL) ARGUMENTS.
;ARG1: SYSTEM CALL NAME IN SIXBIT
;ARG2: FLAGS (CONTROL-BIT ARGUMENT)
;ARG3: NUMBER OF FOLLOWING ARGS THAT HAVE SIGNIFICANCE
;ARG4: 1ST ARG TO SYSTEM CALL
;...
;ARG11: 8TH ARG TO SYSTEM CALL
CREUSE==14 ;REINITIALIZE YOURSELF, BECAUSE WE ARE ABOUT TO BE REUSED
;BY A NEW CREATOR FOR A NEW FILE.
CLOGIN==15 ;LOGIN USER (RECORD XUNAME FOR SYS: DELETION PURPOSES, ETC.)
;ARG1: XUNAME (USED AS "TERMINAL NAME" IN LOGIN CALL)
CMAX==16 ;LARGEST COMMAND NUMBER, PLUS ONE.
;REPLIES FROM SLAVE START WITH AN AOBJN POINTER (RH = REPLY CODE)
;FOLLOWED BY A BLOCK OF ARGUMENTS
R==,,-1 ;REPLY CODES:
RDATA==1 ;INPUT DATA (WD COUNT INCLUDES DATA WDS AND BYTE COUNT WD).
;# OF BYTES OF DATA
;DATA, PACKED ILDB-STYLE INTO WORDS.
;NOTE: SLAVE MUST ALWAYS SEND FULLY POPULATED WORDS
;EXCEPT WHEN EOF IS REACHED.
ROPENI==2 ;INPUT OPEN STATUS. 1 OR 11 ARGUMENTS.
;ARG1: -1 => SUCCEEDED; >0 => OPEN LOSS NUMBER
;ARG2-ARG11 PRESENT ONLY IF ARG1 IS -1.
;ARG2: REAL DEVICE NAME (USUALLY SIXBIT/DSK/)
;ARG3: REAL FN1
;ARG4: REAL FN2
;ARG5: REAL SNAME
;ARG6: FILE LENGTH
;ARG7: BYTE SIZE OPEN IN
;ARG8: FILE LENGTH IN BYTE SIZE WRITTEN IN
;ARG9: BYTE SIZE WRITTEN IN
;ARG10: FILDTP - -1 IF "RFDATE" WINS ON THIS FILE
;ARG11: CREATION DATE (IF "RFDATE" WINS).
ROPENO==3 ;OUTPUT OPEN STATUS. 1 OR 11 ARGUMENTS.
;ARG1: -1 => SUCCEEDED; >0 => OPEN LOSS NUMBER
;ARG2-ARG11 PRESENT ONLY IF ARG1 IS -1.
;ARG2: REAL DEVICE NAME
;ARG3: REAL FN1
;ARG4: REAL FN2
;ARG5: REAL SNAME
;ARG6: FILE LENGTH (-1 => FILLEN FAILS ON THIS DEVICE)
;ARG7: BYTE SIZE OPEN IN
;ARG8: FILE LENGTH IN BYTE SIZE WRITTEN IN
;ARG9: BYTE SIZE WRITTEN IN
;ARG10: FILDTP - -1 IF "RFDATE" WINS ON THIS FILE
;ARG11: CREATION DATE (IF "RFDATE" WINS).
REOF==4 ;EOF ON INPUT
;ARG: IGNORED
RFDELE==5 ;.FDELE STATUS. 1ST ARGUMENT:
;RH: -1 => SUCCEEDED
; >=0 => FAILURE CODE
;LH: -1 => DELETE OR RENAME
; 0 => RENAME WHILE OPEN
;IF RENAME WHILE OPEN CALL SUCCEEDED, THERE ARE 4 MORE ARGS:
;ARG2: REAL DEVICE NAME
;ARG3: REAL FN1 (AS RENAMED)
;ARG4: REAL FN2
;ARG5: REAL SNAME
RNOOP==6 ;NOOP REPLY
;ARG: ECHO ARG SENT BY NOOP COMMAND
RACCES==7 ;ACKNOWLEDGE ACCESS
;ARG: TRANSACTION NUMBER FROM CACCES.
RSYSCL==10 ;RESPOND TO SYSTEM CALL. 9 ARGUMENTS.
;ARG1: <ERROR CODE OR 0>,,<# OF TIMES CALL SKIPPED>
;ARG2: 1ST VALUE FROM SYSTEM CALL.
;...
;ARG9: 8TH VALUE FROM SYSTEM CALL.
RICLOS==11 ;RESPOND TO INPUT-CLOSE.
ROCLOS==12 ;RESPOND TO OUTPUT CLOSE.
RIOC==13 ;REFLECT AN IOC ERROR
;ARG: IOC ERROR CODE, RIGHT-JUSTIFIED IN WORD.
RREUSE==14 ;ACKNOWLEDGE A CREUSE. ARG IS MEANINGLESS (NONE RETURNED).
RLOGIN==15 ;ACKNOWLEDGE A LOGIN. ARG IS MEANINGLESS (NONE RETURNED).
RMAX==16 ;LAST REPLY CODE + 1.
GOL: SKIPL INT ;THERE ARE NO INTERRUPTS => WAIT QUIETLY.
.HANG
GOLOOP: SETZM INT ;HERE TO SERVICE ANY INTERRUPTS THERE ARE.
SKIPGE NTICIN ;NET INTS HAVE PRIORITY.
JRST NTINT
AOSN RETOOU ;NO REPLIES => IF WE ARE INSIDE AN OUTPUT IOT,
JRST JIOT ;XFER ANOTHER BATCH OF STUFF TO THE NET.
SKIPL JBINT
JRST GOL
SETZM JBINT
TRYOV: SETZM RETOIN
AOSG JBGTN ;-1 IF INITIAL, DONT DO AGAIN
JRST TRYOV1
.CALL JBGT
JRST GOLOOP
TRYOV1: MOVE B,JBCOP
TLNE B,60000
JRST JCLS
LDB A,[000400,,JBCOP]
TLNE B,200 ;IF THIS IS A RETRY OF A CALL THAT PCLSR'ED,
JRST RETRY ;GIVE IT THE SAME JOBRET WE TRIED TO GIVE LAST TIME.
RETRYR: SETZM CALING ;NO LONGER WAITING FOR STATUS OF .CALL OR RENMWO SINCE WE
SETZM MLINKS
SETZM RNMWOS ;INTERRUPTED OUT OF IT AND DID SOMETHING ELSE. TOO BAD.
SETZM PCLSRD ;WE CAN'T MANAGE TO NHANDLE A RETRY AFTER ANYTHING ELSE HAPPENS.
CAILE A,7
JRST JSYSCL ; HANDLE A .CALL
JRST @DISP(A)
DISP: JOPEN
JIOT
JMLINK
JRESET
JRCH
JACC
JFDEL1
JRNMWO
;HERE WHEN CREATOR GIVES US A SYSTEM CALL AND SAYS IT'S A RETRY.
RETRY: SKIPL CALING ;IF HE'S RETRYING THE SAME SYSTEM CALL WHOSE REPLY WE ARE
JRST RETRY1 ;NOW WAITING FOR, KEEP WAITING.
CAIE A,10
JRST RETRY1
SKIPE CALACK ;IF ALREADY ACK'D, SEND CALL AGAIN SO WE GET THE ACK AGAIN
JRST GOLOOP ;SO THAT WE CAN RETURN THE CALL'S VALUES.
RETRY1: SKIPL RNMWOS
JRST RETRY2
CAIN A,7
JRST GOLOOP
RETRY2: AOSE PCLSRD ;IF WE HADN'T SEEN THE SYSTEM CALL THE FIRST TIME,
JRST RETRYR ;TREAT IT AS NEW.
MOVE B,LJBRTA ;IF WE FINISHED HANDLING IT AND OUR JOBRET FAILED,
JRST -2(B) ;GIVE HIM THE SAME JOBRET AGAIN.
PCLSR: POP P,LJBRTA ;FOLLOW EVERY JOBRET WITH A PUSHJ P,PCLSR.
PCLSR1: SETOM PCLSRD ;A FAILING JOBRET INDICATES THAT CREATOR WAS PCLSRD AND WE SHOULD
SETOM JBINT ;EXPECT HIM TO RETRY HIS SYSTEM CALL. WE MUST SET JBINT NOW
JRST GOLOOP ;BECAUSE COMING BACK IN MIGHT NOT SET THE INTERRUPT BIT.
PCL==PUSHJ P,PCLSR
LJBRTA: 0 ;2 PLUS ADDRESS OF LAST FAILING JOBRET.
PCLSRD: 0 ;-1 => OUR LAST JOBRET FAILED, SO EXPECT A RESTARTED SYSTEM CALL.
JRESET:
JSTS: .CALL JBRTL
PCL
JRST GOLOOP
JCLS: HRROI B,CICLOS
MOVE IOP,[-2,,B]
PUSHJ P,NETOFR
SETOM SNTCLS ;WE MUSTN'T DIE TILL WE RECEIVE A REPLY FOR THE CICLOS.
JRST REUSE
JSACC: MOVE A,JBCA2 ;ACCESS POINTER FOR SYMBOLIC CALL ACCESS
MOVEM A,JBCWD1
PUSHJ P,JACC1
.CALL JBRT1
PCL
JRST GOLOOP
JACC: PUSHJ P,JACC1
JRST JSTS
JACC1: HRROI IOP,[-3,,CACCES] ;HANDLE .ACCESS
PUSHJ P,NETOUT
AOS B,TRANS ;GENERATE A TRANSACTION NUMBER
MOVEM B,ACCNUM ;REMEMBER IT
HRROI IOP,B
PUSHJ P,NETOUT ;AND SEND IT TO SLAVE, WHICH WILL IDENTIFY REPLY WITH IT.
HRROI IOP,JBCWD1
PUSHJ P,NETOUT ;INFORM THE SLAVE OF NEW ACCESS POINTER
MOVE A,JBCWD1
MOVEM A,ACCP
PUSHJ P,BUFINI ;FLUSH BUFFERED INPUT FROM SLAVE
HRROI IOP,INPALL
PUSHJ P,NETOFR
SETZM INREAL
SETOM ACCACK ;AND ACCEPT NO MORE UNTIL ACCESS IS ACKNOWLEDGED.
POPJ P, ;(THOSE ACTIONS IRRELEVANT ON OUTPUT).
JRCH: SYSCAL JOBRET,[
1000,,CHBOJ
1000,,0
[-5,,RDEVN]]
JRST TRYOV ;NO NEED FOR "PCL" SINCE WE HAVEN'T ALTERED ANYTHING.
JRST GOLOOP
JOPEN: LDB W,[410100,,JBCOP] ;0 => INPUT 1 => OUTPUT
MOVEM W,DIRECTN
JOPNC1: MOVE B,JBCWD6 ;SAVE OPEN-MODE.
MOVEM B,OPMODE
ANDI B,7 ;GET JUST LOW 3 BITS.
TRC B,1 ;FLIP DIRECTION (CREATOR READING =>
;WE MUST WRITE TO HIM).
TRO B,20 ;UNHANG OUR IOTS IF HE PCLSRS.
SYSCAL OPEN,[ 1000,,CHBOJ ? 4000,,B ? ['BOJ,,]]
.VALUE
PUSHJ P,LOGIN
MOVE A,FDEVN
MOVE B,JBCFN1
MOVE C,JBCFN2
MOVE D,JBCSNM
HRRZ E,JBCWD6 ;GET FULL OPEN-MODE.
MOVE IOP,[-6,,0]
MOVE 0,[-5,,COPENI ? -5,,COPENO](W)
PUSHJ P,NETOUT
PUSHJ P,REPLY ;READ REPLY INTO B, RH IN A.
CAIE A,ROPENI ;IT MUST BE AN OPEN-REPLY, OR THERE'S A BUG.
CAIN A,ROPENO
JRST JOPEN1
.VALUE
JOPEN1: HRROI IOP,B
PUSHJ P,NTIIOT ;READ THE SUCCESS/FAILURE CODE.
MOVE A,B
JUMPGE A,OPNIL ;-1 => SUCCESS.
PUSHJ P,OPNSN ;READ THE REAL FILE NAMES
MOVE IOP,[-6,,FILLEN] ;AND THE FILE LENGTHS, BYTE SIZES, DATE.
PUSHJ P,NTIIOT
PUSHJ P,NTIFRC
JOPJRT: .CALL JBRT1 ;NOW TELL THE CREATOR THAT THE OPEN SUCCEEDED.
PUSHJ P,IJBRTF
SETOM FILOPN ;ONCE HE KNOWS THAT, WE ARE ATTACHED UNTIL HE CLOSES.
PUSHJ P,BUFINI ;NOW THAT WE KNOW BYTE SIZE, WE CAN SET UP BUFFER PTRS.
JUMPG W,GOLOOP
MOVE B,INPALL
HRROI A,CALLOC ;READ ALLOCATE
MOVE IOP,[-2,,A]
PUSHJ P,NETOFR
JRST GOLOOP
OPNSN: PUSH P,RDEVN ;DON'T REPLACE "DM", "ML", OR "AI" WITH "DSK"
MOVE IOP,[-4,,RDEVN]
PUSHJ P,NTIIOT ;READ IN REAL FILE NAMES.
POP P,RDEVN
.CALL JBST ;GIVE NAMES TO SYSTEM FOR RCHST/RFNAME
.VALUE
POPJ P,
OPNIL: PUSHJ P,NTIFRC
HRLZM A,ERRCOD ;HERE FOR FAILURE REPLY TO OPEN, ERROR CODE IN A.
.CALL JBRT3
PUSHJ P,IJBRTF
JRST REUSE ;IF WE SUCCEED IN TELLING CREATOR, WE ARE FINISHED.
IJBRTF: MOVEI A,30. ;IF INITIAL JOBRET FAILS, WAIT A WHILE BEFORE JOBGETING,
.SLEEP A, ;SINCE IF WE JOBGET BEFORE HE RETRIES WE WILL READ A CLOSE
JRST PCLSR ;AND GIVE UP, AND HE WILL DO WHATEVER IT IS TWICE.
;SET UP BUFFER POINTERS FROM BYTSIZ (WHICH WE GET IN THE ROPENI/ROPENO).
BUFINI: MOVEI B,36.
IDIV B,BYTSIZ
MOVEM B,BYTSWD
IMULI B,BUFL
MOVEM B,BUFSIZ
MOVE B,OPMODE
MOVEI C,BUF
MOVEM C,BUFI ;BUFI IS ALWAYS AN ADDR
MOVE A,BYTSIZ ; SINCE SLAVE SENDS PACKED BYTES.
LSH A,6
IORI A,440000 ;IN UNIT MODE, BUFO SHOULD BE 44NN00,,ADDR.
TRNN B,.BAI ;IN BLOCK MODE, IT SHOULD BE JUST AN ADDR.
TLO C,(A)
MOVEM C,BUFO
SETZM EOFI ;EOF NOT DETECTED YET.
SETZM INREAL ;SAY THAT ALL THE BUFFER SPACE IS ALLOCATED.
MOVE C,BUFSIZ ;(IT'S CALLER'S RESPONSIBILITY TO DO THAT.
MOVEM C,INPALL ;OF COURSE, FOR OUTPUT, THIS IS IGNORED.)
SETZM BUFONM ;SINCE WE RESET THE ADDR FORMS OF PNTRS,
POPJ P, ;RESET THE BYTE-NUMBER FORM TOO.
LOGIN: SKIPN LOGGED ;LOGIN DONE ?
SKIPE LOGINS ;OR EVEN STARTED ?
POPJ P,
MOVE IOP,[-2,,B] ;HERE TO LOGIN AT FOREIGN HOST
HRROI B,CLOGIN
.SUSET [.RXUNAM,,C]
PUSHJ P,NETOFR
SETOM LOGINS ;SAY SENT
POPJ P,
JIOT: SKIPN FILOPN
.VALUE
MOVE A,JBCOP
TLNN A,100000 ;SKIP IF OUTPUT IOT
JRST JIOTI
TLNN A,200000 ;SKIP IF BLOCK IOT
JRST JIOTO1
HLRE D,JBCWD1 ;USER'S BLOCK IOT POINTER - GET WD COUNT.
MOVNS D
JIOTO5: SKIPN RETOOU ;IF RESUMING PROCESSING OF AN IOT AFTER WE LOOKED AT NET FOR A WHILE,
MOVE D,RETOCT ;GET # BYTES NOT SENT YET. JBCWD1 HAS TOTAL INCLUDING THOSE SENT.
JIOTO2: MOVE C,BYTSWD
IMULI C,200 ;GET # BYTES THAT 200 WORDS WILL HOLD.
CAMLE C,D ;SLAVE CAN'T BE EXPECTED TO HANDLE MORE.
MOVE C,D ;C HAS # BYTES WE WILL SEND NOW.
SUB D,C ;# BYTES OF USER'S IOT THAT WILL BE LEFT.
MOVE A,JBCOP
TLNE A,200000 ;NOW READ THE BYTES FROM THE USER.
JRST JIOTO4 ;USING SIOT OR BLOCK IOT, WHICHEVER WE CAN.
MOVE B,[440000,,BUF]
MOVE A,BYTSIZ
DPB A,[300600,,B] ;FOR SIOT, MAKE BP. WITH APPRO BYTE SIZE.
MOVE A,C
SYSCAL SIOT,[ 1000,,CHBOJ ? B ? C]
.VALUE
SUB A,C ;A GETS # BYTES WE GOT, C # WE WANTED BUT DIDN'T GET.
;HERE SIOT AND BLOCK IOT LINES RECOMBINE.
;A HAS NUMBER OF BYTES GOTTEN FROM CREATOR.
;RH(B) POINTS TO LAST FILLED WORD IN BUF.
;C HAS # BYTES WE TRIED TO READ BUT DIDN'T GET (WILL BE 0 UNLESS
;THE CREATOR WAS PCLSR'ED).
;D HAS # OF EXTRA BYTES CREATOR WAS TRYING TO SEND, THAT WE HAVEN'T
;EVEN TRIED TO READ YET.
;HDR1 HAS # BYTES WE GOT THIS TIME.
JIOTO3: MOVEM A,HDR1
PUSHJ P,UPDACP ;UPDATE ACCP AND MAYBE FILLEN, FILBLN.
MOVNI IOP,-HDR0(B) ;RH(IOP) GETS MINUS # OF WORDS IN CDATA COMMAND.
HRLZS IOP
HRRI IOP,CDATA
MOVEM IOP,HDR0 ;PUT CDATA COMMAND IN BEFORE BYTE COUNT WORD.
ADD IOP,[-1,,HDR0-CDATA] ;MAKE COMMAND (NOTE NO CARRY FROM RH SINCE HDR0 > CDATA)
SKIPE HDR1 ;NOW SEND THE COMMAND (BUT IF 0 BYTES, DON'T BOTHER).
PUSHJ P,[PUSHJ P,NETOUT ;TRANSMIT TO SYSTEM, BUT LET SYSTEM
JRST BUFFRC] ;CHOOSE PACKET SIZE
JUMPN C,GOLOOP ;NOW, IF THIS IOT WAS PCLSR'ED, DON'T TRY TO DO
;ANY MORE FOR IT. IF IT COMES BACK IN WE WILL FIND OUT.
JUMPE D,GOLOOP ;IF THERE IS MORE STUFF TO OUTPUT,
SKIPL NTICIN ;LOOP BACK, UNLESS THERE ARE REPLIES COMING BACK.
JRST JIOTO2
SETOM RETOOU ;IN THAT CASE, SET FLAG SO WE WILL COME BACK TO IOT'ING,
MOVEM D,RETOCT ;REMEMBER HOW MANY BYTES LEFT TO SEND WHEN WE COME BACK,
JRST GOLOOP ;AND CHECK OUT THE REPLIES.
;HERE TO XFER FROM CREATOR IN BLOCK MODE.
JIOTO4: MOVN B,C
HRLZS B
HRRI B,BUF ;AOBJN PTR TO # WDS WE WANT TO READ.
.IOT CHBOJ,B
MOVEI A,-BUF(B) ;A GETS # BYTES WE READ.
SUB C,A ;C GETS # THAT WE EXPECTED BUT DIDN'T GET.
SOJA B,JIOTO3 ;MAKE B POINT AT LAST WORD FILLED.
;HERE TO DECODE A UNIT MODE IOT OR SIOT.
JIOTO1: TLNE A,1000 ;SKIP IF UNIT IOT
SKIPA D,JBCWD1 ;SIOT, GET BYTE COUNT
MOVEI D,1 ;IOT, TRANSFER ONE BYTE
JRST JIOTO5
;UPDATE OUR ACCESS POINTER WHEN WE WRITE C(A) BYTES.
UPDACP: ADDB A,ACCP
SKIPL FILLEN ;IF FILE LENGTH KNOWN,
CAMG A,FILLEN ;AND WRITING PAST END OF FILE
POPJ P,
MOVEM A,FILLEN ;THEN UPDATE THE FILE LENGTH
MOVEM A,FILBLN ;SINCE WE'RE WRITING, BYTE SIZE WRITTEN AND CURRENT BYTE SIZE MUST BE SAME
POPJ P,
JIOTI: TLNN A,200000 ;SKIP IF BLOCK IOT
JRST JIOTI3
HLRE C,JBCWD1 ;USER'S BLOCK IOT POINTER - GET WD COUNT.
MOVNS C
;C HAS # BYTES THE USER WANTS IN THIS IOT OR SIOT.
;A HAS JBCOP, EVERYWHERE ON THIS PAGE. DON'T CLOBBER IT!
JIOTI1: MOVE D,BUFSIZ
SUB D,INPALL
SUB D,INREAL ;D HAS # BYTES OF INPUT WE HAVE IN BUFFER.
JUMPE D,JIOTIS ;NONE => EITHER IT'S EOF OR WE MUST WAIT.
CAMLE D,C
MOVE D,C ;ELSE GIVE USER AT MOST WHAT WE'VE GOT.
MOVE E,BUFSIZ ;NOW, WE CAN'T DO ONE IOT THAT WRAPS AROUND,
SUB E,BUFONM ;SO SEE HOW FAR IT IS TO WRAP AROUND FROM HERE.
CAMLE D,E
MOVE D,E ;THAT'S THE MOST WE CAN GIVE IN ONE SHOT.
JUMPE D,LOSE5
SUB C,D ;C <= # BYTES THAT WILL REMAIN.
TLNN A,200000
JRST JIOTI4 ;NOW IN UNIT MODE GO XFER THEM WITH SIOT.
MOVNS D
HRLZS D
HRR D,BUFO ;IN BLOCK MODE, MAKE AOBJN TO WHAT WE WILL GIVE
.IOT CHBOJ,D ;GIVE
SKIPGE D ;IF CREATOR DIDN'T TAKE ALL WE OFFERED, HE WAS
SETZ C, ;PCLSRED, SO DON'T TRY TO OFFER ANY MORE.
MOVEI E,(D)
SUB E,BUFO ;NUMBER OF WORDS GIVEN TO CREATOR
HRRZS D ;WHAT IS 1ST BUFFER WORD WE HAVEN'T JUST SENT?
CAIN D,EBUF
MOVEI D,BUF
MOVEM D,BUFO ;THAT WILL BE NEXT TO SEND
;HERE E HAS # BYTES WE JUST GAVE THE USER. BUFO HAS BEEN UPDATED,
;BUT NOT BUFONM.
JIOTI5: ADDM E,ACCP
MOVE D,E
ADDB D,BUFONM
CAMN D,BUFSIZ
SETZM BUFONM
ADDB E,INREAL ;WHAT WE SENT IS NOW EMPTY.
JUMPL E,LOSE6
LSH E,1
CAMGE E,BUFSIZ ;MAYBE THERE'S A LOT EMPTY AND WE SHOULD REALLOCATE.
JRST JIOTI2
MOVE E,INREAL
SETZM INREAL
ADDM E,INPALL ;MARK THIS SPACE AS PART OF ALLOCATION
SKIPGE B,INPALL
.VALUE
CAMLE B,BUFSIZ
.VALUE
HRROI D,CALLOC ;AND TELL THE SLAVE.
MOVE IOP,[-2,,D]
PUSHJ P,NETOFR ;REALLOCATE
JIOTI2: JUMPN C,JIOTI1 ;NOW, IF CREATOR'S IOT NOT ALL FILLED, GIVE HIM MORE.
JRST GOLOOP
;HERE TO GIVE THE CREATOR SOME DATA IN UNIT MODE.
JIOTI4: MOVE E,D
SYSCAL SIOT,[1000,,CHBOJ ? BUFO ? D]
.VALUE
SUB E,D ;E GETS # BYTES HE TOOK.
SKIPE D ;IF HE DIDN'T TAKE ALL WE OFFERED, HE WAS PCLSRED,
SETZ C, ;SO DON'T TRY TO GIVE HIM ANY MORE.
MOVNI B,BUFL
MOVE D,BUFO ;NOW, IF BUFO IS POINTING AT END OF BUFFER,
IBP D
ANDI D,-1
CAIN D,EBUF
ADDM B,BUFO ;MAKE IT POINT AT BEGINNING.
JRST JIOTI5
;HERE IF CREATOR WANTS STUFF BUT OUR BUFFER IS EMPTY.
JIOTIS: SKIPGE EOFI
JRST JIOTIE ;MAYBE IT'S EMPTY BECAUSE WE'RE AT EOF.
MOVEM C,RETOIN ;OTHERWISE, WAIT FOR DATA FROM SLAVE
JRST GOLOOP ;AND SAY TO GIVE IT TO CREATOR WHEN IT COMES.
;HANDLE EOF RETURNED BY SLAVE
JIOTIE: MOVE A,JBCOP
TLNN A,201000 ;SKIP IF BLOCK OR SIOT BIT ON
JRST JIOTI6 ;FOR UNIT-MODE IOTS, RETURN SOMETHING.
.CALL JBRTL ;JUST UNHANG A BLOCK IOT OR SIOT.
PCL
JRST GOLOOP
JIOTI6: TLNE A,400000 ;EOF, AND USER'S CHANNEL IS UNIT MODE.
JRST JIOTI8
.IOT CHBOJ,[-1,,^C] ;IF ASCII, INDICATE EOF (CHBOJ IS UNIT MODE)
JRST GOLOOP
JIOTI8: SYSCAL JOBIOC,[MOVEI CHBOJ ? MOVEI 2] ;IOCERR FOR EOF
JRST TRYOV
JRST GOLOOP ;ON UNIT IMAGE CHANNEL
JIOTI3: TLNE A,1000 ;SKIP IF UNIT IOT
SKIPA C,JBCWD1 ;SIOT, GET BYTE COUNT
MOVEI C,1 ;IOT, TRANSFER ONE BYTE
JRST JIOTI1
JFDEL1: PUSHJ P,LOGIN
MOVE A,[-6,,CFDELE] ;5 ARGS, AND THIS IS A DELETE/RENAME.
MOVEM A,JBCOP
MOVE A,FDEVN
EXCH A,JBCWD1 ;DEV GOES IN WD1, FOLLOWED BY FN1 AND FN2 IN NEXT 2 WDS.
EXCH A,JBCWD4 ;FOLLOWED BY NEW FN1; GET SNAME
EXCH A,JBCWD6 ;AND PUT AFTER WHERE NEW FN2 GOES;
MOVEM A,JBCWD5 ;PUT NEW FN2 IN RIGHT PLACE.
MOVE IOP,[-7,,JBCOP]
PUSHJ P,NETOUT
PUSHJ P,REPLY ;SEND COMAND, WAIT FOR REPLY.
CAIE A,RFDELE ;IT HAD BETTER BE THE RIGHT KIND OF REPLY.
.VALUE
HRROI IOP,B ;GET REPLY CODE
PUSHJ P,NTIIOT
PUSHJ P,NTIFRC
TRNN B,400000
JRST JFDEL3 ;THE RENAME FAILED.
.CALL JBRT1
PUSHJ P,IJBRTF
JRST REUSE ;AFTER JOBRETTING ON A DELETE/RENAME WE ARE FINISHED.
JFDEL3: HRLZM B,ERRCOD
.CALL JBRT3
PUSHJ P,IJBRTF
JRST REUSE
JRNMWO: MOVE A,[-2,,CRNMWO] ; RENAME WHILE OPEN
MOVEM A,JBCWD4 ;ARRANGE CODE FOR RENMWO,
MOVE A,JBCWD1
MOVEM A,JBCWD5 ;FOLLOWED BY NEW FN1 (NEW FN2 ALREADY IN WD 6).
MOVE IOP,[-3,,JBCWD4]
PUSHJ P,NETOFR
SETOM RNMWOS ;SAY WE ARE AWAITING A REPLY FOR A RENMWO.
JRST GOLOOP
JSYSCL: MOVE A,JBCWD1 ;HANDLE A .CALL. WHAT IS ITS NAME?
CAMN A,['FILLEN]
JRST JFILLEN ;FILLEN WE CAN HANDLE WITHOUT GOING OVER THE NET.
CAMN A,['SFDATE]
JRST JSFDAT ;SFDATE WE PASS OVER BUT MUST UPDATE OUR DATE FIRST.
CAMN A,['SAUTH]
JRST JSAUTH
CAMN A,['RFDATE]
JRST JRFDAT ;RFDATE WE CAN ANSWER DIRECTLY.
CAMN A,['ACCESS]
JRST JSACC ;ACCESS WE HAVE TO KNOW ABOUT
;THE FOLLOWING IS COMMENTED OUT SINCE THERE IS NO SUCH CALL IN ITS, AND
;IF IT IS EVER PUT IN IT IS UNLIKELY TO BE WITH THIS NAME AND THESE ARGS.
; CAMN A,[SIXBIT/TRUNC/]
; JRST [ SKIPGE JOUOP ;TRUNC ALLOWED ONLY ON OUTPUT FILES;
; JRST .+1 ;ON AN INPUT FILE DON'T DO ANYTHING, IT WILL FAIL.
; MOVE A,JBCWD3 ;IF IT'S AN OUTPUT FILE, AND FILLEN IS KNOWN,
; SKIPGE FILLEN
; JRST .+1
; MOVEM A,FILLEN ;WE MUST TAKE NOTE OF THE CHANGES TO LENGTH AND POINTER.
; CAMGE A,ACCP
; MOVEM A,ACCP
; JRST .+1]
AOS CALACK ;COUNT # OF SYSTEM CALL REQUESTS NOT REPLIED TO.
SETOM CALING ;SAY WAITING FOR RSYSCL REPLY TO WHAT WE ARE ABOUT TO SEND.
PUSHJ P,JSYSC1 ;SEND IT - A COMMAND TO DO THE SYSTEM CALL.
JRST GOLOOP
JSYSC1: PUSHJ P,LOGIN
MOVE A,[-11.,,CSYSCL] ;SEND A CSYSCL COMMAND WITH ITS ARGS.
MOVEM A,JBCOP
MOVE IOP,[-12.,,JBCOP]
PUSHJ P,NETOFR
POPJ P,
;TELL THE SLAVE TO DO AN MLINK SYSTEM CALL
JMLINK: PUSHJ P,LOGIN
MOVEI A,7 ;NUMBER OF .CALL ARGS
MOVEM A,JBCOP
MOVE A,JBCWD1 ;PUT THE ARGS IN THE RIGHT ORDER: DEV, FN1, FN2, SNAME, TO-FN1, FN2, SNAME
MOVEM A,JBCDEV
MOVE A,FDEVN
MOVEM A,JBCWD1
SETOM MLINKS
AOS CALACK ;NO NEED TO TURN OFF INTERRUPTS FOR THIS, SINCE
SETOM CALING ;MLINK HAS TO BE THE FIRST REAL OPERATION DONE.
MOVE IOP,[-12.,,MLINKP]
PUSHJ P,NETOUT
PUSHJ P,REPLY ;NOW WAIT FOR A REPLY.
CAIE A,RSYSCL ;IT HAD BETTER BE THE RIGHT KIND FOR AN MLINK.
.VALUE
JRST XCALL ;NOW GO HANDLE IT AND JOBRET (IT'S A SYSTEM-CALL REPLY).
JFILLEN: ;HANDLE .CALL FILLEN
SKIPL FILLEN ;IF FILE'S LENGTH IS UNKNOWABLE,
JRST JFILL1
WTDERR: MOVSI A,%EBDDV ;RETURN "WRONG TYPE DEVICE" ERROR.
MOVEM A,ERRCOD
.CALL JBRT3
PCL
JRST GOLOOP
JRFDAT: SKIPN FILDTP ;.CALL RFDATE.
JRST WTDERR ;BARF "WRONG TYPE DEVICE" IF DATE NOT DEFINED.
SKIPA A,[-1,,FILDAT]
JFILL1: MOVE A,[-4,,FILLEN]
MOVEM A,JRFDAP ;ALL ARGS OF RFDATE MUST STAY AROUND IN CASE
SYSCAL JOBRET,[ 1000,,CHBOJ ? 1000,,1 ? JRFDAP]
PCL ;THE SYSTEM CALL WAS PCLSR'ED AND COMES IN AGAIN.
JRST GOLOOP
JRFDAP: 0
JSAUTH: SKIPN FILDTP ;SAUTH: ASSUME IT WORKS IF THE DEVICE HAS FILE DATES,
JRST WTDERR
JRST JSAUT1 ;AND DON'T WAIT FOR ACKNOWLEDGEMENT.
JSFDAT: SKIPN FILDTP
JRST WTDERR
MOVE B,JBCA2 ;.CALL SFDATE - TAKE NOTE OF THE DATE
MOVEM B,FILDAT ;BEING SENT TO THE SLAVE.
JSAUT1: AOS CALACK ;COUNT # OF SYSTEM CALL REQUESTS NOT REPLIED TO.
PUSHJ P,JSYSC1 ;SEND IT. BUT DON'T WAIT FOR ACKNOWLDGEMENT;
.CALL JBRT1 ;WE CAN REPORT SUCCESS RIGHT AWAY.
PCL
JRST GOLOOP
NTINT: PUSHJ P,NTCHK
JRST GOLOOP
PUSHJ P,REPLY1
CAIL A,RMAX
.VALUE
MOVEM B,LREPLY'
JRST @CMDTB(A)
;SLAVE REPLY ROUTINES DISPATCHED TO WITH LH(B) = - # ARGS MUST BE READ FROM NET
CMDTB: LOSE1
NTDI
OPNSI
OPNSO
EOF
FDELST
XNOOP
XACC
XCALL
XICLOS
XOCLOS
XIOC
REPLY: PUSHJ P,NETFRC ;HERE TO WAIT FOR A REPLY FROM THE SERVER.
REPLY1: HRROI IOP,B ;WE DON'T CHECK FOR JOB DEVICE INTERRUPTS.
PUSHJ P,NTIIOT ;THAT IS DELIBERATE; IN THE INITIAL OPEN, WE DON'T WANT
HRRZ A,B ;TO DO A JOBGET AND GIVE UP IF HE PCLSRS.
CAIE A,RLOGIN ;LOGIN MIGHT BE "IN THE MIDDLE", SO SKIP IT SO CALLER
POPJ P, ;WILL NOT BE CONFUSED
PUSHJ P,NTIFRC
SKIPE LOGINS ;CONSISTENCY CHECK
SKIPE LOGGED
.VALUE
SETZM LOGINS
SETOM LOGGED
JRST REPLY1
;NETWORK 36-BIT OUTPUT ROUTINES
NETOFR: PUSHJ P,NETOUT ;Output then force
NETFRC: PUSHJ P,BUFFRC ;Force our buffer and system's too
SYSFRC: .CALL [ SETZ ? SIXBIT/FORCE/ ? SETZI CHNETO ] ;Send it
.LOSE %LSSYS
POPJ P,
BUFFRC: PUSH P,H ;Force our buffer into system
PUSH P,J
PUSH P,Q
AOSE NBFOXF
JRST NETFR1
MOVE H,NBFOXW ;Send extra word
MOVEI J,0 ;Padded with zeros
PUSHJ P,NETOU2
NETFR1: PUSHJ P,NETBFO ;Code-convert buffer
POPQJH: POP P,Q
POP P,J
POP P,H
POPJ P,
;Send words, IOP is aobjn pointer
NETOUT: PUSH P,H
PUSH P,J
PUSH P,Q
AOSE NBFOXF
JRST NETOU1
MOVE H,NBFOXW ;Send saved word from last time
MOVE J,(IOP) ;Followed by first new word
PUSHJ P,NETOU2
AOBJP IOP,POPQJH
NETOU1: MOVE H,(IOP) ;Send two words
AOBJP IOP,NETOU3 ;No more
MOVE J,(IOP)
PUSHJ P,NETOU2
AOBJN IOP,NETOU1
JRST POPQJH
NETOU3: MOVEM H,NBFOXW ;Send this word next time
SETOM NBFOXF
JRST POPQJH
;Send pair of 36-bit words in H,J
NETOU2: MOVE Q,NBUFOC ;Space in buffer?
CAIGE Q,9
PUSHJ P,NETBFO ;Make some
MOVNI Q,9
ADDM Q,NBUFOC
REPEAT 9,[
ROTC H,8
IDPB J,NBUFOP
]
POPJ P,
;Send and refresh the buffer -- clobbers Q only
NETBFO: MOVEI Q,NBUFL
SUB Q,NBUFOC ;Number of 8-bit bytes in buffer
JUMPE Q,CPOPJ ;Empty
PUSH P,J
MOVE J,[440800,,NBUFO]
MOVEM J,NBUFOP
ADDM Q,NBUFOC
.CALL [ SETZ ? SIXBIT/SIOT/ ? MOVEI CHNETO ? J ? SETZ Q ]
.LOSE %LSSYS
POP P,J
POPJ P,
;Read 36-bit words from network into aobjn pointer in IOP
;If an odd number of words, NTIFRC will clean up the extra word
;(Calls to NTIFRC must match calls to NETFRC at other end).
NTIFRC: SETZM NBFIXF ;Swallow extra word, if any
POPJ P,
NTIIOT: PUSH P,H
PUSH P,J
PUSH P,Q
AOSE NBFIXF ;If have extra word, recieve it first
JRST NTIIO1
MOVE H,NBFIXW
MOVEM H,(IOP)
AOBJP IOP,POPQJH
NTIIO1: HLRO H,IOP ;Compute how much input we need
ASH H,-1 ;Rounded-up negative number of word pairs
IMUL H,[-9] ;Number of bytes
CAILE H,NBUFL ;Take at most one buffer full
MOVEI H,NBUFL
PUSH P,H
IDIVI H,9 ;Store number of word pairs
MOVEM H,NBUFIC
POP P,H
MOVE J,[440800,,NBUFI]
MOVEM J,NBUFIP
.CALL [ SETZ ? SIXBIT/SIOT/ ? MOVEI CHNETI ? J ? SETZ H ]
.LOSE %LSSYS
JUMPN H,DIE ;Failed to transfer, could be TCP conn closed
NTIIO2: MOVEI J,0 ;Receive two words into H,J
REPEAT 9,[
IFN .RPCNT, LSHC H,8
ILDB Q,NBUFIP
IOR J,Q
]
MOVEM H,(IOP)
AOBJP IOP,NTIIO3
MOVEM J,(IOP)
AOBJP IOP,POPQJH
SOSLE NBUFIC
JRST NTIIO2
JRST NTIIO1 ;Need another buffer full
NTIIO3: MOVEM J,NBFIXW ;Save this word for next time
SETOM NBFIXF
JRST POPQJH
;TEST THE INPUT NETWORK CHANNEL STATUS.
;IF IT HAS INPUT, SKIP.
;IF IT HAS NONE, BUT IS HAPPY, DON'T SKIP.
;IF IT IS IN AN ERROR STATE, SUICIDE AFTER GIVING USER AN IOC ERROR.
NTCHK: SETZM NTICIN ;TENTATIVELY CLEAR INTERRUPT, BEFORE READING STATUS
.CALL [ SETZ ? 'WHYINT ? MOVEI CHNETI
MOVEM A ? MOVEM B ? SETZM C ]
.LOSE %LSSYS
CAIN A,%WYCHA
JRST [ CAIE B,%CSOPN
JRST NTIOC
TLNE C,-1
JRST NTCHK1
POPJ P, ] ;No input available
CAIN A,%WYTCP
JRST [ MOVEI A,1
LSH A,(B)
TRNN A,1_%NSOPN+1_%NSRFN+1_%NSINP
JRST NTIOC ;I guess this means not open?
JUMPN C,NTCHK1
POPJ P, ] ;No input available
.VALUE
NTIOC: .CALL JBIOC ;GIVE USER IO CHANNEL ERROR
JFCL
JRST DIE ;COMMIT SUICIDE. CAN'T TRY TO BE REUSED SINCE NO LONGER HAVE SLAVE.
NTCHK1: SETOM NTICIN ;DATA PRESENT, SET INT AGAIN IN CASE WE DON'T READ IT ALL
POPJ1: AOS (P)
CPOPJ: POPJ P,
;HANDLE "RDATA", DATA FOR ML: DEVICE INPUT.
NTDI: HLRO A,B ;A => - # WORDS TO BE READ
MOVN C,A ;C => NUMBER OF WORDS TO BE READ IN
JUMPGE A,LOSE8
SKIPE ACCACK ;IF INPUT IS INVALID BECAUSE USER DID A .ACCESS,
JRST NTDI3 ;GO READ IT AND DISCARD IT.
HRROI IOP,B
PUSHJ P,NTIIOT ;READ THE BYTE COUNT
SUBI C,1 ;C GETS # WDS LEFT.
MOVEI D,-1(B)
ADD D,BYTSWD
IDIV D,BYTSWD ;NUMBER OF WORDS IT OUGHT TO TAKE
CAME C,D
.VALUE ;MLSLV IS TRYING TO ROUGH US OVER
MOVN A,B
ADDB A,INPALL ;DECREASE ALLOCATION
JUMPL A,LOSE2
CAMLE A,BUFSIZ
.VALUE
NTDI2: MOVEI A,EBUF
SUB A,BUFI ;A => ROOM TILL END OF BUFFER
CAMLE A,C
MOVE A,C ;TRANSFER MIN OF A AND C
SUB C,A ;C => REMAINING # WORDS TO READ
MOVN IOP,A
HRLZS IOP
HRR IOP,BUFI
PUSHJ P,NTIIOT
CAIN IOP,EBUF
MOVEI IOP,BUF
MOVEM IOP,BUFI
JUMPG C,NTDI2
JUMPL C,LOSE7
PUSHJ P,NTIFRC
SKIPN C,RETOIN ;IS CREATOR HANGING IN AN IOT WAITING FOR THIS DATA?
JRST GOLOOP
SETZM RETOIN ;IF SO, RETURN TO IOT CODE AND GIVE IT TO HIM.
MOVE A,JBCOP
JRST JIOTI1
;HERE IF WE MUST IGNORE SOME DATA, BECAUSE WE HAVE GOT A .ACCESS
;THAT THE SLAVE HASN'T ACKNOWLEDGED YET.
NTDI3: MOVEI A,200
CAIGE C,200
MOVE A,C
SUB C,A
MOVN IOP,A
HRLZS IOP
HRRI IOP,BUF
PUSHJ P,NTIIOT
JUMPG C,NTDI3
PUSHJ P,NTIFRC
JRST GOLOOP
OPNSO:
OPNSI: HRRI B,RCH ;FLUSH UNDESIRED OPEN REPLY
PUSHJ P,NTIIOB ;OPEN REPLIES THAT ARE EXPECTED ARE SNARFED UP BY JOPEN.
JRST GOLOOP ;AN OPEN REPLY MAKING IT THRU THE MAIN DISPATCH MUST BE UNEXPECTED.
NTIIOB: MOVE IOP,B
PUSHJ P,NTIIOT
JRST NTIFRC
EOF: HRRI B,C
PUSHJ P,NTIIOB
SKIPE ACCACK
JRST GOLOOP
SETOM EOFI
SKIPN RETOIN ;SKIP IF CREATOR WAITING FOR MORE DATA
JRST GOLOOP
SETZM RETOIN ;GIVE EOF INSTEAD
JRST JIOTIE
FDELST: HRROI IOP,B ;GET REPLY CODE AND NAMES
PUSHJ P,NTIIOT
JUMPL B,FDLST2 ;IF A RENAME/DELETE REPLY, IT MUST BE UNEXPECTED SINCE
;THEY ARE READ IN BY JFDEL1. SO IGNORE IT.
SKIPL RNMWOS ;WERE WE EXPECTING THIS REPLY?
JRST FDELS2 ; NO => IGNORE IT.
SETZM RNMWOS
TRNN B,400000
JRST FDLST1 ;THE RENAME FAILED.
PUSHJ P,OPNSN ;IT WON. READ IN THE NEW REAL FILE NAMES.
.CALL JBRT1
PCL
FDLST2: PUSHJ P,NTIFRC
JRST GOLOOP
FDLST1: HRLZM B,ERRCOD
.CALL JBRT3
PCL
JRST FDLST2
;IGNORE THE REST OF A RENMWO REPLY THAT WAS NOT AWAITED.
FDELS2: MOVE IOP,[-4,,RCH]
TRNE B,400000
PUSHJ P,NTIIOT
JRST FDLST2
XNOOP: HRROI B,C
PUSHJ P,NTIIOB
JRST GOLOOP
XACC: HRRI B,B ;HANDLE ACCESS ACKNOWLEDGEMENT.
PUSHJ P,NTIIOB ;WHAT TRANSACTION NUMBER IS THIS?
CAMN B,ACCNUM ;IF THIS IS RESPONSE TO MOST RECENT ACCESS,
SETZM ACCACK ;ALLOW INPUT TO BE READ AGAIN.
JRST GOLOOP ;AND RESUME PROGRAM, DATA WILL SOON ARRIVE
XCALL: HRRI B,XCALLB
PUSHJ P,NTIIOB ;READ THE NINE VALUES (FIRST IS ERROR CODE AND SKIPPAGE)
SOSG CALACK ; NOTE THE ACKNOWLEDGE AND SKIP IF NOT CURRENT YET
SKIPN CALING ; CURRENT; SKIP IF USER IS WAITING
JRST GOLOOP ; NOT CURRENT YET, KEEP WAITING; OR DON'T WANT IT
SETZM CALING ;WE ARE NO LONGER WAITING FOR A .CALL REPLY.
SYSCAL JOBRET,[ ;GIVE VALUES TO USER.
1000,,CHBOJ
XCALLB
[-8,,XCALLB+1]]
PCL
SKIPL MLINKS ;IF THIS .CALL WAS AN MLINK, WE SHOULD EXIT NOW.
JRST GOLOOP
JRST REUSE
XOCLOS::
XICLOS::
JRST DIE
XIOC: HRROI B,B ;HANDLE "RIOC" (MLSLV GOT AN IOC ERROR FROM DISK)
PUSHJ P,NTIIOB ;READ IN THE IOC ERROR CODE
SYSCAL JOBIOC,[1000,,CHBOJ ? B]
JFCL ;PASS IT TO CREATOR.
;AT THE MOMENT, SINCE DATA IS LOST WHEN AN IOC ERROR IS PASSED BACK,
;THERE IS NO USE IN LEAVING THE FILE OPEN.
JRST DIE
SETZM RETOIN ;THIS FLUSHES ANY .IOT THAT WAS IN PROGRESS.
SETZM CALING
SETZM CALACK
JRST GOLOOP
TSINT: 0
0
SKIPL U,TSINT
JRST TSFW
TRNN U,1_CHBOJ+1_CHNETI
.VALUE
SETOM INT
TRZE U,1_CHBOJ
SETOM JBINT
TRZE U,1_CHNETI
SETOM NTICIN
CAME U,[SETZ]
.VALUE
.DISMISS TSINT+1
TSFW: TRNN U,%PIIOC
.VALUE [ASCIZ /:UNHANDLED RANDOM INTERRUPT/]
.SUSET [.RBCHN,,U] ;Read erring channel number.
CAIE U,CHNETI
CAIN U,CHNETO
CAIA
.VALUE
SKIPN FILOPN
.DISMISS [NOGO] ;ERROR CONNECTING => DEV NOT AVAIL
.DISMISS [NTIOC] ;ERROR TRANSFERRING => IOC ERROR
LOSE1: .VALUE
LOSE2: .VALUE
LOSE3: .VALUE
LOSE4: .VALUE
LOSE5: .VALUE
LOSE6: .VALUE
LOSE7: .VALUE
LOSE8: .VALUE
;COME HERE WHEN WE HAVE BEEN FINISHED WITH BY ONE CREATOR, TO OFFER OURSELVES TO OTHERS.
REUSE: MOVEI A,30.*5 ;WAIT FIVE SECONDS FOR SOMEONE TO TRY TO REUSE US.
.SUSET [.SAMSK2,,[1_CHBOJ]]
SYSCAL JOBREU,[
RDEVN ;DEVICE NAME WE ARE HANDLING.
['JOBDEV] ;FILENAMES WE WERE LOADED FROM.
RDEVN
['DEVICE]
A] ;AMOUNT OF TIME TO WAIT (UPDATED, AS IN .SLEEP).
JRST REUSL
.SUSET [.SIMSK2,,[1_CHBOJ]]
SYSCAL RFNAME,[ ;SOMEBODY GOBBLED US. FIND OUT WHO, FOR PEEK.
1000,,CHBOJ
2000,,0
2000,,CRUNAM
2000,,CRJNAM]
JFCL
MOVE IOP,[-2,,[-1,,CREUSE ? 0]]
PUSHJ P,NETOUT
REUSE2: PUSHJ P,REPLY ;NOW SNARF REPLIES TILL WE GET TO THE RREUSE.
CAIE A,RREUSE
JRST [ HRRI B,BUF ;IGNORE ANY OTHER REPLIES.
PUSHJ P,NTIIOB
JRST REUSE2]
HRRI B,RCH
PUSHJ P,NTIIOB
SETZM SNTCLS ;WE ARE NO LONGER WAITING FOR A CICLOS (WE IGNORED IT)
JRST REUSE1
;HERE IF WE SEE WE ARE NOT GOING TO BE REUSED.
REUSL: SKIPE SNTCLS ;IF WE SENT A CICLOS, WE MUST WAIT FOR THE RICLOS, WHICH WILL
JRST GOLOOP ;COME BACK TO DIE.
;COME HERE TO REALLY GIVE UP THE GHOST.
DIE: SKIPN DEBUG
.LOGOUT
.VALUE
JRST DIE
JBGT: SETZ
'JOBCAL
[CHBOJ]
2000,,JBCOP
SETZ [-11.,,JBCWD1]
JBST: SETZ
'JOBSTS
MOVEI CHBOJ
MOVEI 43 ;SNDSK
RDEVN
RDEVN+1
RDEVN+2
SETZ RDEVN+3
JBRT1: SETZ
SIXBIT /JOBRET/
[CHBOJ]
SETZ [1]
JBRTL: SETZ
SIXBIT /JOBRET/
[CHBOJ]
SETZ [0]
JBRT3: SETZ ;JOBRET AN ERROR CODE.
SIXBIT /JOBRET/
[CHBOJ]
SETZ ERRCOD
ERRCOD: 0 ;ERROR CODE PUT IN HL OF THIS WORD.
JBIOC: SETZ
SIXBIT /JOBIOC/
1000,,CHBOJ
401000,,1
$$HSTMAP==1
$$HOSTNM==1
$$SYMLOOK==1
$$CHAOS==1
$$ARPA==1
$$HST3==1
$$TCP==1
$$CONNECT==1
.SCALAR USENCP,USETCP ;Bullshit
.INSRT SYSTEM;CHSDEF
.INSRT SYSENG;NETWRK
NW%CHS==NETWRK"NW%CHS
NW%ARP==NETWRK"NW%ARP
IFNDEF %WYTCP,%WYTCP==7 ; Until defined in sys
VARIABLES
CONSTANTS
MLINKP: -11.,,CSYSCL ;THESE ARE BEGINNING OF THE BLOCK SENT TO SLAVE
SIXBIT/MLINK/ ;TO HANDLE AN "MLINK" OPERATION. FORMAT OF BLOCK IS SAME
0 ;AS THE BLOCK FOR RANDOM SYSTEM CALL.
;JBCOP MUST BE NEXT LOCATION!
;DATA RETURNED BY JOBCAL.
JBCOP: 0 ;OPCODE: 0-8 MEANING OPEN, IOT, MLINK, RESET, RCHST, ACCESS, DELETE/RENAME, RENMWO, .CALL.
JBCWD1: 0 ;BLOCK IOT PTR / ACCESS PTR / NEW FN1 IN RENAME&MLINK / 0 IN DELETE. / SYSTEM CALL NAME.
JBCFN1:
JBCWD2:: 0 ;FN1
JBCFN2:
JBCWD3:: 0 ;FN2
JBCSNM: ;SNAME
JBCA1:: ;AND 1ST ARGUMENT OF .CALLS.
JBCWD4:: 0
JBCDEV: ;DEVICE NAME
JBCA2:: ;AND 2ND ARGUMENT OF .CALLS.
JBCWD5:: 0
JBCWD6: 0 ;NEW FN2 IN RENAME&MLINK / OPEN MODE IN OPEN.
JBCWD7: 0 ;NEW SNAME IN MLINK.
JBCWD8: 0
JBCWD9: 0
JBCW10: 0
JBCW11: 0
FDEVN: 0 ;FORIGN DEVICE NAME (DSK, FOR ML. DIR, FOR MLDIR. ETC.)
ACCNUM: 0 ;TRANSACTION NUMBER OF LAST CACCES COMMAND.
ACCACK: 0 ;-1 => WE ARE WAITING FOR A RACCES.
RNMWOS: 0 ;-1 => WAITING FOR REPLY FOR RENAME WHILE OPEN.
CALING: 0 ;-1 => MOST RECENT THING USER DID WAS A .CALL.
CALACK: 0 ;NUMBER OF CSYSCL COMMANDS SENT AND NOT YET REPLIED TO.
MLINKS: 0 ;-1 => THE .CALL WE ARE IN IS AN MLINK, SO DIE WHEN IT FINISHES.
TRANS: 0 ;NUMBER OF LAST TRANSACTION (RIGHT NOW, ONLY CACCES USES A
;TRANSACTION NUMBER).
XCALLB: BLOCK 9. ;ARGS TO RSYSCL COMMAND READ IN HERE.
RCH: BLOCK 12. ;BETTER BE AT LEAST AS LONG AS OPEN REPLY ARGS
INPALL: 0 ;INPUT ALLOCATION KNOW TO SLAVE, IN BYTES.
INREAL: 0 ;# BYTES EMPTY IN BUFFER BUT NOT REALLOCATED.
OPMODE: 0 ;MODE CREATOR OPENED US IN.
EOFI: 0 ;-1 => HAVE REACHED EOF ON INPUT
RETOIN: 0 ;NONZERO => CREATOR HUNG IN INPUT IOT, THIS IS # BYTES WANTED.
RETOOU: 0 ;-1 => CREATOR HUNG IN AN OUTPUT IOT WHILE WE EXAMINE REPLIES FROM SERVER.
RETOCT: 0 ;WHEN RETOOU IS -1, THIS HAS # BYTES LEFT TO XFER IN THAT IOT.
FILOPN: 0 ;-1 => OUR CREATOR "HAS A FILE OPEN". WE AREN'T FREE OF HIM TILL HE CLOSES.
LOGGED: 0 ;-1 => HAVE LOGGED IN AT FOREIGN HOST
LOGINS: 0 ;- => LOGIN REQUEST SENT, BUT NOT YET ANSWERED
SNTCLS: 0 ;-1 WE HAVE SENT A CICLOS, SO MUST NOT SUICIDE TILL THE RICLOS.
JBINT: 0 ;-1 => CHBOJ INT
NTICIN: 0 ;-1 => CHNETI INT
LPDLL==100
PDL: BLOCK LPDLL+4
CONSTANTS
VARIABLES
NBUFL==360. ;Number of 8-bit bytes of network buffer
NBUFO: BLOCK NBUFL/4 ;NBUFL must be multiple of 4 and 9
NBUFOP: 440800,,NBUFO ;Fill pointer for network buffer
NBUFOC: NBUFL ;Bytes remaining
NBFOXF: 0 ;-1 => extra word in NBFOXW
NBFOXW: 0 ;extra word not sent yet
NBUFI: BLOCK NBUFL/4
NBUFIP: 440800,,NBUFI ;Take pointer for network buffer
NBUFIC: 0
NBFIXF: 0 ;-1 => extra word in EXTRAW
NBFIXW: 0 ;extra word not sent yet
BUFI: BUF ;POINTER FOR LOADING BUF FROM RDATA'S
BUFO: BUF ;POINTER FOR TAKING FROM BUF TO GIVE TO CREATOR.
BUFSIZ: 0 ;BUFFER SIZE IN BYTES OF SIZE WE'RE USING.
BYTSWD: 0 ;# BYTES IN A WORD.
BUFONM: 0 ;BUFO, IN FORM OF # BYTES FROM BEGINNING OF BFR.
HDR0: 0 ;MUST BE BUF-2. FOR OUTPUT TO NETWORK, THE CDATA COMMAND IS
;PUT HERE, SO ONE .IOT CAN SEND IT AND THE DATA IN BUF.
HDR1: 0 ;BYTE COUNT OF CDATA PUT HERE.
BUFL==6000-. ;TRY TO FIT IN 3K
IFL BUFL-1000,BUFL==BUFL+2000 ;OH, WELL
BUF: BLOCK BUFL
EBUF==.
LOC EBUF-1
-1 ;ENSURE CORE EXISTENCE
LOC EBUF
DEFINE INFORM A,B
PRINTX/A=B
/TERMIN
IF1 INFORM BUFFER SIZE,\BUFL
IF1 INFORM HIGHEST USED,\.
HSTPAG==<.+1777>/2000
END GO