Trailing-Edge
-
PDP-10 Archives
-
BB-P363B-SM_1985
-
mcb/drivers/nrm.m11
There are no other files named nrm.m11 in the archive.
.TITLE NRM - NODE RESOURCE MANAGER
.IDENT /007000/
.ENABL LC
;
; COPYRIGHT (c) 1980, 1981, 1982
; DIGITAL EQUIPMENT CORPORATION
; Maynard, Massachusetts
;
; This software is furnished under a license and may be used
; and copied only in accordance with the terms of such license
; and with the inclusion of the above copyright notice. This
; software or any other copies thereof may not be provided or
; otherwise made available to any other person. No title to
; and ownership of the software is hereby transferred.
;
; The information in this software is subject to change
; without notice and should not be construed as a commitment
; by DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL assumes no responsibility for the use or reliability
; of its software on equipment which is not supplied by
; DIGITAL.
;
; VERSION 01
;
; R.A. MODEEN 02-MAY-77
;
; VERSION 02
;
; L.D. WEBBER 26-SEP-77
;
; VERSION 5
;
; A.D. PECKHAM 25-JAN-78
;
; VERSION 7
;
; A.D. PECKHAM 6-JUN-80
;
; MACRO LIBRARY CALLS
;
.MCALL CCBDF$,DAT$,DSP$B,ScDF$,PHD$b
.MCALL MAP$,POP$S,PUSH$S,SAVMAP,RESMAP
.MCALL NCRA$,NACC$,NREJ$,NDAK$,NDIS$,NABO$
.MCALL NDAT$,NDRQ$,NRTN$,NIRQ$,NRTI$
CCBDF$ ; DEFINE CCB OFFSETS
scDF$ ; DEFINE Sc OFFSETS
nrmdf$
;
; LOCAL MACROS
;
; GTPCB$ - GET THE ASSOCIATED PCB IN R3
;
.MACRO GTPCB$
GTULA$ R0
CALL $PCBPT
.ENDM GTPCB$
;
; GTTCB$ - GET THE ASSOCIATED TCB IN R5
;
.MACRO GTTCB$
CLR R0
BISB C.lix(R4),R0
CALL $TCBTT
.ENDM GTTCB$
;
; RESPOND - SEND A RESPONSE TO THE CURRENT RESOURCE MESSAGE
;
.MACRO RESPOND CODE,SUB
.IF EQ <'CODE'-RC.IRC> ; ILLEGAL REQUEST CODE
JMP INVALID
.IFF
.IF NB,<CODE> ; RESPONSE CODE
MOV #'CODE',R0
.ENDC
.IF NB,<SUB> ; OPTIONAL DATA
MOV #'SUB',R5
.ENDC
JMP RSPNS
.ENDC
.ENDM RESPOND
.SBTTL ATS RESOURCE MANAGER SYMBOL DEFINITIONS
;+
; THESE SYMBOL DEFINITIONS ARE LOCAL TO THE ATS RESOURCE MANAGER.
; THE SYMBOLS WHICH ARE USED BY ALL THE ATS COMPONENTS (RESOURCE
; MANAGER AND DIALOGUE MANAGERS) ARE DEFINED IN THE MACRO TTDF$
; IN THE LIBRARY CELIB.MLB.
;-
; REQUEST CODES (SET IN 1ST BYTE OF RESOURCE MESSAGE)
RQ.RID= 041 ; REQUESTOR ID
RQ.CAP= 042 ; CAPABILITIES
RQ.RES= 047 ; RESPONSE
RQ.SPC= 050 ; SPECIFY
RQ.ACC= 051 ; ACCESS
RQ.ASS= 052 ; ASSIGN
RQ.STS= 053 ; STATUS
RQ.CTL= 054 ; CONTROL
; REQUEST TYPE CODES (SET IN 2ND BYTE OF RESOURCE MESSAGE)
; <SPECIFY> MESSAGE TYPES
SY.RES= 001 ; RESERVE
SY.SHR= 002 ; SHARE
SY.REF= 003 ; REFER
; <SPECIFY> MESSAGE FLAGS
SY.DBL= 020 ; DOUBLE (CONCATENATED) MESSAGE FLAG
; RANGE LIMITS FOR REQUEST CODE OF SECOND (CONCATENATED) MESSAGE
RS.LOW= 051 ; LOW LIMIT FOR REQUEST CODE
RS.HIH= 053 ; HIGH LIMIT FOR REQUEST CODE
; <ACCESS> MESSAGE TYPES
AC.SIN= 001 ; OPEN SINGLE LOGICAL LINK
AC.SEP= 002 ; OPEN SEPARATE DATA LINK
AC.CLO= 003 ; CLOSE
AC.REL= 004 ; RELEASE
; <ASSIGN> MESSAGE TYPES
AS.ASS= 001 ; ASSIGN
AS.RES= 002 ; RECLAIM
AS.HAN= 003 ; HANDOFF
; <STATUS> MESSAGE TYPES
ST.QRY= 001 ; QUERY
ST.REP= 002 ; STATUS-REPORT
ST.ALT= 003 ; STATUS-ALTER
; <STATUS> MESSAGE SUB-TYPES
SS.OPR= 001 ; OPERATIONAL STATUS
SS.RES= 002 ; RESOURCE CONTROL
SS.ERR= 003 ; ERROR STATISTICS
SS.USA= 004 ; USAGE ACCOUNTING
SS.ATS= 010 ; ATS TERMINAL STATUS
; <STATUS> MESSAGE FLAGS
ST.REL= 020 ; AUTOMATIC STATUS-RELEASE FLAG
; <RESPONSE> CODE DEFINITIONS
RC.FIN= 0. ; FINAL RESPONSE, NO ERROR
RC.INT= 1. ; INTERMEDIATE RESPONSE
RC.ACC= 2. ; HANDOFEE ACCEPTS RESOURCE
RC.ANP= 20. ; ACCESS NOT PERMITTED
RC.IAC= 21. ; INVALID ACCOUNTING INFORMATION
RC.IRC= 22. ; INVALID OR UNSUPPORTED REQUEST TYPE
RC.ICT= 23. ; INVALID REQUEST CONCATENATION
RC.RQO= 24. ; CONTROL ID ALREADY IN USE
RC.RNE= 25. ; SPECIFIED RESOURCE DOES NOT EXIST
RC.RNA= 26. ; REQUESTED RESOURCE NOT AVAILABLE
RC.IRD= 27. ; INVALID RESOURCE DESCRIPTOR FORMAT
RC.GND= 28. ; GENERIC DESCRIPTOR NOT SUPPORTED
RC.SHN= 29. ; SHARED ACCESS NOT SUPPORTED
RC.RSO= 30. ; TOO MANY USERS OF THE RESOURCE
RC.MLN= 31. ; MULTI-LINK USAGE NOT SUPPORTED
RC.SLN= 32. ; SINGLE-LINK USAGE NOT SUPPORTED
RC.ISO= 33. ; INVALID SERVOR OPTION FIELD
RC.SNE= 34. ; SPECIFIED SERVOR DOES NOT EXIST
RC.CNO= 35. ; TOO MANY CONNECTIONS TO SERVOR
RC.RNS= 36. ; RESOURCE NOT SUPPORTED BY SERVOR
RC.RJS= 37. ; REQUEST REJECTED BY SERVOR
RC.RSI= 38. ; RESOURCE OR SERVOR STATE INCONSISTENCY
RC.RSE= 39. ; REQUEST MESSAGE SEQUENCE ERROR
RC.HNE= 40. ; HANDOFEE DOES NOT EXIST
RC.REJ= 41. ; HANDOFEE REJECTS RESOURCE
RC.ACA= 42. ; ACCEPTANCE OF HANDOFF ABORTED
; <RESPONSE> MESSAGE DATA
RD.PNC= 1. ; DATA PIPE NOT CONNECTED
RD.STR= 2. ; START THRESHOLD ERROR
RD.NDI= 1. ; REQUESTED RESOURCE NOT ONLINE
; <STATUS-REPORT> MESSAGE DATA
RP.RCV= 1. ; RECEIVE ERROR THRESHOLD ERROR
RP.REP= 2. ; REPLY THRESHOLD ERROR
RP.NAK= 3. ; NAK THRESHOLD ERROR
RP.TRM= 4. ; HARD TERMINAL ERROR
RP.IRQ= 5. ; INTERVENTION REQUIRED AT TERMINAL
RP.PWF= 6. ; POWERFAIL
RP.DSC= 7. ; DATA PIPE DISCONNECTED
;*THESE DEFINITIONS MUST *NOT* BE CHANGED !!!
;
; BIT MASKS
;
PS.RCN = PS.CI!PS.CC!PS.DIP ; PIPE READY FOR CONNECT
TS.OCP = TS.CLP!TS.OPP!TS.OP ; TERMINAL OPEN OR CLOE PENDING
TS.ROP = TS.OCP!TS.RLP!TS.HP ; TERMINAL READY FOR OPEN
TF.RAL = TF.DEA!TF.DIS ; TERMINAL READY FOR ALLOCATION
;+
; INTERNAL DATA BASE FOR PROCESS
;-
;+
; THESE DISPATCH TABLES ARE USED BY THE CCB DISPATCHER TO PASS CONTROL
; TO THE APPROPRIATE ROUTINE IN THE RESOURCE MANAGER BASED ON THE FUNCTION
; AND SUBFUNCTION PASSED IN THE CCB.
;-
phd$b NRM
phd$d nrmtb
phd$e
; FUNCTION DISPATCH TABLE
.PSECT $PLIT$,D
NRMTB: DSP$B ; DISPATCH TABLE ADDRESS
DSP$ FC.AST ; SRV Server error
DSP$ FC.XME ; TRANSMIT ENABLE ENTRY
DSP$ FC.RCE ; RECEIVE ENABLE ENTRY
DSP$ FC.KIL ; KILL ENABLE ENTRY
DSP$ FC.CTL ; SRV CONTROL ENABLE ENTRY
DSP$ FC.TIM,NRMTIM ; TIMEOUT ENTRY
DSP$ FC.XCP,NRMXCP ; TRANSMIT COMPLETE ENTRY
DSP$ FC.RCP,NRMRCP ; NSP RECEIVE COMPLETE ENTRY
DSP$ FC.KCP ; KILL COMPLETE ENTRY
DSP$ FC.CCP,NRMCCP ; CONTROL COMPLETE ENTRY
RM$RWT = .-NRMTB
DSP$ RM$RWT,NRMRWC ; NRM RESOURCE WAIT COMPLETE
DSP$E
;
; SUB-FUNCTION DISPATCH
;
NRMXCP: JMP @10$(R3) ; Dispatch SC Transmit Complete:
10$: DSP$B
DSP$ ; S$CON - Connect complete
DSP$ ,REQUEST ; S$ACC - Accept complete
DSP$ ; S$REJ - Reject complete
DSP$ ,NRMDAT ; S$SND - Data transmited
DSP$ ; S$MRQ - Message request
DSP$ ,$CCBRT ; S$DRQ - Segment request
DSP$ ; S$SNI - Interrupt transmitted
DSP$ ; S$IRQ - Interrupt requested
DSP$ ; S$DIS - Disconnect complete
DSP$ ,NRMDIS ; S$ABO - Abort complete
DSP$ ; S$GLN - Here is local node information
DSP$E
NRMTIM: jmp @10$(r3) ; Timer dispatch vector
10$: dsp$b
dsp$ ;short timer
dsp$ ,nrmtm ;long timer
dsp$ ;power fail
dsp$ ,pinset ;process initilization
dsp$e
NRMRCP: JMP @10$(R3) ; Dispatch SC Receive Complete:
10$: DSP$B
DSP$ ,NSPCON ; S$CNR - Connect received
DSP$ ,NSPDAT ; S$DAT - Data received
DSP$ ; S$INT - Interrupt message received
DSP$ ,nspdis ; S$DSR - Disconnect received
DSP$E
NRMCCP: JMP @10$(R3) ;DISPATCH CONTROL COMPLETE:
10$: DSP$B
DSP$
DSP$ FM.STR,SRVSTR ; SRV START COMPLETE ENTRY POINT
DSP$ FM.STP,SRVSTP ; SRV STOP COMPLETE ENTRY POINT
DSP$E
.SBTTL RESOURCE MESSAGE DISPATCH TABLES
;+
; THESE DISPATCH TABLES ARE USED TO DISPATCH RESOURCE MESSAGES BASED
; ON THE REQUEST CODES AND REQUEST TYPES IN THE RESOURCE MESSAGE.
; ALSO INCLUDED IS THE DISPATCH TABLE USED BY THE ERROR PROCESSOR
; ($ERROR) TO DISPATCH ACCORDING TO ERROR CODE.
;
;-
.PSECT $PLIT$,D
; REQUEST CODE DISPATCH TABLE
RQ.MIN= 041 ; MINIMUM REQUEST CODE
MSGDSP: .WORD unsupported ; 041 REQUESTOR ID
.WORD UNSUPPORTED ; 042 CAPABILITIES
.WORD INVALID ; 043
.WORD INVALID ; 044
.WORD INVALID ; 045
.WORD INVALID ; 046
.WORD unsupported ; 047 RESPONSE
.WORD SPECIFY ; 050 SPECIFY
.WORD ACCESS ; 051 ACCESS
.WORD ASSIGN ; 052 ASSIGN
.WORD unsupported ; 053 STATUS
.WORD UNSUPPORTED ; 054 CONTROL
RQ.MAX = .-MSGDSP/2-1 ; MAXIMUM REQUEST CODE
; REQUEST TYPE DISPATCH TABLES
; <CAPABILITIES> DISPATCH TABLE
CAPDSP: .WORD INVALID ; 000
.WORD UNSUPPORTED ; 001 CAPABILITIES-REPORT
.WORD UNSUPPORTED ; 002 CAPABILITIES-REQUEST
CP.MAX = .-CAPDSP/2-1 ; MAXIMUM REQUEST CODE
; <SPECIFY> DISPATCH TABLE
SPCDSP: .WORD INVALID ; 000
.WORD RESERVE ; 001 SPECIFY-RESERVE
.WORD SHARE ; 002 SPECIFY-SHARE
.WORD unsupported ; 003 SPECIFY-REFER
SY.MAX = .-SPCDSP/2-1 ; MAXIMUM REQUEST CODE
; <ACCESS> DISPATCH TABLE
ACCDSP: .WORD INVALID ; 000
.WORD OPEN1 ; 001 ACCESS-OPEN, SINGLE LOGICAL LINK
.WORD OPEN2 ; 002 ACCESS-OPEN ON SEPARATE DATA LINK
.WORD CLOSE ; 003 ACCESS-CLOSE
.WORD unsupported ; 004 ACCESS-RELEASE
AC.MAX = .-ACCDSP/2-1 ; MAXIMUM REQUEST CODE
; <ASSIGN> DISPATCH TABLE
ASNDSP: .WORD INVALID ; 000
.WORD UNSUPPORTED ; 001 ASSIGN
.WORD UNSUPPORTED ; 002 ASSIGN-RECLAIM
.WORD UNSUPPORTED ; 003 ASSIGN-HANDOFF
AS.MAX = .-ASNDSP/2-1 ; MAXIMUM REQUEST CODE
.SBTTL $PCBGT - Allocate a PCB
;+
; This routine will allocate a pipe control block (if available).
;
; Input:
; None
;
; Output:
; If success:
; R3 = address of PCB.
; If failure:
; R3 = undefined.
;-
.PSECT $CODE$,I
$PCBGT::PUSH$S <R5,R4> ; Get room to move
mov .crdat+2,r5 ; pick up data base address
MOV R$PCB+2(R5),R3 ; Get the PCB table
MOV R$PCB+0(R5),R5 ; and number of pipes.
BEQ 90$ ; (if there are any)
MOV R5,R4 ; Save for later.
70$: TST P.STS(R3) ; Is this PCB free?
BEQ 80$ ; If not,
ADD #PCBLEN,R3 ; then go on to the next
SOB R4,70$ ; until we run out.
BR 90$ ; Whoops! None available.
80$: SUB R4,R5 ; Get the
INC R5 ; pipe number
MOVB R5,P.NUM(R3) ; and store it.
CLR P.RES(R3) ; Initialize various items.
CLR P.REF(R3)
TST (PC)+ ; (clear the carry)
90$: SEC
POP$S <R4,R5> ; Restore his registers.
RETURN
.SBTTL Deallocate a PCB
;+
; This routine deallocates a PCB by clearing the status word.
;
; Input:
; R3 = address of PCB
;
; Output:
; None
;-
.PSECT $CODE$,I
$PCBRT::CLR P.STS(R3) ; Make sure it is free.
RETURN
;routine performs process initilization
PINSET: call $ltmen ;enable long timer
mov #^rNRD,r0 ;get nrd's pix
call pidid
movb r0,-(sp)
mov #^rLE,r0 ;get LE's pix
call pidid
movb r0,-(sp)
mov #^rCR,r0
call pidid
movb r0,-(sp)
clr r0
1$: inc r0
call $tcbpt
bcs 4$
movb 4(sp),t.spi(r5) ;set NRD's pix
cmpb t.tt(r5),#tt.le ;LP11 ?
beq 2$
cmpb t.tt(r5),#tt.lp ;LP20 ?
beq 2$
cmpb t.tt(r5),#tt.cr ;CR11 ?
beq 3$
cmpb t.tt(r5),#tt.cd ;CD11 ?
clrb t.pri(r5) ;ickmay !
br 1$
2$: tstb 2(sp) ;is LE in system ?
beq 5$
movb 2(sp),t.pri(r5) ;set LE's pix
br 1$
5$: clrb t.obj(r5) ;no LE here
br 1$
3$: tstb (sp) ;is CR in system
beq 6$
movb (sp),t.pri(r5) ;set CR's pix
br 1$
6$: clrb t.obj(r5) ;no CR here
br 1$
4$: mov .crdat+2,r5 ;set timer ticking
incb (r5)
cmp (sp)+,(sp)+ ;house clean
tst (sp)+
return
;routine $PCBCL called from NRD
$PCBCL::
mov 2(r5),r0 ;get the ULA
call $pcbpt ;get the PCB address
bcs 1$
call $pcbrt ;close up shop
1$: return
.SBTTL $PCBPT - Get the Address of a PCB
;+
; This routine gets the address of the given PCB.
;
; Input:
; R0 = pipe number (ULA)
;
; Output:
; If success:
; R3 = address of PCB.
; If failure:
; R3 = undefined.
;-
.PSECT $CODE$,I
$PCBPT::PUSH$S R5 ; Get room to move
mov .crdat+2,r5 ; pick up data base address
MOV R0,R3 ; copy ULA
DEC R3 ; and turn into index.
CMP R$PCB+0(R5),R3 ; If in range
BLOS 90$ ; then
MUL #PCBLEN,R3 ; index into
ADD R$PCB+2(R5),R3 ; PCB table.
TST (PC)+ ; (clear the carry)
90$: SEC
POP$S R5 ; Recover his register.
RETURN
;routine $PCBDB called from NRD
$PCBDB::
mov 2(r5),r0 ;get the ULA
call $pcbpt ;point to the PCB
bcc 1$ ;huray(sp)!
clr r3 ;too bad so sad
1$: mov r3,r0 ;return the PCB
return
.SBTTL $TCBPT - Get the Address of a TCB
;+
; This routine gets the address of the given TCB.
;
; Input:
; R0 = resource number (BTN)
;
; Output:
; If success:
; R5 = address of PCB.
; If failure:
; R5 = undefined.
;-
.PSECT $CODE$,I
$TCBPT::PUSH$S R3 ; Get room to move
mov .crdat+2,r5 ; pick up data base address
MOV R0,R3 ; copy BTN
DEC R3 ; and turn into index.
CMP R$TCB+0(R5),R3 ; If within range
BLOS 90$ ; then
MUL #TCBLEN,R3 ; index into
ADD R$TCB+2(R5),R3 ; TCB table
MOV R3,R5 ; and put in R5.
TST (PC)+ ; (clear the carry)
90$: SEC
POP$S R3 ; Restore his register.
RETURN
;routine $TCBDB called from NRD
$TCBDB::
mov .crdat+2,r0 ;point to TCB's
mov r$tcb(r0),r3 ;... and the
mov r$tcb+2(r0),r1 ;the number of the buggers
1$: cmpb 2(r5),t.pri(r1) ;do the pix's match
beq 2$ ;jolly good show
add #tcblen,r1 ;ring around the rosie
sob r3,1$ ;...
clr r0 ;confusion for later
br 3$ ;exit
2$: mov r1,r0 ;return TCB
3$: return
.SBTTL GETCPB - Get Connect Pending Block
;+
; Address the two parts of the NSP connect pending block.
;
; Input:
; R4 = address NSP connect-received CCB.
;
; Output:
; R0 = address of connect pending buffer.
; R2 = address of accounting information (k.RQDL)
; KISAR6 = mapped to connect pending buffer.
;-
.PSECT $CODE$,I
GETCPB::MAP$ C.BUF(R4) ; Map CPB to APR6.
MOV C.BUF+2(R4),R0 ; Address CPB
MOV #k.RQDL,R2 ; and
ADD R0,R2 ; accounting area.
RETURN
$TCBTT::
push$s <r1,r3>
mov .crdat+2,r3 ;get data base address
mov r$tcb(r3),r1 ;number of the buggers
mov r$tcb+2(r3),r5 ;where they is at
1$: cmpb r0,t.pri(r5) ;got a match
beq 2$ ;yes
add #tcblen,r5 ;more,more
sob r1,1$
mov #-1,r5 ;ickmay oemay
2$: pop$s <r3,r1>
return
;routine $PCBOP called by NRD to open a data PCB
$PCBOP::
mov 2(r5),r4 ; connect CCB
map$ c.buf(r4) ;map in connect block
mov c.buf+2(r4),r2 ;....
cmp k.rqdl(r2),#2 ;requestor-id length
bne 2$ ;not the right length
clr r0
1$: inc r0
call $pcbpt ;get a pcb
bcs 3$ ;none left
bit #ps.dat,p.sts(r3) ;a data pipe?
beq 1$ ;no only look at data pipes
cmp p.user(r3),k.rqid(r2) ;can't have duplicate userid's
bne 1$
2$: clr r0 ;error return
return
3$: call $pcbgt ;allocate a pcb
bcs 2$ ;all gone too bad!!!
mov k.rqid(r2),p.user(r3) ;copy all the good stuff..
mov #^rNRD,r0 ;get NRD's pix
call pidid ;...
movb r0,p.spi(r3) ;...
bis #ps.cc!ps.dat,p.sts(r3) ;set connected data pipe
mov r3,r0 ;return PCB address
return
.SBTTL CCB DISPATCHER/RESOURCE MANAGER SCHEDULER
;+
; THESE ROUTINES HANDLES LINE CONTROL REQUESTS AND RESOURCE ALLOCATION
; FAILURE RECOVERY.
;-
;+
; QUEUE UP A CCB FOR A RESOURCE WAIT
;
; INPUTS:
; R4 - CCB TO QUEUE UP
; (SP) - RETRY ADDRESS
;
; REGISTERS MODIFIED: R4,R3
;-
.PSECT $CODE$,I
NRMRWT: MOV (SP)+,C.prm2(R4) ; SET RETURN ADDRESS
MOVB #RM$RWT,C.fnc(R4) ; AND FUNCTION CODE.
ENQUE:
mov .crdat+2,r5 ; pick up data base address
MOV R5,R3 ; and copy address
add #r$rwt,r3 ; point to resource queue
BIS #RF.CCB,r$flg(r5) ; IF NO RECOVERY IN PROGRESS
BMI 10$ ; THEN
callr $CMQIN ; QUEUE TO THE REAR
10$: callr $CMQIF ; OTHERWISE TO THE FRONT.
;+
; TIMER INTERRUPT - DO ANY RESOURCE RECOVERY WHICH IS REQUIRED AND THEN
; HANDLE ANY TCBS WHICH REQUIRE LINE CONTROL SERVICE.
;
; INPUT:
; R5 - NRM DATA BASE ADDRESS
;-
.PSECT $CODE$,I
NRMTM:
mov .crdat+2,r5 ;data base address
incb (r5) ;reset timer
BIT #RF.CCB,r$flg(R5) ; IF NOTHING TO DO
BEQ 900$ ; THEN QUIT.
BIC #RF.CCB,r$flg(R5) ; RESET CCB PENDING SWITCH
BIS #RF.CVR,r$flg(R5) ; AND SET RECOVERY SWITCH.
120$: MOV R5,R3 ; GET ADDRESS
add #r$rwt,r3 ;of resource queue
CALL $CMQRM ; AND SEE IF ANYTHING IS THERE.
BCS 190$ ; IF SO,
MOVB C.MOD(R4),R3 ; PICK UP MODIFIER
MOVB C.FNC(R4),R0 ; AND FUNCTION CODE
CALL @NRMTB(R0) ; AND RE-DISPATCH FUNCTION.
mov .crdat+2,r5 ; pick up data base address
BIT #RF.CCB,r$flg(R5) ; IF NO RESOURCE ERROR,
BEQ 120$ ; THEN GO FOR MORE.
190$: BIC #RF.CVR,r$flg(R5) ; RESET RECOVERY SWITCH
900$: RETURN ; AND WAIT.
;+
; RESOURCE WAIT COMPLETE - DISPATCH THE CCB TO THE RETRY ROUTINE
;-
NRMRWC: GTPCB$ ;GET THE PCB ADDRESS AND
JMP @C.prm2(R4) ;DISPATCH TO RETRY ROUTINE.
.PAGE
;+
; FLUSH THE RESOURCE WAIT QUEUE OF REQUESTS FOR THE PIPE SPECIFIED
; IN r$flg
;-
NRMFLS: mov .crdat+2,r5 ;data bese address
BIS #RF.CVR,r$flg(r5) ; SIMULATE RESOURCE RECOVERY
BIC #RF.CCB,r$flg(r5) ; AND CLEAR THE CCB INDICATOR.
MOV r$rwt+2(r5),-(SP) ; PUSH THE LIST HEAD
MOV r$rwt(r5),-(SP) ; ONTO THE STACK
CLR r$rwt(r5) ; AND CLEAR IT.
mov r5,r3 ; and clean out
add #r$rwt,r3 ; the resource queue
mov r3,r$rwt+2(r5) ; ...
10$: mov .crdat+2,r5 ;point to data base address
MOV SP,R3 ; GET STACK LISTHEAD
CALL $CMQRM ; AND GET NEXT ITEM
BCS 30$ ; IF THERE IS ONE.
cmpb r$flg(r5),c.prm1(r4) ; GET SWITCHES
BEQ 20$ ; IF NOT,
BIS #RF.CCB,r$flg(R5) ; INDICATE QUEUE NOT CLEAR
CALL $CMQIN ; AND RE-INSERT THE REQUEST.
BR 10$
20$: MOVB C.MOD(R4),R3 ; PICK UP MODIFIER
MOVB C.FNC(R4),R0 ; FUNCTION CODE
CALL @NRMTB(R0) ; AND DISPATCH.
BR 10$ ; GO BACK FOR MORE.
30$: BIC #RF.CVR,r$flg(r5) ; TURN OFF RECOVERY BIT
CMP (SP)+,(SP)+ ; CLEAR OFF STACK
RETURN ; AND GO BACK.
.SBTTL NSPCON - CONNECT PROCESSOR
;+
; THIS ROUTINE HANDLES CONNECT REQUESTS FOR CONTROL PIPES.
; IT SEARCHES FOR A FREE PIPE. IF OK, IT STORES THE USER ID IN THE
; PCB, INITIALIZES THE PCB AND POSTS COMPLETION TO THE USER.
;
; INPUTS: R4 -> CONNECT CCB
;
; SCAN FOR A FREE PIPE
;
nspcon:
mov r4,-(sp) ;save connect ccb
MAP$ c.buf(r4) ;map in connect block
mov c.buf+2(r4),r2 ;...
call $ccbgt ;try for accept ccb
bcc 1$ ;got one
clr r1 ;failure indicator
mov #s.eres,r5 ;set reject code
br 3$ ;reject the connection
1$: mov r4,r1 ;stash accept ccb
clr r0 ;now check out the pipes..
2$: inc r0 ;..for a duplicate user id
call $pcbpt ;pcb comes back in r3
bcs 4$ ;looked at them all
bit #ps.ctl,p.sts(r3) ;only want control pipes
beq 2$
cmp p.user(r3),k.rqid(r2) ;have we had this one before
bne 2$ ;no good
6$: mov #s.erbo,r5 ;set reject code
3$: mov (sp)+,r4 ;get back connect ccb
NCRA$ ,r5 ;reject the connect
mov r1,r4 ;point to accept ccb
beq 5$
call $ccbrt ;release accept ccb
5$: return ;and exit
; FORMAT THE PIPE AND ACCEPT THE CONNECT
4$: call $pcbgt ; get a pcb
mov #s.eres,r5 ; set reject code
bcs 3$ ; and reject the connection
mov k.rqid(r2),p.user(r3) ; save user id
movb .crpix,p.spi(r3) ; save owner of pipe
bis #ps.cc!ps.ctl,p.sts(r3) ; set pipe flags
mov (sp)+,r4 ; point to connect ccb
movb c.lix(r4),c.lix(r1) ; copy info to accept ccb
movb c.lix(r4),p.lla(r3) ; put LLA in PCB
movb c.pix(r4),c.pix(r1) ; put in dest pix
movb c.pix(r4),p.pix(r3) ; and save it for later
ncra$ p.num(r3) ; acknowledge intent to connect
mov r1,r4 ; accept the connection
clr c.cnt(r4) ; no optional data
NACC$ ,p.num(r3),#s$pseg ;....
return
;this routine processes the connect complete from SC. if the
;connect completes successfully then data segments are requested, else
;the link is closed.
request:
GTPCB$
bic #ps.ci,p.sts(r3) ;clear connect initiated
cmp c.sts(r4),#s.ssuc ;operation a success
bne 2$
bis #ps.cc,p.sts(r3) ;set pipe connected
NDRQ$ ,,r$flw(r5) ;request a few segments
movb r$flw(r5),p.segs(r3) ;set req cnt in PCB
return
2$:
NABO$ p.num(r3) ;abort the link
return ;and exit
.SBTTL NSPDIS - DISCONNECT NSP CONTROL PIPE
.SBTTL SRVDIS - DISCONNECT SERVER DATA PIPE
;+
; THIS ROUTINE HANDLES DISCONNECTS FOR BOTH CONTROL AND DATA PIPES.
; CONTROL DISCONNECTS ARE RECEIVED BY THE NRM DIRECTLY FROM NSP.
; IF A CONTROL PIPE, THE FOLLOWING OCCURS:
; 1. ALL TERMINALS ARE CLOSED
; 2. ALL TERMINALS ARE RELEASED
; 3. ALL REFERRALS ARE TERMINATED
;
; DATA PIPE DISCONNECTS ARE RECEIVED BY THE ATS GENERIC MANAGER
; AND SENT TO THE NRM BY A "TERMINATE" CONTROL ENABLE COMMAND.
; IF A DATA PIPE, THE FOLLOWING OCCURS:
; ALL TERMINALS ARE CLOSED
;
; THE GENERAL PROCEDURE IS TO SEARCH THE RESERVED TERMINAL LIST UNTIL
; AN OPEN TERMINAL IS FOUND. A CLOSE IS THEN INITIATED FOR THAT TERMINAL
; AND THE PROCESS EXITS. AT THIS POINT THE NEXT TERMINAL IS
; CLOSED WHEN A CLOSE COMPLETION IS RECEIVED FOR THE PRESENT TERMINAL.
; WHEN ALL TERMINALS ARE CLOSED, THE PIPE TYPE IS DETERMINED. IF DATA
; PIPE, THE PROCESS SIMPLY POSTS DISCONNECT COMPLETION. IF A CONTROL
; PIPE, THE RESERVED TERMINALS ON THE PIPE ARE RELEASED, ALL REFERAL
; THREADS ARE TERMINATED, AND DISCONNECT COMPLETION IS POSTED.
;
; IF AN ABORT REQUEST IS RECEIVED, THE PROCESSING IS IDENTICAL TO THE
; ABOVE, EXCEPT THAT COMPLETION IS NOT POSTED TO THE REQUESTOR.
;
; INPUT:
; R4= DISCONNECT CCB FROM NSP OR SERVER
;
;-
NSPDIS: ;DISCONNECT CONTROL PIPE
mov r4,r2 ;save disconnect ccb
call $ccbgt ;try for working ccb
mov r4,r1 ;sqve it if got one
mov r2,r4 ;fetch disconnect ccb
bcc 10$
jmp enque ;resource recovery queue
10$:
GTPCB$ ;GET THE PIPE CONTROL BLOCK
MOVB R0,r$flg(r5) ;SAVE THE PIPE NUMBER for nrmfls routine
NDAK$
mov r1,r4 ;working ccb
BIC #PS.CC,P.STS(R3) ;CLEAR CONNECT COMPLETE.
mov r5,-(sp) ;save the world
MOV R4,-(SP) ;
mov r3,-(sp) ;
mov r1,-(sp) ;.....
CALL NRMFLS ;FLUSH RECOVERY REQUESTS
mov (sp)+,r1 ;recover the world
mov (sp)+,r3 ;
MOV (SP)+,R4 ;
mov (sp)+,r5 ;...
jmp discp
.PAGE
;+
; CONTROL PIPE DISCONNECT (ENTRY FROM <STOP> AND <START> COMPLETE PROCESSORS)
;
; INPUTS:
; R4= ADDRESS OF FREE CCB
; R3= ADDRESS OF CONTROL PCB
;-
DISCP: BIC #PS.DIP,P.STS(R3) ;CLEAR DISCONNECT PENDING
; CLOSE ALL TERMINALS ON CONTROL PIPE
MOV R3,R5 ;POINT TO RESERVED TERMINAL LISTHEAD
ADD #P.RES,R5 ;...
10$: MOV (R5),R5 ;GET ADDRESS OF NEXT TCB
BEQ 20$ ;IF EQ, ALL TERMINALS PROCESSED
BIT #TS.OCP,T.STS(R5) ;OPEN OR CLOSE PENDING OR TERM. OPEN?
BEQ 10$ ;IF EQ, NO- TERMINAL IS NOT OPEN
BIS #PS.DIP,P.STS(R3) ;ELSE YES- SET DISCONNECT PENDING
BIT #TS.OPP,T.STS(R5) ;IF OPEN IN PROGRESS
BNE 15$ ;THEN WAIT FOR OPEN TO FINISH.
BIT #TS.CLP,T.STS(R5) ;IF CLOSE NOT ISSUED YET
BNE 10$ ;THEN
JMP CLOSE2 ;INITIATE A CLOSE ON THIS TERMINAL.
15$: MOVB P.NUM(R3),C.prm1(R4) ;SAVE WHO WE ARE WORKING ON.
CALL NRMRWT ;WAIT FOR ACTION TO FINISH
BR DISCP ;AND TRY AGAIN.
20$: BIT #PS.DIP,P.STS(R3) ;DISCONNECT PENDING?
BEQ 30$ ;IF SO,
JMP $ccbrt ;THEN WAIT FOR IT TO COME BACK.
; CLEAR DISCONNECT PENDING FOR ALL ASSOCIATED DATA PIPES
; AND SEND DISCONNECT COMPLETE FOR EACH DISCONNECTED DATA PIPE
; DO NOT SEND COMPLETION FOR ABORTED DATA PIPES
30$: PUSH$S R4 ;SAVE CCB ADDRESS (USE FOR CONTROL PIPE
MOV R3,R5 ;DISCONNECT COMPLETION)
CLR R0 ;SET FOR FIRST PCB
40$: INC R0 ;GO TO NEXT PCB.
CALL $PCBPT ;GET THE PCB
BCS 70$ ;IF THERE IS ONE.
TST P.STS(R3) ;IF NOT ACTIVE
BEQ 40$ ;THEN IGNORE.
BIT #PS.CTL,P.STS(R3) ;IS THIS A CONTROL PIPE?
BNE 40$ ;IF EQ, YES- GET NEXT PCB
CMP P.USER(R5),P.USER(R3) ;CONTROL PIPE ASSOCIATED WITH DATA PIPE?
BNE 40$ ;IF NE, NO- GET NEXT PCB
BIT #PS.DIP,P.STS(R3) ;DISCONNECT PENDING?
BEQ 40$ ;IF EQ, NO
CALL $CCBGT ;GET A CCB
BCC 60$ ;IF CC, GOT ONE
;
; RESOURCE FAILURE - WAIT A TICK AND TRY AGAIN
;
BIS #PS.DIP,P.STS(R3) ;MARK AS STILL DISCONNECTING
POP$S R4 ;RESTORE CCB ADDRESS
MOVB P.NUM(R3),c.prm1(R4) ;SAVE WHO WE ARE WORKING ON.
CALL NRMRWT ;GO TO RESOURCE SCHEDULER
BR 30$ ;AND TRY AGAIN.
; CONTROL PIPE DISCONNECT REENTRY POINT
60$: CALL DISPC ;TELL THE SERVER TO DISCONNECT
BR 40$ ;AND CHECK SOME MORE.
; RELEASE ALL TERMINALS ON CONTROL PIPE
70$: MOV R5,R3
80$: MOV P.RES(R3),R5 ;IF THERE IS ANOTHER RESOURCE
BEQ 110$ ;THEN
MOV (R5),P.RES(R3) ;DE-LINK AND
BIC #<TS.RS!TS.RLP!TS.HP!TS.SRP>,T.STS(R5) ;UNRESERVE IT.
BR 80$
110$: POP$S R4 ;RESTORE CCB POINTER
BIC #PS.DIP,P.STS(R3) ;CLEAR DISCONNECT PENDING FOR CONTROL PIPE
BR DISPC ;AND GO FINISH UP IN COMMON CODE
;+
; DATA PIPE DISCONNECT (ENTRY FROM <START> AND <STOP> COMPLETE ROUTINES)
;
; INPUTS:
; R4= ADDRESS OF CCB
; R3= ADDRESS OF DATA PCB
;-
DISDP: BIC #PS.DIP,P.STS(R3) ;CLEAR DISCONNECT PENDING
; CHECK IF ASSOCIATED CONTROL PIPE IS ACTIVE
MOV R3,R5 ;SAVE PCB ADDRESS
CLR R0 ;AND SET FOR FIRST PCB.
10$: INC R0 ;GO TO NEXT PCB
CALL $PCBPT ;POINT TO IT
BCS 20$ ;IF IT IS THERE.
TST P.STS(R3) ;IF NOT ACTIVE
BEQ 10$ ;THEN IGNORE.
BIT #PS.CTL,P.STS(R3) ;IS THIS A CONTROL PIPE?
BEQ 10$ ;IF EQ, NO
CMP P.USER(R5),P.USER(R3) ;DATA PIPE ASSOCIATED W/CONTROL PIPE?
BNE 10$ ;IF NE, NO
BIT #PS.DIP,P.STS(R3) ;DISCONNECT PENDING?
BEQ 20$ ;IF EQ, NO
MOV R5,R3 ;RESTORE PCB ADDRESS
BIS #PS.DIP,P.STS(R3) ;SET DISCONNECT PENDING
JMP $ccbrt ;RETURN CCB
; CLOSE ALL TERMINALS ON DATA PIPE
20$: MOV R5,R3 ;RESTORE PCB POINTER
BIC #PS.DIP,P.STS(R3) ;CLEAR DISCONNECT PENDING
ADD #<P.OPN-T.OLNK>,R5 ;POINT INTO OPEN LIST
30$: MOV T.OLNK(R5),R5 ;GET ADDRESS OF NEXT TCB
BEQ 40$ ;IF THERE IS ONE
BIS #PS.DIP,P.STS(R3) ;SET DISCONNECT PENDING
BIT #TS.OPP,T.STS(R5) ;IF OPEN IN PROGRESS
BNE 35$ ;THEN WAIT FOR OPEN TO FINISH.
BIT #TS.CLP,T.STS(R5) ;IF CLOSE NOT PENDING
BNE 30$ ;THEN
JMP CLOSE2 ;INITIATE A CLOSE ON THIS TERMINAL.
35$: MOVB P.NUM(R3),C.prm1(R4) ;SAVE WHO WE ARE WORKING ON
CALL NRMRWT ;WAIT FOR ACTION TO FINISH
BR DISDP ;AND TRY AGAIN.
40$: BIT #PS.DIP,P.STS(R3) ;DISCONNECT PENDING?
BEQ DISPC ;IF SO,
MOVB P.NUM(R3),C.prm1(R4) ;SAVE WHO WE ARE WORKING ON.
CALL NRMRWT ;WAIT FOR ACTION TO FINISH
BR DISDP ;AND TRY AGAIN.
;+
; PIPE DISCONNECT COMPLETED - NOTIFY NSP OR SERVER
;
; INPUTS:
; R4= ADDRESS OF CCB
; R3= ADDRESS OF PCB
;-
DISPC: BIT #PS.CTL,P.STS(R3) ;IF NOT CONTROL PIPE
BEQ 80$ ;THEN NOTIFY PIPE OWNER PIPE CLOSED.
clr c.cnt(r4) ;no data
movb p.pix(r3),c.pix(r4) ;set dest.
movb p.lla(r3),c.lix(r4) ;set LLA
NABO$ P.NUM(R3) ;ABORT
RETURN
80$: MOVB P.NUM(R3),C.prm1(R4)
MOVB P.SPI(R3),C.pix(R4)
MOVB #FC.AST,C.FNC(R4) ; NOTIFY PIPE OWNER.
JMP $SCHED
.SBTTL NRMDIS - PIPE DISCONNECTED
;+
; LINK IS CLOSED - RETURN THE PIPE
;
; INPUTS:
; R4 - DISCONNECT OR ABORT COMPLETE CCB
;-
NRMDIS: GTPCB$ ; GET THE PCB ADDRESS
mov r3,r5 ; save ctl pcb
CALL $PCBRT ; RETURN THE PCB
CLR R0 ;AND SET FOR FIRST PCB.
10$: INC R0 ;GO TO NEXT PCB
CALL $PCBPT ;POINT TO IT
BCS 20$ ;IF IT IS THERE.
TST P.STS(R3) ;IF NOT ACTIVE
BEQ 10$ ;THEN IGNORE.
BIT #PS.CTL,P.STS(R3) ;IS THIS A CONTROL PIPE?
Bne 10$ ;IF EQ, NO
CMP P.USER(R5),P.USER(R3) ;DATA PIPE ASSOCIATED W/CONTROL PIPE?
BNE 10$ ;IF NE, NO
MOVB P.NUM(R3),C.prm1(R4)
MOVB P.SPI(R3),C.pix(R4)
MOVB #FC.AST,C.FNC(R4) ; NOTIFY PIPE OWNER.
JMP $SCHED
20$: JMP $CCBRT ; AND THE DISCONNECT CCB.
.SBTTL NSPDAT - RESOURCE MESSAGE DISPATCHER
;+
; THIS ROUTINE RECEIVES CONTROL FROM THE CCB DISPATCHER.
; ITS PURPOSE IS TO PASS CONTROL TO THE APPROPRIATE MESSAGE PROCESSOR
; BASED ON THE REQUEST CODE.
; A RECEIVE DATA BUFFER (RDB) MAY CONTAIN TWO RESOURCE MESSAGES.
; FOR EXAMPLE, AN OPEN MESSAGE MAY BE CONCATENATED WITH A RESERVE
; MESSAGE. FOR SUCH A CASE, THE FIRST MESSAGE WILL ALWAYS HAVE A
; SPECIFY MESSAGE REQUEST CODE AND THE DOUBLE MESSAGE FLAG WILL
; BE SET IN THE REQUEST TYPE BYTE (M.TYP). FOR DOUBLE MESSAGES
; ONLY ONE STATUS RESPONSE (INDICATING FAILURE OR THE HIGHEST LEVEL
; MESSAGE COMPLETION STATUS) IS RETURNED TO THE REQUESTOR .
;
; INPUT:
; R5= ADDRESS OF NRM DATA BASE
; R4= ADDRESS OF CCB-RDB (WHICH POINTS TO RESOURCE MESSAGE)
;
; OUTPUT:
; APR6= BIASED INTO RESOURCE MESSAGE
; R4= ADDRESS OF WORKING CCB
; R3= ADDRESS OF CONTROL PCB (OVER WHICH MESSAGE WAS RECEIVED)
; R2= CURRENT ADDRESS OF RESOURCE MESSAGE
; R0= MESSAGE SUBTYPE
;
;-
.ENABL LSB
NSPDAT: ;MESSAGE ENTRY POINT
GTPCB$ ;GET THE PCB
10$: TST r$flg(R5) ; IF RESOURCE ERROR RECOVERY
BMI 20$ ; NOT IN EFFECT
TST R$RWT(R5) ; AND THE QUEUE IS NOT EMPTY
BNE 30$ ; THEN ADD THIS TO IT.
20$: MOV R4,R1 ; SAVE THIS CCB
CALL $CCBGT ; AND TRY FOR A SPAWN CCB.
BCC 40$ ; IF FAILURE
MOV R1,R4 ; GET NSP CCB BACK
30$: JMP ENQUE ; AND WAIT FOR THE PROPER MOMENT.
40$: mov r4,-(sp) ;stash away stack ccb for now
decb p.segs(r3) ;decrement flow count
bne 48$ ;still permissions outstanding
call $ccbgt ;must request data segments
bcc 45$ ;do it
mov (sp)+,r4 ;return stacked ccb
call $ccbrt
incb p.segs(r3) ;reset flow count
mov r1,r4 ;and queue up received ccb
jmp enque ;....
45$: movb p.pix(r3),c.pix(r4)
movb r$flw(r5),p.segs(r3)
movb p.segs(r3),r0
NDRQ$ p.lla(r3),p.num(r3),r0
48$: mov (sp)+,r4 ;get back stack ccb
50$: MOVB C.prm1(R1),C.lin(R4) ;SAVE PIPE NUMBER
MOV R1,C.stk(R4) ;NSP CCB-RDB ADDRESS
MOV C.BUF+2(R1),C.STS(R1) ;SET MESSAGE START ADDRESS.
; GET MESSAGE ADDRESS
NRMMSG: MOV C.stk(R4),R5 ;GET NSP BUFFER ADDRESS
MAP$ C.BUF(R5) ;MAP TO RECIEVE DATA BUFFER
MOV C.STS(R5),R2 ;POINT TO RESOURCE MESSAGE BUFFER
; RANGE CHECK REQUEST CODE
CALL GET1 ;GET REQUEST CODE
SUB #RQ.MIN,R0 ;REQUEST CODE TOO LOW?
BLT 70$ ;IF LT, YES
CMP #RQ.MAX,R0 ;REQUEST CODE TOO HIGH?
BHIS 80$ ;IF LOS, NO- CONTINUE
70$: RESPOND RC.IRC ;ERROR - ILLEGAL REQUEST CODE
; DISPATCH MESSAGE TO MESSAGE PROCESSOR
80$: ASL R0 ;MAKE A WORD INDEX
MOV MSGDSP(R0),-(SP) ;SAVE DISPATCH ADDRESS
CALL GET1 ;GET SUBTYPE
PUSH$S R0 ;SAVE WHILE WE
CALL GET2 ;GET CONTROL ID
MOV R0,C.prm1(R4) ;AND STORE IT.
POP$S R0 ;RESTORE SUBTYPE
RTS PC ;AND DISPATCH MESSAGE (WITHOUT RETURN)
.DSABL LSB
.SBTTL SPECIFY - <SPECIFY> MESSAGE PRE-PROCESSOR
;+
; THIS ROUTINE RECEIVES SPECIFY MESSAGES. ITS DOES THE PROCESSING COMMON
; TO ALL SPECIFY MESSAGES.
; ALGORITHM:
; CHECK FOR VALID SPECIFY-REQUEST TYPES. IF NOT VALID RETURN ERROR
; SEARCH REFERRAL LIST FOR CCB WITH CONTROL ID. IF FOUND GO TO 1.
; SEARCH RESERVED LIST FOR TCB WITH CONTROL ID. IF FOUND RETURN ERROR
; ALLOCATE CCB AND LINK TO REFERRAL LIST
; 1. IF REFERRAL CCB DOES NOT POINT TO HANDOFF TCB GO TO 2.
; DELINK REFERRAL CCB AND RETURN IT TO POOL
; LINK TCB TO HANDOFEE'S RESERVED TERMINAL LIST
; SEND RESPONSE MESSAGE TO HANDOFEE
; SEND RESPONSE MESSAGE TO HANDOFER AND EXIT
; 2. SEARCH TCB TABLE FOR TCB CONTAINING TERMINAL NAME. IF FOUND RETURN SUCCESS
; ELSE RETURN ERROR
;
; INPUT:
; APR6= BIASED INTO RESOURCE MESSAGE
; R4= ADDRESS OF WORKING CCB
; R3= ADDRESS OF CONTROL PCB (OVER WHICH MESSAGE WAS RECEIVED)
; R2= CURRENT ADDRESS OF RESOURCE MESSAGE
; = AT 'RESTYPE' FIELD
; R0= MESSAGE SUBTYPE
;
; OUTPUT:
; R4= ADDRESS OF WORKING CCB
; R0= RESPONSE CODE
;
; IF SUCCESS:
; APR6= BIASED INTO RESOURCE MESSAGE
; R5= ADDRESS OF TCB
; R0= ADDRESS OF CCB CONTAINING CONTROL ID
;
;-
SPECIFY:
; VALIDATE REQUEST TYPE
BICB #^C17,R0 ;CLEAR OUT GARBAGE
BEQ 10$ ;IF EQ, INVALID REQUEST TYPE
CMPB #SY.MAX,R0 ;REQUEST TYPE IN RANGE?
BHIS 20$ ;IF LOS, YES- CONTINUE
10$: RESPOND RC.IRC ;ERROR - ILLEGAL REQUEST CODE
; THE CONTROL ID SHOULD NOT BE ASSOCIATED WITH A RESERVED RESOURCE
20$: CALL FNDRES ;CHECK RESERVED LIST
BCS 40$ ;IF CS, CONTINUE
RESPOND RC.RQO ;ERROR - CONROL ID IN USE
; LOOK UP TCB CONTAINING RESOURCE DESCRIPTOR (TERMINAL NAME)
40$: CALL GET1 ;GET THE RESOURCE OBJECT TYPE
MOVB R0,C.prm3(R4) ;SAVE THIS
CALL GET1 ;GET THE FIELD LENGTH
MOVB R0,C.prm4(R4) ;SAVE THIS ALSO
MOV R2,C.prm5(R4) ;SAVE NAME POSITION
CLR R0 ;START WITH FIRST TCB
50$: INC R0
CALL $TCBPT ;POINT TO TCB
BCC 70$ ;IF NO MORE RESOURCES
60$: RESPOND RC.RNE ;ERROR - RESOURCE DOES NOT EXIST
61$: RESPOND RC.IRD ;ERROR - INVALID RESOURCE DESCRIPTOR
.IIF NE <T.NAML-1-T.OBJ>,.ERROR T.NAML;MUST BE ADJACENT TO T.OBJ
.IIF NE <T.NAM-1-T.NAML>,.ERROR T.NAM;MUST BE ADJACENT TO T.NAML
70$: ADD #T.OBJ,R5 ;POINT TO OBJECT TYPE
CMPB C.prm3(R4),(R5)+ ;IF OBJECT CODES DON'T MATCH
BNE 50$ ;THEN REJECT.
MOVB C.prm4(R4),R1 ;GET NAME LENGTH
CMPB R1,(R5)+ ;AND IF NO MATCH
BNE 50$ ;THEN REJECT THIS ALSO.
MOV C.prm5(R4),R2 ;POINT TO BEGINNING OF TERMINAL NAME
80$: CMPB (R2)+,(R5)+ ;AND COMPARE THE NAMES
BNE 50$ ;IF NO MATCH, REJECT
SOB R1,80$ ;CHECK THE FULL NAME
MOVB C.prm4(R4),R1 ;GET LENGTH AGAIN
SUB R1,R5 ;AND
SUB #T.NAM,R5 ;BACK UP TO TCB BEGINNING
; DISPATCH MESSAGE TO REQUEST PROCESSOR
;R5 POINTS TO TCB
90$: MOV C.stk(R4),R0 ;GET
MOV C.STS(R0),R0 ;MESSAGE ADDRESS
MOVB 1(R0),R0 ;AND REQUEST CODE
BICB #^C17,R0 ;CLEAR OUT GARBAGE
ASL R0 ;MAKE A WORD INDEX
JMP @SPCDSP(R0) ;DISPATCH <SPECIFY> MESSAGE
.SBTTL RESERVE - <SPECIFY-RESERVE> PROCESSOR
;+
; THIS ROUTINE RECEIVES CONTROL FROM THE <SPECIFY> PRE-PROCESSOR.
; ITS FUNCTION IS TO RESERVE A TERMINAL FOR A REQUESTOR.
; THE STATE OF THE TERMINAL IS CHECKED AND IF FREE, IT IS RESERVED.
;
; NOTE: ANY REFERRAL CCB IS LEFT ALONE UNTIL THE FULL COMMAND MESSAGE
; IS PROCESSED (INCLUDING CONCATENATED MESSAGES)
;
;
; INPUT:
; R5= ADDRESS OF TCB
; R4= ADDRESS OF WORKING CCB
; R3= ADDRESS OF CONTROL PCB
;
; OUTPUT:
; R4= ADDRESS OF WORKING CCB
; R0= RESPONSE CODE
;-
RESERVE:
BIT #TF.RAL,T.FLG(R5) ;IF NOT READY FOR ALLOCATION
Beq 10$ ;OR
BIT #TS.RS,T.STS(R5) ;TERMINAL RESERVED
BEQ 20$ ;THEN
10$: RESPOND RC.RNA ;ERROR - RESOURCE NOT AVAILABLE
; RESERVE TERMINAL
20$: MOV C.prm1(R4),T.RID(R5) ;STORE CONTROL ID
MOV R3,T.PCBR(R5) ;STORE CONTROL PCB THREAD IN TCB
BIS #TS.RS,T.STS(R5) ;SET STATUS= 'RESERVED'
CALL SETRES ;LINK INTO RESERVED LIST.
RESPOND RC.INT ;SUCCESS - CONTROL THREAD OPEN
;+
; SEND 'SPECIFY-SHARE' NOT SUPPORTED
;-
SHARE: RESPOND RC.SHN ;ERROR - SHARED ACCESS NOT SUPPORTED
.SBTTL ACCESS - <ACCESS> MESSAGE PRE-PROCESSOR
;+
; THIS ROUTINE RECEIVES CONTROL FROM THE ATS RESOURCE MESSAGE DISPATCHER.
; IT GETS THE CONTROL ID AND SEARCHES THE RESERVED TERMINAL LIST
; FOR IT. IF FOUND, THE <ACCESS> MESSAGE IS DISPATCHED. ELSE A CHECK IS
; MADE FOR A REQUEST TYPE= RELEASE. IF RELEASE, THE MESSAGE IS DISPATCHED,
; ELSE THE ACCESS IS REJECTED.
;
; INPUTS:
; APR6= BIASED INTO RESOURCE MESSAGE
; R4= ADDRESS OF WORKING CCB
; R3= ADDRESS OF CONTROL PCB (OVER WHICH MESSAGE WAS RECEIVED)
; R2= CURRENT ADDRESS OF RESOURCE MESSAGE
; = AT 'SRVTYPE' FIELD
; R0= MESSAGE SUBTYPE
;
; OUTPUT:
; APR6= BIASED INTO RESOURCE MESSAGE
; R4= ADDRESS OF WORKING CCB
; R3= ADDRESS OF PCB
; R2= ADDRESS OF RESOURCE MESSAGE
; R1= CONTROL ID
;
; IF SUCCESS:
; R5= ADDRESS OF TCB
;
; IF FAILURE:
; R0= RESPONSE CODE
;-
ACCESS: ;FIRST MESSAGE ENTRY POINT
; RANGE CHECK REQUEST TYPE
BEQ 10$ ;IF EQ, INVALID REQUEST TYPE
CMPB #AC.MAX,R0 ;<ACCESS> TYPE IN RANGE?
BHIS 20$ ;IF LOS, YES- CONTINUE
10$: RESPOND RC.IRC ;ERROR - ILLEGAL REQUEST CODE
; LOOK UP TCB
20$: CALL FNDRES ;CHECK RESERVED LIST FOR TERMINAL
BCC 40$ ;IF CC, FOUND IT
CMPB #AC.REL,R0 ;IS THIS A RELEASE?
BEQ 30$ ;IF EQ, YES
RESPOND RC.RSE ;ERROR - REQUEST OUT OF SEQUENCE
30$: CLR R5 ;INDICATE TCB NOT FOUND
40$: ASL R0 ;MAKE A WORD INDEX
JMP @ACCDSP(R0) ;DISPATCH <ACCESS> MESSAGE
;+
; SEND 'ACCESS-OPEN ON SINGLE LINK' NOT SUPPORTED
;-
OPEN1: RESPOND RC.SLN ;ERROR - SINGLE LINK NOT SUPPORTED
.SBTTL OPEN - <ACCESS-OPEN> MESSAGE PROCESSOR
;+
; THIS ROUTINE RECEIVES CONTROL FROM THE <ACCESS> MESSAGE PRE-PROCESSOR.
; ITS FUNCTION IS TO OPEN A TERMINAL FOR A REQUESTOR. THE BULA RECEIVED
; IN THE <OPEN> MESSAGE INDICATES THE DATA PIPE ONTO WHICH THE TERMINAL IS
; TO BE OPENED. THE BULA IS VERIFIED TO BE A VALID DATA PIPE ASSOCIATED
; WITH THE REQUESTOR. IF OK, THE DATA PIPE IS CHECKED TO BE CONNECTED,
; AND IF SO, A START CCB IS QUEUED TO THE APPROPRIATE DIALOGUE MANAGER.
; [THE OPEN PROCESS IS COMPLETED IN THE <OPEN COMPLETE> PROCESSOR].
;
; INPUT:
; APR6= BIASED INTO RESOURCE MESSAGE
; R5= ADDRESS OF TCB
; R4= ADDRESS OF WORKING CCB
; R3= ADDRESS OF PCB
; R2= CURRENT ADDRESS OF RESOURCE MESSAGE
; = AT 'SRVTYPE' FIELD
;
; OUTPUT:
; IF SUCCESS:
; R4= ADDRESS OF WORKING CCB
;
; IF FAILURE:
; R4= ADDRESS OF WORKING CCB
; R0= RESPONSE CODE
;
;-
OPEN2:
BIT #TS.ROP,T.STS(R5) ;TERMINAL READY FOR OPEN?
BEQ 60$ ;IF EQ, YES
RESPOND RC.RSI ;ERROR - RESOURCE STATE INCONSISTENCY
40$: RESPOND RC.ISO ;ERROR - INVALID SERVER OPTION
60$:
inc r2 ;past server obj type
call get1 ;length of srvdesc field
add r0,r2 ;get server opts field
call get1 ;...
tst r0 ;can't be null
beq 40$
call get1 ;pick up bula
push$s r3 ;save ctl pipe
call $pcbpt ;get data pipe
mov r3,r0 ;...
pop$s r3
bcs 40$ ;youcky poo
BIT #PS.DAT,P.STS(R0) ;IS THIS A DATA PIPE?
BEQ 40$ ;IF EQ, NO- GIVE ISO ERROR
CMP P.USER(R3),P.USER(R0) ;CONTROL PIPE OK FOR DATA PIPE?
BNE 40$ ;IF NE, NO- GIVE ISO ERROR
BIT #PS.CC,P.STS(R0) ;DATA PIPE CONNECTED?
BNE 70$ ;IF NE, YES- CONTINUE
RESPOND RC.RJS,RD.PNC ;ERROR - DATA PIPE NOT CONNECTED
70$: MOV R0,T.PCBD(R5) ;SET DATA PCB INTO TCB
BIS #TS.OPP,T.STS(R5) ;SET OPEN PENDING
MOVB T.SPI(R5),C.pix(R4)
movb t.pri(r5),c.lix(r4)
MOVB #FC.CTL,C.FNC(R4)
MOVB #FM.STR,C.MOD(R4)
JMP $SCHED
.SBTTL SRVSTR - START COMPLETE PROCESSOR
;+
; THIS ROUTINE RECEIVES CONTROL WHEN A DIALOGUE MANAGER POSTS AN
; OPEN COMPLETION TO THE RESOURCE MANAGER.
; THE OPEN CCB IS RETURNED TO THE POOL. THE TCB ASSOCIATED WITH THE
; TERMINAL NUMBER IS LOOKED UP, AND THE REGISTERS ARE SET UP FOR THE
; RESPONSE PROCESSOR. THEN A RESPONSE MESSAGE IS GENERATED BASED ON THE
; STATUS OF THE OPEN COMPLETION.
;
; INPUT:
; R4= ADDRESS OF OPEN CCB
;
; OUTPUT:
; R4= ADDRESS OF CCB-RDB
; R0= RESPONSE CODE
;
; IF SUCCESS:
; R5(LOW BYTE)= TERMINAL NUMBER (BTN)
; R5(HIGH BYTE)= BOUNDARY USER LINK ADDRESS (BULA)
;
;-
SRVSTR:
GTTCB$ ;GET THE TCB
MOV T.PCBR(R5),R3 ;THE CONTROL PIPE
BIC #TS.OPP,T.STS(R5) ;CLEAR START PENDING
; CHECK FOR SUCCESS OR FAILURE ON START
TSTB C.STS(R4) ;START SUCCESSFUL?
BPL 60$ ;IF PL, YES
RESPOND RC.RJS,RD.STR ;ERROR - STARTUP FAILED
60$: MOV T.PCBD(R5),R3 ;GET DATA PCB ADDRESS
CALL SETOPN ;LINK TCB INTO OPEN LIST.
BIS #TS.OP,T.STS(R5) ;SET STATUS= 'OPEN'
MOVB T.NUM(R5),-(SP) ;SAVE TERMINAL NUMBER (BTN)
MOVB P.NUM(R3),1(SP) ;PUT BULA IN HIGH BYTE
MOV (SP)+,R5 ;LOAD BULA-BTN COMBO IN R5
RESPOND RC.INT ;SUCCESS - RESOURCE OPEN
.SBTTL CLOSE - <ACCESS-CLOSE> MESSAGE PROCESSOR
;+
; THIS ROUTINE RECEIVES CONTROL FROM THE <ACCESS> MESSAGE PRE-PROCESSOR.
; ITS FUNCTION IS TO CLOSE A TERMINAL FOR A REQUESTOR. THE 'OPEN' BIT
; IS CLEARED, THE 'CLOSE PENDING' BIT IS SET, AND THE T.PCBR THREAD IS
; REDIRECTED FROM THE DATA PIPE TO THE CONTROL PIPE.
;
; INPUT:
; APR6= BIASED INTO RESOURCE MESSAGE
; R5= ADDRESS OF TCB
; R4= ADDRESS OF WORKING CCB
; R3= ADDRESS OF PCB
; R2= CURRENT ADDRESS OF RESOURCE MESSAGE
; = AT 'SRVTYPE' FIELD
;
; OUTPUT:
; IF SUCCESS:
; R4= ADDRESS OF WORKING CCB
;
; IF FAILURE:
; R4= ADDRESS OF WORKING CCB
; R0= RESPONSE CODE
;
;-
CLOSE: ;ENTRY POINT
BIT #TS.OP,T.STS(R5) ;TERMINAL OPEN?
BNE CLOSE1 ;IF NE, YES
RESPOND RC.RSI ;ERROR - RESOURCE STATE INCONSISTENCY
; SECONDARY ENTRY POINT (FROM RELEASE PROCESSOR)
CLOSE1:
; SECONDARY ENTRY POINT (FROM ERROR PROCESSOR)
CLOSE2:
CLR C.BUF+2(R4) ;INDICATE NO OPTIONAL DATA
CLR C.CNT(R4)
; SEND CLOSE (STOP) MESSAGE TO DIALOGUE MANAGER
80$: BIC #TS.OP,T.STS(R5) ;TERMINAL NO LONGER OPEN
BIS #TS.CLP,T.STS(R5) ;SET CLOSE PENDING
MOVB T.SPI(R5),C.pix(R4)
movb t.pri(r5),c.lix(r4)
MOVB #FC.CTL,C.FNC(R4)
MOVB #FM.STP,C.MOD(R4)
CALL $SCHED
CLC ;INDICATE SUCCESS
RETURN ;EXIT
.SBTTL SRVSTP - STOP COMPLETE PROCESSOR
;+
; THIS ROUTINE RECEIVES CONTROL WHEN A DIALOGUE MANAGER POSTS A
; CLOSE COMPLETION TO THE RESOURCE MANAGER.
; IF RELEASE PENDING IS SET, THE RELEASE PROCESSOR IS CALLED AT
; ITS 'RELES1' ENTRY POINT. IN THIS CASE THE STATUS RETURNED TO
; THE USER WILL BE FOR A RELEASE REQUEST.
; IF A RELEASE IS NOT PENDING, A RESPONSE MESSAGE IS RETURNED
; TO THE USER FOR THE CLOSE REQUEST.
; IF THE CLOSE IS BEING DONE BECAUSE OF A DISCONNECT ON THE DATA
; PIPE AND THE CONTROL PIPE IS STILL ACTIVE, A <STATUS-REPORT>
; MESSAGE IS SENT ON THE CONTROL PIPE FOR THE TERMINAL BEING CLOSED.
; IN ANY CASE, THE CLOSE CCB IS RETURNED TO THE POOL.
;
; INPUT:
; R4= ADDRESS OF CLOSE CCB
;
; OUTPUT:
; R4= ADDRESS OF CCB-RDB
; R0= RESPONSE CODE
;
;-
SRVSTP: ;ENTRY POINT
GTTCB$ ;FIND THE RESOURCE CONTROL BLOCK
BIC #TS.CLP,T.STS(R5) ;CLEAR CLOSE PENDING
MOV T.PCBD(R5),R3 ;POINT TO DATA PCB
CALL REMOPN ;REMOVE RESOURCE FROM OPEN LIST.
CLR R1 ; TRANSFER RESOURCE
BISB T.SPI(R5),R1 ; FROM THE SERVER
10$: MOV T.PCBR(R5),R3 ;POINT TO CONTROL PCB
MOVB P.NUM(R3),C.prm1(R4) ;AND RESET THE PIPE NUMBER.
TST C.stk(R4) ;IF THIS IS A DISCONNECT OPERATION
BNE 40$ ;THEN
BIT #PS.DIP,P.STS(R3) ;DISCONNECT PENDING ON CONTROL PIPE?
BEQ 20$ ;IF EQ, NO
BIC #<TS.STE!TS.OSP!TS.RLP>,T.STS(R5) ;ELSE CLEAR PENDING BITS
JMP DISCP ;FINISH DISCONNECTING CONTROL PIPE
20$: MOV T.PCBD(R5),R0 ;GET DATA PCB ADDRESS
BIT #PS.DIP,P.STS(R0) ;DISCONNECT PENDING ON DATA PIPE?
BEQ 30$ ;IF EQ, NO
25$: BIT #PS.CC,P.STS(R3) ;IF CONTROL PIPE
BEQ 26$ ; IS STILL ACTIVE,
MOV T.RID(R5),R1 ; SEND A <STATUS-REPORT> MESSAGE
MOV #RP.DSC,R0 ; ON THE PIPE
CALL ASYREP ; ASYNCHRONOUSLY
BCC 26$ ;IF NO RESOURCES
MOV R5,C.prm3(R4) ;SAVE THE TCB ADDRESS
CALL NRMRWT ;WAIT A TICK
MOV C.prm3(R4),R5 ;RESTORE THE TCB
BR 25$ ;AND TRY AGAIN
26$: MOV T.PCBD(R5),R3 ;POINT TO DATA PCB
BIC #<TS.STE!TS.OSP!TS.RLP>,T.STS(R5) ;CLEAR PENDING BITS
JMP DISDP ;FINISH DISCONNECTING DATA PIPE
30$: BIT #TS.STE,T.STS(R5) ;START ERROR PENDING?
BEQ 40$ ;IF EQ, NO
BIC #TS.STE,T.STS(R5) ;ELSE YES- CLEAR START ERROR PENDING
35$: JMP $CCBRT ;RETURN STOP CCB
40$: BIT #TS.RLP,T.STS(R5) ;IF RELEASE PENDING
BNE 50$ ;OR
BIT #TS.OSP,T.STS(R5) ;NO OPR RPT REQUEST PENDING
BEQ 50$ ;THEN
45$: BIT #PS.CC,P.STS(R3) ;IF CONTROL PIPE
BEQ 50$ ; IS STILL ACTIVE,
BIC #TS.OSP,T.STS(R5) ;CLEAR OPERATIONAL STATUS BIT
MOV T.RID(R5),R1 ;GET CONTROL ID
MOV C.PRM1(R4),R0 ;GET OPERATIONAL STATUS
CALL ASYREP ;AND SEND STATUS-REPORT TO USER
BCC 50$ ;IF NOT SUCCESSFUL
BIS #TS.OSP,T.STS(R5) ;RESET THE BIT
MOV R5,C.prm3(R4) ;SAVE THE TCB ADDRESS
CALL NRMRWT ;WAIT A TICK
MOV C.prm3(R4),R5 ;RESTORE THE TCB
BR 45$ ;AND TRY AGAIN.
50$: TST C.stk(R4) ;IF NO ASSOCIATED MESSAGE
BEQ 35$ ;THEN THROW THIS AWAY.
70$: RESPOND RC.INT ;SUCCESS - CONTROL THREAD OPEN
.SBTTL ASSIGN - <ASSIGN> MESSAGE PRE-PROCESSOR
;+
; THIS ROUTINE RECEIVES CONTROL FROM THE RESOURCE MANAGER DISPATCHER.
; IT DOES PROCESSING COMMON TO ALL ASSIGN REQUEST MESSAGES.
; A RANGE CHECK IS DONE ON THE REQUEST TYPE AND THE MESSAGE IS DISPATCHED.
;
; INPUT:
; APR6= BIASED INTO RESOURCE MESSAGE
; R4= ADDRESS OF WORKING CCB
; R3= ADDRESS OF CONTROL PCB
; R2= ADDRESS OF RESOURCE MESSAGE
; = AT 'MSGFLDS' FIELD
; R0= MESSAGE SUBTYPE
;
; OUTPUT:
; IF SUCCESS:
; SAME AS INPUT
;
; IF FAILURE:
; SAME AS INPUT, PLUS:
; R0= RESPONSE CODE
;-
ASSIGN:
; RANGE CHECK REQUEST TYPE
TST R0
BEQ 10$ ;IF EQ, INVALID STATUS TYPE
CMPB R0,#AS.MAX ;ASSIGN TYPE IN RANGE?
BLOS 20$ ;IF LOS, YES- CONTINUE
10$: RESPOND RC.IRC ;ERROR - INVALID REQUEST CODE
20$: ASL R0 ;MAKE A WORD INDEX
JMP @ASNDSP(R0) ;AND DISPATCH ASSIGN MESSAGE
.SBTTL ASYREP - ASYNCHRONOUS STATUS REPORT
;+
; THIS ROUTINE RECEIVES CONTROL FROM THE ERROR PROCESSOR.
; ITS FUNCTION IS TO GET THE ATS TERMINAL STATUS AND THE OPERATIONAL
; STATUS, BUILD THE STATUS MESSAGE, ANS TRANSMIT THE MESSAGE.
;
; INPUTS:
; R5= ADDRESS OF TCB
; R3= ADDRESS OF CONTROL PCB
; R1= CONTROL ID
; R0= OPERATIONAL STATUS
;
; OUTPUT:
; CARRY CLEAR= STATUS SENT
; CARRY SET= COULD NOT OBTAIN RESOURCES
;
; REGISTERS MODIFIED: APR6,R2
;-
ASYREP: PUSH$S R4 ; SAVE HIS CCB
CALL CSBGT ; AND GET A REPORT BUFFER
BCS 90$ ; IF WE CAN.
MOV R1,C.prm1(R4) ; SAVE CONTROL ID
MOVB P.LLA(R3),C.LIN(R4) ; PIPE NUMBER
MOVB #SS.ATS,C.MOD(R4) ; AND SET STATUS TYPE.
MOV C.BUF+2(R4),R2 ; GET BUFFER ADDRESS
CALL STATSM ; AND SET UP THE MESSAGE.
SUB C.BUF+2(R4),R2 ; FIGURE THE LENGTH AND
MOV R2,C.CNT(R4) ; STORE IT.
movb p.pix(r3),c.pix(r4) ;set destination
NDAT$ P.LLA(R3),p.num(r3),#s$peom
CLC ; INDICATE SUCCESS
90$: POP$S R4 ; RESTORE HIS CCB
RETURN
.SBTTL INVALID - INVALID OR UNSUPPORTED REQUEST PROCESSOR
;+
; THIS ROUTINE PROVIDES A DISPATCH TARGET FOR ALL INVALID OR UNSUPPORTED
; REQUESTS DISPATCHED THRU THE DISPATCH TABLES.
;
; INPUT:
; R4= ADDRESS OF CCB-RDB
;
; OUTPUT:
; SAME AS INPUT, PLUS:
; R0= RESPONSE CODE
;-
UNSUPPORTED:
INVALID:
MOV #RC.IRC,R0 ;ERROR - ILLEGAL REQUEST CODE
.IIF NE,<.-RSPNS>,.ERROR RSPNS; routine must follow this one
.SBTTL RSPNS - RESPONSE MESSAGE GENERATOR
;+
; GET DATA PIPE AND MESSAGE TYPE BEING RESPONDED TO AND FALL THROUGH TO
; RESPOND TO THE MESSAGE.
;
; INPUTS:
; R5= RESPONSE DATA, IF R0=RC.RJS OR <ACCESS-OPEN> MESSAGE RESPONSE
; R4= ADDRESS OF WORKING CCB
; R0= RESPONSE CODE
;
; OUTPUTS (TO RSPNS1):
; APR6= MAPPED TO RESOURCE MESSAGE
; R5= RESPONSE DATA, IF R0=RC.RJS OR <ACCESS-OPEN> MESSAGE RESPONSE
; R4= ADDRESS OF WORKING CCB
; R3= ADDRESS OF CONTROL PCB
; R1= MESSAGE TYPE (LOW BYTE) / SUBTYPE (HIGH BYTE)
; R0= RESPONSE CODE
;-
RSPNS: PUSH$S <R0,R4> ; ROOM TO MOVE.
MOV C.stk(R4),R4 ; GET NSP BUFFER
GTPCB$ ; AND PCB ADDRESS.
MAP$ C.BUF(R4) ; MAP TO BUFFER
MOV C.STS(R4),R2 ; GET ADDRESS
CALL GET2 ; AND PICK UP
MOV R0,R1 ; MESSAGE TYPE / SUBTYPE.
POP$S <R4,R0> ; RESET REGISTERS.
.IIF NE,<.-RSPNS2>,.ERROR RSPNS2; routine must follow this one
.PAGE
;+
; RELEASE THE NSP RESOURCE MESSAGE BUFFER, GET A RESPONSE BUFFER
; AND FALL THROUGH TO FILL THE BUFFER AND SEND THE RESPONSE.
;
; INPUT:
; R5= RESPONSE DATA, IF R0=RC.RJS OR <ACCESS-OPEN> MESSAGE RESPONSE
; R4= ADDRESS OF WORKING CCB
; R3= PCB ADDRESS
; R1= MESSAGE TYPE (LOW BYTE), SUBTYPE (HIGH BYTE)
; R0= RESPONSE CODE
;
; OUTPUT (TO RSPNSM):
; R4= ADDRESS OF WORKING CCB
; C.prm1= CONTROL ID
; C.FLG= MESSAGE TYPE (LOW BYTE), SUBTYPE (HIGH BYTE)
; C.PRM1= RESPONSE CODE
; C.PRM2= RESPONSE DATA, IF R0=45 OR <OPEN> MESSAGE RESPONSE
;
; ALL REGISTERS MODIFIED
;-
RSPNS2: MOV R4,R2
MOV C.stk(R4),R4 ; GET NSP'S CCB-BUFFER
NRTN$
MOV R2,R4 ; RECOVER THE WORKING CCB.
20$: CALL SDBGT ; PUT A SDB IN OUR CCB
BCC 30$ ; IF NOT AVAILABLE
MOV R1,C.prm3(R4) ; MESSAGE BEING RESPONDED TO
MOV R0,C.prm4(R4) ; RESPONSE CODE
MOV R5,C.prm5(R4) ; AND DATA.
mov c.prm1(r4),c.sts(r4) ; save the ctl-id
movb p.num(r3),c.prm1(r4) ; set up ULA for dispatch
CALL NRMRWT ; WAIT FOR BETTER CONDITIONS
MOV C.prm5(R4),R5 ; RESTORE
MOV C.prm4(R4),R0 ; NEEDED
MOV C.prm3(R4),R1 ; DATA
mov c.sts(r4),c.prm1(r4) ; set up ctl-id
BR 20$ ; AND TRY AGAIN
30$: MOV C.BUF+2(R4),R2 ; AND BUFFER ADDRESS
CALL RSPNSM ; SET UP THE MESSAGE
SUB C.BUF+2(R4),R2 ; FIGURE THE LENGTH AND
MOV R2,C.CNT(R4) ; STORE IT.
movb p.pix(r3),c.pix(r4) ;set destination
NDAT$ P.LLA(R3),p.num(r3),#s$peom
RETURN
.SBTTL RSPNSM - GENERATE A <RESPONSE> MESSAGE
;+
; SET UP A RESPONSE MESSAGE IN A GIVEN BUFFER.
;
; INPUT:
; APR6= MAPPED TO RESPONSE BUFFER
; R5= RESPONSE DATA, IF R0=45 OR <OPEN> MESSAGE RESPONSE
; R4= ADDRESS OF RESPONSE CCB-BUFFER
; C.prm1= CONTROL ID
; R2= ADDRESS TO INSERT THE STATUS MESSAGE
; R1= MESSAGE TYPE (LOW BYTE), SUBTYPE (HIGH BYTE)
; R0= RESPONSE CODE
;
; OUTPUTS:
; R2= MOVED PAST THE MESSAGE INSERTED
;
; REGISTERS MODIFIED: R5,R2
;-
RSPNSM: MOVB #RQ.RES,(R2)+ ; LOAD RESPONSE REQUEST CODE
MOVB R1,(R2)+ ; LOAD RECEIVED MESSAGE'S REQUEST CODE
MOVB C.prm1(R4),(R2)+ ; LOAD LOW BYTE OF CONTROL ID
MOVB C.prm1+1(R4),(R2)+ ; LOAD HIGH BYTE OF CONTROL ID
MOVB R0,(R2)+ ; LOAD LOW BYTE
SWAB R0 ; AND
MOVB R0,(R2)+ ; HIGH BYTE OF RESPONSE CODE
SWAB R0 ; RESTORE THE CODE.
CMP #RC.RJS,R0 ; IS THIS A SERVOR REJECTION?
BNE 60$ ; IF NE, NO
TST R5 ; IS THERE RESPONSE DATA?
BEQ 70$ ; IF EQ, NO
MOVB #2,(R2)+ ; SET RESPONSE DATA COUNT
MOVB R5,(R2)+ ; LOAD LOW BYTE
SWAB R5 ; AND
MOVB R5,(R2)+ ; HIGH BYTE OF RESPONSE DATA
RETURN ; SEND RESPONSE MESSGAGE
60$: CMP #RQ.ACC+<AC.SEP*400>,R1 ; IF <ACCESS-OPEN>
BNE 70$ ; WITH SEPERATE DATA PIPE
MOVB #3,(R2)+ ; THEN SET RESPONSE DATA COUNT
MOVB R5,(R2)+ ; LOAD BTN
CLRB (R2)+ ; CLEAR HIGH BYTE OF BTN
SWAB R5 ; AND
MOVB R5,(R2)+ ; LOAD BULA
RETURN ; AND SEND RESPONSE MESSAGE
70$: CLRB (R2)+ ; SET RESPONSE DATA LENGTH= 0
RETURN
.SBTTL STATSM - GENERATE A <STATUS> MESSAGE
;+
; SET UP A STATUS MESSAGE IN A GIVEN BUFFER.
;
; INPUT:
; APR6= MAPPED TO RESPONSE BUFFER
; R5= ADDRESS OF TCB FOR STATUS MESSAGE
; R4= ADDRESS OF RESPONSE CCB-BUFFER
; C.prm1= CONTROL ID
; C.MOD= STATUS MESSAGE TYPE
; R2= ADDRESS TO INSERT THE STATUS MESSAGE
; R0= OPERATIONAL STATUS OR ZERO
;
; OUTPUTS:
; R2= MOVED PAST THE MESSAGE INSERTED
;
; REGISTERS MODIFIED: R2
;-
STATSM: MOVB #RQ.STS,(R2)+ ; LOAD STATUS REQUEST CODE
MOVB #ST.REP,(R2)+ ; AS <STATUS-REPORT>
MOVB C.prm1(R4),(R2)+ ; LOAD LOW BYTE OF CONTROL ID
MOVB C.prm1+1(R4),(R2)+ ; LOAD HIGH BYTE OF CONTROL ID
MOVB C.MOD(R4),(R2)+ ; SET STATUS TYPE
MOVB #2,(R2)+ ; AND DEFAULT TO TWO.
MOVB T.STS+0(R5),(R2)+ ; AND STORE
MOVB T.STS+1(R5),(R2)+ ; TCB STATUS.
TST R0 ; IS THERE ANY OPERATIONAL STATUS ?
BEQ 80$ ; IF SO,
MOVB #4,-3(R2) ; SET COUNT TO FOUR
MOVB R0,(R2)+ ; AND LOAD THE
SWAB R0
MOVB R0,(R2)+ ; OPERATIONAL STATUS.
SWAB R0
80$: RETURN
.SBTTL CSBGT - GET A CCB/SDB AND SAVE BUFFER ADDRESS
;+
; GET A CCB/SDB AND FIX IT UP.
;
; NO INPUTS
;
; OUTPUTS:
; APR6 - MAPPED TO SDB
; R4 - CCB/SDB IF CARRY IS CLEAR
;
; REGISTERS MODIFIED: APR6,R4
;-
CSBGT:
push$s <r1>
mov #60.,r1
CALL $CBBGT ;GET A CCB/SDB
pop$s <r1>
RETURN
.SBTTL SDBGT - GET A SDB AND INSERT IN CCB
;+
; THIS ROUTINE IS HERE FOR THE SAME REASON AS ABOVE.
;
; INPUTS:
; R4 - CCB TO INSERT SDB INTO
;
; OUTPUTS (IF CARRY IS CLEAR):
; APR6 - MAPPED TO SDB
; C.BUF+0(R4) - SDB APR BIAS
; C.BUF+2(R4) - SDB VIRTUAL ADDRESS
;
; REGISTERS MODIFIED: APR6
;-
SDBGT: PUSH$S <r1,r0> ; SAVE VOLOTILE REGISTERS
mov #60.,r1
CALL $corGT ; AND BID FOR A SDB.
BCS 90$ ; IF WE WON
SMAP$ c.BUF+0(R4) ; INSERT APR BIAS
MOV R0,C.BUF+2(R4) ; AND VIRTUAL ADDRSS
90$: POP$S <r0,R1>
RETURN
.SBTTL NRMDAT - RETURN A NRM DATA BUFFER
;+
; THIS ROUTINE RETURNS BUFFERS AFTER A TRANSMIT OPERATION COMPLETES.
;
; INPUT:
; R4= ADDRESS OF CCB-SDB
;
; OUTPUT:
; CCB-SDB RETURNED TO POOL
;-
NRMDAT:
mov #60.,r1 ;return 80. bytes
JMP $CbBRT ;AND RETURN CCB-SDB.
.SBTTL NSPRT - RETURN CCB & ASSOCIATED NSP BUFFER
;+
; THIS ROUTINE RETURNS CCBS AND RECEIVE BUFFERS ACQUIRED FROM NSP
; IF ANY ARE ATTACHED TO THE CCB
;
; INPUT:
; R4 = ADDRESS OF CCB FOR BUFFER
; R3 = CONTROL PCB
;
; REGISTERS MODIFIED: R1
;-
NSPRT: MOV C.stk(R4),R1 ; PICK UP MYTHICAL NSP MESSAGE
CALL $CCBRT ; AND RELEASE THE CCB.
MOV R1,R4 ; IF THE IS A NSP MESSAGE
BEQ 90$ ; THEN
NRTN$
90$: RETURN
; ***- RESOURCE MANAGER UTILITIES -***
;+
; THE FOLLOWING ROUTINES ARE GENERAL UTILITIES USED BY THE RESOURCE
; MANAGER AND THE ATS DIALOGUE MANAGERS FOR TABLE LOOKUP; INSERTION,
; DELETION AND SCANNING OF ITEMS IN LINKED LISTS; AND A 'PUSH ONTO QUEUE'
; ROUTINE.
;-
.SBTTL GET* - GET DATA FROM NRM MESSAGE
;+
; THE FOLLOWING ROUTINES EXTRACT DATA FROM THE NRM MESSAGE POINTED TO BY R2
; AND UPDATE R2 TO POINT AFTER THE DATA EXTRACTED.
;
; GET1 - GET A SINGLE BYTE (NO SIGN EXTENSION)
; GET2 - GET TWO BYTES AND ASSEMBLE AS WORD
;
; INPUTS:
; APR6= BIASED INTO RESOURCE MESSAGE
; R2 - POINTS TO DATA TO EXTRACT
;
; OUTPUTS:
; R2 - POINTS AFTER EXTRACTED DATA
; R0 - ASSEMBLED DATA
;-
GET1: CLR R0 ;PICK UP ONE BYTE
BISB (R2)+,R0 ;WITHOUT EXTENDING SIGN.
RETURN
GET2: CLR R0 ;START WITH NOTHING
BISB (R2)+,R0 ;PICK UP LOW BYTE
SWAB R0
BISB (R2)+,R0 ;PICK UP HIGH BYTE
SWAB R0
RETURN
;+
; LIST MANIPULATION ROUTINES FOR REFERRAL LIST, RESERVED LIST, AND OPEN LIST.
;
; INPUTS:
; R5= REFERRAL CCB OR RESOURCE TCB (IN SETXXX & REMXXX)
; R4= WORKING CCB
; C.prm1= CONTROL ID
; R3= CONTROL / DATA PIPE ADDRESS
;
; OUTPUTS:
; R5= REFERRAL CCB OR RESOURCE TCB (IN FNDXXX)
;-
SETRES: MOV P.RES(R3),(R5) ; LINK INTO
MOV R5,P.RES(R3) ; RESERVED RESOURCE LIST.
RETURN
SETOPN: MOV P.OPN(R3),T.OLNK(R5) ; LINK INTO
MOV R5,P.OPN(R3) ; OPEN RESOURCE LIST.
RETURN
FNDRES: MOV P.RES(R3),R5 ; GET FIRST RESERVED RESOURCE
BEQ 80$ ; IF THERE IS ONE.
10$: CMP C.prm1(R4),T.RID(R5) ; IF CONTROL IDS MATCH
BEQ 90$ ; THEN ALL DONE
MOV (R5),R5 ; OTHERWISE
BNE 10$ ; GO THROUGH LINKS
80$: SEC ; UNTIL WE RUN OUT.
90$: RETURN
REMRES: PUSH$S R4 ; GET A WORK REGISTER
MOV #P.RES,R4 ; AND POINT IT
ADD R3,R4 ; TO RESERVED RESOURCE LIST.
10$: CMP (R4),R5 ; IF NO MATCH
BEQ 20$ ; THEN
MOV (R4),R4 ; GO THROUGH
BNE 10$ ; THE LINKS
SEC ; UMMMM....
BR 80$ ; UNTIL RUN OUT.
20$: MOV (R5),(R4) ; IF FOUND, DE-LINK IT.
80$: POP$S R4 ; RETURN R4
RETURN
REMOPN: PUSH$S R4 ; GET A WORK REGISTER
MOV #P.OPN-T.OLNK,R4 ; AND POINT IT
ADD R3,R4 ; TO OPEN RESOURCE LIST.
10$: CMP T.OLNK(R4),R5 ; IF NO MATCH
BEQ 20$ ; THEN
MOV T.OLNK(R4),R4 ; GO THROUGH
BNE 10$ ; THE LINKS
SEC ; UMMMM....
BR 80$ ; UNTIL RUN OUT.
20$: MOV T.OLNK(R5),T.OLNK(R4) ; IF FOUND, DE-LINK IT.
80$: POP$S R4 ; RETURN R4
RETURN
.END