mirror of
https://github.com/PDP-10/stacken.git
synced 2026-03-01 01:19:17 +00:00
4891 lines
155 KiB
Plaintext
4891 lines
155 KiB
Plaintext
TITLE KLPSER - SERVICE ROUTINES FOR CI20 (KLIPA) V105
|
||
SUBTTL JOSEPH A. DZIEDZIC/JAD 2 AUG 88
|
||
|
||
SEARCH F,S,DEVPRM,KLPPRM,SCAPRM
|
||
SEARCH MSCPAR,MACSYM
|
||
$RELOC
|
||
$XHIGH
|
||
|
||
PURGEACS ;PURGE DEFAULT (TOPS-10) AC NAMES
|
||
T20SYM ;SWITCH TO TOPS-20 AC NAMES
|
||
;(NEEDED FOR INTERFACE TO SCAMPI)
|
||
|
||
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
|
||
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
|
||
;
|
||
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1984,1986,1988.
|
||
;ALL RIGHTS RESERVED.
|
||
|
||
.CPYRT<1984,1988>
|
||
|
||
|
||
XP VKLPSR,105 ;VERSION NUMBER FOR GLOB AND MAP
|
||
|
||
|
||
KLPSER:!ENTRY KLPSER ;LOAD IF LIBRARY SEARCH
|
||
SUBTTL PARAMETERS
|
||
|
||
|
||
;CI OPERATION CODES
|
||
|
||
OP.SDG==1 ;SEND DATAGRAM
|
||
OP.SMS==2 ;SEND MESSAGE
|
||
OP.RCF==3 ;CONFIRM RECEIVED
|
||
OP.MCR==4 ;MAINTENANCE CONFIRM RECEIVED
|
||
OP.RID==5 ;REQUEST ID
|
||
OP.RRS==6 ;RESET REMOTE SYSTEM
|
||
OP.SRS==7 ;START REMOTE SYSTEM
|
||
OP.RD0==10 ;REQUEST DATA ON QUEUE 0
|
||
OP.RD1==11 ;REQUEST DATA 1
|
||
OP.RD2==12 ;REQUEST DATA 2
|
||
OP.IDR==13 ;ID RECEIVED
|
||
OP.LPB==15 ;SEND/RECEIVE LOOPBACK
|
||
OP.RMD==16 ;REQUEST MAINTENANCE DATA
|
||
OP.SDT==20 ;SEND DATA
|
||
OP.RDT==21 ;RETURN DATA (DATREC)
|
||
OP.SMD==22 ;SEND MAINTENANCE DATA
|
||
OP.MDR==23 ;MAINTENANCE DATA RECEIVED
|
||
OP.CKT==200 ;SET VIRTUAL CIRCUIT
|
||
OP.SPT==201 ;SET STATISTICS COUNTER
|
||
OP.RCT==202 ;READ STATISTICS COUNTER
|
||
OP.RRG==203 ;READ REGISTER
|
||
OP.WRG==204 ;WRITE REGISTER
|
||
OP.CLB==205 ;CLOSE BUFFER
|
||
OP.RMT==40 ;ON IN REMOTELY GENERATED RESPONSES
|
||
|
||
INCXID==1B31 ;VALUE TO INCREMENT TRANSACTION ID BY
|
||
|
||
MINUVR==100,,711 ;MINIMUM KLIPA MICROCODE VERSION
|
||
|
||
MAXNOR==77 ;NUMBER OF TIME OUTS BEFORE WE DECLARE THE OTHER PORT SICK
|
||
|
||
RIDTIM==^D2 ;TIMEOUT FOR REQUEST-ID (SECONDS)
|
||
STSTIM==^D10 ;TIMEOUT FOR START SEQUENCE (SECONDS)
|
||
CTRTIM==^D60*^D60 ;TIMEOUT FOR PERIODIC READ-COUNTERS (SECONDS)
|
||
|
||
TIMOUT==^D1000 ;VALUE OF INTERLOCK WORD AT WHICH WE DECLARE THE KLIPA DEAD
|
||
RSTIME==^D60*^D3 ;LEAVE KLIPA STOPPED IF 2 ERRORS IN THIS INTERVAL
|
||
|
||
KAFTIM==^D10*^D1000 ;KEEP ALIVE TIMEOUT (MILLISECONDS)
|
||
IDLTIM==^D1*^D1000 ;IDLE TIME (MILLISECONDS)
|
||
|
||
CO.BTS==CO.ENA+CO.MRN ;BITS WHICH MUST BE ON IN ALL CONOS
|
||
|
||
KLPBTS==CI.CPE!CI.MER!CI.EPE!CI.FQE!CI.RQA ;BITS TO TEST FOR ON INTERRUPT
|
||
;MACRO TO DEFINE SNOOP POINT (SINCE SNOOP. CAN'T HACK EXTENDED CODE SECTIONS)
|
||
|
||
DEFINE SNOOP(LABEL,%DUMMY),<
|
||
..EXTH==0 ;;ASSUME NOT IN EXTENDED HIGH SEGMENT
|
||
IFE PSECT.-.XHGH.,..EXTH==1 ;;BUT IF WE ARE, REMEMBER THE FACT
|
||
IFN ..EXTH,< ;;IF IN EXTENDED HIGH SEGMENT,
|
||
XJRST [MCSEC0+LABEL] ;;CALL THE TRACKING ROUTINE IN SECTION 0
|
||
$HIGH ;;SWITCH PSECTS
|
||
LABEL::!JFCL ;;RANDOM NO-OP
|
||
XJRST [%DUMMY] ;;RETURN TO EXTENDED HIGH SEGMENT
|
||
$XHIGH ;;AS YOU WERE
|
||
%DUMMY:! ;;USELESS LABEL
|
||
>;; END IFN ..EXTH
|
||
IFE ..EXTH,< ;;IF NOT IN EXTENDED HIGH SEGMENT,
|
||
LABEL::!JFCL ;; THINGS ARE MUCH EASIER
|
||
>;; END IFE ..EXTH
|
||
>; END DEFINE SNOOP
|
||
|
||
|
||
;KLIPA TOPS-20 ERROR CODES
|
||
|
||
KLPX1==602547
|
||
KLPX2==602050
|
||
KLPX5==602027
|
||
KLPX7==602031
|
||
KLPX9==602033
|
||
KLPX10==602734
|
||
KLPX11==602735
|
||
KLPX13==602052
|
||
KLPX14==602054
|
||
SUBTTL AUTOCONFIGURATION TABLES
|
||
|
||
;DRIVER CHARARCTERISTICS
|
||
; KLP = KLPCNF
|
||
; KLP = KLIPA
|
||
; M.CPU = MAXIMUM DEVICES IN SYSTEM
|
||
; 0 = KONTROLLER TYPE
|
||
; 0 = MAXIMUM DRIVES PER KONTROLLER
|
||
; 0 = HIGHEST DRIVE NUMBER ON KONTROLLER
|
||
; MDSEC0 = SECTION FOR KDB/UDB
|
||
; MDSEC0 = SECTION FOR DDB
|
||
DRVCHR (KLP,KLP,M.CPU##,0,0,0,MDSEC0,MDSEC0,<DR.XAD!DR.MCD!DR.NMC>)
|
||
|
||
|
||
.ORG IPKSIZ
|
||
BLOCK .PCLEN ;PCB
|
||
KLPKLN:! ;LENGTH OF KDB
|
||
.ORG
|
||
|
||
|
||
KLPKDB: KDBBEG (KLP,KLPKLN)
|
||
SETWRD (KDBNAM,<SIXBIT/KLP/>) ;KONTROLLER NAME
|
||
SETWRD (KDBPCC,<.PCPCL,,.PCPCB>) ;PHYSICALLY CONTIGUOUS CORE
|
||
SETWRD (.PCOLD,<EXP -1>) ;FULL CONFIGURE FIRST TIME
|
||
KDBEND
|
||
|
||
|
||
EQUATE (LOCAL,0,<KLPCKT,KLPUDB,KLPULN>)
|
||
EQUATE (LOCAL,CPOPJ##,<KLPINI>)
|
||
|
||
KLPULB==.PCULB ;OFFSET OF UCODE LOADER BLOCK
|
||
KLPICD==IPAICD## ;PROTOTYPE INTERRUPT CODE ADDRESS
|
||
KLPICL==IPAICL## ;PROTOTYPE INTERRUPT CODE LENGTH
|
||
|
||
$HIGH ;MUST BE IN .HIGH. DUE TO 18-BIT .LINK PSEUDO-OP
|
||
|
||
KLPDSP: DRVDSP (KLP,DSKCHN##,,,KLPDIA)
|
||
|
||
;DEFAULT MONGEN'ED DEVICE TABLE
|
||
DEFMDT: MDKL10 (7,574,0,0,<MD.KON>) ;DEVICE CODE 574
|
||
MDTERM ;TERMINATE TABLE
|
||
|
||
$XHIGH
|
||
|
||
;PROTOTYPE MICROCODE PARAMETER BLOCK
|
||
KLPULP: EXP .BTKLP## ;MICROCODE INDEX
|
||
XWD 000,0 ;DEVICE CODE,,MASSBUS UNIT NUMBER
|
||
SIXBIT /KLIPA/ ;INTERFACE NAME
|
||
SIXBIT /CI20/ ;CHANNEL NAME
|
||
EXP MINUVR ;MINIMUM MICROCODE VERSION
|
||
EXP 0 ;DATE/TIME OF LOAD SUCCESS OR FAILURE
|
||
EXP 0 ;MICROCODE VERSION
|
||
EXP 0 ;POINTER TO MAGIC TABLE
|
||
EXP 0 ;MICROCODE LENGTH
|
||
EXP 0 ;MICROCODE ADDRESS
|
||
SUBTTL BHD/BSD INITIALIZATION
|
||
|
||
|
||
;ROUTINE TO GET SPACE FOR BHD'S AND BSD'S. CALLED DURING ONCE BEFORE
|
||
;THE CALL TO PPDINX SO BHDADR IS VALID. NOTE ALL KLIPAS IN THE
|
||
;SYSTEM SHARE THE SAME POOL OF BHD'S AND BSD'S.
|
||
;CALL:
|
||
; PUSHJ P,BHDINI
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XSENT (BHDINI::)
|
||
SKIPE BHDIPT ;ALREADY HAVE A BUFFER DESCRIPTOR TABLE SET UP?
|
||
POPJ P, ;YES, NOTHING ELSE TO DO
|
||
SE1ENT ;ENTER NON-ZERO SECTION
|
||
MOVEI T1,C%BHDN*.BHSIZ ;NUMBER OF WORDS FOR BUFFER HEADER DESCRIPTORS
|
||
IDIVI T1,PAGSIZ ;DETERMINE NUMBER OF PAGES
|
||
SKIPE T2 ;IF A REMAINDER,
|
||
AOS T1 ; ROUND UP
|
||
PUSH P,T1 ;SAVE THE COUNT FOR LATER
|
||
PUSHJ P,PGRSKD ;GET THE RESIDENT SPACE
|
||
JRST TPOPJ## ;NOT AVAILABLE?!
|
||
MOVEM T1,BHDIPT ;STORE INITIAL POINTER FOR BHD SEARCHES
|
||
POP P,T2 ;RESTORE NUMBER OF PAGES REQUESTED
|
||
MOVEM T2,BHDPGS ;STORE FOR MEMORY OFFLINE CODE
|
||
LSH T2,P2WLSH ;HOW MANY WORDS WERE ALLOCATED
|
||
MOVE T3,T2 ;SAVE A COPY FOR LATER
|
||
ADD T2,T1 ;COMPUTE LAST ADDRESS IN BUFFER DESCRIPTOR TABLE
|
||
SUBI T2,1 ;...
|
||
MOVEM T2,BHDEND ;STORE FOR BHD SEARCHES
|
||
MOVEM T3,BHDMTI ;SAVE MAXIMUM BDT INDEX
|
||
IDIVI T3,.BHSIZ ;COMPUTE HOW MANY BHD'S WILL FIT IN SPACE ALLOCATED
|
||
MOVEM T3,BHDNUM ;STORE FOR POSSIBLE FUTURE BHD RE-INIT
|
||
PUSHJ P,BHDCLR ;CLEAR ALL BHD'S
|
||
|
||
MOVEI T1,C%BSDN*.BSSIZ ;NUMBER OF WORDS FOR BUFFER SEGMENT DESCRIPTORS
|
||
IDIVI T1,PAGSIZ ;DETERMINE NUMBER OF PAGES
|
||
SKIPE T2 ;IF A REMAINDER,
|
||
AOS T1 ; ROUND UP
|
||
PUSH P,T1 ;SAVE THE COUNT FOR LATER
|
||
PUSHJ P,PGRSKD ;GET THE RESIDENT SPACE
|
||
JRST TPOPJ## ;NOT AVAILABLE?!
|
||
MOVEM T1,BSDVRT ;SAVE VIRTUAL ADDRESS OF START OF BSD CHAIN
|
||
POP P,T2 ;RESTORE NUMBER OF PAGES REQUESTED
|
||
MOVEM T2,BSDPGS ;SAVE FOR MEMORY OFFLINE CODE
|
||
LSH T2,P2WLSH ;HOW MANY WORDS WERE ALLOCATED
|
||
IDIVI T2,.BSSIZ ;COMPUTE HOW MANY BSD'S WILL FIT IN SPACE ALLOCATED
|
||
MOVEM T2,BSDNUM ;STORE FOR POSSIBLE FUTURE BSD RE-INIT
|
||
PJRST BSDLNK ;LINK ALL THE BSD'S AND RETURN
|
||
;ROUTINE TO CLEAR ALL BHD'S. CALLED BY BHDINI OR SET MEMORY OFFLINE
|
||
;CODE AFTER MEMORY HAS BEEN DIDDLED AS NECESSARY.
|
||
;CALL:
|
||
; PUSHJ P,BHDCLR
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
BHDCLR: MOVE T1,BHDIPT ;START OF BUFFER DESCRIPTOR TABLE
|
||
MOVEM T1,BHDCPT ;RESET CURRENT POINTER FOR BHD SEARCHES
|
||
MAP T2,0(T1) ;GET THE PHYSICAL ADDRESS FOR THE KLIPA
|
||
TXZ T2,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
MOVEM T2,BHDADR ;SAVE PHYSICAL ADDRESS OF BDT FOR PCBINI
|
||
MOVE T2,BHDNUM ;NUMBER OF BHD'S IN BDT
|
||
BHDCL1: SETZM .BHKEY(T1) ;ZERO VALID WORD
|
||
SETZM .BHBSA(T1) ;DITTO FOR POINTER TO FIRST BSD
|
||
ADDI T1,.BHSIZ ;ADVANCE POINTER
|
||
SOJG T2,BHDCL1 ;INITIALIZE ALL BHD'S
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;ROUTINE TO LINK ALL BSD'S. CALLED BY BHDINI OR SET MEMORY OFFLINE
|
||
;CODE AFTER MEMORY HAS BEEN DIDDLED AS NECESSARY.
|
||
;CALL:
|
||
; PUSHJ P,BSDLNK
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
BSDLNK: MOVE T1,BSDVRT ;GET VIRTUAL ADDRESS OF START OF BSD CHAIN
|
||
MAP T2,(T1) ;GET THE PHYSICAL ADDRESS
|
||
TXZ T2,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
MOVEM T2,BSDADR ;SAVE PHYSICAL ADDRESS OF START OF BSD CHAIN
|
||
MOVEM T2,BSDLOC ;ALSO SAVE AS START OF FREE BSD CHAIN
|
||
MOVE T2,BSDNUM ;NUMBER OF BSD'S WHICH WERE ALLOCATED
|
||
SUBI T2,1 ;MINUS ONE
|
||
BHDIN2: MAP T3,.BSSIZ(T1) ;GET PHYSICAL ADDRESS OF NEXT BSD
|
||
TXZ T3,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
MOVEM T3,.BSNXT(T1) ;LINK NEXT TO THIS
|
||
ADDI T1,.BSSIZ ;GET ADDRESS OF NEXT BSD
|
||
SOJG T2,BHDIN2 ;LOOP FOR ALL BSD'S
|
||
SETZM .BSNXT(T1) ;CLEAR LINK TO NEXT IN LAST BSD
|
||
POPJ P, ;RETURN
|
||
SUBTTL BHD/BSD MANIPULATION
|
||
|
||
|
||
;ROUTINE TO GET A BUFFER HEADER DESCRIPTOR.
|
||
;CALL:
|
||
; PUSHJ P,PPDGBH
|
||
;RETURN:
|
||
; CPOPJ IF NO FREE BHDS
|
||
; CPOPJ1 WITH:
|
||
; T1/ INDEX INTO BUFFER DESCRIPTOR TABLE
|
||
; T2/ VIRTUAL ADDRESS OF BHD
|
||
|
||
$XSENT (PPDGBH::)
|
||
SKIPN BSDLOC ;ANY FREE BSDS?
|
||
RETBAD (KLPX2) ;NO, NO SENSE IN TRYING
|
||
CIOFF ;PREVENT RACES
|
||
MOVE T1,BHDCPT ;GET CURRENT POINTER FOR BHD SEARCHES
|
||
PPDGH1: SKIPN .BHKEY(T1) ;THIS BHD FREE?
|
||
JRST PPDGH2 ;YES
|
||
XMOVEI T1,.BHSIZ(T1) ;ADDRESS OF NEXT BHD
|
||
CAML T1,BHDEND ;PAST THE END OF THE TABLE?
|
||
MOVE T1,BHDIPT ;YES, RESET TO BEGINNING
|
||
CAME T1,BHDCPT ;HAVE WE LOOPED OVER THE ENTIRE TABLE?
|
||
JRST PPDGH1 ;NO, KEEP LOOKING
|
||
RETBAD (KLPX1,<CION>) ;YOU LOSE
|
||
|
||
PPDGH2: MOVX T2,1B0 ;GET A TEMPORARY FLAG
|
||
IORM T2,.BHKEY(T1) ;(OVERWRITTEN WITH KEY LATER)
|
||
XMOVEI T2,.BHSIZ(T1) ;ADDRESS OF NEXT BHD
|
||
CAML T2,BHDEND ;PAST THE END OF THE TABLE?
|
||
MOVE T2,BHDIPT ;YES, RESET TO BEGINNING
|
||
MOVEM T2,BHDCPT ;WHERE TO RESUME SEARCHING
|
||
CION ;OK TO INTERRUPT
|
||
MOVE T2,T1 ;COPY THE BHD ADDRESS
|
||
SUB T1,BHDIPT ;COMPUTE INDEX INTO TABLE
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
|
||
;ROUTINE TO RETURN A BUFFER HEADER DESCRIPTOR.
|
||
;CALL:
|
||
; T1/ BUFFER NAME
|
||
; PUSHJ P,PPDRBH
|
||
;RETURN:
|
||
; CPOPJ ALWAYS WITH:
|
||
; T2/ ADDRESS OF FIRST BSD (IF ANY)
|
||
; T4/ CONTENTS OF .BHKEY WORD
|
||
|
||
$XSENT (PPDRBH::)
|
||
LDB T2,[POINT BHSIDX,T1,BHPIDX] ;GET INDEX INTO TABLE
|
||
CAML T2,BHDMTI ;INDEX WITHIN REASON?
|
||
STOPCD .,STOP,KLPBIO, ;++BHD TABLE INDEX OUT OF RANGE
|
||
MOVE T1,T2 ;COPY INDEX
|
||
ADD T1,BHDIPT ;COMPUTE VIRTUAL BHD ADDRESS
|
||
MOVE T2,.BHBSA(T1) ;SAVE POINTER TO ANY BSDS
|
||
MOVE T4,.BHKEY(T1) ;RETURN THE KEY WORD FOR ERROR CHECKING
|
||
SETZM .BHKEY(T1) ;MARK THIS BHD AS FREE
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO GET A BUFFER SEGMENT DESCRIPTOR.
|
||
;CALL:
|
||
; PUSHJ P,PPDGBD
|
||
;RETURN:
|
||
; CPOPJ IF NO FREE BSDS
|
||
; CPOPJ1 WITH:
|
||
; T1/ PHYSICAL ADDRESS OF BSD
|
||
; T2/ VIRTUAL ADDRESS OF BSD
|
||
|
||
$XSENT (PPDGBD::)
|
||
CIOFF ;PREVENT RACES
|
||
SKIPN T1,BSDLOC ;GET HEAD OF FREE LIST
|
||
RETBAD (KLPX2,<CION>) ;NONE FREE, RETURN ERROR
|
||
MOVE T2,T1 ;COPY ADDRESS
|
||
ADDI T2,.BSNXT ;OFFSET TO WORD WE WANT
|
||
PMOVE T2,T2 ;FETCH THE LINK WORD
|
||
;***
|
||
;SUPPOSED TO RESERVE 1 BHD/BSD FOR DIAGNOSTIC FOLKS' USE
|
||
;***
|
||
JUMPE T2,[JFCL ;DIAGNOSTIC?
|
||
JRST .+1 ;YES, GO AHEAD AND USE THIS BSD
|
||
RETBAD (KLPX2,<CION>)] ;NO, DON'T USE LAST BSD
|
||
MOVEM T2,BSDLOC ;NEW HEAD OF FREE LIST
|
||
MOVE T2,T1 ;COPY PHYSICAL BSD ADDRESS
|
||
SUB T2,BSDADR ;CALCULATE OFFSET FROM START OF AREA
|
||
ADD T2,BSDVRT ;MAKE THIS A VIRTUAL ADDRESS
|
||
PJRST CINPJ1## ;INTERRUPTS BACK ON AND SKIP RETURN
|
||
|
||
|
||
;ROUTINE TO RETURN A BUFFER SEGMENT DESCRIPTOR.
|
||
;CALL:
|
||
; T1/ PHYSICAL ADDRESS OF BSD
|
||
; PUSHJ P,PPDRBD
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XSENT (PPDRBD::)
|
||
CIOFF ;PREVENT RACES
|
||
MOVE T3,BSDLOC ;GET HEAD OF FREE LIST
|
||
MOVE T2,T1 ;COPY ADDRESS
|
||
ADDI T2,.BSNXT ;OFFSET TO WORD WE WANT
|
||
PMOVEM T3,T2 ;LINK THE FREE LIST TO THIS BSD
|
||
MOVEM T1,BSDLOC ;NEW HEAD OF THE FREE LIST
|
||
PJRST CIONPJ## ;INTERRUPTS BACK ON AND RETURN
|
||
;ROUTINE TO RETURN A BUFFER HEADER DESCRIPTOR AND ANY BUFFER SEGMENT
|
||
;DESCRIPTORS LINKED TO THE BHD.
|
||
;CALL:
|
||
; T1/ BUFFER NAME
|
||
; PUSHJ P,PPDRHD
|
||
;RETURN:
|
||
; CPOPJ ALWAYS WITH:
|
||
; T4/ CONTENTS OF .BHKEY WORD FROM BHD
|
||
|
||
$XSENT (PPDRHD::)
|
||
PUSHJ P,PPDRBH ;RETURN THE BHD
|
||
PUSH P,T4 ;SAVE THE KEY WORD FOR RETURN TO CALLER
|
||
SKIPA T4,T2 ;COPY ADDRESS OF FIRST BSD TO T4 AND SKIP
|
||
PPDRH1: PUSHJ P,PPDRBD ;RETURN THE BSD
|
||
SKIPN T1,T4 ;IS THERE A NEXT BSD?
|
||
JRST T4POPJ## ;NO, DONE
|
||
MOVE T2,T1 ;COPY ADDRESS
|
||
ADDI T2,.BSNXT ;OFFSET TO WORD WE WANT
|
||
PMOVE T2,T2 ;FETCH THE LINK
|
||
MOVE T4,T2 ;COPY NEXT BSD ADDRESS TO T4
|
||
JRST PPDRH1 ;RETURN THIS BSD
|
||
SUBTTL KLIPA CONFIGURATION
|
||
|
||
|
||
;ROUTINE CALLED FROM AUTCON
|
||
;LINKAGE:
|
||
; T1/ DEVICE CODE
|
||
; T2/ CONI BITS
|
||
; PUSHJ P,KLPCFG
|
||
;RETURNS:
|
||
; CPOPJ TO STOP SCANNING DRIVERS
|
||
; CPOPJ1 TO SCAN OTHER DRIVERS
|
||
|
||
$HIGH
|
||
|
||
KLPCFG: CAIL T1,FSTICD/4 ;AN RH20?
|
||
CAILE T1,LSTICD/4 ;...
|
||
JRST CPOPJ1## ;WRONG DRIVER
|
||
TLNN T2,(CI.PPT) ;IPA CHANNEL?
|
||
JRST CPOPJ1## ;NO
|
||
PUSHJ P,TYIPA## ;TRY TO DETERMINE THE PORT TYPE
|
||
JRST KLPCF1 ;CAN'T
|
||
CAIN T1,.CIKLP ;KLIPA?
|
||
JRST KLPCF2 ;YES
|
||
JRST CPOPJ1## ;ON TO THE NEXT DRIVER
|
||
|
||
KLPCF1: XMOVEI T1,KLPMDT## ;MONGEN'ED DEVICE TABLE
|
||
XMOVEI T2,DEFMDT ;DEFAULT TABLE
|
||
MOVNI T3,1 ;NO MASSBUS UNIT OR DRIVE INFORMATION
|
||
MOVEI T4,MD.KON ;MATCH ON KONTROLLER DEFINITION
|
||
PUSHJ P,AUTMDT## ;SCAN THE TABLES
|
||
JRST CPOPJ1## ;NO MATCHES
|
||
|
||
KLPCF2: MOVSI T1,CP.KLP ;KLIPA CHANNEL
|
||
PUSHJ P,AUTCHN## ;BUILD A CHANNEL DATA BLOCK
|
||
POPJ P, ;NO CORE
|
||
MOVNI T1,1 ;NOT MULTI-UNIT, BUT MUST DO ANYWAY
|
||
PUSHJ P,AUTKDB## ;BUILD A KDB
|
||
POPJ P, ;GIVE UP IF NO CORE
|
||
AOSE .PCOLD(W) ;BEEN HERE BEFORE?
|
||
POPJ P, ;YES--DO NOTHING OR I/O WILL STOP
|
||
|
||
MOVE T1,.CPCHA## ;GET CHANNEL DATA BLOCK ADDRESS
|
||
MOVEM T1,.PCCDB(W) ;SAVE IN THE PCB
|
||
|
||
HRRZ T1,@KDBCSO(W) ;ADDRESS OF CONI BITS TO TEST IN SKIP CHAIN
|
||
MOVEM T1,.PCBIT(W) ;UPDATE
|
||
MOVE T1,[KLPBTS] ;BITS TO TEST FOR ON INTERRUPT
|
||
MOVEM T1,@.PCBIT(W) ;SET IN THE CONSO SKIP CHAIN CODE
|
||
|
||
IFN FTMP,<
|
||
MOVE T1,.CPCPN## ;GET OUR CPU NUMBER
|
||
MOVEM T1,.PCCPU(W) ;SAVE FOR QUEUED I/O TESTS IN KLPSND
|
||
>; END IFN FTMP
|
||
MOVEI T1,DSKCHN## ;GET PI CHANNEL KLIPA WILL RESIDE ON
|
||
MOVEM T1,.PCPIA(W) ;STORE IN PCB
|
||
MOVX T1,C%MGSZ ;GET MAXIMUM MESSAGE SIZE
|
||
MOVEM T1,.PCMQE(W) ;STORE FOR THE KLIPA
|
||
MOVX T1,C%DGSZ ;GET MAXIMUM DATAGRAM SIZE
|
||
MOVEM T1,.PCDQE(W) ;STORE FOR THE KLIPA
|
||
; MOVX T1,C%RGSZ ;GET MAXIMUM RESERVED SIZE
|
||
; MOVEM T1,.PCRQE(W) ;STORE FOR THE KLIPA
|
||
PUSHJ P,IPAADB## ;ALLOCATE DRAM DUMP BUFFER
|
||
MOVE Q3,W ;SET UP PCB POINTER
|
||
XJRST [KLPCFH] ;FINISH IN EXTENDED HIGH SEGMENT
|
||
|
||
$XHIGH
|
||
|
||
KLPCFH: PUSHJ P,PCBINI ;INITIALIZE QUEUE STRUCTURES IN THE PCB
|
||
PJRST PPDINX ;LOAD MICROCODE, ETC.
|
||
SUBTTL KLIPA INITIALIZATION
|
||
|
||
|
||
;ROUTINE TO INITIALIZE THE KLIPA ON THIS CPU. MUST BE CALLED
|
||
;AFTER DSKCHN PI CHANNEL AND PI SYSTEM ARE TURNED ON.
|
||
;CALL:
|
||
; PUSHJ P,PPDINX
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XSENT (PPDINX::)
|
||
PUSHJ P,SAVPQ## ;SAVE LOTS OF ACS
|
||
XMOVEI P1,SYSCHN##-CHNSYS ;SET PREDECESSOR
|
||
MOVEI T1,CP.KLP ;KLIPA CHANNEL BITS
|
||
|
||
PPDIN1: MOVE P1,CHNSYS(P1) ;GET CHANNEL ADDRESS
|
||
HLRZS P1 ;ADDRESS IN LH QUANTITY
|
||
JUMPE P1,CPOPJ## ;THERE MUST BE ONE!
|
||
HLRZ T2,CHNTYP(P1) ;GET INTERESTING BITS
|
||
CAIE T1,(T2) ;A KLIPA?
|
||
JRST PPDIN1 ;TRY AGAIN
|
||
LDB T2,CHYCPU## ;GET CPU NUMBER
|
||
CAME T2,.CPCPN## ;OURS?
|
||
JRST PPDIN1 ;NO
|
||
MOVE T1,CHNTBP(P1) ;FETCH THE KDB (PCB) TABLE POINTER
|
||
SKIPN Q3,(T1) ;AND GET THE PORT CONTROL BLOCK
|
||
POPJ P, ;NO KLNI ON THIS CPU
|
||
PUSHJ P,PCBINI ;INITIALIZE THE PCB
|
||
SKIPE .CPPCB## ;RESTART?
|
||
SKIPN .PCFQC(Q3) ;YES, DO WE HAVE RESTOCK COUNTS?
|
||
JRST PPDIN2 ;RESTART OR NO RESTOCK COUNTS
|
||
PUSHJ P,RSTKQS ;RESTOCK THE QUEUES
|
||
JRST PPDIN3 ;CONTINUE
|
||
|
||
PPDIN2: MOVEM Q3,.CPPCB## ;STORE PCB ADDRESS IN CPU DATA BLOCK
|
||
PUSHJ P,STKDFQ ;STOCK THE DATAGRAM FREE QUEUE
|
||
|
||
;ENABLE THE KLIPA BUT DON'T GIVE IT ITS PI ASSIGNMENT YET
|
||
|
||
PPDIN3: SETZM .PCFQE(Q3) ;CLEAR COUNT OF FREE QUEUE ERRORS
|
||
SETOM .PCONN(Q3) ;WE DON'T KNOW OUR NODE NUMBER
|
||
MOVE T1,.CPBIT## ;GET OUR CPU'S BIT
|
||
TSNN T1,IPAMSK## ;WANT TO SKIP STARTING THE CI?
|
||
PUSHJ P,RLDKLI ;LOAD AND START KLIPA MICROCODE
|
||
POPJ P, ;FAILED, SKIP REST OF INITIALIZATION
|
||
|
||
;EMPTY THE RESPONSE QUEUE AND RETURN THE PACKET(S) TO THE FREE QUEUE(S)
|
||
|
||
PPDIN4: PUSHJ P,CLEANQ ;CLEAN OUT SOME RESPONSES
|
||
SKIPA ;NONE FOUND, DONE
|
||
JRST PPDIN4 ;FOUND SOME, LOOK FOR MORE
|
||
;ENABLE INTERRUPTS AND CLEAN UP ANY RESPONSES THAT COULD HAVE COME IN
|
||
;AFTER THE QUEUE WAS CLEANED UP
|
||
|
||
CONO PI,PI.OFF ;STOP INTERRUPTS
|
||
PUSHJ P,PIAKLP ;GIVE THE KLIPA A PI ASSIGNMENT
|
||
XCT KDBCNI(Q3) ;READ STATUS
|
||
TRNE T1,CI.RQA ;RESPONSE AVAILABLE?
|
||
JRST [MOVEI T1,CO.BTS+CO.RQA ;YES, CLEAR PI AND RESP AVAILABLE
|
||
XCT KDBCNO(Q3) ;...
|
||
CONO PI,PI.ON ;ENABLE INTERRUPTS
|
||
JRST PPDIN4] ;GO TOSS THE RESPONSES
|
||
CONO PI,PI.ON ;ENABLE INTERRUPTS
|
||
|
||
;FINISH INITIALIZATION STUFF USING COMMON ROUTINE
|
||
|
||
PJRST PPDCSS ;DO COMMON STARTUP STUFF
|
||
;ROUTINE TO REMOVE PACKETS FROM THE RESPONSE QUEUE AND RETURN
|
||
;THEM TO THE APPROPRIATE FREE QUEUE.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CLEANQ
|
||
;RETURN:
|
||
; CPOPJ IF DIDN'T FIND ANY
|
||
; CPOPJ1 IF FOUND SOME
|
||
|
||
CLEANQ: STKVAR <QEMPTY> ;ALLOCATE A WORD OF STACK STORAGE
|
||
SETZM QEMPTY ;AND ZERO IT
|
||
CLENQ1: MOVEI T1,CO.BTS!CO.RQA!CO.FQE ;RESP QUEUE AVAILABLE, FREE QUEUE ERR
|
||
XCT KDBCNO(Q3) ;CLEAR BITS
|
||
CLENQ2: XMOVEI T1,.PCRSQ(Q3) ;RESPONSE QUEUE
|
||
PUSHJ P,REMQUE ;REMOVE THE TOP PACKET
|
||
JRST CLENQ3 ;EMPTY, WE'RE DONE
|
||
AOS QEMPTY ;FOUND ONE, COUNT IT
|
||
PUSHJ P,RMASAG ;BYTE SWAP THE PPD BYTE
|
||
PUSHJ P,TOSSIT ;RETURN IT TO THE PROPER FREE QUEUE
|
||
JRST CLENQ2 ;LOOP FOR MORE
|
||
|
||
CLENQ3: XCT KDBCNI(Q3) ;READ STATUS
|
||
TRNE T1,CI.RQA ;SOMETHING SHOW UP WHILE WE WERE WORKING?
|
||
JRST CLENQ1 ;YES, GO GET IT
|
||
SKIPE QEMPTY ;DID WE GET ANY RESPONSES?
|
||
AOS (P) ;YES, SET FOR SKIP RETURN
|
||
POPJ P, ;RETURN
|
||
|
||
ENDSV. ;END OF STACK VARIABLE RANGE
|
||
|
||
|
||
;ROUTINE TO RETURN A PACKET TO THE PROPER FREE QUEUE.
|
||
;CALL:
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,TOSSIT
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
TOSSIT: MOVX T1,PK.SRB ;CLEAR ALL SOFTWARE RESPONSE BITS
|
||
ANDCAM T1,.PKVRT(Q2) ;...
|
||
LDB T1,PKYOP ;OP CODE
|
||
TXZ T1,OP.RMT ;MINUS REMOTE BIT
|
||
CAIE T1,OP.SMS ;IS IT A MESSAGE?
|
||
PJRST RETDG ;NO, RETURN THE DATAGRAM
|
||
PJRST RETMSG ;RETURN THE MESSAGE
|
||
SUBTTL PCB INITIALIZATION
|
||
|
||
|
||
;ROUTINE TO INITIALIZE A PCB.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,PCBINI
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
;
|
||
;NOTE: PCBINI SHOULD INITIALIZE ANY INFORMATION IN THE PCB WHICH
|
||
;MIGHT CHANGE IF THE PCB IS MOVED IN PHYSICAL MEMORY. CONSTANTS
|
||
;(SUCH AS MAXIMUM DG/MSG SIZE) SHOULD BE SET AT PPDINX.
|
||
|
||
PCBINI: SKIPN T1,BHDADR ;GET PHYSICAL ADDR OF BUFFER DESCRIPTOR TABLE
|
||
BUG. (HLT,KLPNBD,KLPSER,SOFT,<No buffer descriptor table>,,)
|
||
MOVEM T1,.PCBDT(Q3) ;STORE FOR THE KLIPA
|
||
MAP T1,.PCPCB(Q3) ;DETERMINE PHYSICAL ADDRESS OF PCB
|
||
TXZ T1,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
MOVEM T1,.PCPBA(Q3) ;STORE PHYSICAL PCB ADDRESS FOR THE KLIPA
|
||
MOVX T1,ST.DED ;INITIALLY IT IS ASSUMED TO BE DEAD
|
||
IORM T1,.PCSTS(Q3) ; WILL GET CLEARED WHEN RESTARTED
|
||
LDB T1,[POINT 3,KDBDVC(Q3),35] ;GET RH20 NUMBER
|
||
LSH T1,2 ;COMPUTE EPT OFFSET TO CHANNEL LOGOUT AREA
|
||
ADD T1,.CPEPT## ;PLUS ADDRESS OF EPT
|
||
MOVEM T1,.PCLGO(Q3) ;STORE IN PORT CONTROL BLOCK
|
||
MAP T1,.CSCLP(T1) ;GET PHYSICAL ADDRESS OF CHANNEL LOGOUT WORD 1
|
||
TXZ T1,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
MOVEM T1,.PCAL1(Q3) ;STORE IT FOR THE KLIPA
|
||
PJRST RSTQS ;RESET PCB QUEUES AND RETURN
|
||
SUBTTL INTERRUPT SERVICE
|
||
|
||
|
||
;DISPATCH HERE FROM THE CONSO SKIP CHAIN ON A KLIPA INTERRUPT.
|
||
;THE SKIP CHAIN CODE HAS ALREADY SAVED ALL ACS, AND LOADED T1
|
||
;WITH THE CONI STATUS BITS AND T2 WITH THE ADDRESS OF THE PORT
|
||
;CONTROL BLOCK.
|
||
|
||
KLPINT::MOVX T2,ST.MAI ;SEE IF IN MAINTENANCE MODE
|
||
TDNE T2,.PCSTS(W) ;...
|
||
POPJ P, ;YES, DON'T GET IN THE WAY
|
||
MOVE Q3,W ;COPY PCB ADDRESS TO "STANDARD" REGISTER
|
||
MOVEM T1,.PCCSR(Q3) ;SAVE CONI STATUS FOR LATER EXAMINATION
|
||
TXNN T1,CI.CPE!CI.MER ;CRAM PARITY ERROR OR MBUS ERROR?
|
||
JRST KLPIN1 ;NO
|
||
PUSHJ P,REPORT ;MAKE ERROR.SYS ENTRY
|
||
MOVX T1,CI.CPE ;GET CRAM PARITY ERROR BIT
|
||
TDNE T1,.PCCSR(Q3) ;CRAM PARITY ERROR?
|
||
PUSHJ P,KLECPE ;OUTPUT DESCRIPTIVE TEXT
|
||
PUSHJ P,NONODS ;TELL SCA ABOUT NODES GOING AWAY
|
||
PUSHJ P,RSTLKS ;RESET THE PCB QUEUE INTERLOCKS
|
||
PUSHJ P,RSTRID ;RESET REQUEST-ID DATA
|
||
MOVX T1,CI.CPE ;GET CRAM PARITY ERROR BIT
|
||
TDNE T1,.PCCSR(Q3) ;CRAM PARITY ERROR?
|
||
PUSHJ P,KLPCPD ;YES (KLPCPD MAY CALL KLPRQC)
|
||
MOVX T1,CI.MER ;GET MBUS ERROR BIT
|
||
TDNE T1,.PCCSR(Q3) ;MBUS ERROR?
|
||
PUSHJ P,KLPMBD ;YES (KLPRQC WON'T BE CALLED)
|
||
POPJ P, ;DISMISS THE INTERRUPT
|
||
|
||
;NEITHER A CRAM PARITY ERROR OR AN MBUS ERROR
|
||
|
||
KLPIN1: TXNE T1,CI.RQA ;RESPONSE QUEUE AVAILABLE?
|
||
PUSHJ P,KLPRQA ;YES, PROCESS THE PACKETS
|
||
MOVX T1,CI.FQE ;GET FREE QUEUE ERROR BIT
|
||
TDNE T1,.PCCSR(Q3) ;FREE QUEUE ERROR?
|
||
PUSHJ P,KLPFQE ;YES, FIND OUT WHICH ONE
|
||
POPJ P, ;DISMISS THE INTERRUPT
|
||
;ROUTINE CALLED WHEN RESPONSE QUEUE IS AVAILABLE.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,KLPRQA
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
;COMMON USE OF THE ACS IN KLPRQA:
|
||
; Q1/ CI NODE NUMBER
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; P1/ PCB ADDRESS OFFSET BY CI NODE NUMBER
|
||
; P2/ OPCODE FROM PACKET
|
||
; P3/ -1 IF LOCALLY GENERATED, 0 IF REMOTELY GENERATED
|
||
; P4/ SBK ADDRESS
|
||
; P5/ PBK ADDRESS
|
||
; P6/ PPD BYTE
|
||
|
||
KLPRQC: MOVEI T1,CO.EPE!CO.RQA ;RESPONSE AVAILABLE, EBUS PARITY
|
||
XCT KDBCNO(Q3) ;CLEAR BITS
|
||
JRST KLPRQ1 ;JOIN COMMON CODE
|
||
|
||
KLPRQA: MOVE T1,.PCPIA(Q3) ;GET KLIPA PI ASSIGNMENT
|
||
TRO T1,CO.EPE!CO.RQA!CO.BTS ;PLUS RESPONSE AVAILABLE & EBUS PARITY
|
||
XCT KDBCNO(Q3) ;CLEAR BITS
|
||
|
||
KLPRQ1: XMOVEI T1,.PCRSQ(Q3) ;WHICH QUEUE
|
||
PUSHJ P,REMQUE ;REMOVE FIRST PACKET FROM QUEUE
|
||
POPJ P, ;QUEUE IS EMPTY, DISMISS INTERRUPT AND RETURN
|
||
|
||
SNOOP (CISPKR) ;CISNUP SNOOP POINT - PACKET RECEIVED
|
||
;Q2/ PACKET ADDRESS
|
||
;Q3/ PCB ADDRESS
|
||
|
||
MOVE T1,.CPUPT## ;GET CPU UPTIME
|
||
MOVEM T1,.PCKRT(Q3) ;REMEMBER WHEN LAST PACKET WAS RECEIVED
|
||
PUSHJ P,RMASAG ;SWAP THE PPD BYTE AND ADJUST LENGTH
|
||
LDB Q1,PKYNOD ;GET CI NODE NUMBER
|
||
CAIL Q1,0 ;A LEGAL CI
|
||
CAIL Q1,MAXNDS ; NODE NUMBER?
|
||
JRST KLPRQ6 ;NODE NUMBER OUT OF RANGE
|
||
MOVE P1,Q3 ;GET PCB ADDRESS
|
||
ADD P1,Q1 ; OFFSET FOR THIS NODE
|
||
LDB P2,PKYOP ;GET OP CODE
|
||
TXZE P2,OP.RMT ;REMOTELY GENERATED?
|
||
TDZA P3,P3 ;YES, CLEAR P3 (LOCALLY GENERATED FLAG) AND SKIP
|
||
SETO P3, ;NO, SAY LOCALLY GENERATED
|
||
MOVE P4,.PCSBK(P1) ;GET THE SYSTEM BLOCK ADDRESS
|
||
MOVE P5,.PCPBK(P1) ;GET THE PATH BLOCK ADDRESS
|
||
;HERE TO DISPATCH THE PACKET BASED ON OP CODE (IN P2)
|
||
|
||
MOVSI T2,-KLPOPL ;GET LENGTH OF TABLE FOR OPCODE SEARCH
|
||
KLPRQ2: CAMN P2,KLPOPS(T2) ;THIS THE ONE?
|
||
JRST KLPRQ3 ;YES, GO TO IT
|
||
AOBJN T2,KLPRQ2 ;NO, TRY NEXT ONE
|
||
LDB T1,PKYSTS ;GET STATUS
|
||
LDB T2,PKYFLG ;GET FLAGS
|
||
BUG. (INF,KLPOPC,KLPSER,SOFT,<Packet with bad opcode>,<<P2,OPCODE>,<T1,STATUS>,<T2,FLAGS>,<Q1,NODE>>,)
|
||
PUSHJ P,RETMSG ;RETURN PACKET TO MESSAGE FREE QUEUE
|
||
JRST KLPRQ1 ;TRY FOR ANOTHER
|
||
|
||
;ALL ACS ARE SET UP AT THIS POINT EXCEPT FOR THE PPD BYTE.
|
||
;T2 CONTAINS THE DISPATCH INDEX.
|
||
|
||
KLPRQ3: SETO P6, ;NO PPD BYTE
|
||
MOVE T1,.PKSTS(Q2) ;GET PACKET STATUS WORD
|
||
TXNN T1,PS.ERR!PS.CLO ;ERRORS OR PATH CLOSED?
|
||
JRST KLPRQ5 ;NO
|
||
TXNN T1,PS.ERR ;YES, ERROR?
|
||
JRST KLPRQ4 ;NO, PATH CLOSED
|
||
PUSHJ P,@KLPERB(T2) ;DO ERROR PROCESSING
|
||
JRST KLPRQ1 ;GO FOR NEXT PACKET
|
||
|
||
KLPRQ4: PUSH P,T2 ;SAVE INDEX INTO DISPATCH TABLES
|
||
PUSHJ P,CLOPTH ;PATH CLOSED, UPDATE PATH INFO
|
||
POP P,T2 ;RESTORE DISPATCH INDEX
|
||
MOVX T1,PK.SRB ;WERE WE EXPECTING A RESPONSE?
|
||
TDNE T1,.PKVRT(Q2) ;...
|
||
JRST KLPRQ5 ;YES
|
||
PUSHJ P,@KLPRET(T2) ;RETURN THE PACKET
|
||
JRST KLPRQ1 ;GO FOR NEXT PACKET
|
||
|
||
KLPRQ5: PUSHJ P,@KLPROU(T2) ;PROCESS THE PACKET
|
||
JRST KLPRQ1 ;GO FOR NEXT PACKET
|
||
|
||
|
||
;THE CI NODE NUMBER IN THE RECEIVED PACKET IS BAD
|
||
|
||
KLPRQ6: LDB T1,PKYSTS ;GET STATUS
|
||
LDB T2,PKYFLG ;GET FLAGS
|
||
LDB T3,PKYOP ;GET OPCODE
|
||
BUG. (INF,KLPNDE,KLPSER,SOFT,<Packet with bad node number>,<<Q1,NODE>,<T1,STATUS>,<T2,FLAGS>,<T3,OPCODE>>,)
|
||
PUSHJ P,TOSSIT ;RETURN TO APPROPRIATE FREE QUEUE
|
||
JRST KLPRQ1 ;TRY FOR ANOTHER RESPONSE
|
||
;ROUTINE TO PROCESS A PACKET RECEIVED WITH THE PATH CLOSED BIT SET.
|
||
;CALL:
|
||
; T1/ PACKET STATUS WORD
|
||
; Q1/ NODE NUMBER
|
||
; Q2/ PACKET ADDRESS
|
||
; P1/ PCB ADDRESS OFFSET BY CI NODE NUMBER
|
||
|
||
CLOPTH: PUSHJ P,SAVQ## ;SAVE REGISTERS WHICH WILL GET STEPPED ON
|
||
STKVAR <AFLAG> ;ALLOCATE A WORD OF STACK STORAGE
|
||
SETZM AFLAG ;ASSUME ACKED ON PATH A
|
||
TXNE T1,PS.AKA ;ACKED ON PATH A?
|
||
SETOM AFLAG ;NO, REMEMBER THAT
|
||
MOVX T1,RI.PBO ;ASSUME ACKED ON PATH A (I.E., PATH B CLOSED)
|
||
SKIPE AFLAG ;RIGHT GUESS?
|
||
MOVX T1,RI.PAO ;NO, SO PATH A WAS CLOSED
|
||
ANDCAM T1,.PCRIS(P1) ;CLEAR THE BIT
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
POPJ P, ;CAN'T, MUST WAIT FOR POLLER
|
||
MOVX T3,PF.PT0 ;ASSUME PATH A WAS CLOSED
|
||
SKIPE AFLAG ;WAS IT?
|
||
MOVX T3,PF.PT1 ;NO, PATH B
|
||
PJRST KLPRID ;SEND A REQUEST-ID AND RETURN
|
||
|
||
ENDSV. ;END OF STACK VARIABLE RANGE
|
||
;MACRO TO DEFINE OPCODE AND CORRESPONDING DISPATCH ROUTINE.
|
||
;ALSO INCLUDES DISPATCH FOR PACKETS WITH ERRORS AND THE
|
||
;PATH CLOSED BIT ON.
|
||
|
||
DEFINE OPS,<
|
||
|
||
DISP OP.SMS,GIVSCA,GIVERR,RETMSG ;SEND MESSAGE
|
||
DISP OP.SDG,INTDG,DGERR,RETDG ;SEND DATAGRAM
|
||
DISP OP.RCF,INTNBF,NBFERR,RETMSG ;DATA CONFIRM RECEIVED
|
||
DISP OP.RDT,INTNBF,NBFERR,RETMSG ;RETURN DATA (DATREC)
|
||
DISP OP.RID,INTRID,RIDERR,RETDG ;REQUEST-ID
|
||
DISP OP.IDR,INTIDR,RETDG,RETDG ;ID RECEIVED
|
||
DISP OP.LPB,INTLPB,LPBERR,RETDG ;SEND/RECEIVE LOOPBACK
|
||
DISP OP.RD1,INTRD1,RD1ERR,RETMSG ;REQUEST DATA ON COMMAND QUEUE 1
|
||
DISP OP.CKT,INTCKT,CKTERR,RETDG ;SET VIRTUAL CIRCUIT
|
||
DISP OP.RCT,INTRCT,RCTERR,RETDG ;READ STATISTICS COUNTERS
|
||
DISP OP.MCR,INTMCR,MCRERR,RETDG ;MAINTENANCE CONFIRM RECEIVED
|
||
DISP OP.MDR,INTMDR,MDRERR,RETDG ;MAINTENANCE DATA RECEIVED
|
||
DISP OP.RRG,INTRRG,RRGERR,RETDG ;READ REGISTER
|
||
DISP OP.RD0,INTRD0,RD0ERR,RETMSG ;REQUEST DATA ON COMMAND QUEUE 0
|
||
DISP OP.RD2,INTRD2,RD2ERR,RETMSG ;REQUEST DATA ON COMMAND QUEUE 2
|
||
DISP OP.SDT,INTSDT,SDTERR,RETMSG ;SEND DATA
|
||
DISP OP.RRS,RETDG,RETDG,RETDG ;RESET REMOTE SYSTEM
|
||
DISP OP.SRS,RETDG,RETDG,RETDG ;START REMOTE SYSTEM
|
||
DISP OP.RMD,RETDG,RETDG,RETDG ;REQUEST MAINTENANCE DATA
|
||
DISP OP.SMD,RETDG,RETDG,RETDG ;SEND MAINTENANCE DATA
|
||
DISP OP.SPT,RETDG,RETDG,RETDG ;SET STATISTICS COUNTERS
|
||
DISP OP.WRG,RETDG,RETDG,RETDG ;WRITE REGISTER
|
||
DISP OP.CLB,INTCLB,CLBERR,RETDG ;CLOSE BUFFER
|
||
|
||
>; END DEFINE OPS
|
||
;GENERATE OPCODE LOOKUP TABLE
|
||
|
||
DEFINE DISP(CODE,ROU,ERB,RET),<
|
||
CODE
|
||
>; END DEFINE DISP
|
||
|
||
KLPOPS: OPS ;GENERATE OPCODE LOOKUP TABLE
|
||
KLPOPL==.-KLPOPS ;LENGTH OF TABLE
|
||
|
||
;GENERATE PARALLEL DISPATCH TABLE
|
||
|
||
DEFINE DISP(CODE,ROU,ERB,RET),<
|
||
IFIW ROU
|
||
>; END DEFINE DISP
|
||
|
||
KLPROU: OPS ;GENERATE DISPATCH TABLE
|
||
|
||
;GENERATE PARALLEL DISPATCH TABLE FOR PACKETS WITH ERROR BIT ON
|
||
|
||
DEFINE DISP(CODE,ROU,ERB,RET),<
|
||
IFIW ERB
|
||
>; END DEFINE DISP
|
||
|
||
KLPERB: OPS
|
||
|
||
;GENERATE PARALLEL DISPATCH TABLE FOR PACKETS WITH ERROR BIT OFF
|
||
;BUT THE CLOSED PATH BIT ON AND NO RESPONSE WAS REQUESTED
|
||
|
||
DEFINE DISP(CODE,ROU,ERB,RET),<
|
||
IFIW RET
|
||
>; END DEFINE DISP
|
||
|
||
KLPRET: OPS
|
||
;RECEIVED EITHER AN APPLICATION DATAGRAM OR AN APPLICATION MESSAGE
|
||
|
||
GIVSCA: JUMPN P5,GIVSC1 ;PROCEED IF HAVE A PATH BLOCK
|
||
LDB T1,PKYSTS ;GET STATUS
|
||
LDB T2,PKYFLG ;GET FLAGS
|
||
BUG. (INF,KLPIPA,KLPSER,SOFT,<Invalid packet arrived>,<<T1,STATUS>,<T2,FLAGS>,<P2,OPCODE>,<Q1,NODE>>,)
|
||
CAIN P2,OP.SDG ;A DATAGRAM?
|
||
PJRST RETDG ;YES, RETURN TO DATAGRAM FREE QUEUE
|
||
PJRST RETMSG ;NO, RETURN TO MESSAGE FREE QUEUE
|
||
|
||
GIVSC1: JUMPN P3,GV2SCA ;JUMP IF LOCALLY GENERATED
|
||
LOAD T1,PBVCST,(P5) ;GET VIRTUAL CIRCUIT STATE
|
||
CAIE T1,VC.STR ;START-RECEIVED?
|
||
JRST GV2SCA ;NO
|
||
SETZM .PBSST(P5) ;TURN OFF START SEQUENCE TIMER
|
||
PUSHJ P,OPNSCA ;TELL SCA ABOUT NEW NODE
|
||
;FALL INTO GV2SCA
|
||
;HERE TO ACTUALLY HAND THE PACKET TO SCA.
|
||
;CALL:
|
||
; Q2/ PACKET ADDRESS
|
||
; P3/ FLAGS
|
||
; P5/ PBK ADDRESS
|
||
|
||
GV2SCA: MOVX T1,PK.SCA ;SCA REQUEST A RESPONSE?
|
||
TDNN T1,.PKVRT(Q2) ;...
|
||
JRST GV2SC1 ;NO
|
||
SKIPL P3 ;YES, THIS SHOULD BE LOCALLY GENERATED, THEN
|
||
BUG. (INF,KLPIRP,KLPSER,HARD,<Software response bit on in remotely-generated packet>,<<Q1,NODE>,<T1,STATUS>>,)
|
||
MOVX P3,F.RSP ;TELL SCA THIS IS A RETURNED BUFFER
|
||
MOVX T1,PK.SRB ;CLEAR ALL SOFTWARE RESPONSE BITS
|
||
ANDCAM T1,.PKVRT(Q2) ;...
|
||
JRST GV2SC2 ;PROCEED
|
||
|
||
GV2SC1: JUMPE P3,GV2SC2 ;NO RESPONSE REQUESTED, THIS SHOULD BE REMOTE THEN
|
||
|
||
;THE PORT SHOULDN'T HAVE GIVEN US THIS BUFFER. SCASER DOESN'T
|
||
;WANT IT, SO PUT IT BACK ON THE FREE QUEUE.
|
||
|
||
BUG. (INF,KLPILP,KLPSER,HARD,<Software response bit off in locally-generated packet>,<<Q1,NODE>,<T1,STATUS>>,)
|
||
CAIN P2,OP.SDG ;IS THIS A DATAGRAM?
|
||
PJRST RETDG ;YES, RETURN TO DATAGRAM FREE QUEUE
|
||
PJRST RETMSG ;NO, RETURN TO MESSAGE FREE QUEUE
|
||
|
||
GV2SC2: MOVE T1,.PKSTS(Q2) ;GET STATUS FLAGS
|
||
LDB T2,PKYLEN ;GET THE PACKET LENGTH
|
||
TXNN T1,PF.FMT ;HIGH DENSITY?
|
||
JRST GV2SC3 ;NO
|
||
TXO P3,F.SPM ;YES, SET FLAG
|
||
MOVEI T2,3(T2) ;ROUND UP BYTE COUNT IN CASE OF PARTIAL WORD
|
||
IMULI T2,2 ;CONVERT BYTE COUNT TO WORD COUNT
|
||
IDIVI T2,^D9 ; (BYTE COUNT/4.5) = WORD COUNT
|
||
GV2SC3: LOAD T1,PBPBI,(P5) ;GET THE PATH BLOCK INDEX
|
||
BLCAL. (SC.INT##,<T1,Q2,T2,P3>) ;TELL SCA
|
||
POPJ P, ;RETURN
|
||
;RECEIVED A PACKET FOR SCA WITH THE ERROR FLAG SET
|
||
|
||
GIVERR: JUMPE P3,GIVER1 ;IF REMOTELY-GENERATED, WE'RE DONE
|
||
MOVX T1,PK.SCA ;WAS A RESPONSE REQUESTED?
|
||
TDNE T1,.PKVRT(Q2) ;...
|
||
JRST GIVER2 ;NO
|
||
|
||
;ERROR IN A REMOTELY-GENERATED PACKET, OR IN A LOCALLY-GENERATED
|
||
;PACKET AND NO RESPONSE WAS REQUESTED
|
||
|
||
GIVER1: CAIN P2,OP.SDG ;IS IT A DATAGRAM?
|
||
PJRST RETDG ;YES, RETURN IT TO FREE QUEUE
|
||
PUSHJ P,SCAERR ;NO, A MESSAGE, REPORT THE FAILURE
|
||
PJRST RETMSG ;RETURN IT TO FREE QUEUE
|
||
|
||
;ERROR IN A LOCALLY-GENERATED PACKET AND A RESPONSE WAS REQUESTED
|
||
|
||
GIVER2: CAIN P2,OP.SMS ;IS IT A MESSAGE?
|
||
PUSHJ P,SCAERR ;YES, SPEAR ENTRY, TELL SCA
|
||
PJRST GV2SCA ;GIVE THE PACKET TO SCA
|
||
;WE GOT A PACKET FOR SCA WITH AN ERROR AND IT WILL CLOSE AN OPEN VC.
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; P5/ PBK ADDRESS
|
||
|
||
SCAERR: LOAD T1,PBVCST,(P5) ;GET VIRTUAL CIRCUIT STATE
|
||
CAIE T1,VC.OPN ;OPEN?
|
||
POPJ P, ;NO, DON'T NEED TO REPORT ANYTHING
|
||
LDB T1,PKYSTS ;GET STATUS
|
||
LDB T2,PKYFLG ;GET FLAGS
|
||
LDB T3,PKYOP ;GET OPCODE
|
||
BUG. (INF,KLPERR,KLPSER,SOFT,<Received packet with error>,<<T1,STATUS>,<T2,FLAGS>,<T3,OPCODE>,<Q1,NODE>>,)
|
||
SAVEAC (Q2) ;PRESERVE EXISTING PACKET ADDRESS
|
||
SETZB Q2,P4 ;WE NEED A BUFFER TO DO THE SET CIRCUIT
|
||
PJRST CLOSV1 ;CLOSE THE VC, TELL SCA, AND RETURN
|
||
;RECEIVED A DATAGRAM
|
||
|
||
INTDG: PUSHJ P,CHKPPD ;CHECK THE PPD BYTE
|
||
PJRST RETDG ;BAD PPD, RETURN PACKET TO FREE QUEUE AND RETURN
|
||
PJRST @DGDSP(P6) ;PROCESS THE PACKET AND RETURN
|
||
|
||
DGDSP: IFIW INTSTR ;START
|
||
IFIW INTSTK ;STACK
|
||
IFIW INTACK ;ACK
|
||
IFIW GIVSCA ;APPLICATION DATAGRAM
|
||
IFIW CHKPP1 ;APPLICATION MESSAGE (OPCODE/PPD BYTE MISMATCH)
|
||
IFIW INTERP ;ERROR PACKET
|
||
IFIW INTSHT ;SHUTDOWN
|
||
|
||
|
||
;RECEIVED A DATAGRAM WITH AN ERROR
|
||
|
||
DGERR: PUSHJ P,CHKPPD ;CHECK THE PPD BYTE
|
||
PJRST RETDG ;BAD PPD, RETURN PACKET TO FREE QUEUE AND RETURN
|
||
PJRST @DGEDSP(P6) ;PROCESS THE PACKET AND RETURN
|
||
|
||
DGEDSP: IFIW RETDG ;START
|
||
IFIW RETDG ;STACK
|
||
IFIW RETDG ;ACK
|
||
IFIW GIVERR ;APPLICATION DATAGRAM
|
||
IFIW CHKPP1 ;APPLICATION MESSAGE (OPCODE/PPD BYTE MISMATCH)
|
||
IFIW ERPERR ;ERROR PACKET
|
||
IFIW RETDG ;SHUTDOWN WHICH FAILED
|
||
;HERE ON RECEIPT OF A START DATAGRAM
|
||
|
||
INTSTR: JUMPN P5,INTSR1 ;MUST HAVE BOTH A SYSTEM BLOCK AND PATH BLOCK
|
||
; TO HANDLE THE START
|
||
PUSHJ P,CHKIDT ;REQUEST-ID TIMER RUNNING?
|
||
PJRST RETDG ;YES, ONE OUTSTANDING IS ENOUGH
|
||
PUSHJ P,GTCPTH ;GET CURRENT PATH
|
||
PJRST KLPRID ;SEND A REQUEST-ID IN THIS PACKET AND RETURN
|
||
|
||
INTSR1: PUSHJ P,FILLSB ;FILL IN THE SYSTEM BLOCK
|
||
LOAD T1,PBVCST,(P5) ;GET VIRTUAL CIRCUIT STATE
|
||
PJRST @STRDSP(T1) ;GO DO THE WORK
|
||
|
||
STRDSP: IFIW RETDG ;CLOSED
|
||
IFIW STRSSN ;START-SENT
|
||
IFIW STRSTR ;START-RECEIVED
|
||
IFIW STROPN ;OPEN
|
||
|
||
|
||
;ROUTINE TO COPY DATA FROM THE START PACKET TO THE SYSTEM BLOCK.
|
||
|
||
FILLSB: MOVEI T1,.SBBLE-.SBDSA ;AMOUNT OF DATA TO MOVE
|
||
XMOVEI T2,.SRSSY(Q2) ;FROM THE PACKET
|
||
XMOVEI T3,.SBDSA(P4) ; TO THE SYSTEM BLOCK
|
||
EXTEND T1,[XBLT] ;FILL IN THE DATA
|
||
MOVE T1,.SBMMS(P4) ;GET MAXIMUM MESSAGE SIZE
|
||
PUSHJ P,REVFUL ;REVERSE THE BYTES TO MAKE THEM MEANINGFUL
|
||
MOVEM T1,.SBMMS(P4) ;PUT IT BACK
|
||
POPJ P, ;RETURN
|
||
;RECEIVED A START WHEN IN EITHER START-SENT OR START-RECEIVED STATE.
|
||
;RESET THE TIMER, NEW STATE IS START-RECEIVED, AND SEND A STACK.
|
||
|
||
STRSSN: PUSHJ P,KLPOPN ;TELL PORT TO OPEN ITS CIRCUIT
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
JRST STRST1 ;NO BIG DEAL, JUST LIKE THE STACK GETTING LOST
|
||
STRSTR: MOVEI T1,PP.STK ;GET STACK CODE
|
||
PUSHJ P,STRTDT ;MAKE A STACK
|
||
PUSHJ P,KLPSDG ;SEND IT
|
||
STRST1: MOVEI T1,VC.STR ;GET START-RECEIVED CODE
|
||
STOR T1,PBVCST,(P5) ;UPDATE STATE
|
||
PJRST STSST ;SET TIMER AND RETURN
|
||
|
||
|
||
;RECEIVED A START WHEN IN OPEN STATE.
|
||
;CLOSE VC AND TELL SCA OF THE ERROR.
|
||
|
||
STROPN: BUG. (INF,KLPSWO,KLPSER,SOFT,<Received a START when VC was open>,<<Q1,NODE>>,)
|
||
SETZ P4, ;WE NEED TO SEND A SETCKT
|
||
PJRST CLOSV1 ;CLOSE THE VC AND TELL SCA
|
||
;RECEIVED A STACK
|
||
|
||
INTSTK: PUSHJ P,FILLSB ;FILL IN THE SYSTEM BLOCK
|
||
LOAD T1,PBVCST,(P5) ;GET VIRTUAL CIRCUIT STATE
|
||
PJRST @STKDSP(T1) ;GO DO THE WORK
|
||
|
||
STKDSP: IFIW RETDG ;CLOSED
|
||
IFIW STKSTS ;START-SENT
|
||
IFIW STKSTR ;START-RECEIVED
|
||
IFIW STKOPN ;OPEN
|
||
|
||
|
||
;RECEIVED A STACK WHEN IN START-SENT OR START-RECEIVED STATE.
|
||
;STOP TIMER, SEND ACK, NEW STATE IS OPEN.
|
||
|
||
STKSTS: PUSHJ P,KLPOPN ;TELL PORT TO OPEN ITS CIRCUIT
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
JRST STKST1 ;NO SWEAT, JUST LIKE ACK GETTING LOST
|
||
STKSTR: MOVEI T1,PP.ACK ;GET ACK CODE
|
||
DPB T1,PKYPPD ;STORE PPD BYTE
|
||
PUSHJ P,KLPSDG ;SEND THE DATAGRAM
|
||
STKST1: SETZM .PBSST(P5) ;TURN OFF THE TIMER
|
||
PJRST OPNSCA ;TELL SCA ABOUT THE NEW PATH
|
||
|
||
|
||
;RECEIVED A STACK WHEN IN OPEN STATE. SEND AN ACK.
|
||
|
||
STKOPN: MOVEI T1,PP.ACK ;GET ACK CODE
|
||
DPB T1,PKYPPD ;PUT IT IN
|
||
PJRST KLPSDG ;SEND IT AND RETURN
|
||
;RECEIVED AN ACK
|
||
|
||
INTACK: LOAD T1,PBVCST,(P5) ;GET STATE OF VC
|
||
PJRST @ACKDSP(T1) ;GO DO THE WORK
|
||
|
||
ACKDSP: IFIW RETDG ;CLOSED
|
||
IFIW RETDG ;START-SENT
|
||
IFIW ACKSTR ;START-RECEIVED
|
||
IFIW RETDG ;OPEN
|
||
|
||
;RECEIVED AN ACK WHEN IN START-RECEIVED STATE. STOP TIMER AND
|
||
;SET NEW STATE TO OPEN.
|
||
|
||
ACKSTR: SETZM .PBSST(P5) ;TURN OFF THE START SEQUENCE TIMER
|
||
PJRST OPNSCA ;TELL SCA ABOUT THE NEW PATH
|
||
;RECEIVED AN ERROR LOG PACKET
|
||
|
||
INTERP: LDB P4,PKYLEN ;GET LENGTH OF PACKET IN BYTES
|
||
ADDI P4,3 ;ROUND ODD BYTES TO AN EVEN NUMBER OF WORDS
|
||
LSH P4,-2 ;...
|
||
ADDI P4,KE%LEN ;INCLUDE THE ADDITIONAL WORD(S) WE SUPPLY
|
||
MOVE T1,P4 ;COPY LENGTH REQUIRED TO T1
|
||
PUSHJ P,ALCSEB## ;ALLOCATE A SYSTEM ERROR BLOCK
|
||
PJRST RETDG ;NOT AVAILABLE, JUST TOSS PACKET
|
||
MOVEI T2,SEC%KE ;GET THE BLOCK TYPE
|
||
DPB T2,[POINT 9,.EBTYP(T1),8] ;STORE IN HEADER
|
||
MOVE T2,Q1 ;COPY THE SOURCE NODE NUMBER
|
||
LDB T3,[POINT 3,KDBDVC(Q3),35] ;GET RH20 NUMBER
|
||
DPB T3,[POINTR (T2,KE%CHN)] ;INCLUDE INTERNAL CHANNEL NUMBER
|
||
MOVEM T2,.EBHDR+KE%SRC(T1) ;STORE IN BODY
|
||
MOVEI T2,-KE%ELG(P4) ;NUMBER OF WORDS TO MOVE (EXCLUDING HEADER)
|
||
XMOVEI T3,.PKLEN+1(Q2) ;SOURCE
|
||
MOVEI T4,.EBHDR+KE%ELG(T1) ;DESTINATION
|
||
EXTEND T2,[XBLT] ;MOVE THE DATA
|
||
PUSHJ P,QUESEB## ;QUEUE THE ERROR BLOCK
|
||
PJRST RETDG ;RETURN THE PACKET UNTIL WE KNOW WHAT TO DO
|
||
|
||
|
||
;RECEIVED AN ERROR LOG PACKET WITH AN ERROR
|
||
|
||
ERPERR: LDB T1,PKYSTS ;GET STATUS
|
||
LDB T2,PKYFLG ;GET FLAGS
|
||
BUG. (CHK,KLPEPB,KLPSER,SOFT,<Received bad error logging packet>,<<T2,STATUS>,<T3,FLAGS>,<P2,OPCODE>,<Q1,NODE>>,)
|
||
PJRST RETDG ;RETURN PACKET TO FREE QUEUE
|
||
|
||
|
||
;RECEIVED A SHUTDOWN
|
||
|
||
INTSHT: BUG. (INF,KLPRSH,KLPSER,SOFT,<Received shutdown message>,<<Q1,NODE>>,)
|
||
SETZ P4, ;WE NEED TO SEND A SETCKT
|
||
PJRST CLOSV1 ;CLOSE THE VC, TELL SCA, AND RETURN
|
||
;ROUTINE TO TELL SCA A PATH HAS COME ON LINE (A VC IS NOW OPEN).
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q3/ PCB ADDRESS
|
||
; P5/ PBK ADDRESS
|
||
; PUSHJ P,OPNSCA
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
OPNSCA: MOVEI T1,VC.OPN ;GET OPEN CODE
|
||
STOR T1,PBVCST,(P5) ;SET NEW VC STATE
|
||
MOVX T1,PB.OKO ;NO LONGER OK TO OPEN THE VC
|
||
ANDCAM T1,.PBFLG(P5) ;...
|
||
LOAD T1,PBPBI,(P5) ;GET PATH BLOCK INDEX
|
||
BLCAL. (SC.ONL##,<T1>) ;TELL SCA ABOUT NEW PATH
|
||
POPJ P, ;RETURN
|
||
;ROUTINE THE CHECK THE PPD BYTE FROM A RECEIVED PACKET.
|
||
;CALL:
|
||
; Q2/ PACKET ADDRESS
|
||
; PUSHJ P,CHKPPD
|
||
;RETURN:
|
||
; CPOPJ IF BAD PPD BYTE
|
||
; CPOPJ1 IF GOOD PPD BYTE
|
||
;
|
||
;PPD BYTE IS RETURNED IN P6.
|
||
|
||
CHKPPD: LDB P6,PKYPPD ;GET THE PPD BYTE
|
||
CAIL P6,PP.STA ;LEGAL
|
||
CAILE P6,PP.MAX ; PPD BYTE?
|
||
JRST CHKPP1 ;NO
|
||
JRST CPOPJ1## ;YES
|
||
|
||
|
||
;SPECIAL ENTRY POINT FOR OPCODE/PPD BYTE MISMATCH.
|
||
|
||
CHKPP1: LDB T1,PKYSTS ;GET STATUS
|
||
LDB T2,PKYOP ;GET OPCODE
|
||
LDB T3,PKYNOD ;GET NODE
|
||
BUG. (INF,KLPPPD,KLPSER,SOFT,<Packet with bad PPD byte>,<<T1,STATUS>,<T2,OPCODE>,<T3,NODE>,<P6,PPD>>,)
|
||
POPJ P, ;RETURN
|
||
;RECEIVED A CONFIRM OR A DATA RECEIVED
|
||
|
||
INTNBF: CAMN P3,[-1] ;LOCALLY GENERATED?
|
||
PJRST RETMSG ;YES, GIVE PACKET BACK TO FREE QUEUE
|
||
DMOVE T1,.PKXID(Q2) ;T1 = BUFFER NAME, T2 = CID
|
||
BLCAL. (SC.DMA##,<T1,T2>) ;TELL SCA, GIVE BUFFER NAME AND CID
|
||
MOVE T1,Q2 ;POSITION BUFFER ADDRESS
|
||
PJRST SC.RBF## ;RETURN THE BUFFER AND RETURN
|
||
;RECEIVED A REQUEST-ID
|
||
|
||
;NOTE: WE ONLY GET HERE IF THE REQUEST-ID WE SENT WAS RETURNED DUE
|
||
; TO SOME KIND OF ERROR, AS THE KLIPA RESPONDS TO IDREQ PACKETS
|
||
; FROM OTHER NODES WITHOUT OUR INTERVENTION.
|
||
|
||
INTRID: MOVX T1,PK.SRB ;CLEAR ALL SOFTWARE RESPONSE BITS
|
||
ANDCAM T1,.PKVRT(Q2) ;...
|
||
MOVX T1,RI.WFR ;NO LONGER WAITING FOR RESPONSE
|
||
ANDCAM T1,.PCRIS(P1) ; (IN CASE IT WAS SECOND TRY)
|
||
PJRST RETDG ;RETURN THE PACKET TO FREE QUEUE AND RETURN
|
||
|
||
|
||
;RECEIVED A REQUEST-ID WITH AN ERROR
|
||
|
||
RIDERR: PUSH P,.PKSTS(Q2) ;SAVE THE ERROR BITS
|
||
LDB T1,PKYSTS ;GET THE STATUS FIELD
|
||
PUSH P,T1 ;SAVE THAT TOO
|
||
PUSHJ P,INTRID ;CLEAR BITS AND RETURN BUFFER
|
||
POP P,T2 ;RESTORE THE STATUS FIELD
|
||
POP P,T1 ;GET THE ERROR BITS BACK
|
||
SETZM .PCRIT(P1) ;TURN OFF TIMER
|
||
TXNN T1,PF.PT0 ;RECEIVED ON PATH A??
|
||
JRST RIDER2 ;NO
|
||
CAIE T2,PS.NRA ;WAS IT A NO RESPONSE?
|
||
JRST RIDER1 ;NO
|
||
MOVX T1,RI.NRA ;YES, UPDATE STATUS
|
||
IORB T1,.PCRIS(P1) ;...
|
||
PJRST RIDERX ;GO SEE IF WE SHOULD DO SOMETHING
|
||
|
||
RIDER1: MOVX T1,RI.NRA ;NO LONGER NO-RESPONSE
|
||
ANDCAM T1,.PCRIS(P1) ;...
|
||
POPJ P, ;RETURN
|
||
|
||
RIDER2: CAIE T2,PS.NRB ;WAS IT A NO RESPONSE?
|
||
JRST RIDER3 ;NO
|
||
MOVX T1,RI.NRB ;YES, UPDATE STATUS
|
||
IORB T1,.PCRIS(P1) ;...
|
||
PJRST RIDERX ;GO SEE IF WE SHOULD DO SOMETHING
|
||
|
||
RIDER3: MOVX T1,RI.NRB ;NO LONGER NO-RESPONSE
|
||
ANDCAM T1,.PCRIS(P1) ;...
|
||
POPJ P, ;RETURN
|
||
;HERE WHEN WE'VE RECEIVED A NO RESPONSE. IF WE'VE RECEIVED ONE ON
|
||
;BOTH PATHS WE'LL ASSUME THE LISTENER HAS DIED AND CLOSE THE VC.
|
||
|
||
RIDERX: JUMPE P5,CPOPJ## ;MAY NOT HAVE A PATH BLOCK (NON-EXISTANT NODE)
|
||
TXC T1,RI.NRA!RI.NRB ;COMPLEMENT THE BITS
|
||
TXCE T1,RI.NRA!RI.NRB ;BOTH ON?
|
||
POPJ P, ;NO, RETURN
|
||
LOAD T1,PBVCST,(P5) ;GET VIRTUAL CIRCUIT STATE
|
||
CAIE T1,VC.OPN ;OPEN?
|
||
POPJ P, ;NO, DON'T NEED TO DO ANYTHING
|
||
BUG. (INF,KLPNRS,KLPSER,SOFT,<Closing VC due to No Response>,<<Q1,NODE>>,)
|
||
SETZB Q2,P4 ;WE NEED A BUFFER TO DO THE SET CIRCUIT
|
||
PJRST CLOSV1 ;CLOSE THE VC, TELL SCA, AND RETURN
|
||
;RECEIVED AN IDREC
|
||
|
||
INTIDR: STKVAR <WFIFL> ;ALLOCATE SOME STACK STORAGE
|
||
SETZM WFIFL ;ASSUME NOT WAITING FOR IDREC
|
||
SETZM .PCRIT(P1) ;TURN OFF REQUEST-ID TIMER FOR THIS NODE
|
||
MOVE T1,.PKSTS(Q2) ;GET THE PACKET STATUS
|
||
TXNN T1,PF.PT0 ;DID IT ARRIVE ON PATH A?
|
||
JRST INTID3 ;NO, PATH B
|
||
PUSHJ P,CHKVCO ;DO WE HAVE AN OPEN VC?
|
||
JRST INTID2 ;NO, ONWARD
|
||
MOVX T1,RI.PAO ;IS PATH A ALREADY OPEN?
|
||
TDNE T1,.PCRIS(P1) ;...
|
||
JRST INTID2 ;YES
|
||
PUSH P,Q2 ;SAVE ADDRESS OF IDREC PACKET
|
||
PUSHJ P,KLPGDB ;GET A BUFFER
|
||
JRST INTID1 ;NOT AVAILABLE
|
||
MOVX T1,CK.LPT!CK.PAA!CK.PBA ;TELL PORT TO USE BOTH PATHS AGAIN
|
||
MOVEM T1,.PKCKT(Q2) ;...
|
||
PUSHJ P,KLPSCK ;SEND THE SET-CIRCUIT
|
||
MOVX T1,RI.PAO!RI.PBO ;BOTH PATHS ARE NOW OPEN
|
||
IORM T1,.PCRIS(P1) ;...
|
||
INTID1: POP P,Q2 ;RESTORE ADDRESS OF IDREC PACKET
|
||
INTID2: MOVX T1,RI.NRA ;CLEAR NO-RESPONSE FLAG
|
||
ANDCAM T1,.PCRIS(P1) ;...
|
||
JRST INTID6 ;PROCEED
|
||
|
||
INTID3: PUSHJ P,CHKVCO ;DO WE HAVE AN OPEN VC?
|
||
JRST INTID5 ;NO, ONWARD
|
||
MOVX T1,RI.PBO ;IS PATH B ALREADY OPEN?
|
||
TDNE T1,.PCRIS(P1) ;...
|
||
JRST INTID5 ;YES
|
||
PUSH P,Q2 ;SAVE ADDRESS OF IDREC PACKET
|
||
PUSHJ P,KLPGDB ;GET A BUFFER
|
||
JRST INTID4 ;NOT AVAILABLE
|
||
MOVX T1,CK.LPT!CK.PAA!CK.PBA ;TELL PORT TO USE BOTH PATHS AGAIN
|
||
MOVEM T1,.PKCKT(Q2) ;...
|
||
PUSHJ P,KLPSCK ;SEND THE SET-CIRCUIT
|
||
MOVX T1,RI.PAO!RI.PBO ;BOTH PATHS ARE NOW OPEN
|
||
IORM T1,.PCRIS(P1) ;...
|
||
INTID4: POP P,Q2 ;RESTORE ADDRESS OF IDREC PACKET
|
||
INTID5: MOVX T1,RI.NRB ;CLEAR NO-RESPONSE FLAG
|
||
ANDCAM T1,.PCRIS(P1) ;...
|
||
INTID6: JUMPE P5,INTID7 ;JUMP IF NO PATH BLOCK (BUILD ONE)
|
||
MOVE T1,.PKPST(Q2) ;GET THE PORT STATE
|
||
MOVEM T1,.PBDPS(P5) ;STORE IT IN THE PBK
|
||
LOAD T1,PBVCST,(P5) ;GET VIRTUAL CIRCUIT STATE
|
||
CAIE T1,VC.CLO ;CLOSED?
|
||
PJRST RETDG ;NO, THAT'S ALL WE HAVE TO DO
|
||
MOVX T1,PB.WFI ;NO LONGER WAITING FOR AN IDREC
|
||
ANDCAB T1,.PBFLG(P5) ;CLEAR FLAGS AND COPY TO T1
|
||
SETOM WFIFL ;SAY WE TURNED IT OFF
|
||
TXNE T1,PB.NTC ;STILL NEED TO CLOSE VC?
|
||
PJRST RETDG ;YES, CAN'T DO ANYTHING ELSE NOW
|
||
TXNN T1,PB.OKO ;IS IT OK TO OPEN THIS VC?
|
||
PJRST RETDG ;NO, DONE
|
||
INTID7: LDB T1,PKYPST ;GET OTHER PORT'S STATE
|
||
CAIE T1,PS.ENB ;ENABLED?
|
||
PJRST RETDG ;NO, DON'T TRY TO SEND NOW
|
||
|
||
JUMPN P4,INTID8 ;JUMP IF WE HAVE A SYSTEM BLOCK FOR THIS NODE
|
||
PUSHJ P,BLDSBK ;BUILD A SYSTEM BLOCK
|
||
PJRST RETDG ;CAN'T, RETURN THE DATAGRAM AND TRY AGAIN LATER
|
||
INTID8: JUMPN P5,INTID9 ;JUMP IF WE HAVE A PATH BLOCK FOR THIS NODE
|
||
PUSHJ P,BLDPBK ;BUILD A PATH BLOCK
|
||
PJRST RETDG ;CAN'T, RETURN THE DATAGRAM AND TRY AGAIN LATER
|
||
INTID9: PJRST SNDSTA ;SEND A START AND RETURN
|
||
|
||
ENDSV. ;END OF STACK VARIABLE RANGE
|
||
;ROUTINE TO CHECK FOR AN OPEN VC.
|
||
;CALL:
|
||
; P5/ PBK ADDRESS
|
||
; PUSHJ P,CHKVCO
|
||
;RETURN:
|
||
; CPOPJ IF VC NOT OPEN (OR NO PB)
|
||
; CPOPJ1 IF VC OPEN
|
||
|
||
CHKVCO: JUMPE P5,CPOPJ## ;RETURN IF NO PATH BLOCK
|
||
LOAD T1,PBVCST,(P5) ;GET VC STATE
|
||
CAIN T1,VC.OPN ;VC OPEN?
|
||
AOS (P) ;YES, SET FOR SKIP
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO BUILD A SYSTEM BLOCK.
|
||
;CALL:
|
||
; Q1/ CI NODE NUMBER
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,BLDSBK
|
||
;RETURN:
|
||
; CPOPJ ON FAILURE
|
||
; CPOPJ1 ON SUCCESS WITH:
|
||
; P4/ SBK ADDRESS
|
||
|
||
BLDSBK: CIOFF ;PREVENT RACES
|
||
MOVSI T1,-C%SBLL ;-VE LENGTH OF SYSTEM BLOCK LIST
|
||
BLDSB1: SKIPN P4,SBLIST##(T1) ;GET AN ENTRY
|
||
JRST BLDSB2 ;NONE, TRY NEXT
|
||
LOAD T2,SBDPN,(P4) ;GET DESTINATION PORT NUMBER
|
||
CAMN T2,Q1 ;A MATCH?
|
||
JRST BLDSB3 ;YES, USE THIS ONE
|
||
BLDSB2: AOBJN T1,BLDSB1 ;LOOP FOR ANY OTHER SYSTEM BLOCKS
|
||
|
||
MOVEI T2,.SBLEN ;NUMBER OF WORDS REQUIRED
|
||
PUSHJ P,GETCOR ;GET THE SPACE
|
||
PJRST CIONPJ## ;NOT AVAILABLE, INTERRUPTS BACK ON AND RETURN
|
||
MOVE P4,T1 ;COPY ADDRESS TO PROPER AC
|
||
MOVSI T1,-C%SBLL ;-VE LENGTH OF SYSTEM BLOCK LIST
|
||
SKIPE SBLIST##(T1) ;LOOK FOR A FREE SLOT
|
||
AOBJN T1,.-1 ;...
|
||
JUMPGE T1,BLDSBE ;ERROR RETURN IF NO FREE SLOTS
|
||
MOVEM P4,SBLIST##(T1) ;CLAIM THIS SLOT
|
||
ADDI T1,1 ;MAKE SYSTEM BLOCK INDEX 1-BASED TO COMPLY WITH SCA SPEC
|
||
STOR T1,SBSBI,(P4) ;SAVE SYSTEM BLOCK INDEX
|
||
STOR Q1,SBDPN,(P4) ;STORE DESTINATION PORT NUMBER (CI NODE NUMBER)
|
||
BLDSB3: MOVE T1,Q3 ;GET PCB ADDRESS
|
||
ADD T1,Q1 ; OFFSET FOR THIS NODE
|
||
MOVEM P4,.PCSBK(T1) ;STORE SYSTEM BLOCK ADDRESS IN PCB
|
||
PJRST CINPJ1## ;INTERRUPTS BACK ON AND SKIP RETURN
|
||
|
||
BLDSBE: CION ;OK TO INTERRUPT AGAIN
|
||
MOVEI T1,.SBLEN ;LENGTH OF BLOCK
|
||
MOVE T2,P4 ;COPY SYSTEM BLOCK ADDRESS
|
||
PUSHJ P,GIVSWS## ;RETURN THE SPACE
|
||
SETZ P4, ;GET A ZERO
|
||
POPJ P, ;TAKE THE ERROR RETURN
|
||
;ROUTINE TO BUILD A PATH BLOCK.
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q2/ ADDRESS OF IDREC PACKET
|
||
; Q3/ PCB ADDRESS
|
||
; P4/ SBK ADDRESS
|
||
; PUSHJ P,BLDPBK
|
||
;RETURN:
|
||
; CPOPJ ON FAILURE
|
||
; CPOPJ1 ON SUCCESS WITH:
|
||
; P5/ PBK ADDRESS
|
||
|
||
BLDPBK: MOVEI T2,.PBLEN ;NUMBER OF WORDS REQUIRED
|
||
PUSHJ P,GETCOR ;GET THE SPACE
|
||
POPJ P, ;NOT AVAILABLE
|
||
MOVE P5,T1 ;COPY ADDRESS TO PROPER AC
|
||
CIOFF ;PREVENT RACES
|
||
MOVSI T1,-C%PBLL ;-VE LENGTH OF PATH BLOCK LIST
|
||
SKIPE PBLIST##(T1) ;LOOK FOR A FREE SLOT
|
||
AOBJN T1,.-1 ;...
|
||
JUMPGE T1,BLDPBE ;ERROR RETURN IF NO FREE SLOTS
|
||
MOVEM P5,PBLIST##(T1) ;CLAIM THIS SLOT
|
||
ADDI T1,1 ;MAKE PATH BLOCK INDEX 1-BASED TO COMPLY WITH SCA SPEC
|
||
STOR T1,PBPBI,(P5) ;SAVE PATH BLOCK INDEX
|
||
MOVE T1,Q3 ;GET PB ADDRESS
|
||
ADD T1,Q1 ; OFFSET FOR THIS NODE
|
||
MOVEM P5,.PCPBK(T1) ;STORE PATH BLOCK ADDRESS IN PCB
|
||
LOAD T1,SBPBI,(P4) ;GET INDEX OF FIRST PATH BLOCK
|
||
STOR T1,PBNPI,(P5) ;LINK THAT PATH BLOCK TO THIS ONE
|
||
LOAD T1,PBPBI,(P5) ;GET OUR PATH BLOCK INDEX
|
||
STOR T1,SBPBI,(P4) ;INSERT THIS PATH BLOCK AS HEAD OF LIST
|
||
INCR SBDPC,(P4) ;INCREMENT DESTINATION PORT COUNT
|
||
LOAD T1,SBSBI,(P4) ;GET SYSTEM BLOCK INDEX
|
||
STOR T1,PBSBI,(P5) ;STORE IN PATH BLOCK
|
||
STOR Q1,PBDPN,(P5) ;STORE DESTINATION PORT NUMBER (CI NODE NUMBER)
|
||
CION ;ALLOW INTERRUPTS AGAIN
|
||
XMOVEI T1,.PBFCB(P5) ;POINTER TO FIRST CONNECTION BLOCK
|
||
MOVEM T1,.PBLCB(P5) ;STORE IN BLINK
|
||
SETZM .PBFCB(P5) ;CLEAR FLINK
|
||
XMOVEI T1,.PBTWQ(P5) ;POINTER TO TOP OF WORK QUEUE
|
||
MOVEM T1,.PBBWQ(P5) ;STORE IN BLINK
|
||
SETZM .PBTWQ(P5) ;CLEAR FLINK
|
||
SETZM .PBOBB(P5) ;ZERO THE SCA OUTBOUND MESSAGE WORD
|
||
MOVE T1,.PKMID(Q2) ;TYPE OF NODE
|
||
MOVEM T1,.PBDPC(P5) ;SAVE IT IN SYSTEM BLOCK
|
||
MOVE T1,.PKCOD(Q2) ;GET PORT CODE REVISION
|
||
MOVEM T1,.PBDCR(P5) ;SAVE IN SYSTEM BLOCK
|
||
MOVE T1,.PKFUN(Q2) ;PORT FUNCTIONALITY
|
||
MOVEM T1,.PBDPF(P5) ;SAVE IN SYSTEM BLOCK
|
||
MOVE T1,.PKPST(Q2) ;GET PORT STATE
|
||
MOVEM T1,.PBDPS(P5) ;SAVE IN SYSTEM BLOCK
|
||
MOVEM Q3,.PBPCB(P5) ;STORE ADDRESS OF PORT CONTROL BLOCK
|
||
IFN FTMP,<
|
||
MOVE T1,.CPCPN## ;OUR CPU NUMBER
|
||
MOVEM T1,.PBCPU(P5) ;STORE
|
||
>; END IFN FTMP
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
BLDPBE: CION ;OK TO INTERRUPT
|
||
MOVEI T1,.PBLEN ;LENGTH OF BLOCK
|
||
MOVE T2,P5 ;COPY PATH BLOCK ADDRESS
|
||
PUSHJ P,GIVSWS## ;RETURN THE SPACE
|
||
SETZ P5, ;GET A ZERO
|
||
POPJ P, ;TAKE THE ERROR RETURN
|
||
;ROUTINE TO SEND A START.
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; P5/ PBK ADDRESS
|
||
; PUSHJ P,SNDSTA
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
SNDSTA: MOVEI T1,VC.STS ;GET START-SENT CODE
|
||
STOR T1,PBVCST,(P5) ;SET INITIAL VC STATE
|
||
MOVEI T1,PP.STA ;GET START CODE
|
||
PUSHJ P,STRTDT ;MAKE A START PACKET
|
||
PUSHJ P,KLPSDG ;SEND THE DATAGRAM
|
||
PJRST STSST ;SET THE TIMER AND RETURN
|
||
;ROUTINE TO PUT START DATA INTO A BUFFER.
|
||
;CALL:
|
||
; T1/ FUNCTION (START OR STACK)
|
||
; Q2/ PACKET ADDRESS
|
||
; PUSHJ P,SRTRDT
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
STRTDT: DPB T1,PKYPPD ;OPCODE = SCA PPD FIELD
|
||
SETZM .SRSSY(Q2) ;CLEAR SENDING SYSTEM
|
||
SETZM .SRRSV(Q2) ;CLEAR RESERVED WORD
|
||
MOVEI T1,1 ;CI PROTOCOL VERSION
|
||
STOR T1,SRVRS,(Q2) ;SAVE IN PACKET
|
||
MOVE T1,.SRRSV(Q2) ;GET THE WORD
|
||
PUSHJ P,REVFUL ;REVERSE IT
|
||
MOVEM T1,.SRRSV(Q2) ;PUT IT BACK
|
||
MOVE T1,[C%MXMP_2,,C%MXDP_4] ;MAX MESSAGE, DG SIZES
|
||
PUSHJ P,REVFUL ;REVERSE THEM FOR THE HSC
|
||
MOVEM T1,.SRMMS(Q2) ;SAVE IN PACKET
|
||
MOVE T1,[BYTE (8) "T","-","1","0"] ;"T-10" IS SOFTWARE TYPE
|
||
MOVEM T1,.SRSWT(Q2) ;SAVE IN PACKET
|
||
MOVE T1,[POINT 3,.JBVER##] ;POINTER TO RELEASE NUMBER
|
||
MOVEI T2,.SRSWV(Q2) ;WHERE IN PACKET TO STORE IT
|
||
MOVEI T3,4 ;4 BYTES
|
||
PUSHJ P,STORNO ;SAVE SW VERSION
|
||
MOVE T1,[POINT 3,SCASIN##,35-<8*3>] ;POINTER TO SOFTWARE INCARNATION
|
||
MOVEI T2,.SRSWI(Q2) ;WHERE IN PACKET TO STORE IT
|
||
MOVEI T3,8 ;8 BYTES
|
||
PUSHJ P,STORNO ;SAVE SW INCARNATION
|
||
MOVE T1,[BYTE (8) "K","L","1","0"] ;"KL10"
|
||
MOVEM T1,.SRHWT(Q2) ;IS HARDWARE TYPE
|
||
PUSHJ P,SAVE1## ;FREE UP P1
|
||
APRID P1 ;READ MICROCODE VERSION (APRID)
|
||
ANDX P1,ID.UVN ;KEEP JUST VERSION
|
||
MOVE T1,[POINT 3,P1,5] ;POINT TO START OF VERSION
|
||
MOVEI T2,.SRHWV(Q2) ;WHERE TO STORE IT
|
||
MOVEI T3,4 ;4 BYTES
|
||
PUSHJ P,STORNO ;SAVE MICROCODE VERSION
|
||
MOVE T1,[BYTE (8) " "," "," "," "] ;PAD LAST 2 WORDS OF HARDWARE VERSION
|
||
MOVEM T1,.SRHWV+1(Q2) ;...
|
||
MOVEM T1,.SRHWV+2(Q2) ;...
|
||
MOVE T1,[BYTE (8)"K","L","-"] ;NODE NAME
|
||
MOVEM T1,.SRNNM(Q2)
|
||
SETZM .SRNNM+1(Q2)
|
||
MOVE T3,Q2
|
||
ADDI T3,.SRNNM
|
||
MOVSI CX,(POINT 8,(T3),23)
|
||
MOVE T1,.CPASN##
|
||
PUSHJ P,STRDEC
|
||
PUSHJ P,VAXTOD ;COMPUTE VAX-STYLE TIME OF DAY
|
||
DMOVEM T1,.SRTOD(Q2) ;SAVE
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO STORE AN OCTAL NUMBER AS 8-BIT ASCII BYTES IN A PACKET.
|
||
;CALL:
|
||
; T1/ POINTER TO DATA
|
||
; T2/ ADDRESS OF WHERE TO STORE
|
||
; T3/ COUNT OF BYTES TO STORE
|
||
; Q2/ PACKET ADDRESS
|
||
; PUSHJ P,STORNO
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
STORNO: MOVSI CX,(POINT 8,0(T2)) ;SET CX AS A BYTE POINTER
|
||
HLL T2,Q2 ;TURN ON RIGHT SECTION BITS
|
||
STORN1: ILDB T4,T1 ;GET A BYTE
|
||
ADDI T4,"0" ;CONVERT TO ASCII
|
||
IDPB T4,CX ;SAVE IN PACKET
|
||
SOJG T3,STORN1 ;FOR ALL CHARACTERS
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;ROUTINE TO STORE A DECIMAL NUMBER AS 8-BIT ASCII BYTES IN A PACKET.
|
||
;CALL:
|
||
; T1/ NUMBER
|
||
; T3/ CX POINTER WHERE TO STORE
|
||
; PUSHJ P,STRDEC
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
STRDEC: IDIVI T1,^D10 ;BASE 10
|
||
PUSH P,T2
|
||
SKIPE T1
|
||
PUSHJ P,STRDEC
|
||
POP P,T2
|
||
ADDI T2,"0"
|
||
IDPB T2,CX
|
||
POPJ P,
|
||
;ROUTINE TO COMPUTE VAX-STYLE TIME OF DAY.
|
||
;CALL:
|
||
; PUSHJ P,VAXTOD
|
||
;RETURN:
|
||
; CPOPJ ALWAYS WITH:
|
||
; T1 & T2/ 64-BIT VAX-STYLE TIME OF DAY
|
||
|
||
$XSENT (VAXTOD::)
|
||
SKIPN DATE## ;HAS UNIVERSAL DATE/TIME BEEN SET UP?
|
||
SNCALL (SUDATE##,MCSEC0) ;NO, VERY NICE OF US TO DO SO
|
||
MOVE T1,DATE## ;GET UNIVERSAL DATE/TIME
|
||
MUL T1,VAXTIM ;CONVERT TIME TO VAX'S REPRESENTATION
|
||
LSH T2,1 ;KILL OFF THE SIGN BIT SO WE HAVE A 70-BIT
|
||
; QUANTITY IN T1 AND T2
|
||
LSHC T1,-5 ;RIGHT JUSTIFY LOW ORDER TIME
|
||
MOVE T3,T2 ;COPY THE LOW ORDER PART
|
||
LSH T3,4 ;POSITION IT
|
||
LSHC T1,-^D28 ;GET HIGH ORDER PART IN T2
|
||
MOVE T1,T2 ;BACK TO T1
|
||
TRZ T1,17 ;CLEAR THE JUNK BITS
|
||
PUSHJ P,REVFUL ;REVERSE THE BYTES
|
||
PUSH P,T1 ;SAVE THE HIGH ORDER PART
|
||
MOVE T1,T3 ;GET THE LOW ORDER PART
|
||
PUSHJ P,REVFUL ;REVERSE THE BYTES
|
||
PJRST T2POPJ## ;RESTORE HIGH ORDER PART TO T2, LOW ORDER PART
|
||
; ALREADY IN T1
|
||
|
||
VAXTIM: DEC 52734375 ;MAGIC CONSTANT TO CONVERT UDT TO VAX TIME BASE
|
||
|
||
$XHIGH
|
||
;RECEIVED A REQUEST DATA ON QUEUE 0 (WE NEVER USE 0)
|
||
;RECEIVED A REQUEST DATA ON QUEUE 1 (WE ALWAYS USE 1)
|
||
;RECEIVED A REQUEST DATA ON QUEUE 2 (WE NEVER USE 2)
|
||
;RECEIVED A SEND-DATA (WE NEVER SET THE RESPONSE BIT)
|
||
|
||
INTRD0: JRST INTSDT ;USE COMMON ROUTINE
|
||
INTRD1: JRST INTSDT ;USE COMMON ROUTINE
|
||
INTRD2: JRST INTSDT ;USE COMMON ROUTINE
|
||
INTSDT: JUMPE P3,INTSD1 ;JUMP IF REMOTELY-GENERATED
|
||
MOVE T1,Q2 ;POSITION BUFFER ADDRESS
|
||
PJRST SC.RBF## ;GIVE BUFFER BACK TO SCA POOL
|
||
|
||
;REMOTELY-GENERATED PACKET
|
||
|
||
INTSD1: LDB T1,PKYSTS ;GET STATUS
|
||
LDB T2,PKYFLG ;GET FLAGS
|
||
BUG. (INF,KLPIRD,KLPSER,SOFT,<Invalid remotely-generated data request>,<<T1,STATUS>,<T2,FLAGS>,<P2,OPCODE>,<Q1,NODE>>,)
|
||
PJRST RETMSG ;RETURN PACKET TO MESSAGE FREE QUEUE
|
||
;RECEIVE ONE OF THE FOLLOWING WITH AN ERROR:
|
||
;REQUEST DATA ON QUEUE 0 (WE NEVER USE 0)
|
||
;REQUEST DATA ON QUEUE 1 (WE ALWAYS USE 1)
|
||
;REQUEST DATA ON QUEUE 2 (WE NEVER USE 2)
|
||
;SEND-DATA (WE NEVER SET THE RESPONSE BIT)
|
||
|
||
NBFERR: JRST SDTERR ;USE COMMON ROUTINE
|
||
RD0ERR: JRST SDTERR ;USE COMMON ROUTINE
|
||
RD1ERR: JRST SDTERR ;USE COMMON ROUTINE
|
||
RD2ERR: JRST SDTERR ;USE COMMON ROUTINE
|
||
SDTERR: PUSHJ P,SCAERR ;TELL SCA
|
||
JUMPE P3,RETMSG ;IF NOT LOCALLY-GENERATED, RETURN PACKET AND RETURN
|
||
MOVE T1,Q2 ;GET THE BUFFER ADDRESS
|
||
PJRST SC.RBF## ;RETURN THE BUFFER TO SCA POOL AND RETURN
|
||
;RECEIVED A LOOP-BACK
|
||
|
||
INTLPB: MOVE T1,.PKSTS(Q2) ;GET PACKET STATUS WORD
|
||
TXNN T1,PF.PT0 ;DID IT ARRIVE ON PATH A?
|
||
JRST INTLP1 ;NO
|
||
MOVX T1,ST.WAB ;YES, IS WIRE A FLAGGED AS BAD?
|
||
TDNN T1,.PCSTS(Q3) ;...
|
||
PJRST RETDG ;NO, RETURN THE DATAGRAM AND RETURN
|
||
BUG. (INF,KLPWAG,KLPSER,HARD,<CI wire A has gone from bad to good>,,)
|
||
ANDCAM T1,.PCSTS(Q3) ;CLEAR THE FLAG
|
||
MOVEI T2,KS%ABG ;GET READ-COUNTERS REASON CODE
|
||
PUSHJ P,KLPRPT ;DO A READ-COUNTERS
|
||
JRST INTLP2 ;CONTINUE
|
||
|
||
INTLP1: MOVX T1,ST.WBB ;IS WIRE B FLAGGED AS BAD?
|
||
TDNN T1,.PCSTS(Q3) ;...
|
||
PJRST RETDG ;NO, RETURN THE DATAGRAM AND RETURN
|
||
BUG. (INF,KLPWBG,KLPSER,HARD,<CI wire B has gone from bad to good>,,)
|
||
ANDCAM T1,.PCSTS(Q3) ;CLEAR THE FLAG
|
||
MOVEI T2,KS%BBG ;GET READ-COUNTERS REASON CODE
|
||
PUSHJ P,KLPRPT ;DO A READ-COUNTERS
|
||
|
||
INTLP2: SETZ Q1, ;START WITH NODE ZERO
|
||
INTLP3: MOVE P1,Q3 ;GET PCB ADDRESS
|
||
ADD P1,Q1 ; OFFSET BY CI NODE NUMBER
|
||
SKIPN P5,.PCPBK(P1) ;IS THERE A PATH BLOCK?
|
||
JRST INTLP4 ;NO
|
||
LOAD T1,PBVCST,(P5) ;GET VC STATE
|
||
CAIE T1,VC.OPN ;IS VC OPEN?
|
||
JRST INTLP4 ;NO
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
POPJ P, ;CAN'T, NEXT REQID WILL DO THIS
|
||
MOVX T1,CK.LPT!CK.PAA!CK.PBA ;BOTH PATHS ALLOWED
|
||
MOVEM T1,.PKCKT(Q2) ;...
|
||
PUSHJ P,KLPSCK ;SEND A SET-CIRCUIT
|
||
MOVX T1,RI.PAO!RI.PBO ;MARK BOTH PATHS AS OPEN
|
||
IORM T1,.PCRIS(P1) ;...
|
||
INTLP4: CAIL Q1,MAXNDS-1 ;DONE THEM ALL?
|
||
POPJ P, ;YES, RETURN
|
||
AOJA Q1,INTLP3 ;NO, LOOP TO NEXT ONE
|
||
;RECEIVED A LOOP-BACK WITH AN ERROR
|
||
|
||
LPBERR: MOVE T1,.PKSTS(Q2) ;GET STATUS FLAGS
|
||
TXNE T1,PS.PAE!PS.PBE ;PATH ERROR?
|
||
JRST LPBER1 ;YES
|
||
LDB T2,PKYSTS ;GET STATUS
|
||
LDB T3,PKYFLG ;GET FLAGS
|
||
MOVE T4,.PCCSR(Q3) ;GET CSR
|
||
BUG. (INF,KLPLBF,KLPSER,HARD,<Loopback failed>,<<T2,STATUS>,<T3,FLAGS>,<P2,OPCODE>,<T4,CSR>>,)
|
||
PJRST RETDG ;RETURN THE DATAGRAM AND RETURN
|
||
|
||
;PATH ERROR
|
||
|
||
LPBER1: TXNN T1,PS.PAE ;PATH A ERROR?
|
||
JRST LPBER2 ;NO, MUST BE PATH B
|
||
MOVX T1,ST.WAB ;IS WIRE A FLAGGED AS BAD?
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
PJRST RETDG ;YES, RETURN THE DATAGRAM AND RETURN
|
||
BUG. (INF,KLPWAB,KLPSER,HARD,<CI wire A has gone from good to bad>,,)
|
||
IORM T1,.PCSTS(Q3) ;SET THE FLAG
|
||
MOVEI T2,KS%AGB ;GET READ-COUNTERS REASON CODE
|
||
PJRST KLPRPT ;DO A READ-COUNTERS AND RETURN
|
||
|
||
LPBER2: MOVX T1,ST.WBB ;IS WIRE B FLAGGED AS BAD?
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
PJRST RETDG ;YES, RETURN THE DATAGRAM AND RETURN
|
||
BUG. (INF,KLPWBB,KLPSER,HARD,<CI wire B has gone from good to bad>,,)
|
||
IORM T1,.PCSTS(Q3) ;SET THE FLAG
|
||
MOVEI T2,KS%BGB ;GET READ-COUNTERS REASON CODE
|
||
PJRST KLPRPT ;DO A READ-COUNTERS AND RETURN
|
||
;RECEIVED A SET-CIRCUIT
|
||
|
||
INTCKT: LDB T1,PKYSTS ;GET STATUS
|
||
LDB T2,PKYFLG ;GET FLAGS
|
||
BUG. (CHK,KLPSCR,KLPSER,HARD,<SET-CIRCUIT command received>,<<T1,STATUS>,<T2,FLAGS>,<P2,OPCODE>>,)
|
||
PJRST RETDG ;RETURN THE DATAGRAM AND RETURN
|
||
|
||
|
||
;RECEIVED A SET-CIRCUIT WITH AN ERROR
|
||
|
||
CKTERR: LDB T1,PKYSTS ;GET STATUS
|
||
LDB T2,PKYFLG ;GET FLAGS
|
||
BUG. (CHK,KLPCKE,KLPSER,HARD,<SET-CIRCUIT command error>,<<T1,STATUS>,<T2,FLAGS>,<P2,OPCODE>>,)
|
||
PJRST RETDG ;RETURN THE DATAGRAM AND RETURN
|
||
;RECEIVED A READ STATISTICS COUNTERS
|
||
|
||
INTRCT: MOVE T1,.PKSTS(Q2) ;GET PACKET STATUS
|
||
TXNE T1,PF.CPE ;PORT GENERATE PACKET AFTER A CRAM PARITY ERROR?
|
||
SKIPA Q1,[KS%PCP] ;YES, GET SPECIAL REASON CODE AND SKIP
|
||
HRRZ Q1,.PKXID(Q2) ;NO, GET REASON CODE FROM PACKET
|
||
SKIPL Q1 ;CHECK FOR VALIDITY
|
||
CAILE Q1,RCTMAX ;...
|
||
MOVEI Q1,RCTMAX+1 ;OUT OF RANGE, SET ERROR DISPATCH
|
||
PJRST @RCTDSP(Q1) ;GO PROCESS THE PACKET
|
||
|
||
RCTDSP: IFIW RCTBUG ; ILLEGAL
|
||
IFIW RCTSPR ;KS%PCP PORT CRAM PARITY ERROR
|
||
IFIW RCTSPR ;KS%AGB PORT A WENT FROM GOOD TO BAD
|
||
IFIW RCTSPR ;KS%ABG PORT A WENT FROM BAD TO GOOD
|
||
IFIW RCTSPR ;KS%BGB PORT B WENT FROM GOOD TO BAD
|
||
IFIW RCTSPR ;KS%BBG PORT B WENT FROM BAD TO GOOD
|
||
IFIW RCTSPR ;KS%PER PERIODIC READ
|
||
IFIW RCTBUG ;KS%UCD GET MICROCODE VERSION NUMBER (NOT USED)
|
||
IFIW RCTDIA ;KS%DIA DIAG. UUO REQUEST
|
||
RCTMAX==.-RCTDSP-1 ;MAXIMUM REASON CODE
|
||
IFIW RCTBUG ;OUT OF RANGE
|
||
|
||
|
||
;HERE IF TRANSACTION ID IN PACKET WAS OUT OF RANGE
|
||
|
||
RCTBUG: BUG. (INF,KLPBRC,KLPSER,HARD,<Bad READ-COUNTERS packet>,,)
|
||
PJRST RETDG ;RETURN THE PACKET
|
||
|
||
|
||
;RECEIVED A READ-STATISTICS-COUNTERS WITH AN ERROR
|
||
|
||
RCTERR: BUG. (CHK,KLPRCE,KLPSER,HARD,<READ-COUNTERS command failed>,,)
|
||
PJRST RETDG ;RETURN THE DATAGRAM AND RETURN
|
||
;HERE TO MAKE A SPEAR ENTRY (TYPE 241)
|
||
|
||
RCTSPR: MOVEI T1,KS%LEN ;LENGTH OF ERROR BLOCK
|
||
PUSHJ P,ALCSEB## ;ALLOCATE SYSTEM ERROR BLOCK
|
||
PJRST RETDG ;ERROR, JUST TOSS PACKET AND RETURN
|
||
MOVEI T2,SEC%KS ;GET THE ERROR CODE
|
||
DPB T2,[POINT 9,.EBTYP(T1),8] ;STORE THE TYPE IN THE HEADER
|
||
MOVEI T2,2 ;OFFSET TO DATA
|
||
MOVEM T2,.EBHDR+KS%OFF(T1) ;STORE IT
|
||
MOVE T2,.PKUCD(Q2) ;MICROCODE VERSION
|
||
MOVE T3,.PKXID(Q2) ;GET TRANSACTION ID (REASON FOR READ COUNTERS)
|
||
DPB T3,[POINTR T2,KS%RSN] ;STORE IT
|
||
LDB T4,[POINT 3,KDBDVC(Q3),35] ;GET RH20 NUMBER
|
||
DPB T4,[POINTR (T2,KS%CHN)] ;SET INTERNAL CHANNEL NUMBER
|
||
MOVEM T2,.EBHDR+KS%VER(T1) ;STORE IT
|
||
MOVEI T2,NOSTCT-<.PKUCD-.PKPDA+1> ;NUMBER OF WORDS TO MOVE
|
||
XMOVEI T3,.PKUCD+1(Q2) ;SOURCE ADDRESS
|
||
MOVEI T4,.EBHDR+KS%VER+1(T1) ;DESTINATION
|
||
EXTEND T2,[XBLT] ;MOVE THE REMAINDER
|
||
PUSHJ P,QUESEB## ;QUEUE THE BLOCK
|
||
PJRST RETDG ;RETURN THE PACKET AND RETURN
|
||
|
||
|
||
;HERE WHEN DIAG. UUO ASKED TO READ THE COUNTERS
|
||
|
||
RCTDIA: MOVE T1,DATE## ;GET NOW
|
||
MOVEM T1,.PCCTR(Q3) ;SAVE AS FIRST WORD OF BLOCK
|
||
MOVEI T1,NOSTCT ;NUMBER OF COUNTERS TO STORE
|
||
XMOVEI T2,.PKPDA(Q2) ;SOURCE
|
||
XMOVEI T3,.PCCTR+1(Q3) ;DESTINATION
|
||
EXTEND T1,[XBLT] ;MOVE THE DATA
|
||
HLRZ T1,.PKXID(Q2) ;GET JOB WHICH READ COUNTERS
|
||
SNCALL (WAKJOB##,MCSEC0) ;WAKE THEM UP
|
||
PJRST RETDG ;RETURN THE DATAGRAM AND RETURN
|
||
;RECEIVED A READ-REGISTER
|
||
|
||
INTRRG: LDB T1,PKYREG ;GET THE REGISTER NUMBER
|
||
CAIE T1,.RGNOD ;RIGHT ONE?
|
||
BUG. (HLT,KLPKRW,KLPSER,HARD,<CI20 read the wrong register>,<<T1,REG>>,)
|
||
LDB T1,PKYDTA ;GET THE DATA (OUR NODE NUMBER)
|
||
MOVEM T1,.PCONN(Q3) ;STUFF IN PCB
|
||
PJRST RETDG ;RETURN THE DATAGRAM AND RETURN
|
||
|
||
|
||
;RECEIVED A READ-REGISTER WITH AN ERROR
|
||
|
||
RRGERR: BUG. (CHK,KLPCRR,KLPSER,HARD,<READ-REGISTER command failed>,,)
|
||
PJRST RETDG ;RETURN THE DATAGRAM AND RETURN
|
||
;RECEIVED A MAINTENANCE CONFIRM
|
||
;RECEIVED A MAINTENANCE DATA RECEIVED
|
||
|
||
INTMDR:
|
||
INTMCR: PUSHJ P,CHKMAI ;ARE WE EXPECTING THIS?
|
||
PJRST RETDG ;NO, RETURN THE DATAGRAM AND RETURN
|
||
SETZM .PCMFL(Q3) ;YES, THERE IS NO ERROR
|
||
PUSHJ P,WAKMAI ;WAKE THE WAITING JOB
|
||
PJRST RETDG ;RETURN THE DATAGRAM AND RETURN
|
||
|
||
|
||
;RECEIVED A MAINTENANCE CONFIRM WITH AN ERROR
|
||
;RECEIVED A MAINTENANCE DATA RECEIVED WITH AN ERROR
|
||
|
||
MDRERR:
|
||
MCRERR: PUSHJ P,CHKMAI ;ARE WE EXPECTING THIS?
|
||
PJRST RETDG ;NO, RETURN THE DATAGRAM AND RETURN
|
||
BUG. (INF,KLPMCE,KLPSER,HARD,<Received an MCNF or an MDATREC with an error>,<<T1,NODE>,<T2,STATUS>>,)
|
||
MOVEI T1,1 ;GET ERROR INDICATOR
|
||
MOVEM T1,.PCMFL(Q3) ;SET THE ERROR FLAG
|
||
PUSHJ P,WAKMAI ;WAKE THE WAITING JOB
|
||
PJRST RETDG ;RETURN THE DATAGRAM AND RETURN
|
||
|
||
|
||
;ROUTINE TO CHECK FOR MAINTENANCE TYPE MESSAGES EXPECTED.
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CHKMAI
|
||
;RETURN:
|
||
; CPOPJ IF NOT EXPECTED
|
||
; CPOPJ1 IF EXPECTED
|
||
|
||
CHKMAI: SKIPE .PCMJB(Q3) ;IS A MAINTENANCE TYPE MESSAGE EXPECTED?
|
||
JRST CPOPJ1## ;YES
|
||
BUG. (CHK,KLPMCR,KLPSER,HARD,<Received an unexpected MCNF or MDATREC>,<<Q1,NODE>>,)
|
||
POPJ P, ;RETURN
|
||
;RECEIVED A CLOSE BUFFER FINISHED INTERRUPT
|
||
|
||
INTCLB: SKIPN .PCMCN(Q3) ;IS THE DIAG. UUO EXPECTING THIS?
|
||
PJRST RETDG ;NO, RETURN THE DATAGRAM AND RETURN
|
||
MOVE T1,.PKBNM(Q2) ;YES, GET THE BUFFER NAME
|
||
CAME T1,.PCMCN(Q3) ;IS THIS THE ONE THE DIAG. EXPECTS?
|
||
PJRST RETDG ;NO, RETURN THE DATAGRAM AND RETURN
|
||
AOS .PCMCF(Q3) ;YES, SET THE FLAG
|
||
PUSHJ P,WAKMAI ;WAKE THE WAITING JOB
|
||
PJRST RETDG ;RETURN THE DATAGRAM AND RETURN
|
||
|
||
|
||
;RECEIVED A CLOSE-BUFFER WITH AN ERROR
|
||
|
||
CLBERR: LDB T2,PKYSFD ;GET STATUS FIELD LESS ERROR BIT
|
||
CAIE T2,PS.IBN ;IS IT AN INVALID BUFFER NAME ERROR?
|
||
BUG. (INF,KLPCLB,KLPSER,HARD,<Close buffer function failed>,<<T1,STATUS>>,)
|
||
PJRST INTCLB ;FINISH UP LIKE IT SUCCEEDED
|
||
|
||
|
||
;ROUTINE TO WAKE THE JOB WAITING FOR A MAINTENANCE OPERATION TO COMPLETE.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,WAKMAI
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
WAKMAI: MOVE T1,.PCMJB(Q3) ;GET THE JOB
|
||
SNCALL (WAKJOB##,MCSEC0) ;WAKE THEM UP
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO PUT A PACKET ON THE DATAGRAM FREE QUEUE.
|
||
;CALL:
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,RETDG
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
RETDG: XMOVEI T1,.PCDFQ(Q3) ;POINT AT THE PROPER QUEUE
|
||
PJRST PUTQUE ;RETURN THE PACKET AND RETURN
|
||
|
||
|
||
;ROUTINE TO PUT A PACKET ON THE MESSAGE FREE QUEUE.
|
||
;CALL:
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,RETMSG
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
RETMSG: XMOVEI T1,.PCMFQ(Q3) ;POINT AT THE PROPER QUEUE
|
||
PJRST PUTQUE ;RETURN THE PACKET AND RETURN
|
||
SUBTTL INTERRUPT LEVEL ERROR PROCESSING
|
||
|
||
|
||
;ROUTINE CALLED TO PRINT AN ERROR TEXT ON A CRAM PARITY ERROR.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,KLECPE
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
KLECPE: XJRST [MCSEC1+KLECP1] ;MUST EXECUTE IN SECTION 1 FOR INLMES CALLS
|
||
|
||
$HIGH
|
||
KLECP1: MOVE T1,.PCCRA(Q3) ;GET THE CRAM ADDRESS
|
||
CAIL T1,PPEFST ;IS THIS A PLANNED CRAM PARITY ERROR?
|
||
CAILE T1,PPELST ;...
|
||
STOPCD CPOPJ,INFO,KLPCPE,CPETYP ;++KLIPA CRAM PARITY ERROR
|
||
STOPCD CPOPJ,INFO,KLPHLT,HLTTYP ;++KLIPA MICROPROCESSOR HALT
|
||
|
||
;ROUTINE CALLED FROM DIE ON AN UNPLANNED CRAM PARITY ERROR
|
||
|
||
CPETYP: PUSHJ P,INLMES## ;PRINT TEXT
|
||
ASCIZ /CI20 CRAM parity error
|
||
CRAM location /
|
||
MOVE T1,.PCCRA(Q3) ;GET THE CRAM ADDRESS
|
||
PUSHJ P,PRTDI8## ;PRINT IN OCTAL
|
||
PUSHJ P,INLMES## ;TYPE OUT CRAM CONTENTS
|
||
ASCIZ /, CRAM contents /
|
||
MOVE T1,.PCCDL(Q3) ;GET FIRST CRAM HALFWORD
|
||
PUSHJ P,HWDPNT## ;PRINT AS HALFWORDS
|
||
PUSHJ P,PRSPC## ;SPACE OVER
|
||
MOVE T1,.PCCDR(Q3) ;GET SECOND CRAM HALFWORD
|
||
PJRST HWDPNT## ;PRINT AS HALFWORDS AND RETURN (DIE ADDS CRLF)
|
||
|
||
;ROUTINE CALLED FROM DIE ON A PLANNED CRAM PARITY ERROR
|
||
|
||
HLTTYP: PUSHJ P,INLMES## ;PRINT TEXT
|
||
ASCIZ /CI20 microprocessor halted - /
|
||
MOVE T1,.PCCRA(Q3) ;GET THE CRAM ADDRESS
|
||
HRRZ T1,CPETXT-PPEFST(T1) ;GET ERROR TEXT ADDRESS
|
||
PJRST CONMES## ;PRINT AND RETURN (DIE ADDS CRLF)
|
||
|
||
$XHIGH
|
||
;ROUTINE TO FINISH UP PROCESSING OF A CRAM PARITY ERROR.
|
||
;MUST BE CALLED AFTER REPORT AS IT DEPENDS ON SOME
|
||
;OF THE DATA WHICH REPORT STORES IN THE PCB.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,KLPCPD
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
KLPCPD: MOVE T1,.PCCRA(Q3) ;GET THE LAR
|
||
SUBI T1,PPEFST ;OFFSET TO FIRST PLANNED CRAM PARITY ERROR
|
||
SKIPGE T1 ;PLANNED CRAM PARITY ERROR?
|
||
MOVEI T1,CPEUNP ;NO, SET DISPATCH FOR UNPLANNED CRAM PARITY ERROR
|
||
PUSHJ P,@CPEDSP(T1) ;CALL THE APPROPRIATE ROUTINE
|
||
PJRST RSTEWD ;ZERO THE PCB ERROR WORDS AND RETURN
|
||
;MACRO TO DEFINE CLEAN-UP ROUTINE AND TEXT STRING FOR CRAM PARITY ERRORS.
|
||
|
||
DEFINE ERRS,<
|
||
|
||
XALL ;;LIST GENERATED TABLE
|
||
|
||
CPE 7750, CPEDON, <Internal port error>
|
||
CPE 7751, CPEDON, <Self test failed>
|
||
CPE 7752, CPEDON, <EBUS parity error>
|
||
CPE 7753, EPEDON, <EBUS parity error>
|
||
CPE 7754, CPEDON, <PLI parity error>
|
||
CPE 7755, CPEDON, <CBUS parity error>
|
||
CPE 7756, CPEDON, <Data path error>
|
||
CPE 7757, CPEDON, <CBUS request error>
|
||
CPE 7760, CPEDON, <EBUS request error>
|
||
CPE 7761, CPEDON, <Grant CSR error>
|
||
CPE 7762, CPEDON, <Short word count>
|
||
CPE 7763, CPEDON, <Spurious channel error>
|
||
CPE 7764, CPEDON, <Spurious transmit attention error>
|
||
CPE 7765, CPEDON, <Spurious receive attention error>
|
||
CPE 7766, CPEDON, <Transmitter timeout>
|
||
CPE 7767, CPEDON, <Unknown halt code 7767>
|
||
CPE 7770, CPEDON, <Unknown halt code 7770>
|
||
CPE 7771, CPEDON, <Unknown halt code 7771>
|
||
CPE 7772, CPEDON, <Unknown halt code 7772>
|
||
CPE 7773, CPEDON, <Unknown halt code 7773>
|
||
CPE 7774, CPEDON, <Unknown halt code 7774>
|
||
CPE 7775, CPEDON, <Unknown halt code 7775>
|
||
CPE 7776, CPEDON, <Unknown halt code 7776>
|
||
CPE 7777, CPEDON, <Unknown halt code 7777>
|
||
|
||
SALL
|
||
|
||
>; END DEFINE ERRS
|
||
;GENERATE CLEAN-UP ROUTINE TABLE
|
||
|
||
DEFINE CPE(LOC,ADDR,TEXT),<
|
||
IF1,<IFN <<LOC-PPEFST>-<.-CPEDSP>>,<PRINTX ?Table CPEDSP entry LOC is out of order>>
|
||
IFIW ADDR ;'LOC' 'TEXT
|
||
>; END DEFINE CPE
|
||
|
||
CPEDSP: ERRS ;GENERATE CLEAN-UP ROUTINE ADDRESS
|
||
CPEUNP==.-CPEDSP ;OFFSET FOR UNPLANNED CRAM PARITY ERROR
|
||
IFIW KLPUNP ;XXXX UNPLANNED CRAM PARITY ERROR
|
||
;GENERATE ERROR TEXT TABLE
|
||
|
||
DEFINE CPE(LOC,ADDR,TEXT),<
|
||
IF1,<IFN <<LOC-PPEFST>-<.-CPETXT>>,<PRINTX ?Table CPETXT entry LOC is out of order>>
|
||
[ASCIZ |TEXT|] ;'LOC'
|
||
>; END DEFINE CPE
|
||
|
||
$HIGH ;MUST BE TYPE-ABLE
|
||
CPETXT: ERRS ;GENERATE ERROR TEXT TABLE
|
||
$XHIGH
|
||
;HERE WHEN CRAM PARITY ERROR PROCESSING IS DONE
|
||
|
||
CPEDON: PUSHJ P,CLNKLP ;CLEAN UP THE QUEUES
|
||
CPEDN1: PUSHJ P,STRKLP ;RESTART THE KLIPA
|
||
PJRST RLDKLP ;FAILED, RELOAD IT
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;EBUS PARITY ERROR (QUEUES MESSED UP)
|
||
|
||
EPEDON: MOVX T1,E0.RES ;RESPONSE QUEUE HAVE ERROR?
|
||
TDNN T1,.PCER0(Q3) ;...
|
||
JRST EPEDN1 ;NO
|
||
XMOVEI T1,.PCRSQ(Q3) ;YES, GET RESPONSE QUEUE INTERLOCK WORD
|
||
MAP T2,.PQFLI(T1) ;GET THE FLINK
|
||
TXZ T2,MP.NAD ;CLEAR JUNK BITS
|
||
MOVEM T2,.PQFLI(T1) ;MAKE FLINK POINT AT ITSELF
|
||
MOVEM T2,.PQBLI(T1) ;MAKE BLINK POINT AT FLINK
|
||
JRST EPEDN2 ;CONTINUE
|
||
|
||
EPEDN1: MOVX T1,CI.RQA ;IS A RESPONSE QUEUE AVAILABLE?
|
||
TDNE T1,.PCCSR(Q3) ;...
|
||
PUSHJ P,KLPRQC ;YES, PROCESS THE RESPONSES
|
||
EPEDN2: MOVX T1,E0.CMD ;COMMAND QUEUE ERROR?
|
||
TDNN T1,.PCER0(Q3) ;...
|
||
PJRST CPEDN1 ;NO, DONE
|
||
LOAD T2,E0QUE,(Q3) ;YES, GET THE COMMAND QUEUE NUMBER
|
||
IMULI T2,.PQLEN ;TIMES LENGTH OF AN ENTRY
|
||
XMOVEI T1,.PCCQ0(Q3) ;ADDRESS OF COMMAND QUEUE 0 INTERLOCK WORD
|
||
SUB T1,T2 ;MOVE TO THE CORRECT INTERLOCK WORD
|
||
PUSHJ P,CLENCQ ;CLEAN ALL QUEUES EXCEPT THE BAD ONE
|
||
PJRST CPEDN1 ;RESTART THE KLIPA
|
||
;UNPLANNED CRAM PARITY ERROR (0000-7747)
|
||
|
||
KLPUNP: XMOVEI T1,.PCQBG(Q3) ;START OF THE QUEUES
|
||
XMOVEI T4,.PCQND(Q3) ;END OF THE QUEUES
|
||
KLPUN1: MAP T2,.PQFLI(T1) ;GET FLINK
|
||
TXZ T2,MP.NAD ;CLEAR JUNK BITS
|
||
MOVEM T2,.PQFLI(T1) ;MAKE FLINK POINT AT ITSELF
|
||
MOVEM T2,.PQBLI(T1) ;MAKE BLINK POINT AT FLINK
|
||
ADDI T1,.PQLEN ;ADVANCE TO NEXT QUEUE
|
||
CAMGE T1,T4 ;DONE THEM ALL?
|
||
JRST KLPUN1 ;NO
|
||
PUSHJ P,STKDFQ ;RE-STOCK THE DATAGRAM FREE QUEUE
|
||
PJRST RLDKLP ;RELOAD THE KLIPA AND RETURN
|
||
;ROUTINE TO CLEAN ALL QUEUES AND PROCESS ANY RESPONSES.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,CLNKLP
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CLNKLP: XMOVEI T1,.PCRSQ(Q3) ;GET ADDRESS OF RESPONSE QUEUE
|
||
PUSHJ P,CHKMPT ;IS RESPONSE QUEUE EMPTY?
|
||
SKIPA ;YES
|
||
PUSHJ P,KLPRQC ;NO, CLEAN THE RESPONSE QUEUE
|
||
SETZ T1, ;FLAG WE SHOULD CLEAN ALL QUEUES
|
||
PJRST CLENCQ ;CLEAN THE COMMAND QUEUES AND RETURN
|
||
|
||
|
||
;ROUTINE TO CLEAN THE COMMAND QUEUES
|
||
;CALL:
|
||
; T1/ 0 OR ADDRESS OF QUEUE WHICH IS BAD
|
||
; Q3/ PCB
|
||
; PUSHJ P,CLENCQ
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CLENCQ: STKVAR <IWORD,BADQI> ;ALLOCATE SOME STACK STORAGE
|
||
MOVEM T1,BADQI ;SAVE ADDRESS OF .PQIWD FOR BAD QUEUE
|
||
XMOVEI T1,.PCCQB(Q3) ;GET ADDRESS OF FIRST COMMAND QUEUE
|
||
CLENC1: MOVEM T1,IWORD ;SAVE ACROSS CALLS TO CLNCOM
|
||
SETOM .PQIWD(T1) ;RESET THE INTERLOCK
|
||
CAME T1,BADQI ;IS THIS THE BAD ONE?
|
||
JRST CLENC2 ;NO
|
||
MAP T2,.PQFLI(T1) ;YES, GET ADDRESS OF FLINK
|
||
TXZ T2,MP.NAD ;CLEAR JUNK BITS
|
||
MOVEM T2,.PQFLI(T1) ;MAKE FLINK POINT AT ITSELF
|
||
MOVEM T2,.PQBLI(T1) ;MAKE BLINK POINT AT FLINK
|
||
JRST CLENC3 ;CONTINUE
|
||
|
||
CLENC2: PUSHJ P,CLNCOM ;CLEAN THE COMMAND QUEUE
|
||
CLENC3: MOVE T1,IWORD ;WHERE WE WERE
|
||
ADDI T1,.PQLEN ;STEP TO NEXT QUEUE ENTRY
|
||
XMOVEI T2,.PCCQE(Q3) ;END OF THE COMMAND QUEUES
|
||
CAMGE T1,T2 ;GONE PAST THE END?
|
||
JRST CLENC1 ;NO, DO NEXT COMMAND QUEUE
|
||
POPJ P, ;RETURN
|
||
|
||
ENDSV. ;END OF STACK VARIABLE RANGE
|
||
;ROUTINE TO CLEAN AN INDIVIDUAL COMMAND QUEUE
|
||
;CALL:
|
||
; T1/ ADDRESS OF QUEUE'S INTERLOCK WORD
|
||
; Q3/ PCB
|
||
; PUSHJ P,CLNCOM
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CLNCOM: STKVAR <IWORD> ;ALLOCATE A WORD OF STACK STORAGE
|
||
MOVEM T1,IWORD ;STASH ADDRESS OF INTERLOCK WORD
|
||
CLNCM1: PUSHJ P,REMQUE ;GET A PACKET FROM THE QUEUE
|
||
POPJ P, ;QUEUE EMPTY, DONE
|
||
MOVX T1,PK.SCA ;IS PACKET TO BE RETURNED TO SCA?
|
||
TDNE T1,.PKVRT(Q2) ;...
|
||
JRST CLNCM2 ;YES
|
||
PUSHJ P,TOSSIT ;NO, RETURN IT TO PROPER FREE QUEUE
|
||
JRST CLNCM3 ;CONTINUE
|
||
|
||
CLNCM2: SETO P3, ;SAY PACKET WAS LOCALLY GENERATED
|
||
MOVE P5,Q3 ;GET PCB ADDRESS
|
||
LDB T1,PKYNOD ; OFFSET FOR THIS NODE
|
||
ADD P5,T1 ;...
|
||
MOVE P5,.PCPBK(P5) ;GET PBK ADDRESS
|
||
CIOFF ;PREVENT INTERRUPTS WHILE IN SCA LAND
|
||
PUSHJ P,GV2SCA ;GIVE THE PACKET TO SCA
|
||
CION ;OK TO INTERRUPT
|
||
CLNCM3: MOVE T1,IWORD ;RESTORE ADDRESS OF INTERLOCK WORD
|
||
JRST CLNCM1 ;GO GET NEXT PACKET
|
||
|
||
ENDSV. ;END OF STACK VARIABLE RANGE
|
||
;ROUTINE TO STOP, RESET, AND RESTART THE KLIPA
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,URDEAD
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
URDEAD: CIOFF ;PREVENT RACES
|
||
PUSHJ P,STPKLP ;STOP THE KLIPA
|
||
PUSHJ P,CIGONE ;RESET ALL CI ACTIVITY
|
||
PUSH P,W ;SAVE AN AC
|
||
MOVE W,Q3 ;COPY KDB ADDRESS
|
||
PUSHJ P,DMPIPA## ;DUMP THE KLIPA DRAM
|
||
JFCL ;FAILED, DON'T REALLY CARE
|
||
POP P,W ;RESTORE W
|
||
PUSHJ P,RLDKLP ;RELOAD THE KLIPA
|
||
PJRST CIONPJ## ;TURN INTERRUPTS BACK ON AND RETURN
|
||
|
||
|
||
;ROUTINE TO RESET ALL CI ACTIVITY.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CIGONE
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CIGONE: PUSHJ P,NONODS ;INFORM SCA OF DEPARTED NODES
|
||
PUSHJ P,RSTRID ;RESET REQUEST-ID STATUS
|
||
PUSHJ P,RSTLKS ;RESET QUEUE INTERLOCKS IN PCB
|
||
PJRST CLNKLP ;CLEAN THE QUEUES AND RETURN
|
||
|
||
|
||
;ROUTINE TO TELL SCA ABOUT THE DISAPPEARANCE OF EACH NODE
|
||
;WITH AN OPEN VC WHEN THE KLIPA CROAKS.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,NONODS
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
NONODS: SAVEAC <P1,P2,P4,P5> ;SAVE THE AC'S WE NEED
|
||
MOVE P1,Q3 ;GET PCB ADDRESS
|
||
MOVEI P2,MAXNDS ;NUMBER OF ENTRIES
|
||
NONOD1: SKIPN P5,.PCPBK(P1) ;GET A PATH BLOCK ADDRESS
|
||
JRST NONOD2 ;NONE?
|
||
SETZ Q2, ;GET YOUR OWN PACKET
|
||
SETO P4, ;WE NEED A SHUTDOWN PACKET
|
||
PUSHJ P,CLOSV1 ;CLOSE THE VC AND TELL SCA
|
||
NONOD2: SOJLE P2,CPOPJ## ;RETURN IF NO MORE NODES LEFT
|
||
AOJA P1,NONOD1 ;YES, OFFSET TO NEXT NODE AND LOOP
|
||
;CLEAR QUEUE INTERLOCKS
|
||
;CALL WITH:
|
||
; Q3/ PCB
|
||
; PUSHJ P,RSTLKS
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
RSTLKS: SETOM .PCCQ3+.PQIWD(Q3) ;COMMAND QUEUE 3
|
||
SETOM .PCCQ2+.PQIWD(Q3) ;COMMAND QUEUE 2
|
||
SETOM .PCCQ1+.PQIWD(Q3) ;COMMAND QUEUE 1
|
||
SETOM .PCCQ0+.PQIWD(Q3) ;COMMAND QUEUE 0
|
||
SETOM .PCRSQ+.PQIWD(Q3) ;RESPONSE QUEUE
|
||
SETOM .PCMFQ+.PQIWD(Q3) ;MESSAGE FREE QUEUE
|
||
SETOM .PCDFQ+.PQIWD(Q3) ;DATAGRAM FREE QUEUE
|
||
SETOM .PCRFQ+.PQIWD(Q3) ;RESERVED FREE QUEUE
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;CLEAR THE ERROR WORDS
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,RSTEWD
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
RSTEWD: SETZM .PCER0(Q3) ;ERROR WORD 0
|
||
SETZM .PCER1(Q3) ;ERROR WORD 1
|
||
SETZM .PCER2(Q3) ;ERROR WORD 2
|
||
SETZM .PCER3(Q3) ;ERROR WORD 3
|
||
SETZM .PCER4(Q3) ;ERROR WORD 4
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO RESET THE PCB QUEUES.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,RSTQS
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
RSTQS: XMOVEI T1,.PCQBG(Q3) ;POINT AT FIRST QUEUE ENTRY TRIPLET
|
||
XMOVEI T4,.PCQND(Q3) ;POINT AT END OF QUEUE ENTRY TRIPLETS
|
||
RSTQS1: SETOM .PQIWD(T1) ;SET THE INTERLOCK WORD
|
||
MAP T2,.PQFLI(T1) ;GET VIRTUAL ADDRESS OF FORWARD LINK
|
||
TXZ T2,MP.NAD ;CLEAR JUNK BITS
|
||
MOVEM T2,.PQFLI(T1) ;MAKE FLINK POINT AT ITSELF
|
||
MOVEM T2,.PQBLI(T1) ;MAKE BLINK POINT AT FLINK
|
||
ADDI T1,.PQLEN ;ADD LENGTH OF THE QUEUE ENTRY TRIPLET
|
||
CAMGE T1,T4 ;PAST THE END?
|
||
JRST RSTQS1 ;NO, LOOP FOR OTHER QUEUE ENTRY TRIPLETS
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;ROUTINE TO STOCK THE DATAGRAM FREE QUEUE.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,STKDFQ
|
||
;RETURN:
|
||
; CPOPJ ONLY IF SUCCEEDED
|
||
|
||
STKDFQ: MOVNI T1,2*MAXNDS ;GET TWO DATAGRAM BUFFERS FOR EACH NODE
|
||
; (INDICATE WE WANT TO OVER-RIDE THRESHOLD CHECK)
|
||
PUSHJ P,SC.ALD## ;GET THEM FROM SCA
|
||
BUG. (HLT,KLPNOD,KLPSER,SOFT,<Can't stock datagram free queue>,,)
|
||
MOVE Q2,T1 ;POSITION THE FIRST BUFFER ADDRESS
|
||
XMOVEI T1,.PCDFQ(Q3) ;QUEUE ON WHICH TO INSERT PACKET
|
||
PJRST LNKQUE ;LINK THE PACKETS ON THE FREE QUEUE AND RETURN
|
||
;ROUTINE CALLED TO PROCESS AN MBUS ERROR.
|
||
;MUST BE CALLED AFTER REPORT AS IT DEPENDS ON SOME
|
||
;OF THE DATA WHICH REPORT STORES IN THE PCB.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,KLPMBD
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
KLPMBD: MOVE T1,.PCCSR(Q3) ;GET CONI
|
||
MOVE T2,.PCCRA(Q3) ;GET LAR
|
||
DMOVE T3,.PCCDL(Q3) ;GET TWO DATA WORDS
|
||
BUG. (INF,KLPMBE,KLPSER,HARD,<MBUS error>,<<T1,CSR>,<T2,LAR>,<T3,CRAM1>,<T4,CRAM2>>,)
|
||
PUSHJ P,STRKLP ;RESTART THE KLIPA
|
||
PJRST RLDKLP ;FAILED, RELOAD THE MICROCODE
|
||
POPJ P, ;RETURN
|
||
;ROUTINE CALLED TO PROCESS A FREE QUEUE ERROR.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,KLPFQE
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
KLPFQE: MOVE T1,.PCPIA(Q3) ;GET PI ASSIGNMENT
|
||
TRO T1,CO.EPE!CO.FQE!CO.BTS ;FREE QUEUE ERROR, EBUS PARITY
|
||
XCT KDBCNO(Q3) ;CLEAR BITS
|
||
XMOVEI T1,.PCDFQ(Q3) ;ADDRESS OF QUEUE
|
||
PUSHJ P,CHKMPT ;IS QUEUE EMPTY?
|
||
SKIPA ;YES
|
||
JRST KLPFQ2 ;NO
|
||
BUG. (INF,KLPDFQ,KLPSER,SOFT,<Datagram free queue empty>,,)
|
||
MOVEI T1,1 ;GET A DATAGRAM BUFFER
|
||
PUSHJ P,SC.ALD## ;ASK SCA
|
||
JRST KLPFQ1 ;COULDN'T
|
||
MOVE Q2,T1 ;POSITION THE BUFFER ADDRESS
|
||
PUSHJ P,RETDG ;PUT IT ON THE DATAGRAM FREE QUEUE
|
||
KLPFQ1: MOVSI T1,1 ;COUNT A DATAGRAM FREE QUEUE ERROR
|
||
ADDM T1,.PCFQE(Q3) ;...
|
||
POPJ P, ;RETURN
|
||
|
||
KLPFQ2: XMOVEI T1,.PCMFQ(Q3) ;ADDRESS OF QUEUE
|
||
PUSHJ P,CHKMPT ;IS QUEUE EMPTY?
|
||
SKIPA ;YES
|
||
JRST KLPFQ4 ;NO
|
||
BUG. (INF,KLPMFQ,KLPSER,SOFT,<Message free queue empty>,,)
|
||
MOVEI T1,1 ;GET A MESSAGE BUFFER
|
||
PUSHJ P,SC.ABF## ;ASK SCA
|
||
JRST KLPFQ3 ;COULDN'T
|
||
MOVE Q2,T1 ;POSITION THE BUFFER ADDRESS
|
||
PUSHJ P,RETMSG ;PUT IT ON THE MESSAGE FREE QUEUE
|
||
KLPFQ3: MOVEI T1,1 ;COUNT A MESSAGE FREE QUEUE ERROR
|
||
ADDM T1,.PCFQE(Q3) ;...
|
||
POPJ P, ;RETURN
|
||
|
||
KLPFQ4: BUG. (INF,KLPSFQ,KLPSER,SOFT,<Spurious free queue error>,,)
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO RECORD PORT ERROR INFORMATION IN THE PCB AND
|
||
;MAKE A SPEAR ENTRY.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,REPORT
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
REPORT: PUSHJ P,SAVE1## ;SAVE P1 FOR A BIT
|
||
MOVE P1,DATE## ;GET NOW
|
||
SUB P1,.PCLKE(Q3) ;HOW LONG SINCE LAST ERROR
|
||
CAIGE P1,RSTIME ;HAS IT SCREWED UP LATELY?
|
||
TDZA P1,P1 ;NO, WE'LL RESTART IT
|
||
MOVEI P1,1 ;YES, WE'LL LEAVE IT STOPPED
|
||
MOVE T1,DATE## ;GET NOW
|
||
MOVEM T1,.PCLKE(Q3) ;UPDATE TIME OF LAST ERROR
|
||
PUSH P,W ;SAVE W
|
||
MOVE W,Q3 ;SET UP KDB ADDRESS
|
||
PUSHJ P,RDLAR## ;READ LATCHED ADDRESS REGISTER
|
||
SETZ T1, ;IGNORE ERRORS
|
||
MOVEM T1,.PCCRA(Q3) ;SAVE IT
|
||
PUSHJ P,RDIPA## ;READ THAT CRAM ADDRESS
|
||
SETZB T2,T3 ;CHANNEL RUNNING?
|
||
MOVEM T2,.PCCDL(Q3) ;SAVE LH CRAM WORD
|
||
MOVEM T3,.PCCDR(Q3) ;SAVE RH CRAM WORD
|
||
POP P,W ;RESTORE W
|
||
MOVE T1,.PCLGO(Q3) ;CHANNEL LOGOUT AREA ADDRESS
|
||
DMOVE T2,0(T1) ;GET FIRST TWO WORDS OF CHANNEL LOGOUT AREA
|
||
DMOVEM T2,.PCLG0(Q3) ;SAVE THEM
|
||
MOVE T2,2(T1) ;GET THIRD WORD
|
||
MOVEM T2,.PCLG2(Q3) ;SAVE IT
|
||
MOVE T1,.PCCCW(Q3) ;GET PORT'S CCW
|
||
MOVEM T1,.PCECW(Q3) ;SAVE IT
|
||
|
||
;WITH THE NECESSARY DATA GATHERED TRY TO MAKE A SPEAR ENTRY
|
||
MOVEI T1,KP%LEN ;LENGTH OF ERROR BLOCK
|
||
PUSHJ P,ALCSEB## ;ALLOCATE SYSTEM ERROR BLOCK
|
||
POPJ P, ;SORRY, WE TRIED
|
||
MOVEI T2,SEC%KP ;GET THE ERROR CODE
|
||
DPB T2,[POINT 9,.EBTYP(T1),8] ;STORE THE TYPE IN THE HEADER
|
||
MOVE T2,.PCCSR(Q3) ;GET CONI AT INTERRUPT
|
||
MOVEM T2,.EBHDR+KP%CSR(T1) ;STORE IT
|
||
HRRZ T2,.PCULB+.ULVER(Q3) ;GET KLIPA MICROCODE VERSION
|
||
LDB T3,[POINT 3,KDBDVC(Q3),35] ;GET RH20 NUMBER
|
||
DPB T3,[POINTR (T2,KP%CHN)] ;SET INTERNAL CHANNEL NUMBER
|
||
MOVEM T2,.EBHDR+KP%VER(T1) ;STORE IT
|
||
; MOVEI T2,2(P1) ;GET DISPOSITION CODE
|
||
SETZ T2, ;STORE A ZERO LIKE TOPS-20 DOES
|
||
MOVEM T2,.EBHDR+KP%DSP(T1) ;STORE IT
|
||
MOVE T2,.PCCRA(Q3) ;GET CRAM ADDRESS
|
||
MOVEM T2,.EBHDR+KP%CRA(T1) ;STORE IT
|
||
DMOVE T2,.PCCDL(Q3) ;GET CRAM DATA
|
||
DMOVEM T2,.EBHDR+KP%CRD(T1) ;STORE IT
|
||
DMOVE T2,.PCLG0(Q3) ;GET FIRST TWO LOGOUT WORDS
|
||
DMOVEM T2,.EBHDR+KP%LG0(T1) ;STORE THEM
|
||
MOVE T2,.PCLG2(Q3) ;GET THIRD LOGOUT WORD
|
||
MOVEM T2,.EBHDR+KP%LG2(T1) ;STORE IT
|
||
MOVE T2,.PCECW(Q3) ;GET PORT'S CCW AT ERROR
|
||
MOVEM T2,.EBHDR+KP%ECW(T1) ;STORE IT
|
||
DMOVE T2,.PCER0(Q3) ;GET ERROR WORDS
|
||
DMOVEM T2,.EBHDR+KP%PE0(T1) ;STORE THEM
|
||
PJRST QUESEB## ;QUEUE THE BLOCK AND RETURN
|
||
SUBTTL MISCELLANEOUS KLIPA ROUTINES
|
||
|
||
|
||
;ROUTINE TO START THE KLIPA.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,STRKLP
|
||
;RETURN:
|
||
; CPOPJ IF COULDN'T START KLIPA
|
||
; CPOPJ1 IF KLIPA STARTED
|
||
|
||
STRKLP: PUSHJ P,RSTEWD ;RESET THE PCB ERROR WORDS
|
||
PUSHJ P,KIKKLP ;KICK THE KLIPA
|
||
JRST STRKL1 ;IT FAILED
|
||
PUSHJ P,PIAKLP ;GIVE THE KLIPA A PI ASSIGNMENT
|
||
BUG. (INF,KLPSTR,KLPSER,HARD,<CI20 restarted>,,)
|
||
MOVX T1,ST.RDY ;KLIPA NEEDS TO SEND REQUEST-IDS
|
||
ANDCAM T1,.PCSTS(Q3) ;CLEAR FLAG SO PPDSEC KNOWS
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
STRKL1: MOVX T1,ST.DED ;IS THE SECOND TIME WE'VE TRIED TO START THE KLIPA?
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
JRST STRKL2 ;YES, IT MUST BE DEAD
|
||
IORM T1,.PCSTS(Q3) ;NO, SET THE FLAG FOR NEXT TIME
|
||
BUG. (INF,KLPRSF,KLPSER,HARD,<CI20 restart failed>,,)
|
||
POPJ P, ;RETURN
|
||
|
||
STRKL2: BUG. (INF,KLPDED,KLPSER,HARD,<CI20 is dead>,,)
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;ROUTINE TO STOP THE KLIPA.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,STPKLP
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
STPKLP: PUSHJ P,DISKLP ;PUT KLIPA IN DISABLED STATE
|
||
JFCL ;DON'T REALLY CARE
|
||
MOVEI T1,CO.CPT ;CLEAR PORT
|
||
XCT KDBCNO(Q3) ;...
|
||
MOVX T1,ST.DED ;SAY IT'S DEAD
|
||
IORM T1,.PCSTS(Q3) ;...
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO RELOAD THE KLIPA MICROCODE AND START THE KLIPA.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,RLDKLP
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
|
||
;ROUTINE TO RELOAD THE KLIPA MICROCODE AND START THE KLIPA.
|
||
;SIMILAR TO RLDKLP BUT TAKES SKIP RETURN IF RELOAD SUCCEEDED.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,RLDKLI
|
||
;RETURN:
|
||
; CPOPJ IF RELOAD FAILED
|
||
; CPOPJ1 IF RELOAD SUCCEEDED
|
||
|
||
RLDKLP: TDZA T1,T1 ;INDICATE RLDKLP ENTRY
|
||
RLDKLI: MOVEI T1,1 ;INDICATE RLDKLI ENTRY
|
||
PUSHJ P,SAVE1## ;SAVE P1
|
||
MOVE P1,T1 ;SAVE ENTRY INDICATOR
|
||
PUSHJ P,KLPLOD ;LOAD THE KLIPA MICROCODE
|
||
JUMPE T1,RLDKL3 ;NO VERSION MEANS NO UCODE LOADED
|
||
PUSHJ P,KIKKLP ;KICK THE KLIPA
|
||
JRST RLDKL2 ;FAILED
|
||
JUMPN P1,CPOPJ1## ;SKIP PI ASSIGNMENT, ETC., IF INITIALIZATION
|
||
PJRST PIAKLP ;GIVE THE KLIPA A PI ASSIGNMENT AND RETURN
|
||
|
||
RLDKL2: BUG. (INF,KLPRLF,KLPSER,HARD,<CI20 microcode reload failed>,,)
|
||
|
||
RLDKL3: MOVX T1,ST.DED ;SAY IT'S DEAD
|
||
IORM T1,.PCSTS(Q3) ;...
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO GET THE KLIPA READY TO RUN.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,KIKKLP
|
||
;RETURN:
|
||
; CPOPJ IF COULDN'T GET IT READ
|
||
; CPOPJ1 IF KLIPA READY TO RUN
|
||
;
|
||
;CLEARS ST.DED IF KLIPA ENTERED ENABLED STATE.
|
||
|
||
KIKKLP: PUSHJ P,RSTRID ;RESET REQUEST-ID INFO
|
||
MOVE T1,.PCLGO(Q3) ;ADDRESS OF CHANNEL LOGOUT AREA
|
||
MOVE T2,.PCPBA(Q3) ;GET PHYSICAL ADDRESS OF PCB
|
||
ADD T2,[FLD(.CCFTH,CC.OPC)!FLD(3,CC.WDC)!FLD(<.PCPBA-.PCPCB>,CC.ADR)]
|
||
; SET INITIAL CCW TO TRANSFER .PCPBA, .PCPIA,
|
||
; AND .PCAL1 TO THE KLIPA
|
||
MOVEM T2,.CSICW(T1) ;STORE IN THE CHANNEL LOGOUT AREA
|
||
MOVSI T2,(.DOLRA) ;ADDRESS = 0
|
||
XCT KDBDTO(Q3) ;SET START ADDRESS
|
||
PUSHJ P,DISKLX ;PUT KLIPA IN DISABLED STATE
|
||
POPJ P, ;WE COULDN'T MAKE IT
|
||
MOVE T1,.PCLGO(Q3) ;ADDRESS OF CHANNEL LOGOUT AREA AGAIN
|
||
MOVE T2,.PCPBA(Q3) ;GET PHYSICAL ADDRESS OF PCB
|
||
ADD T2,[FLD(.CCJMP,CC.OPC)!FLD(<.PCCCW-.PCPCB>,CC.ADR)] ;JUMP CCW
|
||
; FOR THE KLIPA TO USE
|
||
MOVEM T2,.CSICW(T1) ;STORE IN THE CHANNEL LOGOUT AREA
|
||
PUSHJ P,ENAKLP ;PUT KLIPA IN ENABLED STATE
|
||
POPJ P, ;WE COULND'T MAKE IT
|
||
MOVE T1,.CPUPT## ;RESET KEEP-ALIVE TIMER
|
||
MOVEM T1,.PCKRT(Q3) ; TO PREVENT SPURIOUS KLPKAF
|
||
MOVX T1,ST.DED ;KLIPA ISN'T DEAD
|
||
ANDCAM T1,.PCSTS(Q3) ;...
|
||
JRST CPOPJ1## ;SUCCESS
|
||
|
||
|
||
;ROUTINE TO GIVE THE KLIPA ITS PI ASSIGNMENT.
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,PIAKLP
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
PIAKLP: MOVE T1,.PCPIA(Q3) ;GET PI ASSIGNMENT
|
||
TRO T1,CO.BTS ;PLUS GOOD BITS
|
||
XCT KDBCNO(Q3) ;BIT IT ITS PI ASSIGNMENT
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO MAKE THE KLIPA ENTER THE DISABLED STATE.
|
||
;CALL:
|
||
; PUSHJ P,DISKLP
|
||
;RETURN:
|
||
; CPOPJ IF DIDN'T ENTER DISABLED STATE
|
||
; CPOPJ1 IF KLIPA IN DISABLED STATE
|
||
|
||
DISKLP: XCT KDBCNI(Q3) ;READ STATUS
|
||
TRNN T1,CI.MRN ;MICROCODE RUNNING?
|
||
JRST CPOPJ1## ;NO, THEN DON'T NEED TO STOP IT
|
||
|
||
DISKLX: MOVEI T1,CO.DIS+CO.MRN ;GO FROM UNINITIALIZED TO DISABLED
|
||
XCT KDBCNO(Q3) ;...
|
||
MOVEI T2,5000 ;LOOP COUNT
|
||
DISKL1: XCT KDBCNI(Q3) ;READ STATUS
|
||
TXNE T1,CI.DCP ;DISABLE COMPLETE?
|
||
AOSA (P) ;YES, SET FOR SKIP RETURN
|
||
SOJG T2,DISKL1 ;NO, WAIT A BIT
|
||
POPJ P, ;DIDN'T MAKE IT
|
||
|
||
|
||
;ROUTINE TO MAKE THE KLIPA ENTER THE ENABLED STATE.
|
||
;CALL:
|
||
; PUSHJ P,ENAKLP
|
||
;RETURN:
|
||
; CPOPJ IF DIDN'T ENTER ENABLED STATE
|
||
; CPOPJ1 IF KLIPA ENABLED
|
||
|
||
ENAKLP: MOVEI T1,CO.RQA!CO.BTS ;GO FROM DISABLED TO ENABLED
|
||
XCT KDBCNO(Q3) ;...
|
||
MOVEI T2,5000 ;LOOP COUNT
|
||
ENAKL1: XCT KDBCNI(Q3) ;READ STATUS
|
||
TXNE T1,CI.ECP ;ENABLE COMPLETE?
|
||
AOSA (P) ;YES, SET FOR SKIP RETURN
|
||
SOJG T2,ENAKL1 ;NO, WAIT A BIT
|
||
POPJ P, ;DIDN'T MAKE IT
|
||
SUBTTL LOAD KLIPA MICROCODE
|
||
|
||
|
||
;ROUTINE TO LOAD THE KLIPA MICROCODE.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,KLPLOD
|
||
;RETURN:
|
||
; CPOPJ ALWAYS WITH:
|
||
; T1/ MICROCODE VERSION LOADED
|
||
|
||
KLPLOD: MOVEI T1,CO.CPT ;CLEAR PORT
|
||
XCT KDBCNO(Q3) ;...
|
||
PUSHJ P,SAVE4## ;SAVE P1-P4
|
||
XMOVEI P1,.PCULB(Q3) ;POINT TO MICROCODE LOADER BLOCK
|
||
MOVE T1,P1 ;COPY ADDRESS
|
||
PUSHJ P,BTUCOD## ;FIND THE MICROCODE
|
||
TDZA T1,T1 ;NOT AVAILABLE
|
||
JRST KLPLD1 ;ONWARD
|
||
PUSH P,T1 ;SAVE FAILURE FLAG
|
||
JRST KLPLD2 ;FINISH UP
|
||
|
||
KLPLD1: PUSH P,W ;SAVE W
|
||
MOVE W,Q3 ;SET UP KDB ADDRESS
|
||
MOVE T1,.ULADR(P1) ;GET ADDRESS OF MICROCODE STORAGE
|
||
PUSHJ P,LDIPA## ;LOAD THE CRAM
|
||
TDZA W,W ;CHANNEL IS RUNNING
|
||
MOVE W,.ULVER(P1) ;GET VERSION NUMBER
|
||
EXCH W,(P) ;RESTORE W, SAVE FLAG
|
||
MOVEI T1,.UEMPC ;MICROPROCESSOR CHECK
|
||
SKIPN (P) ;ANY ERRORS?
|
||
DPB T1,ULBEBP## ;STORE ERROR CODE
|
||
|
||
KLPLD2: MOVE T1,P1 ;COPY LOADER BLOCK ADDRESS
|
||
PUSHJ P,BTURPT## ;REPORT A SUCESSFUL LOAD OR FAILURE
|
||
POP P,T1 ;GET SUCCESS/FAILURE FLAG (VERSION WORD)
|
||
POPJ P, ;RETURN
|
||
SUBTTL SET MEMORY OFFLINE SUPPORT
|
||
|
||
|
||
;ROUTINE CALLED WHEN MONITOR MEMORY WILL BE SET OFFLINE.
|
||
;MARK EACH KLIPA TO BE SHUT DOWN BY THE ONCE/SECOND CODE.
|
||
;CALL:
|
||
; PUSHJ P,PPDMFL
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XSENT (PPDMFL::)
|
||
XMOVEI T1,PPDMF1 ;GET ROUTINE TO EXECUTE FOR EACH CPU
|
||
PJRST CPUAPP## ;DO IT
|
||
|
||
PPDMF1: MOVE T1,.CPBIT##-.CPCDB##(P1) ;GET CPU'S BIT
|
||
TSNN T1,IPAMSK## ;KLIPA START-UP INHIBITED?
|
||
SKIPN T2,.CPPCB##-.CPCDB##(P1) ;THIS CPU HAVE A KLIPA?
|
||
POPJ P, ;NO, RETURN
|
||
MOVX T1,ST.MFL ;GET THE APPROPRIATE FLAG
|
||
IORM T1,.PCSTS(T2) ;REMEMBER TO SHUTDOWN THE KLIPA
|
||
POPJ P, ;RETURN
|
||
;ROUTINE CALLED WHEN MONITOR MEMORY HAS BEEN SET OFFLINE AND IT
|
||
;IS SAFE TO RESTORE THE STATE OF THE WORLD.
|
||
;CALL:
|
||
; PUSHJ P,PPDMON
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XSENT (PPDMON::)
|
||
PUSHJ P,BHDCLR ;CLEAR THE BHD AREA
|
||
PUSHJ P,BSDLNK ;RE-LINK THE BSD AREA
|
||
XMOVEI T1,PPDMO1 ;GET ROUTINE TO EXECUTE FOR EACH CPU
|
||
PJRST CPUAPP## ;DO IT
|
||
|
||
PPDMO1: MOVE T1,.CPBIT##-.CPCDB##(P1) ;GET CPU'S BIT
|
||
TSNN T1,IPAMSK## ;KLIPA START-UP INHIBITED?
|
||
SKIPN T2,.CPPCB##-.CPCDB##(P1) ;THIS CPU HAVE A KLIPA?
|
||
POPJ P, ;NO, RETURN NOW
|
||
MOVX T1,ST.MFL ;GET THE MEMORY OFFLINE FLAG
|
||
TDNN T1,.PCSTS(T2) ;WAS THE KLIPA SHUT DOWN?
|
||
POPJ P, ;NO
|
||
ANDCAM T1,.PCSTS(T2) ;CLEAR THE MEMORY OFFLINE FLAG
|
||
MOVX T1,ST.RES ;FLAG WE CAN RESTART THE KLIPA NOW
|
||
IORM T1,.PCSTS(T2) ;...
|
||
POPJ P, ;RETURN
|
||
SUBTTL REMOVE A CPU
|
||
|
||
|
||
;ROUTINE CALLED WHEN REMOVING A CPU.
|
||
;CALL:
|
||
; PUSHJ P,PPDRMV
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XSENT (PPDRMV::)
|
||
PUSHJ P,SAVQ## ;SAVE THE "Q" REGISTERS
|
||
SKIPN Q3,.CPPCB## ;GET PCB ADDRESS
|
||
POPJ P, ;NO KLIPA ON THIS CPU
|
||
MOVX T1,ST.MAI ;SEE IF IN MAINTENANCE MODE
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
POPJ P, ;DON'T CAUSE OTHER PROBLEMS
|
||
PJRST PPDS10 ;SHUT DOWN THE KLIPA, TELL SCA, ETC, AND RETURN
|
||
SUBTTL KLIPA ONCE PER TICK CODE
|
||
|
||
|
||
;ONCE A TICK CODE FOR THE KLIPA.
|
||
;CALL:
|
||
; PUSHJ P,PPDTIC
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XSENT (PPDTIC::)
|
||
PUSHJ P,SAVQ## ;SAVE THE "Q" REGISTERS
|
||
SKIPN Q3,.CPPCB## ;GET PCB ADDRESS
|
||
POPJ P, ;NO KLIPA ON THIS CPU
|
||
MOVE T1,.PCSTS(Q3) ;GET STATUS
|
||
TXNN T1,ST.DED!ST.MAI ;SKIP IF DEAD OR IN MAINTENANCE MODE
|
||
TXNN T1,ST.CQA ;DO WE NEED TO KICK THE KLIPA?
|
||
POPJ P, ;RETURN
|
||
MOVX T1,ST.CQA ;GET THE "KICK KLIPA" BIT
|
||
ANDCAM T1,.PCSTS(Q3) ;CLEAR THE BIT
|
||
MOVE T1,.PCPIA(Q3) ;GET PI ASSIGNMENT
|
||
TRO T1,CO.CQA+CO.BTS ;COMMAND QUEUE AVAILABLE
|
||
XCT KDBCNO(Q3) ;KICK THE PORT
|
||
POPJ P, ;NOT MUCH ELSE TO DO
|
||
SUBTTL KLIPA ONCE PER SECOND CODE
|
||
|
||
|
||
;ONCE A SECOND CODE FOR THE KLIPA.
|
||
;CALL:
|
||
; PUSHJ P,PPDSEC
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XSENT (PPDSEC::)
|
||
MOVSI T1,(CR.ATO) ;BIT TO TEST
|
||
TDNE T1,.CPRUN## ;WAITING FOR AUTCON TO RUN?
|
||
POPJ P, ;THEN DO NOTHING
|
||
PUSHJ P,SAVPQ## ;SAVE LOTS OF AC'S
|
||
SKIPN Q3,.CPPCB## ;GET PCB ADDRESS
|
||
POPJ P, ;NO KLIPA ON THIS CPU?
|
||
|
||
;FIRST CHECK FOR UNUSUAL CONDITIONS
|
||
|
||
MOVE T1,.PCSTS(Q3) ;GET THE IMPORTANT FLAGS
|
||
TXNE T1,ST.MAI ;IS KLIPA IN MAINTENANCE MODE?
|
||
POPJ P, ;YES, GO AWAY
|
||
TXNE T1,ST.MFL ;MEMORY GOING OFFLINE?
|
||
JRST PPDS10 ;YES
|
||
TXNE T1,ST.RES ;TIME TO RESTART KLIPA?
|
||
JRST PPDS20 ;YES
|
||
|
||
;NOTHING UNUSUAL, SEE IF KLIPA IS READY TO ROLL
|
||
|
||
TXNE T1,ST.DED ;KLIPA DEAD?
|
||
POPJ P, ;YES, QUIT
|
||
XCT KDBCNI(Q3) ;GET KLIPA STATUS
|
||
TXNE T1,CI.ENA ;YES, ENABLED?
|
||
JRST PPDSC1 ;YES
|
||
STOPCD .+1,INFO,KLPNEN ;++KLIPA NOT ENABLED (LOST PI ASSIGNMENT)
|
||
PJRST URDEAD ;START OVER
|
||
|
||
;KLIPA IS RUNNING, DO ALL THE CHECKS
|
||
|
||
PPDSC1: MOVX T1,ST.RDY ;IS KLIPA READY TO ROLL?
|
||
TDNN T1,.PCSTS(Q3) ;...
|
||
PJRST PPDCSS ;NO, MUST DO COMMON START-UP STUFF
|
||
PUSHJ P,CHKKAF ;CHECK FOR KEEP ALIVE FAILURE
|
||
POPJ P, ;SKIP REST OF CHECKS THIS SECOND
|
||
PUSHJ P,CHKPCB ;CHECK THE PCB
|
||
PUSHJ P,CHKWIR ;CHECK CI WIRES
|
||
PUSHJ P,CHKRTO ;CHECK FOR REQUEST-ID TIMEOUTS
|
||
PUSHJ P,CHKSTO ;CHECK FOR START SEQUENCE TIMEOUTS
|
||
PUSHJ P,CHKOPC ;CHECK FOR DEFERRED OPENS AND CLOSES
|
||
PUSHJ P,CHKPOL ;POLL THE NEXT NODE WITH A REQUEST-ID
|
||
PUSHJ P,CHKCTR ;CHECK FOR PERIODIC READ-COUNTERS
|
||
POPJ P, ;RETURN
|
||
;HERE IF JUST (RE)STARTED THE KLIPA - MUST ASK FOR IT'S CI NODE
|
||
;NUMBER AND SEND REQUEST-ID PACKETS TO EACH NODE ON THE NETWORK.
|
||
|
||
PPDCSS: SKIPL .PCONN(Q3) ;OUR NODE NUMBER KNOWN?
|
||
JRST PPDCS2 ;YES, DO REQUEST-ID POLLING
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
POPJ P, ;TRY AGAIN LATER
|
||
MOVEI T1,.RGNOD ;REGISTER TO READ
|
||
PUSHJ P,KLPRRG ;SEND A READ REGISTER PACKET
|
||
MOVEI T1,100000 ;GET A SPIN COUNT
|
||
PPDCS1: SKIPL .PCONN(Q3) ;OUR NODE NUMBER RETURNED YET?
|
||
JRST PPDCS2 ;YES, PROCEED
|
||
SOJG T1,PPDCS1 ;NO, WAIT FOR A WHILE
|
||
POPJ P, ;SORRY
|
||
|
||
PPDCS2: PUSHJ P,RSTRID ;ZERO TIMERS AND STATUS
|
||
SETZ Q1, ;START WITH FIRST NODE NUMBER
|
||
PPDCS3: CAMN Q1,.PCONN(Q3) ;SAME AS OUR NODE NUMBER?
|
||
JRST PPDCS4 ;YES, DON'T ASK
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
JRST PPDCS5 ;NONE AVAILABLE, LET PPDSEC DO IT
|
||
SETZ T3, ;LET THE KLIPA SELECT A PATH, NO RESPONSE NEEDED
|
||
PUSHJ P,KLPRID ;SEND A REQUEST-ID
|
||
|
||
PPDCS4: CAIGE Q1,MAXNDS-1 ;TRIED ALL NODES?
|
||
AOJA Q1,PPDCS3 ;NO, LOOP FOR REMAINDER
|
||
|
||
PPDCS5: MOVEI T1,CTRTIM ;SECONDS UNTIL FIRST PERIODIC READ-COUNTERS
|
||
MOVEM T1,.PCCTM(Q3) ;START IT OFF RIGHT
|
||
MOVX T1,ST.RDY ;SHOW KLIPA IS READY FOR USE
|
||
IORM T1,.PCSTS(Q3) ;...
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO CHECK FOR KLIPA KEEP ALIVE FAILURE.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CHKKAF
|
||
;RETURN:
|
||
; CPOPJ IF KLIPA RESTARTED/RELOADED
|
||
; CPOPJ1 IF KLIPA STILL APPEARS TO BE RUNNING
|
||
|
||
CHKKAF: MOVE T1,.CPUPT## ;GET CPU UPTIME
|
||
SUB T1,.PCKRT(Q3) ;CALCULATE TIME SINCE LAST KLIPA RESPONSE
|
||
IMULI T1,^D1000 ;CONVERT TO MILLISECONDS
|
||
IDIV T1,TICSEC## ;...
|
||
CAIGE T1,KAFTIM ;TOO LONG SINCE LAST RESPONSE?
|
||
JRST CHKKF1 ;NO, GO CHECK KLIPA IDLE TIMER
|
||
XCT KDBCNI(Q3) ;READ STATUS
|
||
MOVEM T1,.PCKCI(Q3) ;SAVE CONI FOR LATER SNOOPING
|
||
MOVEI T1,CO.CPT ;CLEAR PORT
|
||
XCT KDBCNO(Q3) ;...
|
||
STOPCD .+1,INFO,KLPKAF ;++KLIPA KEEP ALIVE FAILED
|
||
AOS .PCKAC(Q3) ;UPDATE COUNT OF KLIPA KEEP ALIVE FAILURES
|
||
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
|
||
MOVEM T1,.PCKAT(Q3) ;REMEMBER TIME OF LAST KEEP ALIVE FAILURE
|
||
PJRST URDEAD ;DO KLIPA ERROR STOP PROCESSING AND RETURN
|
||
|
||
CHKKF1: AOS (P) ;SET FOR SKIP RETURN, LOOKS LIKE KLIPA IS RUNNING
|
||
MOVE T1,.CPUPT## ;GET CPU UPTIME
|
||
SUB T1,.PCKCT(Q3) ;CALCULATE TIME SINCE LAST COMMAND QUEUED
|
||
IMULI T1,^D1000 ;CONVERT TO MILLISECONDS
|
||
IDIV T1,TICSEC## ;...
|
||
CAIGE T1,IDLTIM ;TOO LONG SINCE LAST COMMAND?
|
||
POPJ P, ;NO, ALL DONE
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
POPJ P, ;WE TRIED, TRY AGAIN NEXT SECOND
|
||
MOVEI T1,.RGNOD ;WHICH REGISTER TO READ
|
||
PJRST KLPRRG ;SEND THE READ-REGISTER PACKET AND RETURN
|
||
;ROUTINE TO CHECK SOME LOCATIONS IN THE PCB.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CHKPCB
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CHKPCB: MAP T1,.PCPCB(Q3) ;GET PHYSICAL ADDRESS
|
||
TXZ T1,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
CAME T1,.PCPBA(Q3) ;HAS IT CHANGED WITHOUT US KNOWING?
|
||
CHKPC1: BUG. (HLT,KLPPIC,KLPSER,SOFT,<PCB is corrupted>,,)
|
||
MOVE T1,.PCMQE(Q3) ;GET MESSAGE SIZE
|
||
CAIE T1,C%MGSZ ;PCB STILL CORRECT?
|
||
JRST CHKPC1 ;NO
|
||
XCT KDBCNI(Q3) ;READ STATUS
|
||
ANDI T1,CI.PIA ;KEEP JUST PI ASSIGNMENT
|
||
CAMN T1,.PCPIA(Q3) ;SAME AS WHAT PCB SAYS IT IS?
|
||
POPJ P, ;YES, OK
|
||
BUG. (INF,KLPPIA,KLPSER,HARD,<CI20 has lost its PI assignment>,,)
|
||
PJRST URDEAD ;TRY TO START OVER
|
||
;ROUTINE TO CHECK THE CI WIRES BY SENDING LOOPBACK PACKETS.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CHKWIR
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CHKWIR: MOVE Q1,.PCONN(Q3) ;GET OUR NODE NUMBER
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
POPJ P, ;DON'T SWEAT IT
|
||
MOVE T2,LPBCRC(Q1) ;GET THE PROPER CRC
|
||
MOVEM T2,LPBLEN-1(Q2) ;STASH THE CRC
|
||
MOVEI T1,OP.LPB ;OPCODE
|
||
MOVEI T2,KLPDRG ;PRIORITY
|
||
MOVX T3,ST.PTH ;WHICH PATH WAS LAST LOOPBACK SENT ON?
|
||
TDNN T3,.PCSTS(Q3) ;...
|
||
JRST CHKWI1 ;PATH A, USE PATH B THIS TIME
|
||
ANDCAM T3,.PCSTS(Q3) ;CLEAR FLAG
|
||
MOVX T3,PF.PT0 ;GET THE PATH SELECT BIT
|
||
JRST CHKWI2 ;SEND THE PACKET
|
||
|
||
CHKWI1: IORM T3,.PCSTS(Q3) ;SET FLAG
|
||
MOVX T3,PF.PT1 ;GET THE PATH SELECT BIT
|
||
CHKWI2: SETZM .PKLEN(Q2) ;NO LENGTH
|
||
PJRST DRVSND ;SEND THE PACKET AND RETURN
|
||
;ROUTINE TO CHECK FOR REQUEST-ID TIMEOUTS.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CHKRTO
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CHKRTO: SETZ Q1, ;START WITH NODE NUMBER ZERO
|
||
CHKRT1: MOVE P1,Q3 ;GET PCB ADDRESS
|
||
ADD P1,Q1 ; OFFSET BY CI NODE NUMBER
|
||
SKIPE T1,.PCRIT(P1) ;TIMER ON?
|
||
CAMLE T1,DATE## ;YES, TIMED OUT?
|
||
JRST CHKRT6 ;NO, NEXT NODE
|
||
MOVE T1,.PCRIS(P1) ;GET REQUEST-ID STATUS
|
||
TXNN T1,RI.TRY ;WAS THIS THE FIRST TIME?
|
||
JRST CHKRT5 ;YES, TRY A SECOND TIME
|
||
TXNN T1,RI.WFR ;STILL WAITING FOR PORT TO RESPOND?
|
||
JRST CHKRT2 ;NO
|
||
BUG. (INF,KLPHNG,KLPSER,HARD,<CI20 is hung>,,)
|
||
PJRST URDEAD ;TRY TO START OVER
|
||
|
||
;LOOKS LIKE THE REMOTE PORT IS SICK
|
||
|
||
CHKRT2: LOAD T1,IDNOR,(P1) ;GET NUMBER OF NO RESPONSES
|
||
CAIGE T1,MAXNOR ;HAVE WE TRIED ENOUGH?
|
||
JRST CHKRT3 ;NO, TRY AGAIN
|
||
BUG. (INF,KLPNOR,KLPSER,SOFT,<Remote port is sick>,<<Q1,NODE>>,)
|
||
SETZRO IDNOR,(P1) ;START OVER
|
||
JRST CHKRT4 ;...
|
||
|
||
CHKRT3: ADDI T1,1 ;INCREMENT COUNT
|
||
STOR T1,IDNOR,(P1) ;...
|
||
CHKRT4: MOVX T1,RI.TRY!RI.WFR ;CLEAR SECOND TRY FLAG, WAITING FOR RESPONSE
|
||
ANDCAM T1,.PCRIS(P1) ;...
|
||
POPJ P, ;WAIT FOR MORE HAVOC
|
||
;THE FIRST REQUEST-ID TRY HAS TIMED OUT
|
||
|
||
CHKRT5: PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
POPJ P, ;NONE AVAILABLE, TRY AGAIN LATER
|
||
MOVX T1,RI.TRY!RI.WFR ;SECOND TRY, WAITING FOR RESPONSE
|
||
IORB T1,.PCRIS(P1) ;SET THE FLAGS
|
||
MOVX T3,PF.RSP ;SAY WE WANT A RESPONSE
|
||
TXNN T1,RI.PTH ;WHICH PATH SHOULD WE SEND IT ON?
|
||
TXOA T3,PF.PT0 ;PATH A
|
||
TXO T3,PF.PT1 ;PATH B
|
||
PUSHJ P,KLPRID ;SEND THE REQUEST-ID
|
||
PUSHJ P,NXTRID ;MOVE POLLER TO NEXT NODE
|
||
CHKRT6: CAIL Q1,MAXNDS-1 ;WAS THIS THE LAST NODE?
|
||
POPJ P, ;YES, RETURN
|
||
AOJA Q1,CHKRT1 ;CHECK NEXT NODE
|
||
;ROUTINE TO CHECK START SEQUENCE TIMERS.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CHKSTO
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CHKSTO: SETZ Q1, ;START WITH NODE NUMBER ZERO
|
||
CHKST1: MOVE P1,Q3 ;GET PCB ADDRESS
|
||
ADD P1,Q1 ; OFFSET BY CI NODE NUMBER
|
||
SKIPN P5,.PCPBK(P1) ;GET A PATH BLOCK ADDRESS
|
||
JRST CHKST2 ;NOTHING THERE
|
||
SKIPE T1,.PBSST(P5) ;GET EXPIRATION TIME, SKIP IF NOT RUNNING
|
||
CAMLE T1,DATE## ;TIMER EXPIRED?
|
||
JRST CHKST2 ;NO, TRY NEXT ONE
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
JRST CHKST2 ;NONE AVAILABLE, TRY AGAIN NEXT SECOND
|
||
LOAD T1,PBVCST,(P5) ;GET VIRTUAL CIRCUIT STATE
|
||
CAIE T1,VC.STS ;START-SENT?
|
||
SKIPA T1,[PP.STK] ;NO, GET STACK CODE
|
||
MOVEI T1,PP.STA ;YES, GET START CODE
|
||
PUSHJ P,STRTDT ;MAKE THE PACKET
|
||
PUSHJ P,KLPSDG ;SEND IT
|
||
PUSHJ P,STSST ;START THE TIMER
|
||
CHKST2: CAIL Q1,MAXNDS-1 ;WAS THIS THE LAST NODE?
|
||
POPJ P, ;YES, RETURN
|
||
AOJA Q1,CHKST1 ;CHECK NEXT NODE
|
||
;ROUTINE TO PERFORM REGULAR REQUEST-ID POLLING.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CHKPOL
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CHKPOL: MOVE Q1,.PCRIN(Q3) ;GET POLLER'S NEXT NODE
|
||
PUSHJ P,CHKIDT ;IS REQUEST-ID TIMER ALREADY RUNNING?
|
||
PJRST INCRID ;YES, MOVE POLLER TO NEXT NODE
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
POPJ P, ;NONE AVAILABLE, TRY AGAIN LATER
|
||
PUSHJ P,GTNPTH ;GET NEXT PATH FOR REQUEST-ID
|
||
PUSHJ P,KLPRID ;SEND THE REQUEST-ID
|
||
PJRST INCRID ;MOVE POLLER TO NEXT NODE AND RETURN
|
||
|
||
|
||
;ROUTINE TO PERFORM PERIODIC READ-COUNTERS COMMAND.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CHKCTR
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CHKCTR: SOSLE .PCCTM(Q3) ;TIME TO SEND THE NEXT ONE?
|
||
POPJ P, ;NOT YET
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
POPJ P, ;NONE AVAILABLE, TRY AGAIN NEXT SECOND
|
||
MOVEI T1,CTRTIM ;RESET TIMEOUT
|
||
MOVEM T1,.PCCTM(Q3) ;...
|
||
MOVX T2,KS%PER ;REASON FOR READ-COUNTERS
|
||
PJRST KLPRPT ;SEND THE PACKET AND RETURN
|
||
;ROUTINE TO CHECK FOR DEFERRED CLOSES AND OPENS.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CHKOPC
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CHKOPC: SETZ Q1, ;START WITH NODE NUMBER ZERO
|
||
CHKOP1: MOVE P1,Q3 ;GET PCB ADDRESS
|
||
ADD P1,Q1 ; OFFSET BY CI NODE NUMBER
|
||
SKIPN P5,.PCPBK(P1) ;IS THERE PATH TO THIS NODE?
|
||
JRST CHKOP3 ;NO
|
||
MOVX T1,PB.NTC ;DOES IT NEED TO BE CLOSED?
|
||
TDNN T1,.PBFLG(P5) ;...
|
||
JRST CHKOP2 ;NO
|
||
PUSHJ P,KLPGDB ;YES, GET A DATAGRAM BUFFER
|
||
POPJ P, ;NONE AVAILABLE, TRY AGAIN LATER
|
||
PUSHJ P,KLPCLO ;TELL PORT TO CLOSE THE VC
|
||
MOVX T1,PB.NTC ;NO LONGER TRYING TO CLOSE
|
||
ANDCAM T1,.PBFLG(P5) ;...
|
||
MOVX T1,PB.WFI ;FLAG WAITING FOR IDREC
|
||
IORM T1,.PBFLG(P5) ;...
|
||
|
||
CHKOP2: MOVE T1,.PBFLG(P5) ;GET FLAGS BACK
|
||
TXNE T1,PB.OKO ;OK TO OPEN?
|
||
TXNN T1,PB.WFI ;YES, STILL WAITING FOR A NEW IDREC?
|
||
JRST CHKOP3 ;NOT OK TO OPEN OR NOT WAITING FOR AN IDREC
|
||
PUSHJ P,CHKIDT ;ALREADY HAVE A REQUEST-ID OUTSTANDING?
|
||
JRST CHKOP3 ;YES, DON'T SEND ANOTHER
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
POPJ P, ;NONE AVAILABLE, TRY AGAIN LATER
|
||
PUSHJ P,GTNPTH ;GET NEXT PATH FOR REQUEST-ID
|
||
PUSHJ P,KLPRID ;SEND THE REQUEST-ID
|
||
CHKOP3: CAIL Q1,MAXNDS-1 ;WAS THIS THE LAST NODE?
|
||
POPJ P, ;YES, RETURN
|
||
AOJA Q1,CHKOP1 ;CHECK NEXT NODE
|
||
|
||
;MEMORY IS GOING TO BE SET OFFLINE WHICH WILL AFFECT THE KLIPA.
|
||
;SHUT IT DOWN IN AN ORDERLY FASHION SO IT CAN BE RESTARTED LATER.
|
||
|
||
PPDS10: MOVX T1,ST.DED ;HAVE WE ALREADY DONE THIS?
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
POPJ P, ;YES, NOTHING MORE TO DO
|
||
CIOFF ;PREVENT RACES
|
||
PUSHJ P,STPKLP ;STOP THE KLIPA
|
||
PUSHJ P,CIGONE ;RESET ALL CI ACTIVITY
|
||
CION ;ALLOW INTERRUPTS AGAIN
|
||
SETZM .PCFQC(Q3) ;INITIALIZE THE COUNTER
|
||
PPDS12: XMOVEI T1,.PCDFQ(Q3) ;POINT AT DATAGRAM FREE QUEUE
|
||
PUSHJ P,REMQUE ;GET AN ENTRY FROM THE QUEUE
|
||
JRST PPDS13 ;EMPTY
|
||
MOVE T1,Q2 ;COPY PACKET ADDRESS
|
||
PUSHJ P,SC.RLD## ;GIVE IT BACK TO SCA
|
||
MOVSI T1,1 ;COUNT ANOTHER ONE
|
||
ADDM T1,.PCFQC(Q3) ;...
|
||
JRST PPDS12 ;LOOP FOR MORE
|
||
|
||
PPDS13: XMOVEI T1,.PCMFQ(Q3) ;POINT AT MESSAGE FREE QUEUE
|
||
PUSHJ P,REMQUE ;GET AN ENTRY FROM THE QUEUE
|
||
JRST PPDS14 ;EMPTY
|
||
MOVE T1,Q2 ;COPY PACKET ADDRESS
|
||
PUSHJ P,SC.RBF## ;GIVE IT BACK TO SCA
|
||
MOVEI T1,1 ;COUNT ANOTHER ONE
|
||
ADDM T1,.PCFQC(Q3) ;...
|
||
JRST PPDS13 ;LOOP FOR MORE
|
||
|
||
PPDS14:
|
||
; XMOVEI T1,.PCRFQ(Q3) ;POINT AT RESERVED FREE QUEUE
|
||
; PUSHJ P,REMQUE ;GET AN ENTRY FROM THE QUEUE
|
||
; JRST PPDS15 ;EMPTY
|
||
; MOVE T1,Q2 ;COPY PACKET ADDRESS
|
||
; PUSHJ P,SC.RRD## ;GIVE IT BACK TO SCA
|
||
; MOVEI T1,1 ;COUNT ANOTHER ONE
|
||
; ADDM T1,.PCXXX(Q3) ;...
|
||
; JRST PPDS14 ;LOOP FOR MORE
|
||
|
||
;PPDS15:
|
||
POPJ P, ;RETURN
|
||
;MEMORY IS STABLE AFTER BEING SET OFFLINE. RESTART THE KLIPA
|
||
;AFTER POSSIBLY RE-LINKING THE FREE QUEUES.
|
||
|
||
PPDS20: PUSHJ P,PCBINI ;INITIALIZE THE PCB
|
||
PUSHJ P,RSTKQS ;RESTOCK THE DATAGRAM/MESSAGE FREE QUEUES
|
||
MOVX T1,ST.RES ;GET THE RESTART FLAG
|
||
ANDCAM T1,.PCSTS(Q3) ;KLIPA NO LONGER NEEDS RESTARTING
|
||
PJRST RLDKLP ;RELOAD THE KLIPA AND GET IT GOING
|
||
;ROUTINE TO RESTOCK THE DATAGRAM AND MESSAGE FREE QUEUES. CALLED AFTER
|
||
;KLIPA HAS BEEN SHUT DOWN.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,RSTKQS
|
||
;RETURN:
|
||
|
||
RSTKQS: HLRZ T1,.PCFQC(Q3) ;GET RESTOCK COUNT
|
||
JUMPE T1,RSTKQ1 ;JUMP IF NOTHING THERE ORIGINALLY
|
||
PUSHJ P,SC.ALD## ;ASK SCA FOR THE DATAGRAMS BACK
|
||
STOPCD RSTKQ1,INFO,KLPCRD, ;++CAN'T RESTOCK DATAGRAM FREE QUEUE
|
||
MOVE Q2,T1 ;COPY ADDRESS OF FIRST PACKET
|
||
XMOVEI T1,.PCDFQ(Q3) ;POINT AT DATAGRAM FREE QUEUE
|
||
PUSHJ P,LNKQUE ;PUT THE PACKETS BACK ON THE FREE QUEUE
|
||
RSTKQ1: HRRZ T1,.PCFQC(Q3) ;GET RESTOCK COUNT
|
||
JUMPE T1,RSTKQ2 ;JUMP IF NOTHING THERE ORIGINALLY
|
||
PUSHJ P,SC.ABF## ;ASK SCA FOR THE MESSAGES BACK
|
||
STOPCD RSTKQ2,INFO,KLPCRM, ;++CAN'T RESTOCK MESSAGE FREE QUEUE
|
||
MOVE Q2,T1 ;COPY ADDRESS OF FIRST PACKET
|
||
XMOVEI T1,.PCMFQ(Q3) ;POINT AT MESSAGE FREE QUEUE
|
||
PUSHJ P,LNKQUE ;PUT THE PACKETS BACK ON THE FREE QUEUE
|
||
RSTKQ2:
|
||
;GET COUNT, GET DATAGRAMS HERE
|
||
; XMOVEI T1,.PCRFQ(Q3) ;POINT AT RESERVED FREE QUEUE
|
||
; PUSHJ P,LNKQUE ;PUT THE PACKETS BACK ON THE FREE QUEUE
|
||
RSTKQ3: SETZM .PCFQC(Q3) ;ZAP OUT RESTOCK COUNT
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO UPDATE REQUEST-ID POLLER'S NEXT NODE.
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,NXTRID
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
NXTRID: CAMN Q1,.PCRIN(Q3) ;IS THIS THE NEXT NODE TO POLL?
|
||
PJRST INCRID ;YES, INCREMENT AND RETURN
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;ROUTINE TO INCREMENT THE POLLER'S NEXT NODE NUMBER.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,INCRID
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
INCRID: AOS T1,.PCRIN(Q3) ;BUMP THE NEXT NODE NUMBER
|
||
CAILE T1,MAXNDS-1 ;TOO HIGH?
|
||
INCRI1: SETZB T1,.PCRIN(Q3) ;YES, WRAP TO ZERO
|
||
CAMN T1,.PCONN(Q3) ;IS IT OUR NODE?
|
||
JRST INCRID ;YES, DON'T TALK TO OURSELVES
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;ROUTINE TO RESET THE REQUEST-ID DATA IN THE PCB.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,RSTRID
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
RSTRID: MOVEI T1,MAXNDS-1 ;NUMBER OF WORDS TO ZERO
|
||
XMOVEI T2,.PCRIS(Q3) ;POINT AT REQUEST-ID STATUS WORDS
|
||
XMOVEI T3,.PCRIS+1(Q3) ;POINT AT SECOND WORD OF IT
|
||
SETZM (T2) ;ZERO FIRST WORD
|
||
EXTEND T1,[XBLT] ;ZERO THE REMAINDER
|
||
MOVEI T1,MAXNDS-1 ;NUMBER OF WORDS TO ZERO
|
||
XMOVEI T2,.PCRIT(Q3) ;POINT AT REQUEST-ID TIMER WORDS
|
||
XMOVEI T3,.PCRIT+1(Q3) ;POINT AT SECOND WORD OF IT
|
||
SETZM (T2) ;ZERO FIRST WORD
|
||
EXTEND T1,[XBLT] ;ZERO THE REMAINDER
|
||
PJRST INCRI1 ;RESET POLLER'S NEXT NODE TO ZERO AND RETURN
|
||
;GET CURRENT PATH FOR REQUEST-ID.
|
||
;CALL:
|
||
; T1/ PACKET STATUS WORD
|
||
; Q1/ NODE NUMBER
|
||
; Q3/ PCB ADDRESS
|
||
;RETURN:
|
||
; CPOPJ ALWAYS WITH:
|
||
; T3/ FLAGS FIELD SET WITH PATH SELECT
|
||
|
||
GTCPTH: MOVE T2,Q3 ;GET PCB ADDRESS
|
||
ADD T2,Q1 ; OFFSET FOR THIS NODE
|
||
TXNN T1,PF.PT0 ;DID PACKET ARRIVE ON PATH A?
|
||
JRST GTCPT1 ;NO
|
||
MOVX T1,RI.PTH ;INDICATE PATH A USED (CLEAR FLAG)
|
||
ANDCAM T1,.PCRIS(T2) ;...
|
||
MOVX T3,PF.PT0 ;USE PATH A FOR NEXT REQUEST-ID
|
||
POPJ P, ;RETURN
|
||
|
||
GTCPT1: MOVX T1,RI.PTH ;INDICATE PATH B USED (SET FLAG)
|
||
IORM T1,.PCRIS(T2) ;...
|
||
MOVX T3,PF.PT1 ;USE PATH B FOR NEXT REQUEST-ID
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;GET NEXT PATH FOR REQUEST-ID.
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,GTNPTH
|
||
;RETURN:
|
||
; CPOPJ ALWAYS WITH:
|
||
; T3/ FLAGS FIELD SET WITH PATH SELECT
|
||
|
||
GTNPTH: MOVE T1,Q3 ;GET PCB ADDRESS
|
||
ADD T1,Q1 ; OFFSET FOR THIS NODE
|
||
MOVX T2,RI.PTH ;WAS LAST REQUEST-ID ON PATH A?
|
||
TDNN T2,.PCRIS(T1) ;...
|
||
JRST GTNPT1 ;YES, USE PATH B THIS TIME
|
||
ANDCAM T2,.PCRIS(T1) ;CLEAR FLAG
|
||
MOVX T3,PF.PT0 ;GET PATH SELECT BIT
|
||
POPJ P, ;RETURN
|
||
|
||
GTNPT1: IORM T2,.PCRIS(T1) ;SET FLAG
|
||
MOVX T3,PF.PT1 ;GET PATH SELECT BIT
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO CHECK IF THE REQUEST-ID TIMER IS RUNNING FOR A NODE.
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,CHKRIT
|
||
;RETURN:
|
||
; CPOPJ IF TIMER IS RUNNING
|
||
; CPOPJ1 IF TIMER IS NOT RUNNING
|
||
|
||
CHKIDT: MOVE T1,Q3 ;GET PCB ADDRESS
|
||
ADD T1,Q1 ; OFFSET FOR THIS NODE
|
||
SKIPN .PCRIT(T1) ;TIMER RUNNING?
|
||
AOS (P) ;NO, SET FOR SKIP RETURN
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;ROUTINE TO SET START SEQUENCE TIMER.
|
||
;CALL:
|
||
; P5/ PBK ADDRESS
|
||
; PUSHJ P,STSST
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
STSST: MOVEI T1,STSTIM*3 ;CONVERT TIMER LENGTH TO UDT INCREMENTS
|
||
ADD T1,DATE## ;WHEN TIMER WILL EXPIRE
|
||
MOVEM T1,.PBSST(P5) ;SET THE EXPIRATION TIME
|
||
POPJ P, ;RETURN
|
||
SUBTTL SCS-PPD INTERFACE - SEND DATAGRAM/MESSAGE
|
||
|
||
|
||
;ROUTINE TO SEND A DATAGRAM.
|
||
;CALL:
|
||
; BLCAL. (PPDSDG,<SS.PBI,SS.PKT,SS.LEN,SS.FLG,SS.PRI,SS.PTH>)
|
||
;
|
||
;WHERE:
|
||
; SS.PBI - DESTINATION PATH BLOCK INDEX
|
||
; SS.PKT - ADDRESS OF PACKET
|
||
; SS.LEN - LENGTH OF PACKET
|
||
; SS.FLG - FLAGS (F.XXX)
|
||
; SS.PRI - COMMAND QUEUE PRIORITY
|
||
; SS.PTH - PATH SELECT (0 = AUTO, 1 = A, 2 = B)
|
||
;
|
||
;RETURN:
|
||
; CPOPJ IF ERRORS
|
||
; CPOPJ1 IF SUCCESS
|
||
|
||
$XBSUB (PPDSDG::,<SS.PBI,SS.PKT,SS.LEN,SS.FLG,SS.PRI,SS.PTH>)
|
||
MOVEI T1,OP.SDG ;OPCODE = SEND DATAGRAM
|
||
JRST SNDPKT ;JOIN COMMON CODE
|
||
|
||
|
||
;ROUTINE TO SEND A MESSAGE.
|
||
;CALL:
|
||
; BLCAL. (PPDSMS,<SS.PBI,SS.PKT,SS.LEN,SS.FLG,SS.PRI,SS.PTH>)
|
||
;
|
||
;WHERE:
|
||
; SS.PBI - DESTINATION PATH BLOCK INDEX
|
||
; SS.PKT - ADDRESS OF PACKET
|
||
; SS.LEN - LENGTH OF PACKET
|
||
; SS.FLG - FLAGS (F.XXX)
|
||
; SS.PRI - COMMAND QUEUE PRIORITY
|
||
; SS.PTH - PATH SELECT (0 = AUTO, 1 = A, 2 = B)
|
||
;
|
||
;RETURN:
|
||
; CPOPJ IF ERRORS
|
||
; CPOPJ1 IF SUCCESS
|
||
|
||
$XBSUB (PPDSMS::,<SS.PBI,SS.PKT,SS.LEN,SS.FLG,SS.PRI,SS.PTH>)
|
||
MOVEI T1,OP.SMS ;OPCODE = SEND MESSAGE
|
||
; JRST SNDPKT ;JOIN COMMON CODE
|
||
;HERE TO SEND THE PACKET - OPCODE IN T1
|
||
|
||
SNDPKT: PUSHJ P,SAVPQ## ;MIND YOUR P'S AND Q'S
|
||
MOVE P4,T1 ;SAVE THE OPCODE IN P4
|
||
SKIPLE P5,SS.PBI ;GET PATH BLOCK INDEX
|
||
CAIL P5,C%PBLL ;LEGAL?
|
||
POPJ P, ;NO, ERROR
|
||
SKIPN P5,PBLIST##-1(P5) ;GET PATH BLOCK ADDRESS
|
||
POPJ P, ;NONE? AN ERROR
|
||
MOVE Q2,SS.PKT ;GET THE PACKET ADDRESS
|
||
MOVE Q3,SS.FLG ;GET THE FLAGS
|
||
MOVE T4,SS.LEN ;GET THE PACKET LENGTH
|
||
TXNN Q3,F.SPM ;IS THIS HIGH DENSITY, I.E., LENGTH IN WORDS?
|
||
JRST SNDPK1 ;NO
|
||
MOVEI T1,1(T4) ;YES, GET A COPY, ROUNDED UP FOR LATER DIVIDE
|
||
IMULI T4,4 ;CONVERT WORD COUNT TO BYTE COUNT
|
||
IDIVI T1,2 ;GET THE NUMBER OF EXTRA BYTES LEFT OVER
|
||
ADD T4,T1 ;ADD FRACTIONAL PART TO WHOLE TO GET TOTAL
|
||
SNDPK1: DPB T4,PKYLEN ;STORE LENGTH IN PACKET
|
||
MOVEI T4,PP.DG-OP.SDG(P4) ;COMPUTE PPD BYTE
|
||
DPB T4,PKYPPD ;SAVE IT IN THE PACKET
|
||
PUSHJ P,MASAGE ;SWAP THE PPD BYTE AND ADJUST PACKET LENGTH
|
||
MOVE T1,P4 ;GET OPCODE IN T1
|
||
MOVE T2,SS.PRI ;PRIORITY
|
||
SETZ T3, ;CLEAR FLAGS REGISTER
|
||
TXNE Q3,F.RTB ;WANT A RESPONSE?
|
||
TXO T3,PF.RSP ;YES
|
||
TXNE Q3,F.SPM ;WANT HIGH DENSITY MODE?
|
||
TXO T3,PF.FMT ;YES
|
||
MOVE T4,SS.PTH ;GET PATH SELECT INFO
|
||
CAIN T4,1 ;WANT PATH A?
|
||
TXO T3,PF.PT0 ;YES
|
||
CAIN T4,2 ;WANT PATH B?
|
||
TXO T3,PF.PT1 ;YES
|
||
PJRST SENDVC ;SEND THE PACKET UNDER VIRTUAL CIRCUIT CONTROL
|
||
;NON-SKIP RETURN IF ERROR, SKIP RETURN IF SUCCESS
|
||
|
||
ENDBS. ;END OF BLSUB. RANGE
|
||
SUBTTL SCS-PPD INTERFACE - BLOCK DATA SERVICE
|
||
|
||
|
||
;ROUTINE TO SEND DATA.
|
||
;CALL:
|
||
; BLCAL. (PPDSND,<SS.SNM,SS.RNM,SS.SOF,SS.ROF,SS.CID>)
|
||
;
|
||
;WHERE:
|
||
; SS.SNM - SENDER'S BUFFER NAME
|
||
; SS.RNM - RECEIVER'S BUFFER NAME
|
||
; SS.SOF - SENDER'S BUFFER OFFSET
|
||
; SS.ROF - RECEIVER'S BUFFER OFFSET
|
||
; SS.CID - CONNECTION-ID
|
||
;
|
||
;RETURN:
|
||
; CPOPJ IF ERRORS
|
||
; CPOPJ1 IF SUCCESS
|
||
|
||
$XBSUB (PPDSND::,<SS.SNM,SS.RNM,SS.SOF,SS.ROF,SS.CID>)
|
||
MOVEI T1,OP.SDT ;OPCODE FOR SEND DATA
|
||
JRST SNDREC ;JOIN COMMON CODE
|
||
|
||
|
||
;ROUTINE TO REQUEST DATA.
|
||
;CALL:
|
||
; BLCAL. (PPDREQ,<SS.SNM,SS.RNM,SS.SOF,SS.ROF,SS.CID>)
|
||
;
|
||
;WHERE:
|
||
; SS.SNM - SENDER'S BUFFER NAME
|
||
; SS.RNM - RECEIVER'S BUFFER NAME
|
||
; SS.SOF - SENDER'S BUFFER OFFSET
|
||
; SS.ROF - RECEIVER'S BUFFER OFFSET
|
||
; SS.CID - CONNECTION-ID
|
||
;
|
||
;RETURN:
|
||
; CPOPJ IF ERRORS
|
||
; CPOPJ1 IF SUCCESS
|
||
|
||
$XBSUB (PPDREQ::,<SS.SNM,SS.RNM,SS.SOF,SS.ROF,SS.CID>)
|
||
MOVEI T1,OP.RD1 ;OPCODE FOR READ DATA
|
||
; JRST SNDREC ;JOIN COMMON CODE
|
||
;HERE TO FILL IN THE PACKET AND SEND IT OFF
|
||
|
||
SNDREC: PUSHJ P,SAVPQ## ;SAVE LOTS OF ACS
|
||
MOVE Q2,T1 ;SAVE OPCODE
|
||
MOVEI T1,1 ;GET ONE BUFFER
|
||
PUSHJ P,SC.ABF## ; FROM SCA
|
||
RETBAD () ;YOU LOST
|
||
EXCH T1,Q2 ;BUFFER ADDRESS IN Q2, OPCODE IN T1
|
||
MOVE T2,SS.SNM ;SENDER NAME
|
||
MOVE T3,T2 ;IF DOING A SEND, THIS IS OUR BUFFER NAME
|
||
MOVEM T2,.PKSNM(Q2) ;SAVE WHERE PORT WANTS SENDER NAME
|
||
MOVE T2,SS.RNM ;RECEIVER'S NAME
|
||
CAIN T1,OP.RD1 ;REQUEST DATA?
|
||
MOVE T3,T2 ;YES, THIS IS OUR BUFFER NAME
|
||
MOVEM T2,.PKRNM(Q2) ;SAVE WHERE PORT WANTS RECEIVER NAME
|
||
MOVE T2,SS.SOF ;SENDER OFFSET
|
||
MOVEM T2,.PKSOF(Q2) ;INTO PACKET
|
||
MOVE T2,SS.ROF ;RECEIVER OFFSET
|
||
MOVEM T2,.PKROF(Q2) ;INTO PACKET
|
||
MOVEM T3,.PKXID(Q2) ;SENDER OR RECEIVER BUFFER NAME INTO XID
|
||
MOVE T2,SS.CID ;CID INTO OTHER XID
|
||
MOVEM T2,.PKXID+1(Q2) ;SO WE CAN TELL SCA ON THE INTERRUPT
|
||
$LDCID T2,T2 ;GET CONNECTION BLOCK ADDRESS
|
||
MOVE P5,.CBPBK(T2) ;PATH BLOCK ADDRESS
|
||
LDB T2,[POINT BHSIDX,T3,BHPIDX] ;BHD INDEX FROM BUFFER NAME
|
||
ADD T2,BHDIPT ;POINT AT BHD TABLE ENTRY
|
||
MOVE T2,.BHLEN(T2) ;GET NIBBLE COUNT FROM BHD
|
||
LSH T2,-1+4 ;CONVERT TO BYTE COUNT AND THEN SHIFT IT
|
||
MOVEM T2,.PKXLN(Q2) ;SAVE AS TRANSACTION LENGTH
|
||
MOVEI T2,KLPMED ;PRIORITY
|
||
MOVX T3,PF.SIZ ;INDICATE 576-BYTE PACKETS
|
||
PUSHJ P,SENDVC ;SEND UNDER VIRTUAL CIRCUIT CONTROL
|
||
SKIPA ;IT FAILED
|
||
JRST CPOPJ1## ;IT SUCCEEDED
|
||
EXCH T1,Q2 ;SAVE ERROR CODE, GET BUFFER ADDRESS BACK
|
||
PUSHJ P,SC.RBF## ;RETURN BUFFER TO SCA
|
||
MOVE T1,Q2 ;RESTORE ERROR CODE
|
||
RETBAD () ;PASS ALONG THE ERROR
|
||
|
||
ENDBS. ;END OF BLSUB. RANGE
|
||
SUBTTL MAINTENANCE INTERFACE - SEND/REQUEST DATA
|
||
|
||
|
||
;ROUTINE TO SEND MAINTENANCE DATA.
|
||
;CALL:
|
||
; BLCAL. (PPDSMD,<SS.SNM,SS.RNM,SS.SOF,SS.ROF,SS.NOD>)
|
||
;
|
||
;WHERE:
|
||
; SS.SNM - SENDER'S BUFFER NAME
|
||
; SS.RNM - RECEIVER'S BUFFER NAME
|
||
; SS.SOF - SENDER'S BUFFER OFFSET
|
||
; SS.ROF - RECEIVER'S BUFFER OFFSET
|
||
; SS.NOD - NODE TO SEND PACKET TO
|
||
;
|
||
;RETURN:
|
||
; CPOPJ IF ERRORS
|
||
; CPOPJ1 IF SUCCESS
|
||
|
||
$XBSUB (PPDSMD::,<SS.SNM,SS.RNM,SS.SOF,SS.ROF,SS.NOD>)
|
||
MOVEI T1,OP.SMD ;OPCODE FOR SEND MAINTENANCE DATA
|
||
JRST SNDMAI ;JOIN COMMON CODE
|
||
|
||
|
||
;ROUTINE TO REQUEST MAINTENANCE DATA.
|
||
;CALL:
|
||
; BLCAL. (PPDRMD,<SS.SNM,SS.RNM,SS.SOF,SS.ROF,SS.NOD>)
|
||
;
|
||
;WHERE:
|
||
; SS.SNM - SENDER'S BUFFER NAME
|
||
; SS.RNM - RECEIVER'S BUFFER NAME
|
||
; SS.SOF - SENDER'S BUFFER OFFSET
|
||
; SS.ROF - RECEIVER'S BUFFER OFFSET
|
||
; SS.NOD - NODE TO SEND PACKET TO
|
||
;
|
||
;RETURN:
|
||
; CPOPJ IF ERRORS
|
||
; CPOPJ1 IF SUCCESS
|
||
|
||
$XBSUB (PPDRMD::,<SS.SNM,SS.RNM,SS.SOF,SS.ROF,SS.NOD>)
|
||
MOVEI T1,OP.RMD ;OPCODE FOR SEND MAINTENANCE DATA
|
||
; JRST SNDMAI ;JOIN COMMON CODE
|
||
;HERE TO FILL IN THE PACKET AND SEND IT OFF
|
||
|
||
SNDMAI: PUSHJ P,SAVPQ## ;SAVE LOTS OF ACS
|
||
MOVE Q2,T1 ;SAVE OPCODE
|
||
SKIPN Q3,.CPPCB## ;GET PCB ADDRESS
|
||
RETBAD () ;ERROR
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
RETBAD () ;YOU LOST
|
||
EXCH T1,Q2 ;BUFFER ADDRESS IN Q2, OPCODE IN T1
|
||
MOVE T2,SS.SNM ;SENDER NAME
|
||
MOVE T3,T2 ;IF DOING A SEND, THIS IS OUR BUFFER NAME
|
||
MOVEM T2,.PKSNM(Q2) ;SAVE WHERE PORT WANTS SENDER NAME
|
||
MOVE T2,SS.RNM ;RECEIVER'S NAME
|
||
CAIN T1,OP.RD1 ;REQUEST DATA?
|
||
MOVE T3,T2 ;YES, THIS IS OUR BUFFER NAME
|
||
MOVEM T2,.PKRNM(Q2) ;SAVE WHERE PORT WANTS RECEIVER NAME
|
||
MOVE T2,SS.SOF ;SENDER OFFSET
|
||
MOVEM T2,.PKSOF(Q2) ;INTO PACKET
|
||
MOVE T2,SS.ROF ;RECEIVER OFFSET
|
||
MOVEM T2,.PKROF(Q2) ;INTO PACKET
|
||
MOVEM T3,.PKXID(Q2) ;SENDER OR RECEIVER BUFFER NAME INTO XID
|
||
LDB T2,[POINT BHSIDX,T3,BHPIDX] ;BHD INDEX FROM BUFFER NAME
|
||
ADD T2,BHDIPT ;POINT AT BHD TABLE ENTRY
|
||
MOVE T2,.BHLEN(T2) ;GET NIBBLE COUNT FROM BHD
|
||
LSH T2,-1+4 ;CONVERT TO BYTE COUNT AND THEN SHIFT IT
|
||
MOVEM T2,.PKXLN(Q2) ;SAVE AS TRANSACTION LENGTH
|
||
SETZ T3, ;NO FLAGS
|
||
MOVE Q1,SS.NOD ;GET THE NODE NUMBER
|
||
AOS (P) ;SET FOR SKIP RETURN
|
||
PJRST DIASND ;SEND THE DATAGRAM AND RETURN
|
||
|
||
ENDBS. ;END OF BLSUB. RANGE
|
||
;ROUTINE TO SEND A CLOSE BUFFER COMMAND.
|
||
;CALL:
|
||
; BLCAL. (PPDCLB,<SS.BNM,SS.PKT>)
|
||
;
|
||
;WHERE:
|
||
; SS.BNM - BUFFER NAME
|
||
; SS.PKT - PACKET ADDRESS
|
||
;
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XBSUB (PPDCLB::,<SS.BNM,SS.PKT>)
|
||
PUSHJ P,SAVQ## ;SAVE THE Q REGISTERS
|
||
SKIPN Q3,.CPPCB## ;GET PCB ADDRESS
|
||
POPJ P, ;NO PCB?
|
||
MOVE Q2,SS.PKT ;GET THE PACKET ADDRESS
|
||
MOVE T1,SS.BNM ;GET THE BUFFER NAME
|
||
MOVEM T1,.PKBNM(Q2) ;STORE THE BUFFER NAME
|
||
MOVEI T1,OP.CLB ;GET OPCODE
|
||
MOVEI T2,KLPMED ;GET PRIORITY
|
||
SETZ Q1, ;CLEAR NODE NUMBER
|
||
MOVX T3,PF.RSP ;RESPONSE IS REQUESTED
|
||
PJRST DRVSND ;SEND THE PACKET AND RETURN
|
||
|
||
ENDBS. ;END OF BLSUB. RANGE
|
||
SUBTTL SCS-PPD INTERFACE - DEQUEUE BUFFERS
|
||
|
||
|
||
;ROUTINE TO DEQUEUE A DATAGRAM/MESSAGE BUFFER FROM THE PCB FREE QUEUE.
|
||
;CALL:
|
||
; BLCAL. (PPDD?B,<SS.PBI>)
|
||
;
|
||
;WHERE:
|
||
; SS.PBI - PATH BLOCK INDEX
|
||
;
|
||
;RETURN:
|
||
; CPOPJ IF ERRORS
|
||
; CPOPJ1 IF SUCCESS WITH:
|
||
; T1/ ADDRESS OF BUFFER
|
||
|
||
$XBSUB (PPDDDB::,<SS.PBI>)
|
||
MOVEI T2,.PCDFQ ;THE DATAGRAM FREE QUEUE
|
||
JRST PPDDD1 ;JOIN COMMON ROUTINE
|
||
|
||
$XBSUB (PPDDMB::,<SS.PBI>)
|
||
MOVEI T2,.PCMFQ ;THE MESSAGE FREE QUEUE
|
||
PPDDD1: SKIPLE T1,SS.PBI ;CHECK FOR VALID PBI
|
||
CAIL T1,C%PBLL ;...
|
||
POPJ P, ;ERROR, INVALID PBI
|
||
PUSHJ P,SAVQ## ;SAVE THE Q REGISTERS
|
||
MOVE T1,PBLIST##-1(T1) ;GET THE PATH BLOCK ADDRESS IN T1
|
||
MOVE Q3,.PBPCB(T1) ;GET THE PCB ADDRESS FROM THE PATH BLOCK
|
||
MOVX T1,ST.MFL ;MEMORY OFFLINE IN PROGRESS?
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
JRST PPDDD2 ;YES, WE HAVE TO PLAY SOME GAMES TO MAKE SCA
|
||
; HAPPY SINCE WE'VE ALREADY GIVEN EVERYTHING
|
||
; ON OUR FREE QUEUE BACK TO SCA
|
||
MOVE T1,Q3 ;GET A COPY IN T1
|
||
ADD T1,T2 ;OFFSET TO PROPER QUEUE
|
||
PUSHJ P,REMQUE ;REMOVE THE FIRST PACKET
|
||
JRST PPDDD3 ;EMPTY
|
||
MOVE T1,Q2 ;COPY PACKET ADDRESS
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
PPDDD2: CAIE T2,.PCDFQ ;LOOKING FOR A DATAGRAM?
|
||
JRST PPDDD6 ;NO, GET A MESSAGE
|
||
JRST PPDDD4 ;YES, GET A DATAGRAM
|
||
|
||
PPDDD3: XMOVEI T2,.PCDFQ(Q3) ;GET ADDRESS OF DATAGRAM FREE QUEUE
|
||
CAME T1,T2 ;IS THAT THE QUEUE WE TRIED?
|
||
JRST PPDDD5 ;NO, IT WAS THE MESSAGE FREE QUEUE
|
||
BUG. (INF,KLPNDB,KLPSER,SOFT,<No datagram buffer>,,)
|
||
PPDDD4: MOVEI T1,1 ;GET A DATAGRAM BUFFER
|
||
PUSHJ P,SC.ALD## ; FROM SCA'S POOL
|
||
RETBAD (KLPX11) ;ERROR, RETURN AN ERROR CODE
|
||
JRST CPOPJ1## ;SUCCESS
|
||
|
||
PPDDD5: BUG. (INF,KLPNMG,KLPSER,SOFT,<No message buffer>,,)
|
||
PPDDD6: MOVEI T1,1 ;GET A MESSAGE BUFFER
|
||
PUSHJ P,SC.ABF## ; FROM SCA'S POOL
|
||
RETBAD (KLPX11) ;ERROR, RETURN AN ERROR CODE
|
||
JRST CPOPJ1## ;SUCCESS
|
||
|
||
ENDBS. ;END OF BLSUB. RANGE
|
||
SUBTTL SCS-PPD INTERFACE - QUEUE BUFFERS
|
||
|
||
|
||
;ROUTINE TO QUEUE (A) DATAGRAM/MESSAGE BUFFER(S) TO THE PCB FREE QUEUE.
|
||
;CALL:
|
||
; BLCAL. (PPDQ?B,<SS.PBI,SS.PKT>)
|
||
;
|
||
;WHERE:
|
||
; SS.PBI - PATH BLOCK INDEX
|
||
; SS.PKT - ADDRESS OF FIRST PACKET
|
||
;
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XBSUB (PPDQDB::,<SS.PBI,SS.PKT>)
|
||
MOVEI T3,.PCDFQ ;THE DATAGRAM FREE QUEUE
|
||
JRST PPDQD1 ;JOIN COMMON ROUTINE
|
||
|
||
$XBSUB (PPDQMB::,<SS.PBI,SS.PKT>)
|
||
MOVEI T3,.PCMFQ ;THE MESSAGE FREE QUEUE
|
||
PPDQD1: SKIPLE T1,SS.PBI ;CHECK FOR VALID PBI
|
||
CAIL T1,C%PBLL ;...
|
||
PUSHJ P,KLPFOO ;ERROR, INVALID PBI
|
||
PUSHJ P,SAVQ## ;SAVE THE Q REGISTERS
|
||
MOVE T1,PBLIST##-1(T1) ;GET THE PATH BLOCK ADDRESS IN T1
|
||
MOVE Q3,.PBPCB(T1) ;GET THE PCB ADDRESS FROM THE PATH BLOCK
|
||
MOVX T1,ST.MFL ;MEMORY OFFLINE IN PROGRESS?
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
JRST PPDQD2 ;YES
|
||
MOVE T1,Q3 ;GET A COPY IN T1
|
||
ADD T1,T3 ;OFFSET TO PROPER QUEUE
|
||
MOVE Q2,SS.PKT ;COPY ADDRESS OF FIRST PACKET
|
||
PJRST LNKQUE ;LINK THE PACKETS ONTO THE FREE QUEUE AND RETURN
|
||
|
||
;HERE IF SETTING MEMORY OFFLINE - PROBABLY CALLED FROM SCATMO GIVING BACK
|
||
;THE 2 FLOW CONTROL BUFFERS IT QUEUED. COUNT THE NUMBER OF BUFFERS AND
|
||
;REMEMBER TO ASK SCA FOR THAT MANY MORE WHEN RESTARTING.
|
||
|
||
PPDQD2: MOVE T1,SS.PKT ;GET ADDRESS OF FIRST PACKET
|
||
MOVEI T2,1 ;INIT COUNT OF PACKETS
|
||
SKIPE T1,(T1) ;IS THERE ANOTHER PACKET?
|
||
AOJA T2,.-1 ;YES, COUNT AND LOOP
|
||
CAIN T3,.PCDFQ ;DATAGRAMS?
|
||
MOVSS T2 ;YES, MOVE COUNT TO LH
|
||
ADDM T2,.PCFQC(Q3) ;INCLUDE IN RESTOCK COUNT
|
||
MOVE T1,SS.PKT ;GET ADDRESS OF FIRST PACKET
|
||
CAIE T3,.PCDFQ ;DATAGRAMS?
|
||
PJRST SC.RBF## ;NO
|
||
PJRST SC.RLD## ;YES
|
||
|
||
ENDBS. ;END OF BLSUB. RANGE
|
||
SUBTTL SCS-PPD INTERFACE - OPEN VIRTUAL CIRCUIT
|
||
|
||
|
||
;ROUTINE TO REQUEST THE OPENING OF A VIRTUAL CIRCUIT.
|
||
;CALL:
|
||
; BLCAL. (PPDOVC,<SS.PBI>)
|
||
;
|
||
;WHERE:
|
||
; SS.PBI - DESTINATION PATH BLOCK INDEX
|
||
;
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XBSUB (PPDOVC::,<SS.PBI>)
|
||
SKIPLE T1,SS.PBI ;CHECK FOR VALID PBI
|
||
CAIL T1,C%PBLL ;...
|
||
PUSHJ P,KLPFOO ;ERROR, INVALID PBI
|
||
PUSHJ P,SAVPQ## ;SAVE THE P & Q REGISTERS
|
||
SKIPN P5,PBLIST##-1(T1) ;GET THE PATH BLOCK ADDRESS
|
||
BUG. (HLT,KLPNPB,KLPSER,SOFT,<No path block at PPDOVC>,,)
|
||
LOAD T1,PBVCST,(P5) ;GET THE VIRTUAL CIRCUIT STATE
|
||
CAIE T1,VC.CLO ;SHOULD BE CLOSED
|
||
BUG. (HLT,KLPONC,KLPSER,SOFT,<Trying to open a virtual circuit which isn't closed>,,)
|
||
MOVX T1,PB.OKO ;SAY IT'S OK TO OPEN
|
||
IORB T1,.PBFLG(P5) ;...
|
||
TXNE T1,PB.NTC ;TRYING TO CLOSE THE VC?
|
||
POPJ P, ;YES, THAT'S IT FOR NOW, ONCE/SECOND CODE WILL
|
||
; COMPLETE OUR WORK
|
||
LOAD Q1,PBDPN,(P5) ;GET DESTINATION PORT NUMBER
|
||
MOVE Q3,.PBPCB(P5) ;GET THE PCB ADDRESS
|
||
MOVX T1,ST.DED ;SEE IF THE PORT IS IN THE PROCESS OF RELOADING
|
||
TDNE T1,.PCSTS(Q3)
|
||
POPJ P, ;YES, DON'T RESTART THE PORT BY CALLING ONE OF
|
||
; THE SEND PACKET ROUTINES
|
||
PUSHJ P,CHKIDT ;IS THE REQUEST-ID TIMER RUNNING?
|
||
POPJ P, ;YES, DON'T BOTHER SENDING ANOTHER
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
POPJ P, ;NONE AVAILABLE
|
||
PUSHJ P,GTNPTH ;GET NEXT PATH FOR REQUEST-ID
|
||
PJRST KLPRID ;SEND A REQUEST-ID AND RETURN
|
||
|
||
ENDBS. ;END OF BLSUB. RANGE
|
||
SUBTTL SCS-PPD INTERFACE - CLOSE VIRTUAL CIRCUIT
|
||
|
||
|
||
;ROUTINE TO REQUEST A VIRTUAL CIRCUIT BE CLOSED.
|
||
;CALL:
|
||
; BLCAL. (PPDCVC,<SS.PBI>)
|
||
;
|
||
;WHERE:
|
||
; SS.PBI - DESTINATION PATH BLOCK INDEX
|
||
;
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XBSUB (PPDCVC::,<SS.PBI>)
|
||
SKIPLE T1,SS.PBI ;CHECK FOR VALID PBI
|
||
CAIL T1,C%PBLL ;...
|
||
PUSHJ P,KLPFOO ;ERROR, INVALID PBI
|
||
PUSHJ P,SAVPQ## ;SAVE THE P & Q REGISTERS
|
||
SKIPN P5,PBLIST##-1(T1) ;GET THE PATH BLOCK ADDRESS
|
||
PUSHJ P,KLPFOO ;ERROR, INVALID PBI
|
||
SETZB Q2,P4 ;NEED TO GET A BUFFER AND DO A SET CIRCUIT
|
||
SETZ T2, ;FLAG THAT WE WANT TO SEND A SHUTDOWN MESSAGE
|
||
JRST CLOSV2 ;JOIN COMMON CODE
|
||
|
||
|
||
;ROUTINE TO REQUEST A VIRTUAL CIRCUIT BE CLOSED. CALLED INTERNALLY
|
||
;FROM WITHIN KLPSER AS OPPOSED TO PPDCVC.
|
||
;CALL:
|
||
; Q2/ ADDRESS OF BUFFER FOR KLPCLO
|
||
; 0 = NEED TO GET A BUFFER
|
||
; P4/ 0 = DO A SET CIRCUIT
|
||
; -1 = DON'T NEED TO DO A SET CIRCUIT
|
||
; P5/ PBK
|
||
; PUSHJ P,CLOSV1
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CLOSV1: SETO T2, ;NO SHUTDOWN REQUIRED
|
||
CLOSV2: STKVAR <BUFADR> ;ALLOCATE A WORD OF STACK STORAGE
|
||
MOVEM Q2,BUFADR ;SAVE ADDRESS OF BUFFER (IF ANY)
|
||
;AT THIS POINT, T2 = 0 IF SCA INITIATED THE CLOSING. IN THAT CASE,
|
||
;WE'LL SEND A SHUTDOWN TO THE OTHER SIDE. OTHERWISE, T2 = -1 AND THE
|
||
;OTHER SIDE PROBABLY KNOWS ABOUT THE FAILURE.
|
||
|
||
CIOFF ;DON'T LET INTERRUPT LEVEL CHANGE VC STATE
|
||
LOAD T1,PBVCST,(P5) ;GET VC STATE
|
||
CAIE T1,VC.OPN ;OPEN?
|
||
JRST CLOSV7 ;NO, DONE
|
||
MOVEI T1,VC.CLO ;GET CLOSED CODE
|
||
STOR T1,PBVCST,(P5) ;SET IT
|
||
|
||
;TRY TO SEND A SHUTDOWN IF SCA ASKED FOR THE CLOSING. IF THERE'S NO
|
||
;BUFFER, WE CAN CONTINUE, AND THE OTHER SIDE WILL FIND OUT WHEN IT
|
||
;GETS A START PACKET SOMETIME LATER.
|
||
|
||
LOAD Q1,PBDPN,(P5) ;GET DESTINATION PORT NUMBER
|
||
MOVE Q3,.PBPCB(P5) ;GET THE PCB ADDRESS
|
||
MOVE P1,Q3 ;GET PCB ADDRESS
|
||
ADD P1,Q1 ; OFFSET BY CI NODE NUMBER
|
||
JUMPN T2,CLOSV3 ;JUMP IF INTERNAL CALL (NO SHUTDOWN)
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFER
|
||
JRST CLOSV3 ;NO BUFFER, NOT A DISASTER
|
||
MOVEI T1,PP.SHT ;GET PPD BYTE FOR SHUTDOWN
|
||
DPB T1,PKYPPD ;STORE IN PACKET
|
||
PUSHJ P,KLPSDG ;SEND THE DATAGRAM
|
||
CLOSV3: JUMPN P4,CLOSV5 ;JUMP IF WE DON'T NEED A SET CIRCUIT
|
||
SKIPE Q2,BUFADR ;DO WE HAVE A BUFFER FOR THE SETCKT?
|
||
JRST CLOSV4 ;YES, GO DO IT
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
SKIPA ;COULDN'T
|
||
JRST CLOSV4 ;OK
|
||
MOVX T1,PB.NTC ;FAILED, SAY WE STILL NEED TO CLOSE VC
|
||
IORM T1,.PBFLG(P5) ;...
|
||
JRST CLOSV6 ;TELL SCA WE'RE CLOSED
|
||
|
||
CLOSV4: PUSHJ P,KLPCLO ;SEND THE PACKET
|
||
CLOSV5: MOVX T1,PB.WFI ;WAITING FOR A FRESH IDREC
|
||
IORM T1,.PBFLG(P5) ;...
|
||
CLOSV6: LOAD T1,PBPBI,(P5) ;GET THE PATH BLOCK INDEX
|
||
BLCAL. (SC.ERR##,<T1>) ;TELL SCA
|
||
CLOSV7: PJRST CIONPJ## ;INTERRUPTS BACK ON AND RETURN
|
||
|
||
ENDSV. ;END OF STACK VARIABLE RANGE
|
||
ENDBS. ;END OF BLSUB. RANGE
|
||
SUBTTL SCS-PPD INTERFACE - MAP A BUFFER
|
||
|
||
|
||
;ROUTINE TO MAP A BUFFER FOR A SUBSEQUENT DMA/MAINTENANCE OPERATION.
|
||
;CALL:
|
||
; BLCAL. (PPDMAP,<SS.BDA>)
|
||
;
|
||
;WHERE:
|
||
; SS.BDA - ADDRESS OF THE BUFFER DESCRIPTOR
|
||
;
|
||
;RETURN:
|
||
; CPOPJ ON ERROR WITH:
|
||
; T1/ ERROR CODE
|
||
; CPOPJ1 ON SUCCESS WITH:
|
||
; T1/ BUFFER NAME
|
||
|
||
$XBSUB (PPDMAP::,<SS.BDA>)
|
||
PUSHJ P,SAVPQ## ;SAVE THE P & Q REGISTERS
|
||
PUSHJ P,PPDGBH ;GET A BHD
|
||
RETBAD () ;NONE AVAILABLE, RETURN ERROR
|
||
MOVE P1,T2 ;SAVE BHD ADDRESS IN P1
|
||
HRRZ P2,T1 ;GET BHD INDEX
|
||
LSH P2,^D35-BHPIDX ;POSITION IT WHERE THE KLIPA WANTS IT
|
||
PUSHJ P,PPDGCN ;GET A COMMAND REFERENCE NUMBER
|
||
LSH T4,^D35-BHPKEY-4 ;POSITION IT WHERE THE PORT WANTS IT
|
||
IOR P2,T4 ;SAVE BUFFER NAME IN P2
|
||
MOVE T1,SS.BDA ;GET ADDRESS OF BUFFER DESCRIPTOR LIST
|
||
MOVE T1,.MDFLG(T1) ;GET THE FLAGS WORD
|
||
TXNE T1,SQ%WRT ;ALLOW WRITE OF HOST MEMORY?
|
||
TXO T4,BH.WRT ;YES, SET THE WRITABLE BIT IN THE BHD
|
||
TXNE T1,SQ%CVD ;ALLOW CLEARING OF THE VALID BIT?
|
||
TXO T4,BH.PRE ;NO, SET THE DO NOT CLEAR VALID BIT IN THE BHD
|
||
TXO T4,BH.VAL ;SET THE VALID BIT
|
||
MOVEM T4,.BHKEY(P1) ;SAVE KEY/VALID BITS IN BHD
|
||
SETZM .BHLEN(P1) ;ZERO NIBBLE COUNT IN BHD
|
||
XMOVEI P3,.BHBSA-.BSNXT(P1) ;INIT FIRST BSD LINK WORD
|
||
SETZM .BHBSA(P3) ;ZERO THE POINTER IN CASE NO BSDS
|
||
PUSHJ P,PPDGBD ;GET A BSD
|
||
JRST MAPBU8 ;NONE AVAILABLE
|
||
MOVEM T1,.BHBSA(P3) ;POINT BHD AT FIRST BSD (PHYSICAL ADDRESS)
|
||
MOVE P3,T2 ;SAVE THE POINTER TO THE CURRENT BSD
|
||
MOVE Q1,SS.BDA ;GET ADDRESS OF FIRST BUFFER DESCRIPTOR
|
||
MOVE P5,.MDNXT(Q1) ;SAVE THE POINTER TO THE NEXT DESCRIPTOR
|
||
ADDI Q1,.MDSSD ;SET Q1 TO START OF LENGTH/ADDRESS PAIRS
|
||
JRST MAPBU2 ;ALREADY HAVE A BSD
|
||
MAPBU1: SKIPN .MDLEN(Q1) ;ANOTHER BSD NEEDED?
|
||
JRST MAPBU6 ;NO, FINISH UP
|
||
PUSHJ P,PPDGBD ;GET A BSD
|
||
JRST MAPBU8 ;NONE AVAILABLE
|
||
MOVEM T1,.BSNXT(P3) ;POINT PREVIOUS BSD AT THIS ONE (PHYSICAL ADDRESS)
|
||
MOVE P3,T2 ;SAVE THE POINTER TO THE CURRENT BSD
|
||
MAPBU2: MOVE T1,.MDLEN(Q1) ;GET LENGTH OF THIS SEGMENT
|
||
MOVE T3,SS.BDA ;GET DESCRIPTOR ADDRESS
|
||
LOAD T3,MD%DMD,.MDFLG(T3) ;GET THE MODE
|
||
CAIE T3,MD%DIC ;INDUSTRY COMPATIBLE?
|
||
JRST MAPBU3 ;NO
|
||
LSH T1,1 ;YES, LENGTH IN BYTES, CHANGE TO NIBBLES
|
||
MOVX T2,BS.ICM ;GET INDUSTRY COMPATIBLE MODE BIT
|
||
JRST MAPBU5 ;CONTINUE
|
||
|
||
MAPBU3: CAIE T3,MD%DHD ;HIGH DENSITY?
|
||
JRST MAPBU4 ;NO
|
||
LSH T1,1 ;YES, LENGTH IN BYTES, CHANGE TO NIBBLES
|
||
MOVX T2,BS.HDM ;GET HIGH DENSITY MODE BIT
|
||
JRST MAPBU5 ;CONTINUE
|
||
|
||
MAPBU4: IMULI T1,CDNPW ;CALCULATE NIBBLES/WORD FOR CORE DUMP
|
||
MOVX T2,BS.CDM ;GET CORE DUMP MODE BIT
|
||
MAPBU5: MOVEM T1,.BSLEN(P3) ;SAVE LENGTH OF THIS SEGMENT IN NIBBLES
|
||
ADDM T1,.BHLEN(P1) ;ACCUMULATE TOTAL LENGTH IN BHD
|
||
IOR T2,.MDADR(Q1) ;INCLUDE ADDRESS IN MODE BIT
|
||
MOVEM T2,.BSADR(P3) ;SET MODE AND BASE ADDRESS IN BSD
|
||
SETZM .BSNXT(P3) ;ASSUME WE'RE DONE
|
||
ADDI Q1,.MDLSD ;STEP TO NEXT DESCRIPTOR LENGTH PAIR
|
||
JRST MAPBU1 ;HANDLE IT
|
||
|
||
MAPBU6: SKIPN Q1,P5 ;IS THERE ANOTHER BUFFER DESCRIPTOR BLOCK?
|
||
JRST MAPBU7 ;NO
|
||
MOVE P5,.MDNXT(Q1) ;YES, POINT TO ITS NEXT DESCRIPTOR BLOCK
|
||
ADDI Q1,.MDSSD ;POINT TO START OF THE DESCRIPTOR PAIRS
|
||
JRST MAPBU1 ;GO SET UP THE BSDS
|
||
|
||
MAPBU7: MOVE T1,P2 ;GET THE BUFFER NAME
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
MAPBU8: MOVE T1,P2 ;GET THE BUFFER NAME
|
||
PUSHJ P,PPDRHD ;RETURN BHD AND BSD(S)
|
||
RETBAD (KLPX2) ;RETURN ERROR
|
||
|
||
ENDBS. ;END OF BLSUB. RANGE
|
||
SUBTTL SCS-PPD INTERFACE - UNMAP A BUFFER
|
||
|
||
|
||
;ROUTINE TO UNMAP (RETURN ASSOCIATED BHD AND BSD(S) FOR) A BUFFER.
|
||
;CALL:
|
||
; BLCAL. (PPDUMP,<SS.NAM>)
|
||
;
|
||
;WHERE:
|
||
; SS.NAM - BUFFER NAME
|
||
;
|
||
;RETURN:
|
||
; CPOPJ ON ERROR WITH:
|
||
; T1/ ERROR CODE
|
||
; CPOPJ1 ON SUCCESS
|
||
|
||
$XBSUB (PPDUMP::,<SS.NAM>)
|
||
MOVE T1,SS.NAM ;GET THE BUFFER NAME
|
||
PUSHJ P,PPDRHD ;RETURN BUFFER HEADER AND SEGMENT DESCRIPTOR(S)
|
||
TXNN T4,BH.ERR ;WERE THERE ANY ERRORS?
|
||
JRST CPOPJ1## ;NO, SKIP RETURN
|
||
RETBAD (KLPX13) ;YES, RETURN BUFFER TRANSFER ERROR CODE
|
||
|
||
ENDBS. ;END OF BLSUB. RANGE
|
||
SUBTTL DIAGNOSTIC UUO INTERFACE
|
||
|
||
|
||
;HERE ON DIAG. UUO FUNCTIONS FOR A CHANNEL WHICH DID NOT HAVE A KDB.
|
||
;IF IT IS THE KLIPA CHANNEL, AND THE PCB EXISTS, ALLOW THE USER ACCESS.
|
||
;CALL:
|
||
; P1/ NUMBER OF ARGUMENTS
|
||
; P2/ DIAG. UUO FUNCTION CODE
|
||
; P3/ SUBROUTINE (FROM KLPDIA)
|
||
; W/ KDB (PCB) ADDRESS
|
||
; PUSHJ P,@KLPDIA
|
||
;RETURN:
|
||
; CPOPJ ON ERROR (ERROR CODE STORED)
|
||
; CPOPJ1 ON SUCCESS
|
||
|
||
KLPDIA: EXP KLPPPR ;PREPROCESSOR ROUTINE
|
||
DIAFNC (AAU,DIAAAU,) ;ASSIGN ALL UNITS
|
||
DIAFNC (RAU,DIARAU,) ;RELEASE CHANNEL AND ALL UNITS
|
||
DIAFNC (SCP,DIASCP,) ;SPECIFY CHANNEL PROGRAM
|
||
DIAFNC (RCP,DIARCP,) ;RELEASE CHANNEL PROGRAM
|
||
DIAFNC (GCS,DIACST,) ;GET CHANNEL STATUS
|
||
DIAFNC (ELD,DIAELD,) ;ENABLE MICROCODE LOADING
|
||
DIAFNC (DLD,DIADLD,) ;DISABLE MICROCODE LOADING
|
||
DIAFNC (LOD,DIALOD,) ;LOAD MICROCODE
|
||
DIAFNC (ISM,DIAISM,) ;SET MAINTENANCE MODE
|
||
DIAFNC (ICM,DIAICM,) ;CLEAR MAINTENANCE MODE
|
||
DIAFNC ;TERMINATE TABLE
|
||
|
||
;PREPROCESSOR ROUTINE
|
||
$XSENT (KLPPPR:)
|
||
PUSHJ P,DIACHP ;SEE IF THERE IS A PCB
|
||
POPJ P, ;NO, ERROR CODE ALREADY STORED
|
||
CAIL P2,.DIELD ;THSE FUNCTIONS DON'T REQUIRE MAINTENANCE MODE
|
||
CAILE P2,.DIICM ;...
|
||
SKIPA ;NOT A SPECIAL FUNCTION
|
||
PJRST (P3) ;YES, DISPATCH NOW
|
||
MOVX T1,ST.MAI ;IN MAINTENANCE MODE?
|
||
TDNN T1,.PCSTS(Q3) ;...
|
||
JRST DIAADM## ;NO, RETURN AN ERROR
|
||
PJRST (P3) ;DISPATCH BASED ON FUNCTION CODE
|
||
;(2) ASSIGN "CHANNEL" AND ALL UNITS
|
||
|
||
DIAAAU: PUSHJ P,MAILOK ;ENSURE NO ONE ELSE GETS THE USE OF THE PCB
|
||
JRST DIAAAJ## ;SOMEONE ELSE IS ALREADY USING IT
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
|
||
;(3) RELEASE "CHANNEL" AND ALL UNITS
|
||
|
||
DIARAU: PUSHJ P,MAIULK ;LET GO OF EXCLUSIVE OWNERSHIP
|
||
JRST DIAAAJ## ;WE DON'T OWN INTERLOCK
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
|
||
;(4) SPECIFY CHANNEL PROGRAM
|
||
|
||
DIASCP: CAME J,.PCMJB(Q3) ;THIS JOB OWN MAINTENANCE INTERLOCK?
|
||
JRST DIAAAJ## ;NO
|
||
MOVE P3,.PCCDB(Q3) ;GET CDB ADDRESS
|
||
PUSHJ P,DIARCP ;RETURN ANY IOWD
|
||
PUSHJ P,GETWD1## ;GET IOWD
|
||
HLRE T2,T1 ;LENGTH OF IOWD
|
||
JUMPE T2,DIAACP## ;TOO BIG IF 0
|
||
MOVEM T1,CHNICW(P3) ;UNRELOCATED IOWD
|
||
MOVEI T1,1(T1) ;START ADDRESS
|
||
MOVNS T2 ;+LENGTH
|
||
PUSHJ P,ARNGE## ;MAKE SURE THE PAGES ARE OK
|
||
JFCL ;ERROR
|
||
JRST [SETZM CHNICW(P3) ;PAGE NOT THERE
|
||
JRST DIAACP##] ;BOMB HIM OUT
|
||
SETZB P1,P4 ;SAY FIRST CALL, NOT A DX10
|
||
MOVE T2,CHNICW(P3) ;GET IOWD
|
||
SNCALL (MAPIO##,MCSEC1) ;RELOCATE THE IOWD
|
||
JRST [SETZM CHNICW(P3)
|
||
JRST DIAAFC##] ;NO LOW-CORE BLOCKS
|
||
MOVSI T1,(CC.HLT) ;LIGHT HALT BIT IN LAST CCW
|
||
IORM T1,-1(P1) ;...
|
||
SETZM (P1) ;TERMINATE LIST
|
||
MOVEM P2,CHNICW(P3) ;STORE ADDRESS OF CHANNEL PROGRAM
|
||
TLO P2,(FLD(.CCJMP,CC.OPC)) ;MAKE ICW BE A JUMP
|
||
MOVE T1,.PCLGO(Q3) ;ADDRESS OF CHANNEL LOGOUT AREA
|
||
MOVEM P2,.CSICW(T1) ;POINT ICWA AT CORE-BLOCK
|
||
SETZM .CSCLP(T1) ;CLEAR OTHER WORDS
|
||
SETZM .CSDBA(T1) ;...
|
||
PUSHJ P,STOTAC## ;TELL USER ICWA
|
||
JRST CPOPJ1## ;AND TAKE GOOD RETURN
|
||
;(5) RELEASE CHANNEL PROGRAM
|
||
|
||
DIARCP: CAME J,.PCMJB(Q3) ;THIS JOB OWN MAINTENANCE INTERLOCK?
|
||
JRST DIAAAJ## ;NO
|
||
MOVE P3,.PCCDB(Q3) ;GET CHANNEL DATA BLOCK ADDRESS
|
||
SKIPN T1,CHNICW(P3) ;NOTHING TO DO IF NO IOWD
|
||
POPJ P,
|
||
SETZM CHNICW(P3) ;FORGET WE HAD IT
|
||
XJRST [MCSEC1+RTNIOW##] ;RETURN THE SPACE AND RETURN
|
||
|
||
|
||
;(6) TELL USER FINAL CHANNEL STATS
|
||
|
||
DIACST: CAME J,.PCMJB(Q3) ;THIS JOB OWN MAINTENANCE INTERLOCK?
|
||
JRST DIAAAJ## ;NO
|
||
MOVE P2,.PCLGO(Q3) ;ADDRESS OF CHANNEL LOGOUT AREA
|
||
ADDI P2,.CSICW ;OFFSET TO ICWA ADDRESS
|
||
XJRST [MCSEC1+DIAGCS##] ;FINISH UP IN UUOCON
|
||
;(17/20) ENABLE/DISABLE MICROCODE LOADING
|
||
|
||
DIADLD: TDZA T2,T2 ;DISABLE
|
||
DIAELD: MOVEI T2,1 ;ENABLE
|
||
XMOVEI T1,.PCULB(Q3) ;ADDRESS OF MICRO LOADER BLOCK
|
||
PUSHJ P,BTUEDL## ;ENABLE OR DISABLE
|
||
JRST DIAANM## ;ERROR
|
||
JRST CPOPJ1## ;SUCCESS
|
||
|
||
|
||
;(21) LOAD MICROCODE
|
||
|
||
DIALOD: PUSHJ P,URDEAD ;STOP, RELOAD, AND RESTART THE KLIPA
|
||
MOVX T1,ST.DED ;DID IT SUCCEED?
|
||
TDNN T1,.PCSTS(Q3) ;...
|
||
JRST CPOPJ1## ;YES, SKIP RETURN
|
||
JRST DIAARF## ;RETURN ERROR
|
||
;(22) SET MAINTENANCE MODE
|
||
|
||
DIAISM: MOVX T1,ST.MAI ;GET MAINTENANCE MODE FLAG
|
||
TDNE T1,.PCSTS(Q3) ;WAS IT ALREADY IN MAINTENANCE MODE?
|
||
JRST CPOPJ1## ;YES, SO NOTHING ELSE TO DO
|
||
IORM T1,.PCSTS(Q3) ;FLAG FOR NOSY ROUTINES
|
||
PUSHJ P,STPKLP ;STOP THE KLIPA
|
||
PUSHJ P,CIGONE ;RESET ALL CI ACTIVITY
|
||
MOVE P1,.PCCDB(Q3) ;P1 HAS BEEN STOMPED BY CIGONE (KLPRQC)
|
||
SETZM @.PCBIT(Q3) ;ZAP BITS TO TEST FOR ON INTERRUPT
|
||
HRLZ T1,.CPBIT## ;GET OUR CPU'S BIT
|
||
IORM T1,IPAMSK## ;DON'T LET THIS CHANNEL START IF SUSPENDED
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
;(23) CLEAR MAINTENANCE MODE
|
||
|
||
DIAICM: MOVX T1,ST.MAI ;GET MAINTENANCE MODE FLAG
|
||
TDNE T1,.PCSTS(Q3) ;WAS IT IN MAINTENANCE MODE?
|
||
JRST DIAIC1 ;YES
|
||
MOVX T1,ST.DED ;NOT IN MAINTENANCE MODE, IS IT DEAD?
|
||
TDNN T1,.PCSTS(Q3) ;...
|
||
JRST CPOPJ1## ;NO, NOTHING ELSE TO DO
|
||
SKIPA ;YES, TRY TO GET IT GOING AGAIN
|
||
DIAIC1: ANDCAM T1,.PCSTS(Q3) ;CLEAR THE FLAG
|
||
PUSHJ P,STPKLP ;STOP THE KLIPA
|
||
MOVE T1,[KLPBTS] ;BITS TO TEST FOR ON INTERRUPT
|
||
MOVEM T1,@.PCBIT(Q3) ;SET THEM IN CHANNEL DATA BLOCK
|
||
HRLZ T1,.CPBIT## ;GET OUR CPU'S BIT
|
||
ANDCAM T1,IPAMSK## ;LET THIS CHANNEL START IF SUSPENDED
|
||
PUSHJ P,URDEAD ;DO ALL THE RESTART STUFF
|
||
MOVX T1,ST.DED ;DID IT SUCCEED?
|
||
TDNN T1,.PCSTS(Q3) ;...
|
||
JRST CPOPJ1## ;YES, SKIP RETURN
|
||
JRST DIAARF## ;RETURN ERROR
|
||
;DIAG. UUO FUNCTION TO RESET A REMOTE NODE.
|
||
;CALL:
|
||
; J/ CALLER'S JOB NUMBER
|
||
; M/ POINTER TO USER ARGUMENT LIST
|
||
; P1/ NUMBER OF ARGUMENTS IN LIST
|
||
;
|
||
;LIST: CPU #,,105
|
||
; CHAN,,NODE
|
||
; FORCE FLAG (OPTIONAL)
|
||
;
|
||
;RETURN:
|
||
; CPOPJ ON ERROR WITH:
|
||
; T1/ ERROR CODE
|
||
; CPOPJ1 ON SUCCESS
|
||
|
||
$XSENT (DIARRS::)
|
||
PUSHJ P,DIACHK ;SET UP FOR DIAG. FUNCTION, CHECK PCB, ETC.
|
||
POPJ P, ;ERROR, ERROR CODE ALREADY STORED
|
||
CAIGE P1,2 ;AT LEAST 2 ARGUMENTS?
|
||
JRST DIAAIA## ;NO
|
||
MOVX T1,ST.DED ;IS IT RUNNING?
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
PJRST DIAAPN## ;NO, ERROR
|
||
SETZ P2, ;ASSUME NO FLAGS
|
||
CAIGE P1,3 ;INCLUDE THE OPTIONAL FORCE RESET FLAG?
|
||
JRST DIARS1 ;NO
|
||
PUSHJ P,GETWD1## ;GET THE FORCE FLAG
|
||
SKIPE T1 ;WANT TO FORCE A RESET?
|
||
TXO P2,PF.FRC ;YES, SET THE FLAG
|
||
DIARS1: PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
JRST DIAAFC## ;NONE AVAILABLE, GIVE AN ERROR
|
||
MOVEI T1,OP.RRS ;OPCODE = RESET REMOTE SYSTEM
|
||
MOVE T3,P2 ;MOVE THE FLAGS TO T3
|
||
AOS (P) ;SET FOR SKIP RETURN
|
||
PJRST DIASND ;SEND THE PACKET AND RETURN
|
||
;DIAG. UUO FUNCTION TO START A REMOTE NODE.
|
||
;CALL:
|
||
; J/ CALLER'S JOB NUMBER
|
||
; M/ POINTER TO USER ARGUMENT LIST
|
||
; P1/ NUMBER OF ARGUMENTS IN LIST
|
||
;
|
||
;LIST: CPU #,,106
|
||
; CHAN,,NODE
|
||
; STARTING ADDRESS (ZERO IMPLIES DEFAULT)
|
||
;
|
||
;RETURN:
|
||
; CPOPJ ON ERROR WITH:
|
||
; T1/ ERROR CODE
|
||
; CPOPJ1 ON SUCCESS
|
||
|
||
$XSENT (DIASRS::)
|
||
PUSHJ P,DIACHK ;SET UP FOR DIAG. FUNCTION, CHECK PCB, ETC.
|
||
POPJ P, ;ERROR, ERROR CODE ALREADY STORED
|
||
CAIGE P1,2 ;AT LEAST 2 ARGUMENTS?
|
||
JRST DIAAIA## ;NO
|
||
MOVX T1,ST.DED ;IS IT RUNNING?
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
PJRST DIAAPN## ;NO, ERROR
|
||
SETZ P2, ;ASSUME DEFAULT STARTING ADDRESS
|
||
CAIGE P1,3 ;INCLUDE THE OPTIONAL STARTING ADDRESS?
|
||
JRST DIASR1 ;NO
|
||
PUSHJ P,GETWD1## ;GET THE STARTING ADDRESS
|
||
MOVE P2,T1 ;COPY TO P2
|
||
DIASR1: PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
JRST DIAAFC## ;NONE AVAILABLE, GIVE AN ERROR
|
||
MOVEM P2,.PKSAD(Q2) ;STORE STARTING ADDRESS IN PACKET
|
||
MOVEI T1,OP.RRS ;OPCODE = RESET REMOTE SYSTEM
|
||
SETZ T3, ;ASSUME NO FLAGS
|
||
SKIPN P2 ;WAS THERE A NON-ZERO STARTING ADDRESS?
|
||
TXO T3,PF.DSA ;NO, ASK FOR DEFAULT STARTING ADDRESS
|
||
AOS (P) ;SET FOR SKIP RETURN
|
||
PJRST DIASND ;SEND THE PACKET AND RETURN
|
||
;DIAG. UUO FUNCTION TO MANIPULATE THE PORT COUNTERS.
|
||
;CALL:
|
||
; J/ CALLER'S JOB NUMBER
|
||
; M/ POINTER TO USER ARGUMENT LIST
|
||
; P1/ NUMBER OF ARGUMENTS IN LIST
|
||
;
|
||
;LIST: CPU #,,107
|
||
; CHAN,,COUNTERS SUB-FUNCTION
|
||
; SUB-FUNCTION SPECIFIC DATA
|
||
;
|
||
;RETURN:
|
||
; CPOPJ ON ERROR WITH:
|
||
; T1/ ERROR CODE
|
||
; CPOPJ1 ON SUCCESS
|
||
|
||
$XSENT (DIACTR::)
|
||
SKIPN Q3,.CPPCB## ;IS THERE A CI PORT ON THIS CPU?
|
||
JRST DIAACI## ;NO, ERROR
|
||
CAIGE P1,2 ;AT LEAST 2 ARGUMENTS?
|
||
JRST DIAAIA## ;NO
|
||
MOVX T1,ST.DED ;IS IT RUNNING?
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
PJRST DIAAPN## ;NO, ERROR
|
||
PUSHJ P,GETWD1## ;GET FIRST ARGUMENT
|
||
HRRE Q1,T1 ;SAVE SUB-FUNCTION CODE HERE FOR DISPATCH
|
||
HLRZS T1 ;ISOLATE CHANNEL
|
||
LDB T2,[POINT 3,KDBDVC(Q3),35] ;GET RH20 NUMBER
|
||
CAIE T1,(T2) ;THE KLIPA CHANNEL?
|
||
JRST DIAACI## ;NO
|
||
MOVSI T1,JP.POK ;PRIVILEGE BIT THEY NEED
|
||
CAIE Q1,CTRRCT ;THE UNPRIVILEGED FUNCTION?
|
||
SNCALL (PRVBIT##,MCSEC1) ;NO, MAKE SURE USER IS PRIVILEGED
|
||
SKIPA ;OK, UNPRIVILEGED FUNCTION OR PRIVILEGED USER
|
||
JRST DIAANP## ;GIVE AN ERROR
|
||
SKIPL Q1 ;NEGATIVE SUB-FUNCTIONS ARE ILLEGAL
|
||
CAILE Q1,CTRFLN ;LEGAL SUB-FUNCTION?
|
||
JRST DIAABA## ;NO, RETURN AN ERROR
|
||
PJRST @CTRFCN(Q1) ;DISPATCH BASED ON SUB-FUNCTION CODE
|
||
|
||
CTRFCN: IFIW CTRGET ;0 - GET COUNTERS
|
||
IFIW CTRGIV ;1 - RELEASE COUNTERS
|
||
IFIW CTRPNT ;2 - POINT COUNTERS
|
||
CTRRCT==.-CTRFCN ;THE "READ COUNTERS" SUB-FUNCTION
|
||
IFIW CTRRED ;3 - READ COUNTERS
|
||
CTRFLN==.-CTRFCN-1 ;MAXIMUM LEGAL SUB-FUNCTION
|
||
;GET CONTROL OF THE COUNTERS
|
||
|
||
CTRGET: SKIPE T1,.PCCJB(Q3) ;DOES SOME JOB ALREADY OWN THE COUNTERS?
|
||
CAMN T1,J ;YES, IS IT THE CALLER'S JOB?
|
||
SKIPA ;NOT OWNED, OR OWNED BY CALLER
|
||
JRST DIAAAJ## ;SORRY, THEY'RE ALREADY IN USE
|
||
MOVEM J,.PCCJB(Q3) ;YOU'RE THE LUCKY OWNER
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
|
||
;RELINQUISH CONTROL OF THE COUNTERS
|
||
|
||
CTRGIV: CAMN J,.PCCJB(Q3) ;DOES CALLER'S JOB OWN THE COUNTERS?
|
||
JRST CTRGV1 ;YES
|
||
CAIGE P1,3 ;ROOM FOR THE FORCE FLAG?
|
||
JRST DIAAAJ## ;NO, GIVE AN ERROR
|
||
PUSHJ P,GETWD1## ;GET THE FORCE FLAG
|
||
SKIPG T1 ;FORCE THE RELEASE?
|
||
PJRST DIAAAJ## ;NO, GIVE AN ERROR
|
||
CTRGV1: SETZM .PCCJB(Q3) ;NO ONE OWNS THE COUNTERS ANY MORE
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
|
||
;POINT THE COUNTERS AT A PARTICULAR NODE
|
||
|
||
CTRPNT: CAME J,.PCCJB(Q3) ;DOES CALLER'S JOB OWN THE COUNTERS?
|
||
JRST DIAAAJ## ;NO, GIVE AN ERROR
|
||
CAIGE P1,4 ;NEED AT LEAST THIS MANY WORDS
|
||
JRST DIAAIA## ;NOPE, WE'RE A BIT LATE AND A WORD SHORT
|
||
PUSHJ P,GETWD1## ;GET THE MASK ARGUMENT
|
||
MOVE P2,T1 ;SAVE A MOMENT
|
||
PUSHJ P,GETWD1## ;GET THE NODE ARGUMENT
|
||
MOVE P3,T1 ;SAVE A MOMENT
|
||
;*** NO CALLS TO GETWD1 AFTER CALLING KLPGDB
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
JRST DIAAFC## ;NONE AVAILABLE, GIVE AN ERROR
|
||
MOVEM P2,.PKMSK(Q2) ;STORE THE MASK IN THE PACKET
|
||
SETZM .PKPND(Q2) ;CLEAR PORT WORD
|
||
DPB P3,PKYCND ;WHICH NODE TO MONITOR
|
||
MOVEI T1,OP.SPT ;OPERATION IS SET POINTERS
|
||
SETZB T3,Q1 ;NO FLAGS, CLEAR NODE NUMBER
|
||
AOS (P) ;SET FOR SKIP RETURN
|
||
PJRST DIASND ;SEND THE PACKET AND RETURN
|
||
;READ THE COUNTERS
|
||
|
||
CTRRED: PUSH P,M ;WE WANT TO CALL PUTWD1 LATER
|
||
PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
JRST [POP P,M ;NONE AVAILABLE, CLEAN STACK
|
||
JRST DIAAFC##] ;GIVE AN ERROR
|
||
SETZM .PCCTR(Q3) ;ZERO DATE/TIME COUNTERS WERE LAST READ
|
||
MOVX T2,KS%DIA ;REASON FOR READING COUNTERS
|
||
HRL T2,J ;PLUG IN OUR JOB NUMBER
|
||
PUSHJ P,KLPRPT ;SEND A READ-COUNTERS
|
||
POP P,M ;RESTORE ADDRESS FOR PUTWD1
|
||
|
||
;NOW WAIT FOR A RESPONSE - WAIT UP TO 5 SECONDS
|
||
|
||
MOVEI T1,^D5 ;HOW LONG TO WAIT
|
||
SNCALL (SLEEPF##,MCSEC0) ;PUT THE JOB TO SLEEP FOR A WHILE
|
||
SKIPN .PCCTR(Q3) ;ANYTHING GET RETURNED?
|
||
JRST DIAATO## ;NO, ERROR
|
||
|
||
;SOMETHING HAS ARRIVED, ASSUME IT IS THE DATA WE REQUESTED
|
||
|
||
SUBI P1,2 ;ACCOUNT FOR FUNCTION AND SUB-FUNCTION WORDS
|
||
CAILE P1,NOSTCT+1 ;ASKING FOR MORE THAN WE HAVE?
|
||
MOVEI P1,NOSTCT+1 ;YES, REDUCE THEIR REQUEST
|
||
SOJLE P1,CPOPJ1## ;RETURN IF ARGUMENT LIST EXHAUSTED
|
||
MOVE T1,.PCCJB(Q3) ;GET JOB WHICH OWNS THE COUNTERS
|
||
PUSHJ P,PUTWD1## ;STORE FOR USER
|
||
|
||
;THE BLOCK OF DATA RETURNED BY THE READ COUNTERS PACKET
|
||
|
||
MOVE P2,Q3 ;COPY THE PCB ADDRESS TO P2
|
||
CTRRD2: SOJLE P1,CPOPJ1## ;RETURN WHEN ARGUMENT LIST EXHAUSTED
|
||
MOVE T1,.PCCTR+1(P2) ;GET A COUNTER ITEM (SKIP DATE/TIME)
|
||
PUSHJ P,PUTWD1## ;STORE FOR THE USER
|
||
AOJA P2,CTRRD2 ;LOOP FOR MORE DATA
|
||
;DIAG. UUO FUNCTIONS TO REQUEST (READ) AND WRITE MAINTENANCE DATA.
|
||
;CALL:
|
||
; J/ CALLER'S JOB NUMBER
|
||
; M/ POINTER TO USER ARGUMENT LIST
|
||
; P1/ NUMBER OF ARGUMENTS IN LIST
|
||
;
|
||
;LIST: CPU #,,112 FOR WRITE, 113 FOR READ
|
||
; CHAN,,NODE
|
||
; LENGTH OF TRANSFER IN BYTES
|
||
; RECEIVER'S BUFFER NAME
|
||
; ADDRESS OF USER BUFFER
|
||
;
|
||
;RETURN:
|
||
; CPOPJ ON ERROR WITH:
|
||
; T1/ ERROR CODE
|
||
; CPOPJ1 ON SUCCESS
|
||
|
||
$XSENT (DIARMD::)
|
||
STKVAR <RWFLAG,RTDG> ;ALLOCATE SOME STACK STORAGE
|
||
SETZM RWFLAG ;FLAG THIS IS A READ FUNCTION
|
||
JRST DIARWM ;JOIN COMMON CODE
|
||
|
||
$XSENT (DIAWMD::)
|
||
STKVAR <RWFLAG,RTDG> ;ALLOCATE SOME STACK STORAGE
|
||
SETOM RWFLAG ;FLAG THIS IS A WRITE FUNCTION
|
||
DIARWM: CAIGE P1,5 ;ALL THE ARGUMENTS THERE?
|
||
JRST DIAAIA## ;NO, GIVE ERROR
|
||
PUSHJ P,DIACHK ;SET UP FOR DIAG. FUNCTION, CHECK PCB, ETC.
|
||
POPJ P, ;ERROR, ERROR CODE ALREADY STORED
|
||
MOVX T1,ST.DED ;IS IT RUNNING?
|
||
TDNE T1,.PCSTS(Q3) ;...
|
||
PJRST DIAAPN## ;NO, ERROR
|
||
CAIL Q1,0 ;LEGAL CI NODE NUMBER?
|
||
CAIL Q1,MAXNDS ;...
|
||
JRST DIAABA## ;NO
|
||
MOVE T1,Q3 ;GET PCB ADDRESS
|
||
ADD T1,Q1 ; OFFSET BY CI NODE NUMBER
|
||
SKIPN P5,.PCPBK(T1) ;GET PATH BLOCK ADDRESS
|
||
JRST DIAABA## ;ERROR
|
||
MOVE T1,.PBDPF(P5) ;GET DESTINATION PORT FUNCTIONALITY
|
||
SKIPN RWFLAG ;READ OR WRITE?
|
||
SKIPA T2,[TXNN T1,PK.RMD] ;READ, GET THE APPROPRIATE TEST
|
||
MOVE T2,[TXNN T1,PK.SMD] ;WRITE, GET THE APPROPRIATE TEST
|
||
XCT T2 ;DOES IT SUPPORT THE DESIRED FUNCTION?
|
||
JRST DIAABA## ;NO
|
||
LDB T1,[POINT PKSRST,.PBDPS(P5),PKPRST] ;GET THE PORT STATE
|
||
CAIE T1,PS.UMS ;IS IT IN UNITIALIZED MAINTENANCE MODE?
|
||
JRST DIAABA## ;NO
|
||
LDB T1,[POINT PKSRND,.PBDPS(P5),PKPRND] ;GET THE RESETTING NODE
|
||
CAME T1,.PCONN(Q3) ;SAME AS OUR NODE NUMBER?
|
||
JRST DIAABA## ;NO
|
||
PUSHJ P,GETWD1## ;GET THE NUMBER OF 8 BIT BYTES TO READ/WRITE
|
||
CAILE T1,0 ;MUST BE GREATER THAN 0
|
||
CAILE T1,^D512 ; AND LESS THAN 513
|
||
JRST DIAABA## ;ERROR
|
||
MOVE P2,T1 ;SAVE COUNT IN P2
|
||
|
||
PUSHJ P,GETWD1## ;GET THE DESTINATION NODE'S BUFFER NAME
|
||
MOVE P3,T1 ;SAVE IN P3
|
||
|
||
PUSHJ P,GETWD1## ;GET THE ADDRESS OF THE USER'S BUFFER
|
||
MOVE P4,T1 ;SAVE IN P4
|
||
|
||
;AT THIS POINT THE CALLING ARGUMENTS LOOK GOOD. NOW START THE REAL
|
||
;WORK. AFTER THIS POINT, AC "M" IS NO LONGER USABLE, AS IT IS THE
|
||
;SAME AS AC "Q2".
|
||
|
||
PUSHJ P,MAILOK ;GAIN OWNERSHIP OF THE SEND/RECEIVE INTERLOCK
|
||
JRST DIAAAJ## ;SOMEONE ELSE IS ALREADY USING IT
|
||
|
||
MOVEI T1,1 ;ASK FOR A BUFFER
|
||
PUSHJ P,SC.ALD## ;GET A DATAGRAM BUFFER
|
||
JRST [HRLM T1,.PCMFL(Q3) ;ERROR, STORE ERROR CODE
|
||
JRST DIRWF4] ;FINISH UP
|
||
MOVE Q2,T1 ;SAVE BUFFER ADDRESS
|
||
MOVEM T3,RTDG ;SAVE ADDRESS OF ROUTINE TO RETURN BUFFER
|
||
|
||
SETZM .MDNXT(Q2) ;NO NEXT DESCRIPTOR IN CHAIN
|
||
SETZM .MDFLG(Q2) ;START WITH A FRESH FLAGS WORD
|
||
MOVX T1,MD%DIC ;GET INDUSTRY COMPATIBLE MODE BITS
|
||
STOR T1,MD%DMD,.MDFLG(Q2) ;STORE IN BUFFER DESCRIPTOR BLOCK
|
||
MOVX T1,SQ%WRT ;GET THE WRITE FLAG
|
||
SKIPN RWFLAG ;READ OR WRITE?
|
||
IORM T1,.MDFLG(Q2) ;READ, ALLOW KLIPA TO WRITE HOST MEMORY
|
||
MOVE T1,P2 ;GET SIZE (IN 8-BIT BYTES)
|
||
MOVEM T1,.MDSSD+.MDLEN(Q2) ;STORE IN BUFFER DESCRIPTOR BLOCK
|
||
MAP T1,.MDSSD+.MDLSD+1(Q2) ;GET PHYSICAL ADDRESS OF SEGMENT
|
||
TXZ T1,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
MOVEM T1,.MDSSD+.MDADR(Q2) ;STORE IN BUFFER DESCRIPTOR BLOCK
|
||
SETZM .MDSSD+.MDLSD(Q2) ;ZERO LAST WORD OF DESCRIPTOR BLOCK
|
||
BLCAL. (PPDMAP,<Q2>) ;SET UP BHD AND BSD(S), RETURN BUFFER NAME
|
||
JRST [HRLM T1,.PCMFL(Q3) ;ERROR, STORE ERROR CODE
|
||
JRST DIRWF3] ;FINISH UP
|
||
MOVE P1,T1 ;SAVE BUFFER NAME
|
||
SKIPN RWFLAG ;READ OR WRITE?
|
||
JRST DIARW1 ;READ
|
||
MOVEI T1,3(P2) ;WRITE, GET NUMBER OF BYTES AND ROUND UP
|
||
LSH T1,-2 ;CONVERT TO WORDS
|
||
MOVE T2,P4 ;COPY USER'S BUFFER ADDRESS
|
||
EXCTUX <SKIP (T2)> ;IS USER ADDRESS VALID?
|
||
ERJMP DIRWA1 ;NO, GO CLEAN UP
|
||
ADD T2,T1 ;GET ENDING USER ADDRESS
|
||
EXCTUX <SKIP (T2)> ;IS ENDING USER ADDRESS VALID?
|
||
ERJMP DIRWA1 ;NO, GO CLEAN UP
|
||
MOVE T2,P4 ;GET SOURCE ADDRESS
|
||
XMOVEI T3,.MDSSD+.MDLSD+1(Q2) ;GET DESTINATION ADDRESS
|
||
EXCTUX <EXTEND T1,[XBLT]> ;TRANSFER THE DATA
|
||
DIARW1: SETOM .PCMFL(Q3) ;SET THE FLAG: -1 MEANS NOT COMPLETE, 0 MEANS
|
||
; COMPLETED, 1 MEANS COMPLETED WITH ERROR
|
||
LSH P3,4 ;POSITION THE BUFFER NAME FOR KLPSER
|
||
SKIPN RWFLAG ;READ OR WRITE?
|
||
JRST DIARW2 ;READ
|
||
BLCAL. (PPDSMD,<P1,P3,[0],[0]>)
|
||
JRST [HRLM T1,.PCMFL(Q3) ;ERROR, SAVE ERROR CODE
|
||
JRST DIRWF2] ;ERROR ONLY IF UNABLE TO GET A BUFFER
|
||
JRST DIARW3 ;REJOIN COMMON CODE
|
||
|
||
DIARW2: BLCAL. (PPDRMD,<P3,P1,[0],[0]>)
|
||
JRST [HRLM T1,.PCMFL(Q3) ;ERROR, SAVE ERROR CODE
|
||
JRST DIRWF2] ;ERROR ONLY IF UNABLE TO GET A BUFFER
|
||
DIARW3: PUSHJ P,MAIRWT ;WAIT FOR THE WRITE TO FINISH
|
||
JRST [SKIPG .PCMFL(Q3) ;TIMED OUT OR FINISHED WITH ERROR?
|
||
SKIPA T1,[27] ;TIMED OUT
|
||
MOVEI T1,30 ;FINISHED WITH ERROR
|
||
HRLM T1,.PCMFL(Q3) ;SAVE ERROR CODE
|
||
JRST .+1] ;CONTINUE ON
|
||
SKIPE RWFLAG ;READ OR WRITE?
|
||
JRST DIRWF1 ;WRITE, FINISH UP
|
||
MOVEI T1,3(P2) ;READ, GET NUMBER OF BYTES AND ROUND UP
|
||
LSH T1,-2 ;CONVERT TO WORDS
|
||
XMOVEI T2,.MDSSD+.MDLSD+1(Q2) ;GET SOURCE ADDRESS
|
||
MOVE T3,P4 ;GET DESTINATION
|
||
EXCTUU <MOVES (T3)> ;IS USER ADDRESS VALID?
|
||
ERJMP DIRWA2 ;NO
|
||
ADD T3,T1 ;GET ENDING ADDRESS
|
||
EXCTUU <MOVES (T3)> ;IS USER ADDRESS VALID?
|
||
ERJMP DIRWA2 ;NO
|
||
MOVE T3,P4 ;GET DESTINATION AGAIN
|
||
EXCTXU <EXTEND T1,[XBLT]> ;TRANSFER THE DATA
|
||
JRST DIRWF1 ;FINISH UP
|
||
|
||
DIRWA1: MOVEI T1,ECOD1## ;GET ILLEGAL ADDRESS ERROR CODE
|
||
HRLM T1,.PCMFL(Q3) ;STORE ERROR CODE
|
||
JRST DIRWF2 ;GO CLEAN UP
|
||
|
||
DIRWA2: MOVEI T1,ECOD1## ;GET ILLEGAL ADDRESS ERROR CODE
|
||
HRLM T1,.PCMFL(Q3) ;STORE ERROR CODE
|
||
JRST DIRWF1 ;GO CLEAN UP
|
||
;HERE TO FINISH UP FOLLOWING A READ/WRITE FUNCTION.
|
||
|
||
DIRWF1: PUSHJ P,MAICLB ;CLEAN UP
|
||
DIRWF2: BLCAL. (PPDUMP,<Q3>) ;CLEAN UP THE BHD AND BSD (Q3 HAS BUFFER NAME)
|
||
JRST [HRLM T1,.PCMFL(Q3) ;ERROR, STORE ERROR CODE
|
||
JRST DIRWF4] ;FINISH UP
|
||
DIRWF3: MOVE T1,Q2 ;GET THE ADDRESS OF THE BUFFER TO RELEASE
|
||
PUSHJ P,@RTDG ;RELEASE THE BUFFER
|
||
SKIPE .PCMFL(Q3) ;DID MAINTENANCE OPERATION COMPLETE SUCCESSFULLY?
|
||
JRST DIRWF4 ;NO
|
||
PUSHJ P,MAIULK ;RELINQUISH OWNERSHIP OF THE INTERLOCK
|
||
JFCL ;SHOULDN'T HAPPEN
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
|
||
DIRWF4: HLRZ T1,.PCMFL(Q3) ;GET THE ERROR CODE
|
||
PUSH P,T1 ;SAVE IT FOR A MOMENT
|
||
PUSHJ P,MAIULK ;RELINQUISH OWNERSHIP OF THE SEND/RECEIVE INTERLOCK
|
||
JFCL ;SHOULDN'T HAPPEN
|
||
POP P,T1 ;RESTORE ERROR CODE
|
||
JRST STOTAC## ;STORE AND RETURN
|
||
|
||
ENDSV. ;END OF STACK VARIABLE RANGE
|
||
ENDSV. ;END OF STACK VARIABLE RANGE
|
||
;ROUTINE TO GAIN OWNERSHIP OF THE CI PORT MAINTENANCE
|
||
;SEND/RECEIVE INTERLOCK.
|
||
;CALL:
|
||
; J/ CALLER'S JOB NUMBER
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,MAILOK
|
||
;RETURN:
|
||
; CPOPJ IF ERROR
|
||
; CPOPJ1 IF SUCCESS
|
||
|
||
MAILOK: CIOFF ;PREVENT RACES
|
||
SKIPE .PCMJB(Q3) ;IS SOMEONE ELSE DOING A MAINTENANCE SEND/RECEIVE?
|
||
PJRST CIONPJ## ;YES, GIVE UP INTERLOCK AND NON-SKIP RETURN
|
||
MOVEM J,.PCMJB(Q3) ;NO, THEN WE ARE THE LUCKY ONES
|
||
PJRST CINPJ1## ;INTERRUPS BACK ON AND SKIP RETURN
|
||
|
||
|
||
;ROUTINE TO RELINQUISH OWNERSHIP OF THE CI PORT MAINTENANCE
|
||
;SEND/RECEIVE INTERLOCK.
|
||
;CALL:
|
||
; J/ CALLER'S JOB NUMBER
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,MAIULK
|
||
;RETURN:
|
||
; CPOPJ IF DIDN'T OWN INTERLOCK
|
||
; CPOPJ1 IF INTERLOCK RELEASED
|
||
|
||
MAIULK: CAME J,.PCMJB(Q3) ;THIS JOB OWN MAINTENANCE INTERLOCK?
|
||
POPJ P, ;NO
|
||
SETZM .PCMJB(Q3) ;QUITE EASY
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
;ROUTINE TO TELL THE KLIPA TO CLOSE THE BUFFER SO THE KLIPA WILL
|
||
;DELETE THE OPERATION FROM ITS QUEUES.
|
||
;CALL:
|
||
; P1/ BUFFER NAME
|
||
; PUSHJ P,MAICLB
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
MAICLB: PUSHJ P,SAVQ## ;SAVE THE Q REGISTERS
|
||
MAICL1: PUSHJ P,KLPGDB ;GET A DATAGRAM BUFFER
|
||
JRST MAICL2 ;ERROR, WAIT A BIT AND TRY AGAIN
|
||
SETZM .PCMCF(Q3) ;ZERO THE FLAG
|
||
MOVEM P1,.PCMCN(Q3) ;SAVE THE BUFFER NAME
|
||
BLCAL. (PPDCLB,<P1,Q2>) ;DO THE CLOSE BUFFER COMMAND
|
||
PJRST MAIRWT ;WAIT FOR COMPLETION AND RETURN
|
||
|
||
MAICL2: MOVEI T1,1 ;FAILED TO GET A BUFFER, SLEEP A SECOND
|
||
SNCALL (SLEEPF##,MCSEC0)
|
||
JRST MAICL1 ;TRY AGAIN
|
||
|
||
|
||
;ROUTINE TO WAIT FOR A MAINTENANCE OPERATION TO COMPLETE.
|
||
;CALL:
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,MAIRWT
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
MAIRWT: MOVEI T1,^D5 ;HOW LONG TO WAIT
|
||
SNCALL (SLEEPF##,MCSEC0) ;KNOCK OFF FOR A WHILE
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO SET UP FOR A DIAG. UUO FUNCTION.
|
||
;CALL:
|
||
; M/ POINTER TO FUNCTION WORD OF USER ARGUMENT LIST
|
||
; P1/ NUMBER OF ARGUMENTS
|
||
; PUSHJ P,DIACHK
|
||
;RETURN:
|
||
; CPOPJ IF ERRORS (ERROR CODE ALREADY STORED)
|
||
; CPOPJ1 IF SUCCESS WITH:
|
||
; Q1/ RIGHT HALF OF FIRST ARGUMENT (PROBABLY NODE NUMBER)
|
||
; Q3/ PCB ADDRESS
|
||
;
|
||
;NOTE: ALL KLIPA DIAG. UUO FUNCTIONS HAVE THE CHANNEL ARGUMENT IN
|
||
;THE LEFT HALF OF THE FIRST ARGUMENT FOLLOWING THE FUNCTION. IF A
|
||
;FUNCTION IS ADDED WHICH DOESN'T FOLLOW THIS CONVENTION, DIACHK AND
|
||
;ALL CALLERS WILL HAVE TO BE MODIFIED SO THE CHANNEL IS CHECKED BY
|
||
;THE CALLER INSTEAD OF DIACHK.
|
||
|
||
DIACHK: PUSHJ P,DIACHP ;CHECK FOR PRIVILEGES AND A PCB
|
||
POPJ P, ;ERROR, CODE ALREADY STORED
|
||
CAIGE P1,2 ;AT LEAST 2 ARGUMENTS?
|
||
JRST DIAAIA## ;NO
|
||
PUSHJ P,GETWD1## ;GET FIRST ARGUMENT
|
||
HRRZ Q1,T1 ;RETURN AS ADVERTISED
|
||
HLRZS T1 ;ISOLATE CHANNEL
|
||
LDB T2,[POINT 3,KDBDVC(Q3),35] ;GET RH20 NUMBER
|
||
CAIE T1,(T2) ;THE KLIPA CHANNEL?
|
||
JRST DIAACI## ;NO
|
||
JRST CPOPJ1## ;YES, SKIP RETURN
|
||
|
||
|
||
;ROUTINE TO CHECK FOR EXISTANCE OF PCB AND PRIVILEGES. LIKE
|
||
;DIACHK BUT IT DOESN'T CHECK THE CHAN,,NODE WORD.
|
||
;CALL:
|
||
; M/ POINTER TO FUNCTION WORD OF ARGUMENT LIST
|
||
; PUSHJ P,DIACHP
|
||
;RETURN:
|
||
; CPOPJ IF ERRORS (ERROR CODE ALREADY STORED)
|
||
; CPOPJ1 IF SUCCESS WITH:
|
||
; Q3/ PCB ADDRESS
|
||
|
||
DIACHP: MOVSI T1,JP.POK ;MUST HAVE PRIVILEGES
|
||
SNCALL (PRVBIT##,MCSEC1) ;DO THEY?
|
||
SKIPA Q3,W ;YES, GET PCB ADDRESS AND SKIP
|
||
JRST DIAANP## ;NO
|
||
JUMPE Q3,DIAACI## ;IF NO CI PORT, GIVE AN ERROR
|
||
JRST CPOPJ1## ;TAKE SKIP RETURN
|
||
;HERE FROM UUOCON FROM DIACLR DISPATCH (^C, HALT, ETC., TYPED)
|
||
;CALL:
|
||
; J/ JOB NUMBER
|
||
; PUSHJ P,PPDCLR
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
$XSENT (PPDCLR::)
|
||
XMOVEI T1,CLRJOB ;LOAD ADDRESS OF SUBROUTINE TO CLEAR JOB IN PCB
|
||
PJRST CPUAPP## ;DO IT ON ALL CPUS AND RETURN
|
||
|
||
|
||
;ROUTINE EXECUTED TO CLEAR JOB NUMBER FIELDS IN PCB FOR ALL CPUS.
|
||
;ZEROS .PCCJB AND .PCMJB IN THE PCB.
|
||
;CALL:
|
||
; P1/ CDB ADDRESS
|
||
; J/ JOB NUMBER
|
||
; PUSHJ P,CLRJOB
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
CLRJOB: SKIPN T1,.CPPCB##-.CPCDB##(P1) ;IS THERE A KLIPA ON THIS CPU?
|
||
POPJ P, ;NO, RETURN
|
||
CAMN J,.PCCJB(T1) ;DOES THIS JOB OWN THE COUNTERS?
|
||
SETZM .PCCJB(T1) ;YES, BUT NOT ANY LONGER
|
||
CAMN J,.PCMJB(T1) ;DOES THIS JOB OWN THE MAINTENANCE SEND/RECEIVE INTERLOCK?
|
||
SETZM .PCMJB(T1) ;YES, BUT NOT ANY LONGER
|
||
POPJ P, ;RETURN
|
||
SUBTTL ROUTINE TO SEND A PACKET UNDER VIRTUAL CIRCUIT CONTROL
|
||
|
||
|
||
;ROUTINE TO SEND A PACKET UNDER VIRTUAL CIRCUIT CONTROL.
|
||
;CALL:
|
||
; T1/ OPCODE
|
||
; T2/ PRIORITY
|
||
; T3/ FLAGS
|
||
; Q2/ PACKET ADDRESS
|
||
; P5/ PBK ADDRESS
|
||
; PUSHJ P,SENDVC
|
||
;RETURN:
|
||
; CPOPJ ON ERRORS WITH:
|
||
; T1/ ERROR CODE
|
||
; CPOPJ1 ON SUCCESS
|
||
|
||
SENDVC: LOAD T4,PBVCST,(P5) ;GET VC STATE
|
||
CAIE T4,VC.OPN ;IS IT OPEN?
|
||
RETBAD (KLPX9) ;NO
|
||
LOAD Q1,PBDPN,(P5) ;GET THE DESTINATION NODE NUMBER
|
||
MOVE Q3,.PBPCB(P5) ;GET THE PCB ADDRESS
|
||
MOVX T4,PK.SRB ;CLEAR ALL SOFTWARE RESPONSE BITS
|
||
ANDCAM T4,.PKVRT(Q2) ;...
|
||
MOVX T4,PK.SCA ;GET THE SCA SOFTWARE RESPONSE FLAG
|
||
TXNE T3,PF.RSP ;WANT A RESPONSE?
|
||
IORM T4,.PKVRT(Q2) ;YES, SET THE FLAG
|
||
AOS (P) ;SET FOR SKIP RETURN
|
||
PJRST KLPSND ;SEND THE PACKET AND RETURN
|
||
SUBTTL ROUTINES TO SEND DATAGRAMS
|
||
|
||
|
||
;ROUTINES TO SEND A SET CIRCUIT DATAGRAM.
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,KLPSCK/KLPOPN/KLPCLO
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
KLPCLO: MOVX T1,RI.PAO!RI.PBO ;NEITHER PATH NOW OPEN
|
||
ANDCAM T1,.PCRIS(P1) ;...
|
||
MOVX T1,CK.LST ;CLOSE VIRTUAL CIRCUIT
|
||
JRST KLPOCC ;JOIN COMMON CODE
|
||
|
||
KLPOPN: MOVX T1,RI.PAO!RI.PBO ;START WITH BOTH PATHS OPEN
|
||
IORM T1,.PCRIS(P1) ;...
|
||
MOVX T1,CK.LST!CK.CST!CK.LPT!CK.PAA!CK.PBA ;OPEN VIRTUAL CIRCUIT
|
||
KLPOCC: MOVEM T1,.PKCKT(Q2) ;ASSUME NR-NS=0 INITIALLY
|
||
KLPSCK: MOVEI T1,OP.CKT ;OPCODE = SET VIRTUAL CIRCUIT
|
||
MOVEI T2,INCXID ;GET NEW TRANSACTION ID
|
||
ADDB T2,KLPXID ;...
|
||
MOVEM T2,.PKXID(Q2) ;STORE IN PACKET
|
||
MOVEM T2,.PKXID+1(Q2) ; (SAME THING IN BOTH WORDS)
|
||
JRST KLPSX1 ;JOIN COMMON CODE
|
||
|
||
|
||
;ROUTINE TO SEND A READ REGISTER DATAGRAM.
|
||
;CALL:
|
||
; T1/ REGISTER TO READ
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,KLPRRG
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
KLPRRG: SETZB Q1,.PKREG(Q2) ;ZERO NODE NUMBER AND MUST BE ZERO FIELDS
|
||
DPB T1,PKYREG ;STORE THE REGISTER TO READ
|
||
MOVEI T1,OP.RRG ;OPCODE = READ REGISTER
|
||
JRST KLPSX1 ;JOIN COMMON CODE
|
||
;ROUTINE TO SEND A START DATAGRAM.
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,KLPSDG
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
KLPSDG: LDB T1,PKYPPD ;GET PACKET TYPE
|
||
MOVE T2,STRLEN(T1) ;GET APPROPRIATE LENGTH
|
||
DPB T2,PKYLEN ;STORE THE PACKET LENGTH
|
||
PUSHJ P,MASAGE ;SWAP THE PPD BYTE AND ADJUST LENGTH
|
||
MOVEI T1,OP.SDG ;OPCODE = SEND DATAGRAM
|
||
KLPSX1: MOVEI T2,KLPDRG ;PRIORITY
|
||
SETZ T3, ;NO FLAGS
|
||
PJRST DRVSND ;SEND PACKET AND RETURN
|
||
|
||
;START PACKET LENGTH TABLE
|
||
|
||
STRLEN: SR.LEN ;(PPD = 0) START LENGTH
|
||
SR.LEN ;(PPD = 1) STACK LENGTH
|
||
SR.ALN ;(PPD = 2) ACK LENGTH
|
||
0 ;(PPD = 3) APPLICATION DATAGRAM
|
||
0 ;(PPD = 4) APPLICATION MESSAGE
|
||
0 ;(PPD = 5) ERROR PACKET DOESN'T COME HERE
|
||
SR.ALN ;(PPD = 6) SHUTDOWN
|
||
;ROUTINE TO SEND A REQUEST-ID DATAGRAM.
|
||
;CALL:
|
||
; Q1/ NODE NUMBER
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB
|
||
; T3/ PATH BIT
|
||
; PUSHJ P,KLPRID
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
KLPRID: MOVE T1,Q3 ;GET PCB ADDRESS
|
||
ADD T1,Q1 ; OFFSET FOR THIS NODE
|
||
MOVEI T2,RIDTIM*3 ;CONVERT TIMER LENGTH TO UDT INCREMENTS
|
||
ADD T2,DATE## ;WHEN TIMER WILL EXPIRE
|
||
MOVEM T2,.PCRIT(T1) ;SET THE EXPIRATION TIME
|
||
MOVEI T1,OP.RID ;OPCODE = REQUEST ID
|
||
MOVEI T2,INCXID ;GET NEW TRANSACTION ID
|
||
ADDB T2,KLPXID ;...
|
||
MOVEM T2,.PKXID(Q2) ;STORE IN PACKET
|
||
MOVEM T2,.PKXID+1(Q2) ; (SAME THING IN BOTH WORDS)
|
||
MOVEI T2,KLPDRG ;PRIORITY
|
||
PJRST DRVSND ;SEND THE PACKET AND RETURN
|
||
|
||
|
||
;ROUTINE TO SEND A READ-COUNTERS PACKET.
|
||
;CALL:
|
||
; T2/ REASON CODE
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB
|
||
; PUSHJ P,KLPRPT
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
KLPRPT: MOVEM T2,.PKXID(Q2) ;PUT REASON IN PACKET
|
||
MOVEI T1,OP.RCT ;OPERATION = READ COUNTERS
|
||
MOVEI T2,KLPDRG ;PRIORITY
|
||
SETZB T3,Q1 ;NO FLAGS, CLEAR NODE NUMBER
|
||
PJRST DRVSND ;SEND THE PACKET AND RETURN
|
||
;ROUTINE TO SEND A DATAGRAM FOR A DIAGNOSTIC FUNCTION.
|
||
;CALL:
|
||
; T1/ OPCODE
|
||
; T3/ FLAGS
|
||
; Q1/ NODE NUMBER
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,DIASND
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
DIASND: MOVEI T4,INCXID ;GET NEW TRANSACTION ID
|
||
ADDB T4,KLPXID ;...
|
||
MOVEM T4,.PKXID(Q2) ;SAVE FIRST WORD
|
||
MOVEM T4,.PKXID+1(Q2) ; AND SECOND WORD
|
||
MOVEI T2,KLPDRG ;PRIORITY
|
||
PJRST DRVSND ;FINISH UP VIA DRVSND
|
||
|
||
|
||
;ROUTINE TO SEND A DATAGRAM FROM THE DRIVER.
|
||
;CALL:
|
||
; T1/ OPCODE
|
||
; T2/ PRIORITY
|
||
; T3/ FLAGS
|
||
; Q1/ NODE NUMBER
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,DRVSND
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
DRVSND: MOVX T4,PK.SRB ;CLEAR ALL SOFTWARE RESPONSE BITS
|
||
ANDCAM T4,.PKVRT(Q2) ;...
|
||
MOVX T4,PK.DRV ;GET THE DRIVER RESPONSE BIT
|
||
TXNE T3,PF.RSP ;DOES THE DRIVER WANT THE BUFFER BACK?
|
||
IORM T4,.PKVRT(Q2) ;YES, SET THE FLAG
|
||
PJRST KLPSND ;SEND THE PACKET AND RETURN
|
||
;ROUTINE TO SEND A MESSAGE/DATAGRAM.
|
||
;CALL:
|
||
; T1/ OPCODE
|
||
; T2/ PRIORITY
|
||
; T3/ FLAGS
|
||
; Q1/ NODE NUMBER
|
||
; Q2/ PACKET ADDRESS
|
||
; Q3/ PCB ADDRESS
|
||
; PUSHJ P,KLPSND
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
KLPSND: MOVEM T3,.PKSTS(Q2) ;SAVE FLAGS AND INITIALIZE THIS WORD
|
||
DPB T1,PKYOP ;SAVE OPCODE
|
||
DPB Q1,PKYNOD ;SAVE NODE NUMBER
|
||
|
||
SNOOP (CISPKX) ;CISNUP SNOOP POINT - PACKET TRANSMITTED
|
||
;Q2/ PACKET ADDRESS
|
||
;Q3/ PCB ADDRESS
|
||
|
||
MOVE T1,T2 ;GET PRIORITY (WHICH COMMAND QUEUE)
|
||
CAILE T1,MAXQUE ;TOO LOW?
|
||
MOVEI T1,MAXQUE ;YES, REDUCE IT TO LOWEST PRIORITY WE HAVE
|
||
IMULI T1,.PQLEN ;COMPUTE ADDRESS OF QUEUE
|
||
ADDI T1,.PCCQB ;OFFSET TO CORRECT QUEUE
|
||
ADD T1,Q3 ;ADD IN PCB ADDRESS
|
||
PUSHJ P,PUTQUE ;INSERT THE PACKET ON QUEUE
|
||
IFN FTMP,<
|
||
MOVE T1,.PCCPU(Q3) ;GET CPU WHO OWNS PORT
|
||
CAMN T1,.CPCPN## ;ANOTHER CPU?
|
||
JRST KLPSN1 ;NO, NO BOTHER
|
||
MOVX T1,ST.CQA ;GET THE BIT
|
||
IORM T1,.PCSTS(Q3) ;LET OTHER CPU KNOW AT ONCE/TICK LEVEL
|
||
MOVE T1,.CPQPC## ;GET THIS CPU'S QUEUED I/O FLAG
|
||
IORM T1,DOORBL## ;SET QUEUED I/O FLAG
|
||
POPJ P, ;RETURN
|
||
|
||
KLPSN1: MOVX T1,ST.CQA ;CLEAR THE BIT
|
||
ANDCAM T1,.PCSTS(Q3) ; IN CASE OTHER CPU SET IT
|
||
>; END IFN FTMP
|
||
MOVE T1,.CPUPT## ;GET CPU UPTIME WHEN PACKET QUEUED
|
||
MOVEM T1,.PCKCT(Q3) ;SAVE FOR KEEP ALIVE FAILURE CHECKS
|
||
MOVE T1,.PCPIA(Q3) ;GET KLIPA PI ASSIGNMENT
|
||
TRO T1,CO.CQA+CO.BTS ;COMMAND QUEUE AVAILABLE
|
||
XCT KDBCNO(Q3) ;KICK THE PORT
|
||
POPJ P, ;RETURN TO CALLER
|
||
;ROUTINE TO GET A BUFFER FROM THE DATAGRAM FREE QUEUE
|
||
;CALL:
|
||
; Q3/ PCB
|
||
; PUSHJ P,KLPGDB
|
||
;RETURN:
|
||
; CPOPJ IF NONE AVAILABLE
|
||
; CPOPJ1 IF OK WITH:
|
||
; Q2/ ADDRESS OF BUFFER
|
||
|
||
KLPGDB: XMOVEI T1,.PCDFQ(Q3) ;WHICH QUEUE
|
||
PUSHJ P,REMQUE ;GET BUFFER
|
||
POPJ P, ;EMPTY
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
SUBTTL LINK/DELINK PACKET ROUTINES
|
||
|
||
|
||
;ROUTINE TO LINK PACKETS ONTO A FREE QUEUE.
|
||
;CALL:
|
||
; T1/ ADDRESS OF QUEUE
|
||
; Q2/ ADDRESS OF FIRST PACKET
|
||
; PUSHJ P,LNKQUE
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
LNKQUE: PUSH P,(Q2) ;SAVE ADDRESS OF NEXT PACKET
|
||
PUSHJ P,PUTQUE ;STUFF THE PACKET ONTO THE FREE QUEUE
|
||
POP P,Q2 ;GET ADDRESS OF NEXT PACKET BACK
|
||
JUMPN Q2,LNKQUE ;KEEP LOOPING UNTIL ALL ARE LINKED
|
||
POPJ P, ;RETURN
|
||
SUBTTL THREE-WORD QUEUE MANIPULATION ROUTINES
|
||
|
||
|
||
;ROUTINE TO REMOVE FIRST PACKET FROM A QUEUE.
|
||
;CALL:
|
||
; T1/ ADDRESS OF QUEUE
|
||
; PUSHJ P,REMQUE
|
||
;RETURN:
|
||
; CPOPJ IF QUEUE WAS EMPTY
|
||
; CPOPJ1 WITH:
|
||
; Q2/ PACKET ADDRESS
|
||
|
||
REMQUE: CIOFF ;NO INTERRUPTS
|
||
SETZ T3, ;INITIALIZE COUNT
|
||
REMQU1: SKIPGE .PQIWD(T1) ;SKIP IF INTERLOCK NOT AVAILABLE
|
||
AOSE .PQIWD(T1) ;AVAILABLE, TRY TO GET IT
|
||
AOSA T3 ;NOT AVAILABLE, INCREMENT COUNT AND SKIP
|
||
JRST REMQU2 ;GOT IT
|
||
CAIGE T3,TIMOUT ;WAITED LONG ENOUGH?
|
||
JRST REMQU1 ;NO, TRY AGAIN
|
||
AOS BRKCNT ;YES. DO IT ANYWAY. BUMP COUNTER
|
||
BUG. (INF,KLPRMQ,KLPSER,HARD,<Queue interlock timeout>,,)
|
||
|
||
REMQU2: PUSHJ P,CHKMPT ;IS QUEUE ALREADY EMPTY?
|
||
JRST QRET ;EMPTY
|
||
AOS (P) ;NOT EMPTY. SET FOR SKIP/SKIP2 RETURN
|
||
MOVE T2,.PQFLI(T1) ;GET 1ST PACKET FROM QUEUE
|
||
PUSHJ P,CHKPAK ;GET ITS VIRTUAL ADDRESS
|
||
JRST REMQU4 ;VIRTUAL ADDR DOESN'T MATCH PHYSICAL!
|
||
MOVE Q2,T2 ;VIRTUAL ADDR OF PACKET IN Q2
|
||
DMOVE T2,.PKFLI(Q2) ;GET FLINK, BLINK OF THIS PACKET
|
||
CAME T2,T3 ;FLINK=BLINK?
|
||
JRST REMQU3 ;NO, QUEUE IS STILL NON-EMPTY
|
||
DMOVEM T2,.PQFLI(T1) ;YES. QUEUE IS EMPTY. POINT HEADER AT ITSELF
|
||
QRET: SETOM .PQIWD(T1) ;RELEASE INTERLOCK
|
||
PJRST CIONPJ## ;INTERRUPTS BACK ON AND RETURN
|
||
|
||
REMQU3: MOVEM T2,.PQFLI(T1) ;POINT QUEUE HEADER AT NEXT PACKET
|
||
ADDI T2,.PKBLI ;POINT AT FLINK OF NEXT PACKET
|
||
PMOVEM T3,T2 ;POINT NEXT PACKET BACK AT HEADER
|
||
JRST QRET ;NON-SKIP RETURN
|
||
|
||
;HERE IF VIRTUAL ADDR IN PACKET ISN'T WHAT IT SHOULD BE
|
||
|
||
REMQU4: MOVE T4,.PQFLI(T1) ;GET THE FLINK WORD
|
||
BUG. (CHK,KLPVIR,KLPSER,HARD,<Virtual address in packet is wrong>,<<T1,QUEUE>,<T2,VMA>,<T3,PMA>,<T4,FLINK>>,)
|
||
MAP T2,.PQFLI(T1) ;GET PHYSICAL ADDR OF QUEUE HEADER
|
||
TXZ T2,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
MOVEM T2,.PQFLI(T1) ;RESET QUEUE TO EMPTY
|
||
MOVEM T2,.PQBLI(T1) ;...
|
||
SOS (P) ;GIVE EMPTY-QUEUE RETURN
|
||
JRST QRET ;NON-SKIP RETURN
|
||
;ROUTINE TO INSERT A PACKET ONTO A QUEUE.
|
||
;CALL:
|
||
; Q2/ ADDRESS OF PACKET
|
||
; T1/ ADDRESS OF QUEUE
|
||
; PUSHJ P,PUTQUE
|
||
;RETURN:
|
||
; CPOPJ ALWAYS
|
||
|
||
PUTQUE: CIOFF ;NO INTERRUPTS
|
||
SETZ T3, ;INITIALIZE COUNT
|
||
PUTQU1: SKIPGE .PQIWD(T1) ;SKIP IF INTERLOCK NOT AVAILABLE
|
||
AOSE .PQIWD(T1) ;AVAILABLE, TRY TO GET IT
|
||
AOSA T3 ;NOT AVAILABLE, INCREMENT COUNT AND SKIP
|
||
JRST PUTQU2 ;GOT IT
|
||
CAIGE T3,TIMOUT ;WAITED LONG ENOUGH?
|
||
JRST PUTQU1 ;NO, TRY AGAIN
|
||
AOS BRKCNT ;YES. DO IT ANYWAY. BUMP COUNTER
|
||
BUG. (INF,KLPPTQ,KLPSER,HARD,<Queue interlock timeout>,,)
|
||
PUTQU2: STOR Q2,PKVRT,(Q2) ;SAVE VIRTUAL ADDR IN PACKET
|
||
MAP T3,.PKFLI(Q2) ;PHYSICAL ADDR OF PACKET
|
||
TXZ T3,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
MAP T2,.PQFLI(T1) ;PHYSICAL ADDR OF QUEUE HEADER
|
||
TXZ T2,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
CAME T2,.PQFLI(T1) ;FLINK POINT AT ITSELF (EMPTY QUEUE)?
|
||
JRST PUTQU3 ;NO
|
||
MOVEM T2,.PKFLI(Q2) ;YES. POINT PACKET BACK AT QUEUE HEADER
|
||
MOVEM T2,.PKBLI(Q2)
|
||
MOVEM T3,.PQBLI(T1) ;POINT PCB FLINK AND BLINK AT PACKET
|
||
MOVEM T3,.PQFLI(T1)
|
||
JRST QRET
|
||
|
||
PUTQU3: MOVEM T2,.PKFLI(Q2) ;POINT FLINK OF PACKET AT PCB
|
||
MOVE T2,.PQBLI(T1) ;GET FORMER END OF QUEUE
|
||
MOVEM T3,.PQBLI(T1) ;POINT QUEUE TAIL AT THIS PACKET
|
||
MOVEM T2,.PKBLI(Q2) ;POINT BLINK OF THIS PACKET AT FORMER END
|
||
PMOVEM T3,T2 ;POINT BLINK OF FORMER END AT THIS PACKET
|
||
JRST QRET
|
||
;ROUTINE TO CHECK IF A QUEUE IS EMPTY.
|
||
;CALL:
|
||
; T1/ ADDRESS OF QUEUE
|
||
; PUSHJ P,CHKMPT
|
||
;RETURN:
|
||
; CPOPJ IF QUEUE IS EMPTY
|
||
; CPOPJ1 IF QUEUE ISN'T EMPTY
|
||
|
||
CHKMPT: MAP T2,.PQFLI(T1) ;GET PHYSICAL ADDRESS OF QUEUE HEADER
|
||
TXZ T2,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
CAME T2,.PQFLI(T1) ;DOES QUEUE POINT AT ITSELF (EMPTY)?
|
||
AOS (P) ;NO, SET FOR SKIP
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;ROUTINE TO RETURN THE VIRTUAL ADDRESS OF A PACKET.
|
||
;CALL:
|
||
; T2/ PACKET PHYSICAL ADDRESS
|
||
; PUSHJ P,CHKPAK
|
||
;RETURN:
|
||
; CPOPJ IF PACKET IS BAD (VIRT ADDR IN PACKET DOESN'T MATCH PHYS ADDR)
|
||
; CPOPJ1 IF PACKET OK, WITH:
|
||
; T2/ PACKET VIRTUAL ADDRESS
|
||
;THIS ROUTINE MUST PRESERVE T1.
|
||
|
||
CHKPAK: SAVEAC (Q1) ;SAVE Q1
|
||
MOVE Q1,T2 ;COPY PHYSICAL ADDRESS
|
||
ADDI T2,.PKVRT ;POINT AT VIRTUAL ADDRESS WORD WITHIN PACKET
|
||
PMOVE T2,T2 ;FETCH THE CONTENTS
|
||
TXZ T2,PK.SRB ;CLEAR ALL SOFTWARE RESPONSE BITS
|
||
MAP T3,(T2) ;COMPUTE PHYSICAL ADDRESS OF THAT VIRTUAL ADDRESS
|
||
TXZ T3,MP.NAD ;CLEAR NON-ADDRESS BITS
|
||
CAMN T3,Q1 ;PHYSICAL ADDRESS MATCH?
|
||
AOS (P) ;YES, SET FOR SKIP RETURN
|
||
POPJ P, ;RETURN TO CALLER
|
||
SUBTTL MISCELLANEOUS ROUTINES
|
||
|
||
|
||
;ROUTINE TO REVERSE THE FULL WORD IN T1, PRESERVING OTHER AC'S.
|
||
;CALL:
|
||
; T1/ WORD TO REVERSE
|
||
; PUSHJ P,REVFUL
|
||
;RETURN:
|
||
; CPOPJ ALWAYS WITH:
|
||
; T1/ WORD REVERSED
|
||
;PRESERVES OTHER AC'S
|
||
|
||
$CSUB
|
||
|
||
SRVFUL::! ;ANOTHER NAME FOR THIS ROUTINE
|
||
REVFUL::PUSHJ P,SAVE3## ;SAVE P1-P3
|
||
LDB P1,PBYTE1 ;PICK UP THE BYTES
|
||
LDB P2,PBYTE2 ;...
|
||
LDB P3,PBYTE3 ;...
|
||
LSH T1,^D24 ;POSITION LEFT OVER BYTE
|
||
DPB P3,PBYTE2 ;PUT THEM IN BACKWARDS
|
||
DPB P2,PBYTE3 ;...
|
||
DPB P1,PBYTE4 ;...
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;BYTE POINTERS USED BY REVFUL
|
||
|
||
PBYTE1: POINT 8,T1,7
|
||
PBYTE3: POINT 8,T1,23
|
||
PBYTE2: POINT 8,T1,15
|
||
PBYTE4: POINT 8,T1,31
|
||
|
||
$XHIGH
|
||
;ROUTINE TO ACCOUNT FOR PPD BYTE WHICH PORT WILL ADD.
|
||
;WE MUST SWAP THE BYTES INTO ELEVEN FORMAT AND ACCOUNT
|
||
;FOR THE PPD FIELD IN THE TEXT LENGTH.
|
||
;CALL:
|
||
; Q2/ PACKET ADDRESS
|
||
; PUSHJ P,MASAGE
|
||
;RETURN:
|
||
; CPOPJ ALWAYS WITH:
|
||
; Q2/ PACKET ADDRESS
|
||
|
||
MASAGE: MOVEI T1,C%PPDL ;GET # OF BYTES IN PPD FIELD
|
||
ADDM T1,.PKLEN(Q2) ;ACCOUNT FOR THE PPD BYTE
|
||
LDB T1,PKYPPM ;GET THE MOST SIGNIFICANT BYTE OF THE PPD
|
||
LDB T2,PKYPPL ; AND THE LEAST SIGNIFICANT
|
||
DPB T2,PKYPPM ;SWAP THE TWO BYTES
|
||
DPB T1,PKYPPL ; INTO THE CORRECT FORMAT
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;ROUTINE TO SWAP THE BYTES IN THE PPD FIELD OF A PACKET WHICH HAS COME
|
||
;OFF THE BUS. WE CAN ALWAYS ASSUME THE PPD BYTE IS IN ELEVEN FORMAT
|
||
;SINCE THE HSC SENDS IT THAT WAY AND OUR PORT SWAPS IT THAT WAY ON A
|
||
;SEND OPERATION.
|
||
;CALL:
|
||
; Q2/ PACKET ADDRESS
|
||
; PUSHJ P,RMASAG
|
||
;RETURN:
|
||
; CPOPJ ALWAYS WITH:
|
||
; Q2/ PACKET ADDRESS
|
||
|
||
RMASAG: LDB T1,PKYOP ;GET THE OPCODE
|
||
TRZ T1,OP.RMT ;MAKE SURE THE REMOTE BIT IS OFF
|
||
CAIE T1,OP.SMS ;IS THIS A MESSAGE?
|
||
CAIN T1,OP.SDG ; OR A DATAGRAM?
|
||
SKIPA T1,[-C%PPDL] ;YES, GET NEGATIVE LENGTH OF PPD FIELD AND SKIP
|
||
POPJ P, ;NOT A MESSAGE OR DATAGRAM, RETURN
|
||
ADDM T1,.PKLEN(Q2) ;ACCOUNT FOR THE PPD FIELD LENGTH
|
||
LDB T1,PKYPPM ;GET MOST SIGNIFICANT BYTE OF THE PPD FIELD
|
||
LDB T2,PKYPPL ; AND THE LEAST SIGNIFICANT
|
||
DPB T2,PKYPPM ;SWAP THE TWO BYTES
|
||
DPB T1,PKYPPL ; INTO TEN FORMAT
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO GET THE NEXT COMMAND REFERENCE NUMBER.
|
||
;CALL:
|
||
; PUSHJ P,PPDGCN
|
||
;RETURN:
|
||
; CPOPJ ALWAYS WITH:
|
||
; T4/ COMMAND REFERENCE NUMBER
|
||
;PRESERVES ALL OTHER AC'S.
|
||
|
||
$CSUB
|
||
|
||
PPDGCN::AOS T4,CRFNUM ;BUMP COMMAND REFERENCE NUMBER
|
||
ANDI T4,37777 ;KEEP JUST 14 BITS WORTH
|
||
JUMPE T4,PPDGCN ;DON'T ALLOW COMMAND REFERENCE NUMBER OF ZERO
|
||
LSH T4,4 ;POSITION FOR SCA LAND
|
||
POPJ P, ;RETURN
|
||
|
||
$XHIGH
|
||
SUBTTL MEMORY ALLOCATION ROUTINE
|
||
|
||
|
||
;ROUTINE TO ALLOCATE NON-ZERO SECTION MEMORY FOR SCA DATA STRUCTURES.
|
||
;CALL:
|
||
; T2/ NUMBER OF WORDS DESIRED
|
||
; PUSHJ P,GETCOR
|
||
;RETURN:
|
||
; CPOPJ IF NOT AVAILABLE
|
||
; CPOPJ1 IF SUCCESS WITH:
|
||
; T1/ ADDRESS OF CHUNK ALLOCATED
|
||
|
||
GETCOR: PUSHJ P,SAVE3## ;SAVE XBLT ACS
|
||
MOVEI P1,-1(T2) ;SAVE COUNT MINUS ONE
|
||
PUSHJ P,GETSWS## ;GET THE SPACE
|
||
POPJ P, ;SORRY
|
||
MOVE P2,T1 ;START OF CHUNK
|
||
XMOVEI P3,1(P2) ;SECOND WORD OF CHUNK
|
||
SETZM (P2) ;ZERO FIRST WORD
|
||
EXTEND P1,[XBLT] ;AND THE REMAINDER
|
||
JRST CPOPJ1## ;SKIP RETURN
|
||
;SUBROUTINE LIKE ONCMAP BUT ALWAYS CREATES PAGES WRITABLE AND NON-CACHED
|
||
;(FOR INTERFACING TO TOPS-20 CODE).
|
||
;CALL:
|
||
; T1/ NUMBER OF PAGES
|
||
; PUSHJ P,PGRSKD
|
||
;RETURN:
|
||
; CPOPJ IF NOT ENOUGH FREE PAGES
|
||
; CPOPJ1 WITH:
|
||
; T1/ ADDRESS OF THE FIRST PAGE ALLOCATED
|
||
|
||
$CSENT (PGRSKD::)
|
||
MOVE T2,T1 ;COPY NUMBER OF PAGES REQUESTED
|
||
LSH T2,P2WLSH ;CONVERT TO WORDS
|
||
PUSH P,T2 ;SAVE A BIT
|
||
MOVEI T1,(MS.SCA) ;SECTION NUMBER
|
||
;*** FLAG TO INDICATE ALLOCATE ON A PAGE BOUNDARY?
|
||
PUSHJ P,GFWNZN## ;ALLOCATE THE SPACE
|
||
HALT . ;*** FOR NOW
|
||
|
||
;LINK THE PAGES TOGETHER VIA THE FIRST WORD OF THE PAGE.
|
||
;THE LINK WORD OF THE LAST PAGE IS ZERO.
|
||
|
||
POP P,T2 ;NUMBER OF WORDS REQUESTED
|
||
LSH T2,W2PLSH ;CONVERT TO THE NUMBER OF PAGES
|
||
PUSH P,T1 ;SAVE STARTING ADDRESS
|
||
PGRSK1: SETZM (T1) ;ZERO LINK TO NEXT PAGE
|
||
PUSH P,T2 ;SAVE COUNT
|
||
MOVEI T2,PG.BDY ;NUMBER OF WORDS TO ZERO
|
||
MOVE T3,T1 ;FIRST WORD TO COPY
|
||
XMOVEI T4,1(T1) ;DESTINATION
|
||
EXTEND T2,[XBLT] ;ZERO THE PAGE
|
||
POP P,T2 ;RESTORE COUNT
|
||
SOJLE T2,TPOPJ1## ;JUMP WHEN DONE
|
||
XMOVEI T3,PAGSIZ(T1) ;ADDRESS OF NEXT PAGE
|
||
MOVEM T3,0(T1) ;LINK THAT PAGE TO THIS
|
||
MOVE T1,T3 ;COPY NEXT PAGE ADDRESS
|
||
JRST PGRSK1 ;LOOP FOR REMAINING PAGES
|
||
|
||
$XHIGH
|
||
SUBTTL BYTE POINTERS
|
||
|
||
|
||
;POINTERS APPLICABLE TO ALL TYPES OF PACKETS
|
||
|
||
PKYSTS: POINT PKSSTS,.PKSTS(Q2),PKPSTS ;STATUS
|
||
PKYSFD: POINT PKSSTS-1,.PKSTS(Q2),PKPSTS ;STATUS MINUS ERROR BIT
|
||
PKYFLG: POINT PKSFLG,.PKSTS(Q2),PKPFLG ;FLAGS
|
||
PKYOP: POINT PKSOP,.PKSTS(Q2),PKPOP ;OP CODE
|
||
PKYNOD: POINT PKSNOD,.PKSTS(Q2),PKPNOD ;NODE TO SEND TO
|
||
|
||
;POINTERS SPECIFIC TO SPECIFIC PACKETS
|
||
|
||
PKYREG: POINT PKSREG,.PKREG(Q2),PKPREG ;REGISTER TO READ
|
||
PKYDTA: POINT PKSDTA,.PKREG(Q2),PKPDTA ;DATA FROM REGISTER READ
|
||
PKYCND: POINT PKSCND,.PKPND(Q2),PKPCND ;NODE TO POINT PERFORMANCE COUNTER AT
|
||
PKYPST: POINT PKSPST,.PKPST(Q2),PKPPST ;REMOTE PORT STATE
|
||
PKYRST: POINT PKSRST,.PKPST(Q2),PKPRST ;REMOTE PORT STATE AND MAINTENANCE FIELD
|
||
PKYRND: POINT PKSRND,.PKPST(Q2),PKPRND ;RESETTING NODE NUMBER
|
||
|
||
;PPD BYTE POINTERS
|
||
|
||
PKYPPM: POINT 8,.PKLEN(Q2),7 ;MOST SIG BYTE OF PPD FIELD IN 10 FORMAT
|
||
PKYPPL: POINT 8,.PKLEN(Q2),15 ;LEAST SIG BYTE OF PPD FIELD IN 10 FORMAT
|
||
PKYPPD: POINT PKSPPD,.PKLEN(Q2),PKPPPD ;CI.PPD
|
||
|
||
;LENGTH BYTE
|
||
|
||
PKYLEN: POINT PKSLEN,.PKLEN(Q2),PKPLEN ;LENGTH FOR DATAGRAMS AND MESSAGES
|
||
SUBTTL LOOPBACK CRC CODES
|
||
|
||
|
||
;THIS TABLE CONTAINS THE CRC CODES NEEDED FOR A LOOPBACK PACKET.
|
||
;THE TABLE IS INDEXED BY THE CI NODE NUMBER.
|
||
|
||
LPBLEN==6 ;LENGTH OF LOOPBACK PACKET
|
||
|
||
LPBCRC: 365137,,27260 ;NODE 0
|
||
461317,,343360 ;NODE 1
|
||
777542,,171600 ;NODE 2
|
||
73762,,215700 ;NODE 3
|
||
142070,,514540 ;NODE 4
|
||
646250,,670440 ;NODE 5
|
||
550405,,442120 ;NODE 6
|
||
254625,,726020 ;NODE 7
|
||
731224,,250400 ;NODE 8
|
||
35004,,134500 ;NODE 9
|
||
323651,,306060 ;NODE 10
|
||
427471,,62160 ;NODE 11
|
||
516363,,763320 ;NODE 12
|
||
212143,,407220 ;NODE 13
|
||
104716,,635740 ;NODE 14
|
||
600536,,551640 ;NODE 15
|
||
SUBTTL IMPURE STORAGE
|
||
|
||
|
||
$LOW
|
||
|
||
BHDIPT: EXP 0 ;INITIAL POINTER FOR BHD SEARCHES
|
||
BHDCPT: EXP 0 ;CURRENT POINTER FOR BHD SEARCHES
|
||
BHDEND: EXP 0 ;LAST ADDRESS IN BUFFER DESCRIPTOR TABLE
|
||
BHDADR::EXP 0 ;PHYSICAL ADDRESS OF BUFFER DESCRIPTOR TABLE
|
||
; (USED TO SET UP .PCBDT IN THE PCB)
|
||
BHDPGS::EXP 0 ;NUMBER OF PAGES IN BUFFER DESCRIPTOR TABLE
|
||
BHDMTI: EXP 0 ;MAXIMUM BDT INDEX
|
||
BHDNUM: EXP 0 ;NUMBER OF BUFFER HEADER DESCRIPTORS
|
||
|
||
BSDVRT: EXP 0 ;VIRTUAL ADDRESS OF START OF BSD AREA
|
||
BSDADR::EXP 0 ;PHYSICAL ADDRESS OF START OF BSD AREA
|
||
BSDLOC: EXP 0 ;POINTER TO FREE BSD CHAIN
|
||
BSDPGS::EXP 0 ;NUMBER OF PAGES FOR BUFFER SEGMENT DESCRIPTORS
|
||
BSDNUM: EXP 0 ;NUMBER OF BUFFER SEGMENT DESCRIPTORS
|
||
|
||
BRKCNT: EXP 0 ;NUMBER OF TIMES A PCB INTERLOCK WAS BROKEN
|
||
|
||
KLPXID: EXP 0 ;TRANSACTION ID COUNTER
|
||
|
||
CRFNUM: EXP 0 ;COMMAND REFERENCE NUMBER
|
||
|
||
$XHIGH
|
||
SUBTTL THE END
|
||
|
||
|
||
KLPFOO: BUG. (HLT,KLPOHF,KLPSER,SOFT,<Oh foo!>,,)
|
||
|
||
KLPEND::!END
|