mirror of
https://github.com/PDP-10/its.git
synced 2026-01-24 11:22:36 +00:00
318 lines
7.7 KiB
Plaintext
Executable File
318 lines
7.7 KiB
Plaintext
Executable File
;;; Copyright (c) 1999 Massachusetts Institute of Technology
|
||
;;; See the COPYING file at the top-level directory of this project.
|
||
|
||
;.OPEN CHNL,PNTR1
|
||
|
||
;PNTR1: MODE,,(SIXBIT /NET/)
|
||
; PNTR2
|
||
; MYNAME1
|
||
; MYNAME2
|
||
|
||
;PNTR2: HISNAME1
|
||
; HISNAME2
|
||
; COUNT
|
||
; buffer
|
||
|
||
;MODES=> BITS 3.1== READ FROM ANY
|
||
; 3.2== READ FROM SPECIFIC
|
||
; 3.3== SEND AND HANG
|
||
; 3.4== SEND IMMEDIATE
|
||
; 3.5== USE UNAME JNAME AS MY1 AND MY2
|
||
; 3.6== USE UNAME AS HIS1
|
||
|
||
;OPEN FAILURES:
|
||
; 4 HIS NAME 1 & HIS NAME 2 WERE ZERO
|
||
; 6 TABLE FULL
|
||
; 7 ON WRITE, RELOCATION OF READ BUFFER FAILED
|
||
; 11 ATTEMPT TO SEND TO SELF
|
||
; 12 NOT A LEGAL MODE
|
||
; 20 SEND IMMEDIATE, GUY WASN'T THERE
|
||
; 22 BUFFER NOT IN YOUR CORE IMAGE
|
||
|
||
|
||
EBLK
|
||
|
||
MSENTS==40 ;# OF ENTRIES IN THE TABLE
|
||
|
||
MSUSER: BLOCK MSENTS ;USER INDEX
|
||
MSCHNL: BLOCK MSENTS ;USERS CHANNEL
|
||
MSBADR: BLOCK MSENTS ;RELATIVE ADDRR OF USER'S BUFR
|
||
MSBCNT: BLOCK MSENTS ;SIZE OF USERS BUFFER
|
||
|
||
MSWRIT: BLOCK MSENTS ;SENDING NAME 1
|
||
MSWRT2: BLOCK MSENTS ;SENDING NAME 2
|
||
MSREAD: BLOCK MSENTS ;READING NAME 1
|
||
MSRED2: BLOCK MSENTS ;READING NAME 2
|
||
|
||
MSPSW: -1 ;SWITCH FOR MSP VARIABLES
|
||
0 ;EXTRA WORD, FOR SWTL ROUTINE
|
||
|
||
BBLK
|
||
|
||
IPCO: PUSHJ P,SWTL ;LOCK THE MSP SWITCH
|
||
MSPSW
|
||
TLNE C,1 ; read from any?
|
||
JRST MSRA ; yes
|
||
TLNE C,2 ; read from specific?
|
||
JRST MSRS ; yes
|
||
TLNE C,4 ; send and hang?
|
||
JRST MSSH ; yes
|
||
TLNE C,8 ; send immediate?
|
||
JRST MSSI ; yes
|
||
JRST OPNL12 ; none of the above
|
||
|
||
; read from any (RA) and read from specific (RS)
|
||
MSRA: SETOM H ; H/-1 =>RA 0=>RS
|
||
SKIPA
|
||
MSRS: SETZM H
|
||
|
||
; find first free user slot
|
||
MOVSI W,-MSENTS ; W/ slot index
|
||
MSR1: SKIPG MSUSER(W) ; is this slot free?
|
||
JRST MSR2 ; yes
|
||
AOBJN W,MSR1
|
||
JRST OPNL6 ; no free slots, device full
|
||
|
||
; W/ slot index of a free slot
|
||
MSR2: MOVEM U,MSUSER(W) ; occupies this slot
|
||
; make sure we have a legal buffer
|
||
HRRZ D,A ; relative address of second buffer
|
||
MOVEI E,3(D) ; E/ relative address of data area
|
||
XCTR XRW,[MOVES (D)] ;CHECK COUNT FETCH?
|
||
XCTR XRW,[MOVES TT,2(D)] ;CHECK ACTUAL COUNT PLACE
|
||
|
||
; bufr ok, now put data in table
|
||
MOVEM E,MSBADR(W) ; stores buffer address
|
||
MOVEM TT,MSBCNT(W)
|
||
|
||
; store sender name only if RS
|
||
JUMPL H,MSR3
|
||
XCTR XR,[MOVE TT,(D)] ; his name 1
|
||
XCTR XR,[MOVE I,1(D)] ; his name 2
|
||
TLNE C,40 ; his1 = UNAME?
|
||
MOVE TT,UNAME(U) ; yes
|
||
SKIPA
|
||
MSR3: SETZB TT,I ; zero if RA
|
||
MOVEM TT,MSWRIT(W)
|
||
MOVEM I,MSWRT2(W)
|
||
|
||
; 3.5 bit in C means use UNAME JNAME as myname1 and myname2
|
||
TLNN C,20 ; skips if want default
|
||
JRST .+4
|
||
MOVE TT,UNAME(U)
|
||
MOVE I,JNAME(U)
|
||
JRST .+3
|
||
; else me1 is in B and me2 is in SRN3(U)
|
||
MOVE TT,B
|
||
MOVE I,SRN3(U)
|
||
MOVEM TT,MSREAD(W)
|
||
MOVEM I,MSRED2(W)
|
||
|
||
MOVEI TT,(R) ;GET CHANNEL
|
||
SUBI TT,IOCHNM(U)
|
||
MOVEM TT,MSCHNL(W) ;STORE FOR LATER INTERRUPT
|
||
|
||
PUSHJ P,LSWPOP ;UNLOCK MSP SWITCH
|
||
|
||
; now put tabl index in lh of IOCHNM(U)(R)
|
||
HRLZ A,W
|
||
JSP Q,OPSLD1
|
||
MSPIO,,MSPIO ; attempted IOT will get IOCER 10.
|
||
; send and hang (SH) and send immediate (SI)
|
||
MSSI: SETOM H ; H/-1=>SI 0=>SH
|
||
SKIPA
|
||
MSSH: SETZM H
|
||
|
||
; validate his buffer specs
|
||
HRRZ D,A ; relative buffer address
|
||
MOVEI E,3(D) ; E/ relative data addr
|
||
XCTR XRW,[MOVES (D)] ;CHECK NAME
|
||
XCTR XRW,[MOVES Q,2(D)] ;CHECK COUNT
|
||
|
||
; other data
|
||
; E/ absolute data addr
|
||
; Q/ count
|
||
XCTR XR,[MOVE T,(D)] ; T/ his name 1
|
||
TLNE C,40 ; 3.6 bit means use UNAME
|
||
MOVE T,UNAME(U) ; yes
|
||
XCTR XR,[MOVE TT,1(D)] ; TT/ his name 2
|
||
JUMPN T,.+3 ; T and TT can not both be zero
|
||
SKIPN TT
|
||
JRST OPNL4
|
||
MOVEM TT,EPDL(U) ; EPDL(U)/ hisname2
|
||
|
||
; 3.5 bit in C means use UNAME JNAME as myname1 and myname2
|
||
TLNN C,20 ; skips if wants default
|
||
JRST .+4
|
||
MOVE TT,UNAME(U)
|
||
MOVE I,JNAME(U)
|
||
JRST .+3
|
||
; else myname1 is in B and myname2 is in SRN(U)
|
||
MOVE TT,B
|
||
MOVE I,SRN3(U)
|
||
MOVEM TT,EPDL3(U) ; EPDL3/ myname1
|
||
MOVEM I,SRN4(U) ; SRN4/ myname2
|
||
|
||
; see if entry is in the table
|
||
PUSHJ P,MSSTBL
|
||
SKIPA ; no, will havee to wait
|
||
JRST MSS2 ; yes, service the transfer
|
||
JUMPL H,OPNL20 ; was an SI, lose
|
||
MSS1: XCTR XR,[MOVE T,(D)] ; in case it got munged
|
||
TLNE C,40 ; 3.6 bit means use UNAME
|
||
MOVE T,UNAME(U)
|
||
|
||
|
||
; wait for entry to appear in table
|
||
MSDM3: PUSH P,T ;LSWPOP CLOBBERS T
|
||
PUSHJ P,LSWPOP ;UNLOCK MSPSW FOR WAITING
|
||
MOVE T,(P) ;RESTOR T
|
||
SKIPA ; forces a call to ufls
|
||
PUSHJ P,MSSTBL
|
||
PUSHJ P,UFLS ; hang . . . .
|
||
PUSHJ P,SWTL ;RELOCK SWITCH NOW
|
||
MSPSW
|
||
POP P,T ;RESTORE T AFTER CLOBBERING BY SWTL
|
||
PUSHJ P,MSSTBL ; read has been done, get details
|
||
JRST MSS1 ; oops, must have been aborted
|
||
|
||
; FALLS THRU IF MSSTBL SKIPS
|
||
; table index of the user is now in T
|
||
MSS2: MOVE H,T ; H/ table index
|
||
MOVE A,MSUSER(H) ; A/ user index
|
||
CAMN A,U
|
||
JRST [PUSHJ P,LSWPOP ;POP MSPSW
|
||
JRST OPNL11]
|
||
PUSHJ P,RPCLSR ; stop or i'll shoot
|
||
PUSHJ P,SOSSET ;SET TO SOS USTP(A) ON PCLSR
|
||
USTP(A)
|
||
|
||
; get the absolute address of the read data buffer
|
||
MSS3: MOVE A,MSBADR(H) ; relative
|
||
;SET UP PAGE MAP FOR RECEIVER (USER IN MSUSER(H))
|
||
PUSH P,R
|
||
MOVE J,MSUSER(H) ;USER TO RECEIVE
|
||
PUSHJ P,MPLDJ ;LOAD MAP
|
||
; fix count (sender cnt in Q, receiver cnt in MSBCNT(H))
|
||
CAMG Q,MSBCNT(H) ; will it fit?
|
||
JRST MSS4 ; yes
|
||
XCTRI XRW,[SETOM -1(A)] ; no, indicate overflow will be lost
|
||
CAIA ;REFERENCE WORKED, SKIP
|
||
JRST MSS7 ;FAIL, RESTORE STOPS ETC.
|
||
MOVE B,MSBCNT(H) ; B/ count
|
||
JRST MSS5
|
||
MSS4: MOVE B,Q ; B/ count
|
||
MOVE TT,MSBCNT(H)
|
||
SUB TT,B
|
||
XCTRI XRW,[MOVEM TT,-1(A)] ; amount that will be xfered
|
||
CAIA ;REFERENCE WORKED, SKIP
|
||
JRST MSS7 ;FAIL, RESTORE STOPS ETC.
|
||
|
||
; if MSWRIT was zero (RA), fill it in
|
||
MSS5: SKIPN MSWRIT(H)
|
||
SKIPE MSWRT2(H)
|
||
JRST MSS6
|
||
MOVE TT,EPDL3(U)
|
||
XCTRI XRW,[MOVEM TT,-3(A)] ; read's him1
|
||
CAIA ;REFERENCE WORKED, SKIP
|
||
JRST MSS7 ;FAIL, RESTORE STOPS ETC.
|
||
MOVE TT,SRN4(U) ;
|
||
XCTRI XRW,[MOVEM TT,-2(A)] ; read's him2
|
||
CAIA ;REFERENCE WORKED, SKIP
|
||
JRST MSS7 ;FAIL, RESTORE STOPS ETC.
|
||
|
||
; RESTORE USER MAP TO CURRENT USER
|
||
MSS6: PUSHJ P,MPLDZ
|
||
POP P,R
|
||
; XFER => B/ CNT A/READ BUFR E/WRIT BUFR J/UNRELOCATED BUFFER (READ)
|
||
HRRM A,IOCHST-IOCHNM(R) ;STORE RECEIVER ADDRESS FOR UBO
|
||
MOVN W,B ;-COUNT
|
||
MOVSS W ;-COUNT,,
|
||
HRR W,E ;-COUNT,,ADR
|
||
MOVE C,[SETZ W] ;POINTER FOR UBO
|
||
MOVE A,MSUSER(H) ;GET OTHER USERS NUMBER FOR UBO
|
||
PUSHJ P,UBO ;USER BLOCK OUTPUT - DO WRITE TRANSFER
|
||
|
||
; RESTART THE LOSER
|
||
PUSHJ P,LSWPOP ;UNDO RPCLSR (SOS USTP(MSUSR(H)))
|
||
MOVE A,MSUSER(H) ;GET TARGET USER
|
||
MOVE B,MSCHNL(H) ;CHANNEL HE OPENED
|
||
MOVE B,CHNBIT(B) ;BIT CORRESPONDING TO CHAN
|
||
TDNE B,MSKST2(A) ;SKIP IF NOT ENABLED
|
||
IORM B,IFPIR(A) ;SET HIS INTERRUPT
|
||
|
||
; flush read entry from the table
|
||
SETZM MSCHNL(H)
|
||
SETZM MSREAD(H)
|
||
SETZM MSRED2(H)
|
||
SETZM MSWRIT(H)
|
||
SETZM MSWRT2(H)
|
||
SETZM MSBADR(H)
|
||
SETZM MSBCNT(H)
|
||
SETZM MSUSER(H)
|
||
|
||
PUSHJ P,LSWPOP ;UNLOCK MSPSW
|
||
|
||
; end open
|
||
SETOM A ; LH IOCHNM==-1 MEANS SEND (FOR CLOS)
|
||
JSP Q,OPSLD1 ;DOES POPJ BACK TO UUOH
|
||
MSPIO,,MSPIO
|
||
; (DOES NOT COME BACK)
|
||
|
||
;HERE FOR FAILURE OF XCTRI WHILE MAP SET TO RECEIVER
|
||
MSS7: POP P,R ;RESTORE STACK
|
||
PUSHJ P,LSWPOP ;RESTART USER (SOS USTP)
|
||
PUSHJ P,TPFLT ;TAKE PAGE FAULT, CAUSE PAGE LOAD
|
||
PUSHJ P,MPLDZ ;RESTORE MY PAGE MAP
|
||
JRST MSS1 ;TRY AGAIN
|
||
|
||
; FIND LOSER IN TABLE SKIP IF WINS
|
||
; IN => T/READ1 EPDL/READ2 EPDL3/WRITE1 SRN4/WRITE2
|
||
; OUT => IF WINS, T/TABLE OFFSET
|
||
MSSTBL: PUSH P,A
|
||
PUSH P,B
|
||
PUSH P,C
|
||
PUSH P,D
|
||
MOVSI A,-MSENTS
|
||
MOVE B,EPDL(U) ; B/ READ2
|
||
MOVE C,EPDL3(U) ; C/ WRITE1
|
||
MOVE D,SRN4(U) ; D/ WRITE2
|
||
MSSTB1: CAMN T,MSREAD(A)
|
||
CAME B,MSRED2(A)
|
||
JRST MSSTB2
|
||
SKIPN MSWRIT(A) ; if it was read from any
|
||
SKIPE MSWRT2(A) ; win if WRIT and WRT2 are both zero
|
||
JRST .+2
|
||
JRST MSSTB3
|
||
CAMN C,MSWRIT(A)
|
||
CAME D,MSWRT2(A)
|
||
JRST MSSTB2
|
||
MSSTB3: HRRZ T,A
|
||
AOSA -4(P)
|
||
MSSTB2: AOBJN A,MSSTB1
|
||
POP P,D
|
||
POP P,C
|
||
JRST POPBAJ
|
||
|
||
; close routine
|
||
; A/ lf IOCHNM
|
||
; R/ addr of IOCHNM(USER)(CHNL)
|
||
|
||
MSCLOS: TRNE A,400000 ; -1 means write
|
||
POPJ P,
|
||
CAIL A,MSENTS ; in bounds of table?
|
||
POPJ P, ; no
|
||
CAME U,MSUSER(A) ; is this still me?
|
||
POPJ P,
|
||
|
||
; yes, make this a free slot
|
||
SETZM MSCHNL(A)
|
||
SETZM MSREAD(A)
|
||
SETZM MSRED2(A)
|
||
SETZM MSWRIT(A)
|
||
SETZM MSWRT2(A)
|
||
SETZM MSBADR(A)
|
||
SETZM MSBCNT(A)
|
||
SETZM MSUSER(A)
|
||
POPJ P,
|
||
|