Trailing-Edge
-
PDP-10 Archives
-
bb-jr93e-bb
-
7,6/ap017/kniser.x17
There is 1 other file named kniser.x17 in the archive. Click here to see a list.
TITLE KNISER - KLNI DEVICE DRIVER V51
SUBTTL WILLIAM C. DAVENPORT/WXD 15 JULY 86
SEARCH F,S,ETHPRM,KNIPRM,ICHPRM,MACSYM
T20SYM
$RELOC
$HIGH
;THIS MODULE IMPLEMENTS THE KLNI INTERFACE DRIVER FOR ETHERNET
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
.CPYRT<1985,1986>
;COPYRIGHT (C) 1985,1986 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;ALL RIGHTS RESERVED.
XP VKNISR,51 ;KNISER VERSION NUMBER
KNISER::!ENTRY KNISER ;LOAD IF LIBRARY SEARCH
SUBTTL TABLE OF CONTENTS
; TABLE OF CONTENTS FOR KNISER
;
;
; SECTION PAGE
; 1. TABLE OF CONTENTS......................................... 2
; 2. KLNI DEVICE SERVICE
; 2.1 AUTCON PARAMETERS................................. 3
; 2.2 KLNI CONFIGURATION................................ 4
; 2.3 KLNI INITIALIZATION............................... 5
; 2.4 ONCE A TICK CODE.................................. 6
; 2.5 ONCE A SECOND CODE................................ 7
; 2.6 SET MEMORY OFFLINE SUPPORT........................ 9
; 2.7 REMOVE CPU SUPPORT................................ 11
; 2.8 CPU OFFLINE SUPPORT............................... 12
; 2.9 RESET UUO......................................... 13
; 3. KLNI USER SERVICE
; 3.1 ETHSER FUNCTION DISPATCH.......................... 14
; 3.2 SET KONTROLLER ETHERNET ADDRESS................... 16
; 3.3 READ AND CLEAR KONTROLLER COUNTERS................ 18
; 3.4 READ AND CLEAR PORTAL COUNTERS.................... 22
; 3.5 ENABLE PROTOCOL................................... 25
; 3.6 DISABLE PROTOCOL.................................. 28
; 3.7 ENABLE MULTI-CAST ADDRESS......................... 31
; 3.8 DISABLE MULTI-CAST ADDRESS........................ 33
; 3.9 RECEIVE DATAGRAM.................................. 35
; 3.10 TRANSMIT DATAGRAM................................. 37
; 3.11 INTERRUPT ETHSER.................................. 39
; 3.12 GENERATE KLNI COMMAND BUFFER...................... 40
; 4. KLNI DEVICE SERVICE
; 4.1 PORT CONTROL BLOCK INITIALIZATION................. 41
; 4.2 PORT CONTROL BLOCK RESET.......................... 42
; 4.3 ADD PROTOCOL TYPE TO PTT TABLE.................... 43
; 4.4 DELETE PROTOCOL TYPE FROM PTT TABLE............... 44
; 4.5 ADD MULTI-CAST ADDRESS TO MCAT TABLE.............. 45
; 4.6 DELETE MULTI-CAST ADDRESS FROM MCAT TABLE......... 46
; 4.7 UPDATE KLNI COUNTERS AREA......................... 47
; 4.8 GENERATE BSD CHAIN................................ 48
; 4.9 RELEASE A BSD CHAIN............................... 52
; 4.10 ALLOCATE KLNI COMMAND BUFFER...................... 53
; 4.11 RELEASE KLNI COMMAND BUFFER....................... 54
; 4.12 QUEUE KLNI COMMAND TO FREE QUEUE.................. 55
; 4.13 QUEUE KLNI COMMAND TO COMMAND QUEUE............... 56
; 4.14 MISCELLANEOUS..................................... 57
; 5. KLNI INTERRUPT SERVICE
; 5.1 INTERRUPT DISPATCH................................ 58
; 5.2 PROCESS RESPONSE QUEUE............................ 59
; 5.3 FREE QUEUE ERROR.................................. 60
; 5.4 CRAM PARITY ERROR................................. 61
; 5.5 MBUS ERROR........................................ 65
; 5.6 EBUS PARITY ERROR................................. 66
; 5.7 DATA PATH ERROR................................... 67
; 5.8 KLNI ERROR STOP PROCESSING........................ 68
; 5.9 SPEAR ERROR LOGGING............................... 69
; 6. KLNI MAINTENANCE SERVICE
; 6.1 DIAG. UUO......................................... 71
; 6.2 KNIBT. UUO........................................ 77
; 6.3 SHUT DOWN KLNI MICROCODE.......................... 84
; 6.4 STOP KLNI MICROCODE............................... 85
; 6.5 PROCESS KLNI QUEUE................................ 86
; 6.6 START KLNI MICROCODE.............................. 87
; 6.7 DISABLE KLNI MICROCODE............................ 89
; 6.8 ENABLE KLNI MICROCODE............................. 90
; 6.9 INITIALIZE KLNI MICROCODE......................... 91
; 6.10 READ LATCHED ADDRESS REGISTER..................... 97
; 6.11 READ CRAM CONTENTS................................ 98
; 6.12 WRITE CRAM CONTENTS............................... 99
; 6.13 REQUEST MICROCODE RELOAD.......................... 100
; 7. QUEUE MANIPULATION
; 7.1 INITIALIZE QUEUE HEADER........................... 101
; 7.2 FIX A QUEUE....................................... 102
; 7.3 REMOVE AN ENTRY FROM QUEUE........................ 103
; 7.4 INSERT AN ENTRY INTO QUEUE........................ 104
; 8. BYTE POINTERS............................................. 105
; 9. THE END................................................... 106
SUBTTL KLNI DEVICE SERVICE -- AUTCON PARAMETERS
KNIPCB==:BYTE (9) .PBLEN, .PBPCB, .PBPCL, 0 ;BYTE (9) LENGTH OF PCB, OFFSET TO
; PHYSICALLY CONTIGUOUS AREA, LENGTH OF
; PHYSICALLY CONTIGUOUS AREA
KNIBTS==CI.CPE!CI.MER!CI.EPE!CI.FQE!CI.RQA ;BITS TO TEST FOR ON INTERRUPT
CO.BTS==CO.MRN ;BITS WHICH MUST BE ON FOR ALL CONOS
SUBTTL KLNI DEVICE SERVICE -- KLNI CONFIGURATION
;ROUTINE CALLED WHEN AUTCON DETECTS A KLNI ON THIS CPU
;LINKAGE:
; T1/ PORT CONTROL BLOCK ADDRESS
; P1/ CHANNEL DATA BLOCK ADDRESS
; PUSHJ P,KNICFG
;RETURNS:
; CPOPJ ALWAYS
KNICFG::PUSHJ P,SAVQ## ;SAVE Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVE Q3,T1 ;GET PORT CONTROL BLOCK ADDRESS
MOVEM P1,.PBCDB(Q3) ;SAVE ADDRESS OF CHANNEL DATA BLOCK IN PCB
MOVEI T1,.ULLEN ;NUMBER OF WORDS IN MICROCODE PARAMETER BLOCK
XMOVEI T2,KNIULB ;ADDRESS OF PROTOTYPE BLOCK
XMOVEI T3,.PBULB(Q3) ;ADDRESS OF DESTINATION BLOCK IN PCB
EXTEND T1,[XBLT] ;COPY PROTOTYPE TO OUR PCB
MOVE T1,[KNIBTS] ;BITS TO TEST FOR ON INTERRUPT
MOVEM T1,CHNBTS##(P1) ;SET IN CHANNEL DATA BLOCK
POPJ P, ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- KLNI INITIALIZATION
;ROUTINE CALLED TO INITIALIZE THE KLNI ON THIS CPU
;LINKAGE:
; PUSHJ P,KNIINI
;RETURNS:
; CPOPJ ALWAYS
KNIINI::PUSHJ P,SAVQ## ;SAVE Q1-Q3
PUSHJ P,SAVE1## ;SAVE P1
SE1ENT ;RUN IN SECTION 1
SETZB Q1,Q2 ;START CLEAN
SKIPE P1,.CPCHN##+KNIICH ;GET ADDRESS OF CHANNEL DATA BLOCK
SKIPN Q3,CHNPCB##(P1) ;GET THE PORT CONTROL BLOCK ADDRESS
POPJ P, ;NO KLNI ON THIS CPU
SKIPE .CPNPB## ;RESTART?
JRST [PUSHJ P,SHTKNI ;YES, SHUT DOWN KLNI
PUSHJ P,PCBINI ;RESET THE PORT CONTROL BLOCK
JRST RLDKNI] ;REQUEST KLNI RELOAD AND RETURN
PUSHJ P,PCBINI ;INITIALIZE THE PCB
MOVE T1,Q3 ;GET ADDRESS OF PORT CONTROL BLOCK
XMOVEI T2,KNUSER ;AND ADDRESS OF OUR DISPATCH ROUTINE
MOVSI T3,.KTKNI ;GET KONTROLLER TYPE AND NUMBER
PUSHJ P,ETKINI## ;CREATE AN ETHERNET KONTROLLER BLOCK
STOPCD CPOPJ##,DEBUG,KNICCK ;++CAN'T CREATE ETHERNET KONTROLLER BLOCK
MOVEM T1,.PBEKB(Q3) ;LINK KONTROLLER BLOCK TO PORT CONTROL BLOCK
MOVEM Q3,.CPNPB## ;SAVE PCB ADDRESS IN CDB
PJRST RLDKNI ;REQUEST RELOAD OF KLNI AND RETURN
SUBTTL KLNI DEVICE SERVICE -- ONCE A TICK CODE
;ROUTINE CALLED ONCE A TICK ON ALL CPUS
;LINKAGE:
; PUSHJ P,KNITIC
;RETURNS:
; CPOPJ ALWAYS
KNITIC::SKIPN .CPNPB## ;THIS CPU HAVE A KLNI?
POPJ P, ;NO, RETURN
PUSHJ P,SAVQ## ;SAVE Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVE Q3,.CPNPB## ;GET ADDRESS OF PORT CONTROL BLOCK
MOVE T1,.PBSTS(Q3) ;GET CURRENT KLNI STATUS
TXNE T1,PBSMAI ;IS KLNI IN MAINTENANCE MODE?
POPJ P, ;YES, RETURN NOW
TXNE T1,PBSRUN ;IS KLNI RUNNING?
TXNN T1,PBSQIO ;YES, ANY QUEUED I/O REQUESTS?
POPJ P, ;NO, RETURN
MOVX T1,PBSQIO ;CLEAR QUEUED I/O REQUEST FLAG
ANDCAM T1,.PBSTS(Q3) ;...
MOVE T1,.PBPIA(Q3) ;GET KLNI PI ASSIGNMENT
CONO KNI,CO.CQA!CO.BTS(T1) ;SET COMMAND QUEUE AVAILABLE FLAG
POPJ P, ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- ONCE A SECOND CODE
;ROUTINE CALLED ONCE A SECOND ON ALL CPUS
;LINKAGE:
; PUSHJ P,KNISEC
;RETURNS:
; CPOPJ ALWAYS
KNISEC::SKIPN .CPNPB## ;THIS CPU HAVE A KLNI?
POPJ P, ;NO, RETURN
PUSHJ P,SAVQ## ;SAVE Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVE Q3,.CPNPB## ;GET ADDRESS OF PORT CONTROL BLOCK
MOVE T1,.PBSTS(Q3) ;GET CURRENT KLNI STATUS
TXNE T1,PBSMAI ;IS KLNI IN MAINTENANCE MODE?
POPJ P, ;YES, RETURN NOW
TXNE T1,PBSRUN ;KLNI RUNNING?
JRST KNISE1 ;YES, GO PERFORM KEEP ALIVE CHECKS
TXNE T1,PBSINI ;NEED TO INITIALIZE KLNI?
JRST [MOVX T1,PBSINI ;YES, CLEAR INITIALIZE KLNI FLAG
ANDCAM T1,.PBSTS(Q3) ;...
PUSHJ P,PCBINI ;INITIALIZE PORT CONTROL BLOCK
PJRST RLDKNI] ;REQUEST KLNI RELOAD AND RETURN
TXNE T1,PBSQRR ;QUEUED RELOAD REQUESTED?
PJRST KNILOD ;YES, RELOAD MICROCODE AND RETURN
TXNN T1,PBSRLD ;IS A RELOAD PENDING?
POPJ P, ;NO, RETURN
LDB T1,PBPRJB ;GET JOB NUMBER OF RELOAD JOB
JUMPN T1,CPOPJ## ;RETURN IF KNILDR IS RUNNING
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
SUB T1,.PBKLT(Q3) ;COMPUTE TIME SINCE RELOAD REQUESTED
IMULI T1,^D1000 ;CONVERT TO MILLISECONDS
IDIV T1,TICSEC## ;...
CAIL T1,RLDTIM ;TOO LONG SINCE RELOAD REQUESTED?
PJRST RLDKNI ;YES, REQUEST KLNI RELOAD AGAIN AND RETURN
POPJ P, ;RETURN
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
KNISE1: MOVX T1,PBSMOF ;IS MEMORY BEING SET OFFLINE?
TDNE T1,.PBSTS(Q3) ;...
PJRST SHTKNI ;YES, SHUT KLNI DOWN AND RETURN
MOVX T1,PBSONL ;IS KLNI ONLINE?
TDNN T1,.PBSTS(Q3) ;...
POPJ P, ;NO, RETURN
MOVE T1,.CPUPT## ;GET CPU UPTIME
SUB T1,.PBKRT(Q3) ;CALCULATE TIME SINCE LAST KLNI RESPONSE
IMULI T1,^D1000 ;CONVERT TO MILLISECONDS
IDIV T1,TICSEC## ;...
CAIGE T1,KAFTIM ;TOO LONG SINCE LAST RESPONSE?
JRST KNISE2 ;NO, GO CHECK KLNI IDLE TIMER
CONI KNI,T1 ;GET CURRENT CONI STATUS
CONO KNI,CO.CPT ;MAKE SURE KLNI IS REALLY STOPPED
STOPCD .+1,INFO,KNIKAF ;++KLNI KEEP ALIVE FAILED
MOVEM T1,.PBCLI(Q3) ;SAVE CONI FOR ERROR LOGGING
AOS .PBKAC(Q3) ;UPDATE COUNT OF KLNI KEEP ALIVE FAILURES
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
MOVEM T1,.PBKAT(Q3) ;REMEMBER TIME OF LAST KEEP ALIVE FAILURE
PJRST KNESTP ;DO KLNI ERROR STOP PROCESSING AND RETURN
KNISE2: MOVE T1,.CPUPT## ;GET CPU UPTIME
SUB T1,.PBKCT(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
MOVEI T1,CMORSA ;READ NI STATION ADDRESS COMMAND FUNCTION
PUSHJ P,GETCMD ;GENERATE KLNI COMMAND BUFFER
POPJ P, ;ERROR, RETURN NOW
XMOVEI T1,GIVCMD ;GET ADDRESS OF CALLBACK ROUTINE
PJRST KNICMD ;QUEUE COMMAND AND RETURN
SUBTTL KLNI DEVICE SERVICE -- SET MEMORY OFFLINE SUPPORT
;ROUTINE CALLED ON CPU0 WHEN MEMORY IS ABOUT TO BE SET OFFLINE
;LINKAGE:
; PUSHJ P,KNIMOF
;RETURNS:
; CPOPJ ALWAYS
KNIMOF::MOVEI T1,KNIMF1 ;GET ADDRESS OF ROUTINE
PJRST CPUAPP## ;CALL ROUTINE FOR ALL CPUS
;ROUTINE CALLED FOR ALL CPUS
KNIMF1: SKIPN .CPNPB##-.CPCDB##(P1) ;THIS CPU HAVE A KLNI?
POPJ P, ;NO, RETURN NOW
PUSHJ P,SAVQ## ;SAVE Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVE Q3,.CPNPB##-.CPCDB##(P1) ;GET ADDRESS OF PORT CONTROL BLOCK
MOVX T1,PBSMOF ;SET MEMORY OFFLINE FLAG
IORM T1,.PBSTS(Q3) ;...
POPJ P, ;AND RETURN
;ROUTINE CALLED ON CPU0 WHEN SET MEMORY OFFLINE HAS COMPLETED
;LINKAGE:
; PUSHJ P,KNIMON
;RETURNS:
; CPOPJ ALWAYS
KNIMON::MOVEI T1,KNIMN1 ;GET ADDRESS OF ROUTINE
PJRST CPUAPP## ;CALL ROUTINE FOR ALL CPUS
;ROUTINE CALLED FOR ALL CPUS
KNIMN1: MOVE T1,.CPCPN## ;GET OUR CPU NUMBER
MOVE T1,BITTBL##(T1) ;GET THAT BIT
TSNN T1,IPAMSK## ;WANT TO SKIP STARTING THE NI?
SKIPN .CPNPB##-.CPCDB##(P1) ;THIS CPU HAVE A KLNI?
POPJ P, ;NO, RETURN NOW
PUSHJ P,SAVQ## ;SAVE Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVE Q3,.CPNPB##-.CPCDB##(P1) ;GET ADDRESS OF PORT CONTROL BLOCK
MOVX T1,PBSMOF ;GET MEMORY OFFLINE FLAG
TDNN T1,.PBSTS(Q3) ;KLNI STOPPED BECAUSE OF SET MEMORY OFFLINE?
POPJ P, ;NO, RETURN NOW
ANDCAM T1,.PBSTS(Q3) ;YES, CLEAR MEMORY OFFLINE FLAG
MOVX T1,PBSINI ;SET INITIALIZE KLNI FLAG
IORM T1,.PBSTS(Q3) ;...
POPJ P, ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- REMOVE CPU SUPPORT
;ROUTINE CALLED WHEN A CPU IS REMOVED
;LINKAGE:
; PUSHJ P,KNIRMV
;RETURNS:
; CPOPJ ALWAYS
;ALL ACS PRESERVED
KNIRMV::PUSHJ P,SAVT## ;SAVE T1-T4
SKIPN .CPNPB## ;DO WE HAVE A KLNI?
POPJ P, ;NO, RETURN
PUSHJ P,SAVQ## ;SAVE Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVE Q3,.CPNPB## ;GET ADDRESS OF PORT CONTROL BLOCK
PJRST SHTKNI ;SHUT DOWN KLNI AND RETURN
SUBTTL KLNI DEVICE SERVICE -- CPU OFFLINE SUPPORT
;ROUTINE CALLED WHEN A CPU IS DECLARED DEAD
;LINKAGE:
; T1/ CPU NUMBER OF DEAD CPU
; PUSHJ P,KNIDED
;RETURNS:
; CPOPJ ALWAYS
;ALL ACS PRESERVED
KNIDED::PUSHJ P,SAVT## ;SAVE T1-T4
LSH T1,.CPSOF## ;COMPUTE OFFSET FROM CPU0'S CDB
SKIPN .C0NPB##(T1) ;THIS CPU HAVE A KLNI?
POPJ P, ;NO, RETURN
PUSHJ P,SAVQ## ;SAVE Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVE Q3,.C0NPB##(T1) ;GET ADDRESS OF PORT CONTROL BLOCK
PJRST STPKNX ;DECLARE KLNI DEAD AND RETURN
SUBTTL KLNI DEVICE SERVICE -- RESET UUO
;ROUTINE CALLED WHEN A JOB DOES A RESET UUO
;LINKAGE:
; PUSHJ P,KNIRST
;RETURNS:
; CPOPJ ALWAYS
KNIRST::MOVEI T1,KNIRS1 ;GET ADDRESS OF ROUTINE
PJRST CPUAPP## ;CALL ROUTINE FOR ALL CPUS
;ROUTINE CALLED FOR ALL CPUS
KNIRS1: SKIPN .CPNPB##-.CPCDB##(P1) ;THIS CPU HAVE A KLNI?
POPJ P, ;NO, RETURN NOW
PUSHJ P,SAVQ## ;SAVE Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVE Q3,.CPNPB##-.CPCDB##(P1) ;GET ADDRESS OF PORT CONTROL BLOCK
SETZ T1, ;GET A ZERO
LDB T2,PBPRJB ;GET JOB NUMBER OF RELOAD JOB
CAMN T2,.CPJOB## ;SAME AS JOB DOING RESET?
DPB T1,PBPRJB ;YES, CLEAR RELOAD JOB NUMBER
LDB T2,PBPMJB ;GET JOB NUMBER OF MAINTENANCE JOB
CAMN T2,.CPJOB## ;SAME AS JOB DOING RESET?
DPB T1,PBPMJB ;YES, CLEAR MAINTENANCE JOB NUMBER
POPJ P, ;AND RETURN
SUBTTL KLNI USER SERVICE -- ETHSER FUNCTION DISPATCH
;ROUTINE CALLED BY ETHSER FOR DEVICE SPECIFIC FUNCTIONS
;LINKAGE:
; T1/ ADDRESS OF EA BLOCK
; T2/ ADDRESS OF PORT CONTROL BLOCK
; T3/ ADDRESS OF PROTOCOL USER BLOCK (OR ZERO)
; PUSHJ P,KNUSER
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
KNUSER::PUSHJ P,SAVE1## ;SAVE P1
PUSHJ P,SAVQ## ;AND Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVE P1,T1 ;SAVE EA BLOCK ADDRESS
MOVE Q3,T2 ;AND ADDRESS OF PORT CONTROL BLOCK
MOVE Q2,T3 ;AND ADDRESS OF PROTOCOL USER BLOCK
MOVE T1,.EAFCN(P1) ;GET KONTROLLER FUNCTION CODE
SKIPLE T1 ;RANGE CHECK FUNCTION CODE
CAILE T1,EK.MAX ;...
KNUIFC:!STOPCD [ERRRET (UNIFC%)],DEBUG,KNIIFC ;++ILLEGAL FUNCTION CODE
MOVE T1,KNUDSP(T1) ;GET ADDRESS OF FUNCTION SPECIFIC ROUTINE
PJRST (T1) ;DISPATCH
;GENERIC ERROR RETURN WHICH RELEASES KLNI COMMAND BUFFER
KNXSER: PUSH P,T1 ;SAVE ERROR CODE
KNXSR1: PUSHJ P,GIVCMD ;RELEASE KLNI COMMAND BUFFER
PJRST TPOPJ## ;RESTORE ERROR CODE AND RETURN
;KLNI FUNCTION DISPATCH TABLES
DEFINE FNC,<
XALL ;;LIST GENERATED TABLE
DISP 0, KNUIFC ;;ILLEGAL (PLACE HOLDER)
DISP EK.SEA, KNUSEA ;;SET ETHERNET ADDRESS
DISP EK.RKC, KNURKC ;;READ AND CLEAR KONTROLLER COUNTERS
DISP EK.RPC, KNURPC ;;READ AND CLEAR PORTAL COUNTERS
DISP EK.EPT, KNUEPT ;;ENABLE PROTOCOL
DISP EK.DPT, KNUDPT ;;DISABLE PROTOCOL
DISP EK.EMA, KNUEMA ;;ENABLE MULTI-CAST ADDRESS
DISP EK.DMA, KNUDMA ;;DISABLE MULTI-CAST ADDRESS
DISP EK.RDG, KNURDG ;;RECEIVE DATAGRAM
DISP EK.XDG, KNUXDG ;;TRANSMIT DATAGRAM
SALL ;;TURN LISTING BACK OFF
>; END DEFINE FNC
;GENERATE FUNCTION DISPATCH TABLE
DEFINE DISP(CODE,ADDR),<
IF1,<IFN <CODE-<.-KNUDSP>>,<PRINTX ?Table KNUDSP entry CODE is out of order>>
IFIW ADDR ;CODE
>; END DEFINE DISP
KNUDSP: FNC ;GENERATE FUNCTION DISPATCH TABLE
IF1,<IFN <EK.MAX-<.-KNUDSP-1>>,<PRINTX ?Table KNUDSP is missing entries>>
SUBTTL KLNI USER SERVICE -- SET KONTROLLER ETHERNET ADDRESS
;HERE TO PROCESS A SET KONTROLLER ETHERNET ADDRESS CALL TO KNISER
;LINKAGE:
; P1/ ADDRESS OF EA BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNUSEA
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
KNUSEA: MOVEI T1,CMOWSA ;WRITE NI STATION ADDRESS COMMAND FUNCTION
PUSHJ P,GENCMD ;GENERATE KLNI COMMAND BUFFER
POPJ P, ;ERROR, ERROR CODE IN T1
AOS (P) ;PRESET SUCCESS RETURN
DMOVE T1,.EAEAD(P1) ;GET NEW ETHERNET ADDRESS
DMOVEM T1,.PBEAD(Q3) ;STORE INTO PORT CONTROL BLOCK
LDB T1,PBPPRM ;GET PROMISCUOUS RECEIVER FLAG
DPB T1,CMPPRM ;SET AS APPROPRIATE IN COMMAND
LDB T1,PBPPMM ;GET PROMISCUOUS MULTI-CAST FLAG
DPB T1,CMPAAM ;SET AS APPROPRIATE IN COMMAND
DMOVE T1,.PBEAD(Q3) ;GET NEW ETHERNET ADDRESS
DMOVEM T1,.CMNEA(Q1) ;STORE INTO COMMAND BUFFER
XMOVEI T1,KNCSEA ;GET CALLBACK ROUTINE ADDRESS
MOVX T2,PBSONL ;IS KLNI ONLINE?
TDNN T2,.PBSTS(Q3) ;...
PJRST (T1) ;NO, CALL CALLBACK ROUTINE NOW
PJRST KNICMD ;YES, QUEUE KLNI COMMAND
;HERE TO PROCESS WRITE ETHERNET ADDRESS CALLBACK
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; P1/ ADDRESS OF EA BLOCK
; Q1/ ADDRESS OF COMMAND BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNCSEA
;RETURNS:
; CPOPJ ALWAYS
KNCSEA: PUSHJ P,CALETH ;INTERRUPT ETHSER
PJRST GIVCMD ;RELEASE COMMAND BUFFER AND RETURN
SUBTTL KLNI USER SERVICE -- READ AND CLEAR KONTROLLER COUNTERS
;HERE TO PROCESS AN READ AND CLEAR KONTROLLER COUNTERS CALL TO KNISER
;LINKAGE:
; P1/ ADDRESS OF EA BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNURKC
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
KNURKC: MOVEI T1,CMORCC ;READ/CLEAR COUNTERS COMMAND FUNCTION
PUSHJ P,GENCMD ;GENERATE KLNI COMMAND BUFFER
POPJ P, ;ERROR, ERROR CODE IN T1
LDB T1,CMPFLG ;GET CURRENT FLAGS
IORX T1,CMFCLR ;SET CLEAR COUNTERS FLAG
DPB T1,CMPFLG ;...
AOS (P) ;PRESET SUCCESS RETURN
XMOVEI T1,KNCRKC ;GET CALLBACK ROUTINE ADDRESS
MOVX T2,PBSONL ;IS KLNI ONLINE?
TDNN T2,.PBSTS(Q3) ;...
PJRST (T1) ;NO, CALL CALLBACK ROUTINE NOW
PJRST KNICMD ;YES, QUEUE KLNI COMMAND
;HERE TO PROCESS READ/CLEAR COUNTERS CALLBACK
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; P1/ ADDRESS OF EA BLOCK
; Q1/ ADDRESS OF COMMAND BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNCRKC
;RETURNS:
; CPOPJ ALWAYS
KNCRKC: PUSHJ P,SAVP2## ;SAVE P2
PUSHJ P,UPDCTR ;UPDATE KLNI COUNTERS AREA
MOVE P2,.PBVCT(Q3) ;GET ADDRESS OF KLNI COUNTERS AREA
MOVSI T4,-RKCTLN ;GET AOJBN POINTER TO COUNTERS TABLE
KNCRK1: HRRZ T3,RKCTAB(T4) ;GET KONTROLLER COUNTER NUMBER
CAML T3,.EACBS(P1) ;BUFFER LARGE ENOUGH FOR THIS COUNTER?
JRST KNCRK2 ;NO, SKIP IT
ADD T3,.EACBA(P1) ;CALCULATE ADDRESS WHERE COUNTER STORED
SETZ T1, ;ZERO FOR RESETING COUNTER
XCT RKCTAB+1(T4) ;FETCH AND ZERO NEXT COUNTER
MOVEM T1,(T3) ;STORE COUNTER IN USER BUFFER
KNCRK2: AOBJN T4,.+1 ;SKIP OVER COUNTER NUMBER LOCATION
AOBJN T4,KNCRK1 ;LOOP BACK TO PROCESS ENTIRE TABLE
PUSHJ P,CALETH ;INTERRUPT ETHSER
PJRST GIVCMD ;RELEASE COMMAND BUFFER AND RETURN
;TABLE OF INSTRUCTIONS FOR FETCHING AND ZEROING KONTROLLER COUNTERS
DEFINE CTR(CNTR,INST),<
EXP CNTR ;;COUNTER NUMBER
EXP INST ;;INSTRUCTION TO FETCH AND ZERO COUNTER
>; END DEFINE CTR
RKCTAB: CTR KC.BYR,<EXCH T1,.KCBYR(P2)> ;BYTES RECEIVED
CTR KC.BYX,<EXCH T1,.KCBYX(P2)> ;BYTES TRANSMITTED
CTR KC.DGR,<EXCH T1,.KCDGR(P2)> ;DATAGRAMS RECEIVED
CTR KC.DGX,<EXCH T1,.KCDGX(P2)> ;DATAGRAMS TRANSMITTED
CTR KC.MBR,<EXCH T1,.KCMBR(P2)> ;MULTI-CAST BYTES RECEIVED
CTR KC.MDR,<EXCH T1,.KCMDR(P2)> ;MULTI-CAST DATAGRAMS RECEIVED
CTR KC.DXD,<EXCH T1,.KCDXD(P2)> ;DATAGRAMS TRANSMITTED, INITIALLY DEFERRED
CTR KC.DX1,<EXCH T1,.KCDX1(P2)> ;DATAGRAMS TRANSMITTED, SINGLE COLLISION
CTR KC.DXM,<EXCH T1,.KCDXM(P2)> ;DATAGRAMS TRANSMITTED, MULTIPLE COLLISIONS
CTR KC.XMF,<EXCH T1,.KCXMF(P2)> ;TRANSMIT FAILURES
CTR KC.XFM,<PUSHJ P,RKCXFM> ;TRANSMIT FAILURE BIT MASK
CTR KC.RCF,<EXCH T1,.KCRCF(P2)> ;RECEIVE FAILURES
CTR KC.RFM,<PUSHJ P,RKCRFM> ;RECEIVE FAILURE BIT MASK
CTR KC.UFD,<EXCH T1,.KCUFD(P2)> ;UNRECOGNIZED FRAME DESTINATION
CTR KC.DOV,<EXCH T1,.KCDOV(P2)> ;DATA OVERRUN
CTR KC.SBU,<EXCH T1,.KCSBU(P2)> ;SYSTEM BUFFER UNAVAILABLE
CTR KC.UBU,<EXCH T1,.KCFQE(P2)> ;USER DATAGRAM BUFFER UNAVAILABLE
RKCTLN==.-RKCTAB ;LENGTH OF TABLE
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;ROUTINE TO COMPUTE TRANSMIT FAILURE BIT MASK
RKCXFM: EXCH T1,.KCXFM(P2) ;FETCH BIT MASK AND ZERO
LSH T1,-4 ;POSITION ERROR BITS
POPJ P, ;AND RETURN
;ROUTINE TO COMPUTE RECEIVE FAILURE BIT MASK
RKCRFM: EXCH T1,.KCRFM(P2) ;FETCH BIT MASK AND ZERO
LSH T1,-4 ;POSITION ERROR BITS
POPJ P, ;AND RETURN
SUBTTL KLNI USER SERVICE -- READ AND CLEAR PORTAL COUNTERS
;HERE TO PROCESS AN READ AND CLEAR PORTAL COUNTERS CALL TO KNISER
;LINKAGE:
; P1/ ADDRESS OF EA BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNURPC
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
KNURPC: MOVEI T1,CMORCC ;READ/CLEAR COUNTERS COMMAND FUNCTION
PUSHJ P,GENCMD ;GENERATE KLNI COMMAND BUFFER
POPJ P, ;ERROR, ERROR CODE IN T1
LDB T1,CMPFLG ;GET CURRENT FLAGS
IORX T1,CMFCLR ;SET CLEAR COUNTERS FLAG
DPB T1,CMPFLG ;...
AOS (P) ;PRESET SUCCESS RETURN
XMOVEI T1,KNCRPC ;GET CALLBACK ROUTINE ADDRESS
MOVX T2,PBSONL ;IS KLNI ONLINE?
TDNN T2,.PBSTS(Q3) ;...
PJRST (T1) ;NO, CALL CALLBACK ROUTINE NOW
PJRST KNICMD ;YES, QUEUE KLNI COMMAND
;HERE TO PROCESS READ/CLEAR COUNTERS CALLBACK
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; P1/ ADDRESS OF EA BLOCK
; Q1/ ADDRESS OF COMMAND BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNCRPC
;RETURNS:
; CPOPJ ALWAYS
KNCRPC: PUSHJ P,SAVP2## ;SAVE P2
PUSHJ P,UPDCTR ;UPDATE KLNI COUNTERS AREA
MOVE P2,.PBVCT(Q3) ;GET ADDRESS OF KLNI COUNTERS AREA
MOVSI T4,-RPCTLN ;GET AOJBN POINTER TO COUNTERS TABLE
KNCRP1: MOVE T3,RPCTAB(T4) ;GET PORTAL COUNTER NUMBER
CAML T3,.EACBS(P1) ;BUFFER LARGE ENOUGH FOR THIS COUNTER?
JRST KNCRP2 ;NO, SKIP IT
ADD T3,.EACBA(P1) ;CALCULATE ADDRESS WHERE COUNTER STORED
SETZ T1, ;ZERO FOR RESETING COUNTER
XCT RPCTAB+1(T4) ;FETCH AND ZERO NEXT COUNTER
ADDM T1,(T3) ;UPDATE COUNTERS AREA
KNCRP2: AOBJN T4,.+1 ;SKIP OVER COUNTER NUMBER LOCATION
AOBJN T4,KNCRP1 ;LOOP BACK TO PROCESS ENTIRE TABLE
PUSHJ P,CALETH ;INTERRUPT ETHSER
PJRST GIVCMD ;RELEASE COMMAND BUFFER AND RETURN
;TABLE OF INSTRUCTIONS FOR FETCHING AND ZEROING PORTAL COUNTERS
DEFINE CTR(CNTR,INST),<
EXP CNTR ;;COUNTER NUMBER
EXP INST ;;INSTRUCTION TO FETCH AND ZERO COUNTER
>; END DEFINE CTR
RPCTAB: CTR PC.UBU,<PUSHJ P,RPCUBU> ;USER DATAGRAM BUFFER UNAVAILABLE
RPCTLN==.-RPCTAB ;LENGTH OF TABLE
;ROUTINE TO COMPUTE USER BUFFER UNAVAILABLE COUNTER
RPCUBU: LDB T2,PUPPTT ;GET PTT TABLE INDEX
ADD T2,P2 ;ADD STARTING ADDRESS OF COUNTERS AREA
EXCH T1,.KCFQP(T2) ;FETCH AND ZERO FREE QUEUE EMPTY COUNTER
POPJ P, ;RETURN
SUBTTL KLNI USER SERVICE -- ENABLE PROTOCOL
;HERE TO PROCESS AN ENABLE PROTOCOL CALL TO KNISER
;LINKAGE:
; P1/ ADDRESS OF EA BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNUEPT
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
KNUEPT: MOVEI T2,.PULEN ;GET LENGTH OF PROTOCOL USER BLOCK
PUSHJ P,GETNWZ## ;ALLOCATE CORE FOR PROTOCOL USER BLOCK
ERRRET (UNRES%) ;ERROR, NO RESOURCES
MOVE Q2,T1 ;SAVE ADDRESS OF PROTOCOL USER BLOCK
XMOVEI T1,.PUFQH(Q2) ;INITIALIZE PROTOCOL'S FREE QUEUE HEADER
PUSHJ P,INIQUE ;...
MOVE T1,.EAPPB(P1) ;GET ADDRESS OF ETHSER'S PORTAL BLOCK
MOVEM T1,.PUEPB(Q2) ;SAVE IN PROTOCOL USER BLOCK
MOVE T1,.EAPAD(P1) ;GET PROTOCOL PADDING FLAG
DPB T1,PUPPAD ;STORE IN PROTOCOL USER BLOCK
MOVE T1,.EAPTY(P1) ;GET PROTOCOL TYPE CODE
JUMPL T1,KNUEPP ;IF NEGATIVE, GO ENABLE PSEUDO PROTOCOL TYPE
CAILE T1,MAXPTY ;RANGE CHECK PROTOCOL TYPE CODE
ERRRET (UNIVP%,KNXEP2) ;ERROR, INVALID PROTOCOL TYPE
PUSHJ P,SWAB ;SWAP HIGH AND LOW ORDER BYTES FOR KLNI
MOVEM T1,.PUPTY(Q2) ;STORE IN PROTOCOL USER BLOCK
MOVEI T1,CMOLDP ;GET LOAD PTT TABLE COMMAND FUNCTION
PUSHJ P,GENCMD ;GENERATE KLNI COMMAND BUFFER
PJRST KNXEP2 ;ERROR, ERROR CODE IN T1
PUSHJ P,ADDPTT ;ADD PROTOCOL TO PTT TABLE
PJRST KNXEP1 ;ERROR, ERROR CODE IN T1
AOS (P) ;PRESET SUCCESS RETURN
XMOVEI T1,KNCEPT ;GET ADDRESS OF CALLBACK ROUTINE
MOVX T2,PBSONL ;IS KLNI ONLINE?
TDNN T2,.PBSTS(Q3) ;...
PJRST (T1) ;NO, CALL CALLBACK ROUTINE NOW
PJRST KNICMD ;YES, QUEUE KLNI COMMAND
KNXEP1: PUSH P,T1 ;SAVE ERROR CODE
PUSHJ P,GIVCMD ;RELEASE KLNI COMMAND BUFFER
SKIPA ;AND CONTINUE
KNXEP2: PUSH P,T1 ;SAVE ERROR CODE
MOVEI T1,.PULEN ;GET LENGTH OF PROTOCOL USER BLOCK
MOVE T2,Q2 ;GET ADDRESS OF PROTOCOL USER BLOCK
PUSHJ P,GIVNWS## ;RELEASE THE CORE
PJRST TPOPJ## ;RESTORE ERROR CODE AND RETURN
;HERE TO ENABLE A PSEUDO-PROTOCOL TYPE
KNUEPP: CAXGE T1,MINPTY ;RANGE CHECK PSEUDO PROTOCOL TYPE
ERRRET (UNIVP%,KNXEP2) ;ERROR, INVALID PROTOCOL TYPE
MOVEM T1,.PUPTY(Q2) ;STORE PROTOCOL TYPE IN PROTOCOL USER BLOCK
ERRRET (UNIVP%,KNXEP2) ;ERROR, NOT YET IMPLEMENTED
;HERE TO PROCESS LOAD PROTOCOL TYPE TABLE CALLBACK
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; P1/ ADDRESS OF EA BLOCK
; Q1/ ADDRESS OF COMMAND BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNCEPT
;RETURNS:
; CPOPJ ALWAYS
KNCEPT: MOVEM Q2,.EAPPB(P1) ;SAVE ADDRESS OF PROTOCOL USER BLOCK
PUSHJ P,CALETH ;INTERRUPT ETHSER
PJRST GIVCMD ;RELEASE COMMAND BUFFER AND RETURN
SUBTTL KLNI USER SERVICE -- DISABLE PROTOCOL
;HERE TO PROCESS A DISABLE PROTOCOL CALL TO KNISER
;LINKAGE:
; P1/ ADDRESS OF EA BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNUDPT
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
KNUDPT: MOVE T1,.PUPTY(Q2) ;GET PROTOCOL TYPE
JUMPL T1,KNUDPP ;IF NEGATIVE, GO DISABLE PSEUDO PROTOCOL TYPE
MOVEI T1,CMOLDP ;GET LOAD PTT TABLE COMMAND FUNCTION
PUSHJ P,GENCMD ;GENERATE KLNI COMMAND BUFFER
POPJ P, ;ERROR, ERROR CODE IN T1
PUSHJ P,DELPTT ;REMOVE PROTOCOL FROM PTT TABLE
PJRST KNXSER ;ERROR, ERROR CODE IN T1
AOS (P) ;PRESET SUCCESS RETURN
XMOVEI T1,KNCDPT ;GET ADDRESS OF CALLBACK ROUTINE
MOVX T2,PBSONL ;IS KLNI ONLINE?
TDNN T2,.PBSTS(Q3) ;...
PJRST (T1) ;NO, CALL CALLBACK ROUTINE NOW
PJRST KNICMD ;YES, QUEUE KLNI COMMAND
;CONTINUED FROM PREVIOUS PAGE
;HERE TO DISABLE A PSEUDO-PROTOCOL TYPE
KNUDPP: CAXN T1,PT%INF ;INFORMATION ONLY PROTOCOL TYPE?
PJRST KNCDPT ;YES, GIVE DISABLE CALLBACK NOW AND RETURN
ERRRET (UNIVP%) ;ERROR, INVALID PROTOCOL TYPE
;HERE TO PROCESS LOAD PROTOCOL TYPE TABLE CALLBACK
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; P1/ ADDRESS OF EA BLOCK
; Q1/ ADDRESS OF COMMAND BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNCDPT
;RETURNS:
; CPOPJ ALWAYS
KNCDPT: PUSH P,P1 ;SAVE ADDRESS OF EA BLOCK
PUSH P,Q1 ;AND ADDRESS OF COMMAND BLOCK
KNCDP1: XMOVEI T1,.PUFQH(Q2) ;GET ADDRESS OF PROTOCOL'S FREE QUEUE HEADER
PUSHJ P,REMQUE ;REMOVE NEXT ENTRY
JRST KNCDP2 ;NO MORE ENTRIES IN QUEUE
XMOVEI Q1,-.CMQUE(T2) ;GET ADDRESS OF KLNI COMMAND BUFFER
MOVE P1,.CMEAB(Q1) ;AND ADDRESS OF EA BLOCK
MOVEI T1,UNRAB% ;GET RECEIVE ABORTED STATUS CODE
PUSHJ P,KNCRDX ;DO RECEIVE DATAGRAM CALLBACK PROCESSING
JRST KNCDP1 ;LOOP BACK TO EMPTY ENTIRE QUEUE
KNCDP2: POP P,Q1 ;RESTORE COMMAND BLOCK ADDRESS
POP P,P1 ;RESTORE ADDRESS OF EA BLOCK
PUSHJ P,CALETH ;INTERRUPT ETHSER
MOVEI T1,.PULEN ;GET LENGTH OF PROTOCOL USER BLOCK
MOVE T2,Q2 ;GET ADDRESS OF PROTOCOL USER BLOCK
;$ PUSHJ P,GIVNWS## ;RELEASE THE CORE
PJRST GIVCMD ;RELEASE COMMAND BUFFER AND RETURN
SUBTTL KLNI USER SERVICE -- ENABLE MULTI-CAST ADDRESS
;HERE TO PROCESS AN ENABLE MULTI-CAST ADDRESS CALL TO KNISER
;LINKAGE:
; P1/ ADDRESS OF EA BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNUEMA
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
KNUEMA: MOVEI T1,CMOLDM ;LOAD MCAT TABLE COMMAND FUNCTION
PUSHJ P,GENCMD ;GENERATE KLNI COMMAND BUFFER
POPJ P, ;ERROR, ERROR CODE IN T1
DMOVE T1,.EAMCA(P1) ;GET MULTI-CAST ADDRESS
TXNN T1,<BYTE (8) 1,0,0,0> ;IS MULTI-CAST BIT SET?
ERRRET (UNIMA%,KNXSER) ;NO, INVALID MULTI-CAST ADDRESS
TXNN T1,^-MCTHAD ;ANY EXTRANEOUS BITS SET?
TXNE T1,^-MCTLAD ;...
ERRRET (UNIMA%,KNXSER) ;YES, INVALID MULTI-CAST ADDRESS
PUSHJ P,ADDMCA ;ADD ADDRESS TO MCAT TABLE
PJRST KNXSER ;ERROR, ERROR CODE IN T1
AOS (P) ;PRESET SUCCESS RETURN
XMOVEI T1,KNCEMA ;AND ADDRESS OF CALLBACK ROUTINE
MOVX T2,PBSONL ;IS KLNI ONLINE?
TDNN T2,.PBSTS(Q3) ;...
PJRST (T1) ;NO, CALL CALLBACK ROUTINE NOW
PJRST KNICMD ;YES, QUEUE KLNI COMMAND
;HERE TO PROCESS LOAD MULTI-CAST ADDRESS TABLE CALLBACK
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; P1/ ADDRESS OF EA BLOCK
; Q1/ ADDRESS OF COMMAND BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNCEMA
;RETURNS:
; CPOPJ ALWAYS
KNCEMA: PUSHJ P,CALETH ;INTERRUPT ETHSER
PJRST GIVCMD ;RELEASE COMMAND BUFFER AND RETURN
SUBTTL KLNI USER SERVICE -- DISABLE MULTI-CAST ADDRESS
;HERE TO PROCESS A DISABLE MULTI-CAST ADDRESS CALL TO KNISER
;LINKAGE:
; P1/ ADDRESS OF EA BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNUDMA
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
KNUDMA: MOVEI T1,CMOLDM ;LOAD MCAT TABLE COMMAND FUNCTION
PUSHJ P,GENCMD ;GENERATE KLNI COMMAND BUFFER
POPJ P, ;ERROR, ERROR CODE IN T1
DMOVE T1,.EAMCA(P1) ;GET MULTI-CAST ADDRESS
TXNN T1,<BYTE (8) 1,0,0,0> ;IS MULTI-CAST BIT SET?
ERRRET (UNIMA%,KNXSER) ;NO, INVALID MULTI-CAST ADDRESS
TXNN T1,^-MCTHAD ;ANY EXTRANEOUS BITS SET?
TXNE T2,^-MCTLAD ;...
ERRRET (UNIMA%,KNXSER) ;YES, INVALID MULTI-CAST ADDRESS
PUSHJ P,DELMCA ;DELETE ADDRESS FROM MCAT TABLE
PJRST KNXSER ;ERROR, ERROR CODE IN T1
AOS (P) ;PRESET SUCCESS RETURN
XMOVEI T1,KNCDMA ;AND ADDRESS OF CALLBACK ROUTINE
MOVX T2,PBSONL ;IS KLNI ONLINE?
TDNN T2,.PBSTS(Q3) ;...
PJRST (T1) ;NO, CALL CALLBACK ROUTINE NOW
PJRST KNICMD ;YES, QUEUE KLNI COMMAND
;HERE TO PROCESS LOAD MULTI-CAST ADDRESS TABLE CALLBACK
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; P1/ ADDRESS OF EA BLOCK
; Q1/ ADDRESS OF COMMAND BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNCDMA
;RETURNS:
; CPOPJ ALWAYS
KNCDMA: PUSHJ P,CALETH ;INTERRUPT ETHSER
PJRST GIVCMD ;RELEASE COMMAND BUFFER AND RETURN
SUBTTL KLNI USER SERVICE -- RECEIVE DATAGRAM
;HERE TO PROCESS A RECEIVE DATAGRAM CALL TO KNISER
;LINKAGE:
; P1/ ADDRESS OF EA BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNURDG
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
KNURDG: MOVX T1,PBSONL ;IS KLNI ONLINE?
TDNN T1,.PBSTS(Q3) ;...
ERRRET (UNRAB%) ;NO, RECEIVE ABORTED
MOVEI T1,CMORDG ;RECEIVE DATAGRAM COMMAND FUNCTION
PUSHJ P,GENCMD ;GENERATE KLNI COMMAND BUFFER
POPJ P, ;ERROR, ERROR CODE IN T1
LDB T1,CMPFLG ;GET CURRENT FLAGS
IORX T1,CMFBSD ;SET BSD STYLE COMMAND FLAG
LDB T2,PUPPAD ;GET PROTOCOL PADDING FLAG
JUMPE T2,KNURD1 ;JUMP IF DATAGRAM NOT PADDED
IORX T1,CMFPAD ;SET PADDING FLAG
KNURD1: DPB T1,CMPFLG ;STORE UPDATED FLAGS
XMOVEI T1,.EAMSD(P1) ;GET ADDRESS OF FIRST MSD
SETZ T2, ;$ DON'T RECEIVE PADDING SEPERATELY
PUSHJ P,GENBSC ;GENERATE BSD CHAIN
PJRST KNXSER ;ERROR, ERROR CODE IN T1
DPB T1,CMPRDL ;STORE SIZE OF DATAGRAM IN COMMAND BUFFER
MOVEM T2,.CMRVB(Q1) ;SAVE ADDRESS OF BSD CHAIN
MAP T2,0(T2) ;GET PHYSICAL ADDRESS OF BSD CHAIN
TXZ T2,MP.NAD ;...
MOVEM T2,.CMRBA(Q1) ;STORE IN COMMAND BUFFER
LDB T1,CMPRDL ;GET SIZE OF DATAGRAM
SKIPN .PUFQH+.QHELN(Q2) ;HAVE WE ALREADY SET UP QUEUE ENTRY LENGTH?
MOVEM T1,.PUFQH+.QHELN(Q2) ;NO, DO SO NOW
SKIPLE T1 ;VALID DATAGRAM LENGTH?
CAME T1,.PUFQH+.QHELN(Q2) ;YES, SAME SIZE AS PREVIOUS DATAGRAMS?
ERRRET (UNIBS%,KNURDX) ;NO, INVALID DATAGRAM BUFFER SIZE
XMOVEI T1,KNCRDG ;GET ADDRESS OF CALLBACK ROUTINE
PUSHJ P,KNICMF ;QUEUE KLNI COMMAND TO PROTOCOL FREE QUEUE
PJRST CPOPJ1## ;AND RETURN
KNURDX: PUSH P,T1 ;SAVE ERROR CODE
MOVE T1,.CMRVB(Q1) ;GET ADDRESS OF BSD CHAIN
PUSHJ P,GIVBSC ;RELEASE THE CORE
PUSHJ P,GIVCMD ;RELEASE THE KLNI COMMAND
PJRST TPOPJ## ;RESTORE ERROR CODE AND RETURN
;HERE TO PROCESS RECEIVE DATAGRAM CALLBACK
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; P1/ ADDRESS OF EA BLOCK
; Q1/ ADDRESS OF COMMAND BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNCRDG
;RETURNS:
; CPOPJ ALWAYS
KNCRDG: DMOVE T1,.CMRDA(Q1) ;GET DESTINATION ADDRESS OF DATAGRAM
DMOVEM T1,.EADDA(P1) ;STORE IN EA BLOCK
DMOVE T1,.CMRSA(Q1) ;GET SOURCE ETHERNET ADDRESS
DMOVEM T1,.EADSA(P1) ;STORE IN EA BLOCK
LDB T1,CMPRPT ;GET PROTOCOL TYPE OF DATAGRAM
PUSHJ P,SWAB ;SWAP HIGH AND LOW ORDER BYTES
MOVEM T1,.EADPT(P1) ;STORE IN EA BLOCK
LDB T1,CMPRDL ;GET SIZE OF DATAGRAM
SUBI T1,4 ;SUBTRACT OFF CRC OVERHEAD BYTES
MOVEM T1,.EADSZ(P1) ;STORE IN EA BLOCK
LDB T1,PUPPAD ;GET PROTOCOL PADDING FLAG
JUMPE T1,KNCRD1 ;JUMP IF DATAGRAM NOT PADDED
ILDB T1,.EAFCD+1(P1) ;$ CROCK
ILDB T2,.EAFCD+1(P1) ;$ DITTO
LSH T2,^D8 ;$
IOR T1,T2 ;$
;$ MOVE T2,.CMRVB(Q1) ;YES, GET ADDRESS OF FIRST BSD
;$ MOVE T1,.BSRWD(T2) ;GET FIRST TWO BYTES OF DATAGRAM
;$ LSH T1,-<^D36-^D16> ;RIGHT JUSTIFY
;$ PUSHJ P,SWAB ;SWAP BYTES
MOVEM T1,.EADSZ(P1) ;STORE CORRECT DATAGRAM SIZE
KNCRD1: SETZ T1, ;ASSUME DATAGRAM STATUS IS OK
LDB T2,CMPSTS ;GET DATAGRAM STATUS
TXNN T2,CMSERR ;ANY ERRORS?
JRST KNCRDX ;NO, GO GIVE CALLBACK
LDB T1,[POINTR (T2,CMSETY)] ;GET SPECIFIC ERROR TYPE
PUSHJ P,CVTETY ;CONVERT INTO ETHSER STATUS CODE
KNCRDX: MOVEM T1,.EADST(P1) ;STORE DATAGRAM STATUS IN EA BLOCK
PUSHJ P,CALETH ;INTERRUPT ETHSER
MOVE T1,.CMRVB(Q1) ;GET ADDRESS OF BSD CHAIN
PUSHJ P,GIVBSC ;RELEASE THE CORE
PJRST GIVCMD ;RELEASE COMMAND BUFFER AND RETURN
SUBTTL KLNI USER SERVICE -- TRANSMIT DATAGRAM
;HERE TO PROCESS A TRANSMIT DATAGRAM CALL TO KNISER
;LINKAGE:
; P1/ ADDRESS OF EA BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNUXDG
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
KNUXDG: MOVX T1,PBSONL ;IS KLNI ONLINE?
TDNN T1,.PBSTS(Q3) ;...
ERRRET (UNDNS%) ;NO, DATAGRAM NOT SENT
MOVEI T1,CMOXDG ;TRANSMIT DATAGRAM COMMAND FUNCTION
PUSHJ P,GENCMD ;GENERATE KLNI COMMAND BUFFER
POPJ P, ;ERROR, ERROR CODE IN T1
LDB T1,CMPFLG ;GET CURRENT FLAGS
IORX T1,CMFBSD ;SET BSD STYLE COMMAND FLAG
LDB T2,PUPPAD ;GET PROTOCOL PADDING FLAG
JUMPE T2,KNUXD1 ;JUMP IF DATAGRAM NOT PADDED
IORX T1,CMFPAD ;SET PADDING FLAG
KNUXD1: DPB T1,CMPFLG ;STORE UPDATED FLAGS
MOVE T1,.PUPTY(Q2) ;GET PROTOCOL TYPE CODE
DPB T1,CMPXPT ;STORE IN COMMAND BUFFER
DMOVE T1,.EADDA(P1) ;GET DESTINATION ADDRESS OF DATAGRAM
TXNE T1,<BYTE (8) 1,0,0,0> ;MULTI-CAST BIT SET?
AOS .PBMCE(Q3) ;YES, COUNT FOR ADJUSTMENT OF KLNI COUNTERS
DMOVEM T1,.CMXDA(Q1) ;STORE IN COMMAND BUFFER
XMOVEI T1,.EAMSD(P1) ;GET ADDRESS OF FIRST MSD
SETZ T2, ;NO SEPERATE RECEIVE PADDING BYTES
PUSHJ P,GENBSC ;GENERATE BSD CHAIN
PJRST KNXSER ;ERROR, ERROR CODE IN T1
SKIPG T1 ;VALID DATAGRAM SIZE?
ERRRET (UNIBS%,KNUXDX) ;NO, INVALID DATAGRAM BUFFER SIZE
DPB T1,CMPRDL ;STORE SIZE OF DATAGRAM IN COMMAND BUFFER
MOVEM T2,.CMXVB(Q1) ;SAVE ADDRESS OF BSD CHAIN
MAP T2,0(T2) ;GET PHYSICAL ADDRESS OF BSD CHAIN
TXZ T2,MP.NAD ;...
MOVEM T2,.CMXBA(Q1) ;STORE IN COMMAND BUFFER
XMOVEI T1,KNCXDG ;ADDRESS OF CALLBACK ROUTINE
PUSHJ P,KNICMD ;QUEUE KLNI COMMAND
PJRST CPOPJ1## ;AND RETURN
KNUXDX: PUSH P,T1 ;SAVE ERROR CODE
MOVE T1,.CMXVB(Q1) ;GET ADDRESS OF BSD CHAIN
PUSHJ P,GIVBSC ;RELEASE THE CORE
PUSHJ P,GIVCMD ;RELEASE THE KLNI COMMAND
PJRST TPOPJ## ;RESTORE ERROR CODE AND RETURN
;HERE TO PROCESS TRANSMIT DATAGRAM CALLBACK
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; P1/ ADDRESS OF EA BLOCK
; Q1/ ADDRESS OF COMMAND BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNCXDG
;RETURNS:
; CPOPJ ALWAYS
KNCXDG: DMOVE T1,.CMXDA(Q1) ;GET DESTINATION ADDRESS OF DATAGRAM
DMOVEM T1,.EADDA(P1) ;STORE IN EA BLOCK
DMOVE T1,.PBEAD(Q3) ;GET SOURCE ETHERNET ADDRESS
DMOVEM T1,.EADSA(P1) ;STORE IN EA BLOCK
LDB T1,CMPXPT ;GET PROTOCOL TYPE OF DATAGRAM
PUSHJ P,SWAB ;SWAP HIGH AND LOW ORDER BYTES
MOVEM T1,.EADPT(P1) ;STORE IN EA BLOCK
LDB T1,CMPXDL ;GET SIZE OF DATAGRAM
MOVEM T1,.EADSZ(P1) ;STORE IN EA BLOCK
SETZ T1, ;ASSUME DATAGRAM STATUS IS OK
LDB T2,CMPSTS ;GET DATAGRAM STATUS
TXNN T2,CMSERR ;ANY ERRORS?
JRST KNCXDX ;NO, GO GIVE CALLBACK
LDB T1,[POINTR (T2,CMSETY)] ;GET SPECIFIC ERROR TYPE
PUSHJ P,CVTETY ;CONVERT INTO ETHSER STATUS CODE
KNCXDX: MOVEM T1,.EADST(P1) ;STORE DATAGRAM STATUS IN EA BLOCK
PUSHJ P,CALETH ;INTERRUPT ETHSER
MOVE T1,.CMXVB(Q1) ;GET ADDRESS OF BSD CHAIN
PUSHJ P,GIVBSC ;RELEASE THE CORE
PJRST GIVCMD ;RELEASE COMMAND BUFFER AND RETURN
SUBTTL KLNI USER SERVICE -- INTERRUPT ETHSER
;ROUTINE TO INTERRUPT ETHSER
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; P1/ ADDRESS OF EA BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK (OR ZERO)
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,CALETH
;RETURNS:
; CPOPJ ALWAYS
CALETH: MOVE T1,P1 ;GET ADDRESS OF EA BLOCK
MOVE T2,.PBEKB(Q3) ;AND ADDRESS OF ETHERNET KONTROLLER BLOCK
SKIPE T3,Q2 ;HAVE A PROTOCOL USER BLOCK?
MOVE T3,.PUEPB(Q2) ;YES, GET ADDRESS OF ETHERNET PORTAL BLOCK
PJRST ETKINT## ;INTERRUPT ETHSER AND RETURN
SUBTTL KLNI USER SERVICE -- GENERATE KLNI COMMAND BUFFER
;ROUTINE CALLED TO GENERATE A KLNI COMMAND BUFFER
;LINKAGE:
; T1/ KLNI COMMAND OPCODE
; P1/ ADDRESS OF EA BLOCK
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; PUSHJ P,GENCMD
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS WITH:
; Q1/ ADDRESS OF KLNI COMMAND BUFFER
GENCMD: PUSHJ P,GETCMD ;GET A KLNI COMMAND BUFFER
POPJ P, ;ERROR, ERROR CODE IN T1
MOVEM Q2,.CMPUB(Q1) ;STORE ADDRESS OF PROTOCOL USER BLOCK
MOVEM P1,.CMEAB(Q1) ;AND ADDRESS OF EA BLOCK
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- PORT CONTROL BLOCK INITIALIZATION
;ROUTINE TO INITIALIZE A PORT CONTROL BLOCK
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,PCBINI
;RETURNS:
; CPOPJ ALWAYS
PCBINI: MOVE T1,.CPCPN## ;GET OUR CPU NUMBER
DPB T1,PBPCPU ;STORE IN PORT CONTROL BLOCK
MOVEI T1,KNICHN## ;GET PRIORITY INTERRUPT ASSIGNMENT
MOVEM T1,.PBPIA(Q3) ;STORE IN PCB
MOVE T1,.CPEPT## ;GET ADDRESS OF EPT
ADDI T1,KNIICH*4 ;COMPUTE ADDRESS OF CHANNEL LOGOUT AREA
MOVEM T1,.PBLGO(Q3) ;STORE IN PORT CONTROL BLOCK
MAP T1,.PBPCB(Q3) ;DETERMINE PHYSICAL ADDRESS OF PCB
TXZ T1,MP.NAD ;CLEAR NON-ADDRESS BITS
MOVEM T1,.PBPBA(Q3) ;STORE PHYSICAL PCB ADDRESS FOR THE KLNI
MOVE T1,.PBLGO(Q3) ;GET ADDRESS OF RH20 LOGOUT AREA
MAP T1,1(T1) ;GET PHYSICAL ADDRESS OF SECOND WORD
TXZ T1,MP.NAD ;...
MOVEM T1,.PBER2(Q3) ;SAVE IN PCB FOR KLNI
XMOVEI T1,.PBCMQ(Q3) ;GET VIRTUAL ADDRESS OF COMMAND QUEUE
PUSHJ P,INIQUE ;INITIALIZE QUEUE HEADER
XMOVEI T1,.PBRSQ(Q3) ;GET VIRTUAL ADDRESS OF RESPONSE QUEUE
PUSHJ P,INIQUE ;INITIALIZE QUEUE HEADER
XMOVEI T1,.PBUPQ(Q3) ;GET VIRTUAL ADDRESS OF UNKNOWN PROTOCOL QUEUE
PUSHJ P,INIQUE ;INITIALIZE QUEUE HEADER
SETZM .PBPTT(Q3) ;CLEAR ADDRESS OF PTT TABLE
SETZM .PBMCT(Q3) ;AND ADDRESS OF MCAT TABLE
SETZM .PBKCB(Q3) ;AND ADDRESS OF COUNTERS BUFFER
MOVEI T1,1 ;$ SET PROMISCUOUS MULTI-CAST FLAG
DPB T1,PBPPMM ;$ ...
POPJ P, ;RETURN
SUBTTL KLNI DEVICE SERVICE -- PORT CONTROL BLOCK RESET
;ROUTINE CALLED TO RESET A PORT CONTROL BLOCK
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,PCBRST
;RETURNS:
; CPOPJ ALWAYS
PCBRST: SETOM .PBCMQ+.QHIWD(Q3) ;RESET COMMAND QUEUE INTERLOCK
SETOM .PBRSQ+.QHIWD(Q3) ;RESET RESPONSE QUEUE INTERLOCK
SETOM .PBUPQ+.QHIWD(Q3) ;RESET UNKNOWN PROTOCOL TYPE QUEUE INTERLOCK
MOVE T3,.PBLPT(Q3) ;GET LENGTH OF PROTOCOL TYPE TABLE
MOVE T4,.PBVPT(Q3) ;AND ADDRESS OF PTT
PCBRS1: JUMPE T3,PCBRS3 ;CONTINUE IF NO MORE PTT ENTRIES
LDB T1,PTPENA ;IS THIS PROTOCOL ENABLED?
JUMPE T1,PCBRS2 ;JUMP IF NOT ENABLED
MOVE T2,.PTPUB(T4) ;GET ADDRESS OF PROTOCOL USER BLOCK
SETOM .PUFQH+.QHIWD(T2) ;CLEAR PROTOCOL'S FREE QUEUE INTERLOCK
PCBRS2: ADDI T4,.PTLEN ;BUMP PTT TABLE POINTER TO NEXT ENTRY
SOJA T3,PCBRS1 ;LOOP BACK FOR ENTIRE PTT TABLE
PCBRS3: SETZM .PBER0(Q3) ;RESET ERROR WORDS
SETZM .PBER1(Q3) ;...
SETZM .PBER3(Q3) ;...
POPJ P, ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- ADD PROTOCOL TYPE TO PTT TABLE
;ROUTINE TO ADD A PROTOCOL TO THE PTT TABLE
;LINKAGE:
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,ADDPTT
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
ADDPTT: PUSHJ P,SAVE2## ;SAVE P1-P2
ETHLOK ;INTERLOCK AGAINST SMP RACES
SETZ T2, ;USED TO REMEMBER FIRST FREE ENTRY IN PTT
MOVE P1,.PBLPT(Q3) ;GET LENGTH OF PTT TABLE
MOVE P2,.PBVPT(Q3) ;GET VIRTUAL ADDRESS OF PTT TABLE
ADDPT1: JUMPE P1,ADDPT4 ;EXIT LOOP IF NO MORE ENTRIES
LDB T1,PTPENA ;GET PROTOCOL ENTRY ENABLED BIT
JUMPN T1,ADDPT2 ;IF ENABLED, GO CHECK FOR DUPLICATE
SKIPN T2 ;ALREADY HAVE POINTER TO FREE ENTRY?
MOVE T2,P2 ;NO, REMEMBER LOCATION OF FIRST FREE ENTRY
JRST ADDPT3 ;AND CONTINUE CHECK REMAINDER OF TABLE
ADDPT2: LDB T1,PTPPTY ;GET PROTOCOL TYPE OF THIS ENTRY
CAMN T1,.PUPTY(Q2) ;FOUND DUPLICATE PROTOCOL?
ERRRET (UNPIU%,UNLETH##) ;YES, PROTOCOL ALREADY IN USE
ADDPT3: ADDI P2,.PTLEN ;BUMP PTT TABLE POINTER TO NEXT ENTRY
SOJA P1,ADDPT1 ;LOOP BACK TO CHECK ALL TABLE ENTRIES
ADDPT4: JUMPE T2,[ERRRET (UNNRE%,UNLETH##)] ;ERROR IF NO FREE ENTRIES
MOVE P2,T2 ;GET ADDRESS OF FREE ENTRY
MOVE T1,.PUPTY(Q2) ;GET DESIRED PROTOCOL TYPE
DPB T1,PTPPTY ;STORE IN PTT ENTRY
MAP T1,.PUFQH+.QHFLI(Q2) ;GET PHYSICAL ADDRESS OF FREE QUEUE FLINK
TXZ T1,MP.NAD ;CLEAR NON-ADDRESS BITS
MOVEM T1,.PTFRQ(P2) ;SAVE IN PTT ENTRY
MOVEM Q2,.PTPUB(P2) ;SAVE ADDRESS OF PUB IN PTT ENTRY
MOVEI T1,1 ;SET THE PROTOCOL ENABLED FLAG
DPB T1,PTPENA ;...
MOVE T1,P2 ;GET INDEX INTO PTT TABLE
SUB T1,.PBVPT(Q3) ;CALCULATE PTT TABLE ENTRY NUMBER
IDIVI T1,.PTLEN ;...
DPB T1,PUPPTT ;AND REMEMBER IN PROTOCOL USER BLOCK
AOS .PBCPT(Q3) ;ADJUST COUNT OF PTT ENTRIES
ETHULK ;RELEASE SMP INTERLOCK
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- DELETE PROTOCOL TYPE FROM PTT TABLE
;ROUTINE TO DELETE A PROTOCOL FROM THE PTT TABLE
;LINKAGE:
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,DELPTT
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
DELPTT: PUSHJ P,SAVE2## ;SAVE P1-P2
ETHLOK ;INTERLOCK AGAINST SMP RACES
MOVE P1,.PBLPT(Q3) ;GET LENGTH OF PTT TABLE
MOVE P2,.PBVPT(Q3) ;GET VIRTUAL ADDRESS OF PTT TABLE
DELPT1: JUMPE P1,[ERRRET (UNIVP%,UNLETH##)] ;ERROR IF NO MORE ENTRIES
LDB T1,PTPENA ;GET PROTOCOL ENTRY ENABLED BIT
JUMPE T1,DELPT2 ;SKIP CHECK IF NOT ENABLED
CAMN Q2,.PTPUB(P2) ;FOUND SUBJECT PROTOCOL USER BLOCK?
JRST DELPT3 ;YES, EXIT LOOP
DELPT2: ADDI P2,.PTLEN ;BUMP PTT TABLE POINTER TO NEXT ENTRY
SOJA P1,DELPT1 ;LOOP BACK TO CHECK ALL TABLE ENTRIES
DELPT3: SETZ T1, ;CLEAR THE PROTOCOL ENABLED FLAG
DPB T1,PTPENA ;...
SOS .PBCPT(Q3) ;ADJUST COUNT OF PTT ENTRIES
ETHULK ;RELEASE SMP INTERLOCK
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- ADD MULTI-CAST ADDRESS TO MCAT TABLE
;ROUTINE TO ADD A MULTI-CAST ADDRESS TO THE MCAT FOR A PROTOCOL
;LINKAGE:
; T1-T2/ MULTI-CAST ADDRESS
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,ADDMCA
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
ADDMCA: PUSHJ P,SAVE4## ;SAVE P1-P4
DMOVE P3,T1 ;SAVE MULTI-CAST ADDRESS IN P3,P4
ETHLOK ;INTERLOCK AGAINST SMP RACES
SETZ T2, ;USED TO REMEMBER FIRST FREE ENTRY IN MCAT
MOVE P1,.PBLMC(Q3) ;GET LENGTH OF MCAT TABLE
MOVE P2,.PBVMC(Q3) ;GET VIRTUAL ADDRESS OF MCAT TABLE
ADDMC1: JUMPE P1,ADDMC4 ;EXIT LOOP IF NO MORE ENTRIES
LDB T1,MCPENA ;GET MULTI-CAST ADDRESS ENABLED BIT
JUMPN T1,ADDMC2 ;IF ENABLED, GO CHECK FOR DUPLICATE
SKIPN T2 ;ALREADY HAVE POINTER TO FREE ENTRY?
MOVE T2,P2 ;NO, REMEMBER LOCATION OF FIRST FREE ENTRY
JRST ADDMC3 ;AND CONTINUE CHECK REMAINDER OF TABLE
ADDMC2: MOVE T1,.MCHAD(P2) ;GET HIGH ORDER MULTI-CAST ADDRESS
ANDX T1,MCTHAD ;...
CAME T1,P3 ;MATCH SUBJECT ADDRESS?
JRST ADDMC3 ;NO, CONTINUE CHECKING
MOVE T1,.MCLAD(P2) ;GET LOW ORDER MULTI-CAST ADDRESS
ANDX T1,MCTLAD ;...
CAME T1,P4 ;MATCH SUBJECT ADDRESS?
ERRRET (UNIMA%,UNLETH##) ;YES, INVALID MULTI-CAST ADDRESS
ADDMC3: ADDI P2,.MCLEN ;BUMP MCAT TABLE POINTER TO NEXT ENTRY
SOJA P1,ADDMC1 ;LOOP BACK TO CHECK ALL TABLE ENTRIES
ADDMC4: MOVE P2,T2 ;GET ADDRESS OF FREE MCAT ENTRY
JUMPE P2,[ERRRET (UNNRE%,UNLETH##)] ;ERROR IF NO FREE ENTRIES
DMOVEM P3,.MCHAD(P2) ;STORE MULTI-CAST ADDRESS IN TABLE
MOVEI T1,1 ;SET THE MULTI-CAST ADDRESS ENABLED FLAG
DPB T1,MCPENA ;...
AOS .PBCMC(Q3) ;ADJUST COUNT OF MCAT ENTRIES
ETHULK ;RELEASE SMP INTERLOCK
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- DELETE MULTI-CAST ADDRESS FROM MCAT TABLE
;ROUTINE TO DELETE A MULTI-CAST ADDRESS FROM THE MCAT
;LINKAGE:
; T1-T2/ MULTI-CAST ADDRESS
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,DELMCA
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS
DELMCA: PUSHJ P,SAVE4## ;SAVE P1-P4
DMOVE P3,T1 ;SAVE MULTI-CAST ADDRESS IN P3,P4
ETHLOK ;INTERLOCK AGAINST SMP RACES
MOVE P1,.PBLMC(Q3) ;GET LENGTH OF MCAT TABLE
MOVE P2,.PBVMC(Q3) ;GET VIRTUAL ADDRESS OF MCAT TABLE
DELMC1: JUMPE P1,[ERRRET (UNIMA%,UNLETH##)] ;ERROR IF NO MORE ENTRIES
LDB T1,MCPENA ;GET MULTI-CAST ADDRESS ENABLED BIT
JUMPE T1,DELMC2 ;IF NOT ENABLED, SKIP CHECK
MOVE T1,.MCHAD(P2) ;GET MULTI-CAST ADDRESS
ANDX T1,MCTHAD ;...
ANDX T2,MCTLAD ;...
CAMN T1,P3 ;MATCH SUBJECT ADDRESS?
CAME T2,P4 ;...
SKIPA ;NO, KEEP CHECKING
JRST DELMC3 ;YES, EXIT LOOP
DELMC2: ADDI P2,.MCLEN ;BUMP MCAT TABLE POINTER TO NEXT ENTRY
SOJA P1,DELMC1 ;LOOP BACK TO CHECK ALL TABLE ENTRIES
DELMC3: SETZ T1, ;CLEAR THE MULTI-CAST ADDRESS ENABLED FLAG
DPB T1,MCPENA ;...
SOS .PBCMC(Q3) ;ADJUST COUNT OF MCAT ENTRIES
ETHULK ;RELEASE SMP INTERLOCK
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- UPDATE KLNI COUNTERS AREA
;ROUTINE CALLED TO UPDATE KLNI COUNTERS AREA (.PBCTR) FROM
;KLNI COUNTERS DATA BUFFER.
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,UPDCTR
;RETURNS:
; CPOPJ ALWAYS
UPDCTR: PUSHJ P,SAVE3## ;SAVE P1-P3
MOVE P1,.PBLCD(Q3) ;GET LENGTH OF KLNI COUNTERS AREA
MOVE P2,.PBVCD(Q3) ;GET ADDRESS OF COUNTERS DATA BUFFER
MOVE P3,.PBVCT(Q3) ;AND ADDRESS OF KLNI COUNTERS AREA
SETZ T1, ;FETCH AND ZERO MULTICAST CHECKSUM ERROR COUNT
EXCH T1,.PBMCE(Q3) ;...
MOVNS T1 ;NEGATE
ADDB T1,.KCRCF(P2) ;ADJUST COUNT OF RECEIVE FAILURES
JUMPG T1,UPDCT1 ;CONTINUE IF COUNT POSITIVE
SETZM .KCRCF(P2) ;CLEAR RECEIVE FAILURE COUNT
SETZM .KCRFM(P2) ;AND RECEIVE FAILURE BIT MASK
UPDCT1: MOVE T1,(P2) ;GET COUNTER VALUE FROM DATA BUFFER
ADDM T1,(P3) ;UPDATE KLNI COUNTERS AREA
AOJ P2, ;UPDATE POINTER TO COUNTERS DATA BUFFER
AOJ P3, ;AND POINTER TO KLNI COUNTERS AREA
SOJG P1,UPDCT1 ;LOOP BACK TO UPDATE ALL COUNTERS
MOVE P2,.PBVCD(Q3) ;GET ADDRESS OF COUNTERS DATA BUFFER
MOVE P3,.PBVCT(Q3) ;AND ADDRESS OF KLNI COUNTERS AREA
MOVE T1,.KCXFM(P3) ;GET TRANSMIT FAILURE BIT MASK
SUB T1,.KCXFM(P2) ;COMPENSATE FOR PREVIOUS LOOP
IOR T1,.KCXFM(P2) ;UPDATE TRANSMIT FAILURE BIT MASK
MOVEM T1,.KCXFM(P3) ;...
MOVE T1,.KCRFM(P3) ;GET RECEIVE FAILURE BIT MASK
SUB T1,.KCRFM(P2) ;COMPENSATE FOR PREVIOUS LOOP
IOR T1,.KCRFM(P2) ;UPDATE RECEIVE FAILURE BIT MASK
MOVEM T1,.KCRFM(P3) ;...
POPJ P, ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- GENERATE BSD CHAIN
;ROUTINE TO GENERATE A BSD CHAIN FOR A DATAGRAM
;LINKAGE:
; T1/ ADDRESS OF FIRST MSD
; PUSHJ P,GENBSC
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS WITH:
; T1/ COMPUTED SIZE OF DATAGRAM
; T2/ ADDRESS OF START OF BSD CHAIN
GENBSC: PUSHJ P,SAVE4## ;SAVE P1-P4
SETZ P1, ;START WITH COMPUTED DATAGRAM SIZE OF ZERO
MOVE P2,T1 ;SAVE ADDRESS OF FIRST MSD
SETZB P3,P4 ;ZERO POINTERS TO BSD CHAIN
JUMPE T2,GENBC1 ;JUMP IF NOT DOING PADDING ON RECEIVE
MOVEI T2,.BSLEN ;GET SIZE OF BSD
PUSHJ P,GETNWZ## ;ALLOCATE ZEROED CORE FOR BSD
ERRRET (UNRES%) ;ERROR, NO RESOURCES
MOVE P3,T1 ;SAVE START ADDRESS OF BSD CHAIN IN P3
MOVE P4,T1 ;AND CURRENT BSD ADDRESS IN P4
MOVEI T1,2 ;SET UP BSD FOR TWO LENGTH BYTES
DPB T1,BSPSGL ;...
MAP T1,.BSRWD(P4) ;GET PHYSICAL ADDRESS OF BSD DATA WORD
TXZ T1,MP.NAD ;...
DPB T1,BSPSBA ;STORE AS BASE ADDRESS OF THIS SEGMENT
ADDI P1,2 ;ADJUST COMPUTED DATAGRAM SIZE
GENBC1: SKIPA ;ENTER MAIN LOOP
GENBC2: LOAD P2,MDNXT,(P2) ;GET ADDRESS OF NEXT MSD
JUMPE P2,GENBC5 ;EXIT LOOP AT END OF BSD CHAIN
LOAD T1,MDBYT,(P2) ;GET BYTE COUNT
JUMPE T1,GENBC2 ;LOOP BACK IF EMPTY MSD
ADD P1,T1 ;ADJUST COMPUTED DATAGRAM SIZE
LDB T2,[POINT 6,MD.AUX(P2),11] ;GET "S" FIELD FROM BYTE POINTER
CAIE T2,^D8 ;EIGHT BIT BYTES?
ERRRET (UNIBP%,GENBCX) ;NO, ILLEGAL BYTE POINTER
LDB T2,[POINT 6,MD.AUX(P2),5] ;GET "P" FIELD FROM BYTE POINTER
IDIVI T2,^D8 ;COMPUTE BYTE OFFSET
SUBI T2,4 ;...
MOVMS T2 ;...
CAIE T3,4 ;CORRECTLY ALIGNED BYTES?
ERRRET (UNIBP%,GENBCX) ;NO, ILLEGAL BYTE POINTER
HRRZ T3,MD.AUX(P2) ;GET ANY OFFSET FROM BYTE POINTER
ADD T3,MD.ALA(P2) ;COMPUTE ADDRESS OF DATA AREA
TLNE T3,777740 ;ANY BITS EXCEPT FOR ADDRESS PRESENT?
ERRRET (UNIBP%,GENBCX) ;YES, ILLEGAL BYTE POINTER
TRZE T2,4 ;WORD ALIGNED ON SECOND WORD OF DATA?
ADDI T3,1 ;YES, BUMP ADDRESS
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
GENBC3: PUSHJ P,GENBSD ;GENERATE NEXT BSD FOR THIS SEGMENT
JRST GENBCX ;ERROR, ERROR CODE IN T1
JUMPE P3,[MOVE P3,T4 ;IF FIRST BSD, SET UP INITIAL POINTER
JRST GENBC4] ;AND CONTINUE
PUSH P,T4 ;SAVE ADDRESS OF NEW BSD
MOVEM T4,.BSVNB(P4) ;LINK NEW BSD TO END OF CURRENT BSD CHAIN
MAP T4,0(T4) ;GET PHYSICAL ADDRESS OF BSD
TXZ T4,MP.NAD ;...
DPB T4,BSPNXT ;LINK TO PREVIOUS CHAIN
POP P,T4 ;GET BACK BSD ADDRESS
GENBC4: MOVE P4,T4 ;UPDATE POINTER TO CURRENT BSD
JUMPN T1,GENBC3 ;LOOP BACK TO COMPLETE THIS DATA SEGMENT
JRST GENBC2 ;THEN LOOP BACK FOR REMAINDER OF BSD CHAIN
GENBC5: MOVE T1,P1 ;GET COMPUTED SIZE OF DATAGRAM
MOVE T2,P3 ;AND ADDRESS OF BSD CHAIN
PJRST CPOPJ1## ;RETURN
GENBCX: PJUMPE P3,CPOPJ## ;JUST RETURN IF NO BSD CHAIN
PUSH P,T1 ;SAVE ERROR CODE
MOVE T1,P3 ;GET START OF BSD CHAIN
PUSHJ P,GIVBSC ;RELEASE BSD CHAIN
PJRST TPOPJ## ;RESTORE ERROR CODE AND RETURN
;ROUTINE CALLED TO BUILD A BUFFER SEGMENT DESCRIPTOR GIVEN
;A BYTE COUNT, BYTE OFFSET, AND ADDRESS OF A DATAGRAM SEGMENT
;LINKAGE:
; T1/ BYTE COUNT OF DATAGRAM SEGMENT
; T2/ BYTE OFFSET TO DATAGRAM SEGMENT
; T3/ ADDRESS OF DATAGRAM SEGMENT
; PUSHJ P,GENBSD
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS WITH:
; T1/ UPDATED BYTE COUNT OF DATAGRAM SEGMENT
; T2/ UPDATED BYTE OFFSET TO DATAGRAM SEGMENT
; T3/ UPDATED ADDRESS OF DATAGRAM SEGMENT
; T4/ ADDRESS OF BUFFER SEGMENT DESCRIPTOR
GENBSD: PUSHJ P,SAVE4## ;SAVE P1-P4
DMOVE P1,T1 ;SAVE BYTE COUNT AND BYTE OFFSET
MOVE P3,T3 ;AND ADDRESS OF DATAGRAM SEGMENT
JUMPE P2,GENBS1 ;JUMP IF WORD ALIGNED DATA
MOVEI T2,.BSLEN ;GET LENGTH OF BSD
PUSHJ P,GETNWZ## ;ALLOCATE ZEROED CORE FOR BSD
ERRRET (UNRES%) ;ERROR, NO RESOURCES
MOVE P4,T1 ;SAVE ADDRESS OF BSD IN P4
MOVEI T1,4 ;COMPUTE BYTE COUNT OF MIS-ALIGNED DATA
SUB T1,P2 ;...
CAMLE T1,P1 ;COMPARE TO SEGMENT'S BYTE COUNT
MOVE T1,P1 ;USE SMALLER OF THE TWO
DPB T1,BSPSGL ;STORE BYTE COUNT INTO BSD
SUB P1,T1 ;UPDATE SEGMENT BYTE COUNT
MOVE T1,P2 ;GET BYTE OFFSET
IMULI T1,^D8 ;COMPUTE SHIFT COUNT TO ALIGN DATA
MOVE T2,0(P3) ;FETCH FIRST DATA WORD
LSH T2,(T1) ;WORD ALIGN THE DATA
MOVEM P2,.BSRWB(P4) ;SAVE RE-ALIGNED WORD BYTE OFFSET
MOVEM P3,.BSRWA(P4) ;AND RE-ALIGNED WORD ADDRESS
MOVEM T2,.BSRWD(P4) ;AND RE-ALIGNED WORD DATA
MAP T1,.BSRWD(P4) ;GET PHYSICAL ADDRESS OF RE-ALIGNED DATA
TXZ T1,MP.NAD ;...
DPB T1,BSPSBA ;STORE IN BSD
SETZ P2, ;ZERO BYTE OFFSET AS NOW WORD ALIGNED
ADDI P3,1 ;UPDATE SEGMENT ADDRESS
JRST GENBS3 ;AND RETURN
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
GENBS1: MOVEI T2,.BSLEN ;GET LENGTH OF BSD
PUSHJ P,GETNWZ## ;ALLOCATE ZEROED CORE FOR BSD
ERRRET (UNRES%) ;ERROR, NO RESOURCES
MOVE P4,T1 ;SAVE BSD ADDRESS IN P4
MAP T1,0(P3) ;GET PHYSICAL ADDRESS OF DATA SEGMENT
TXZ T1,MP.NAD ;...
DPB T1,BSPSBA ;STORE IN BSD
MOVE T2,T1 ;CALCULATE NEXT PAGE BOUNDARY
ADDI T2,PAGSIZ## ;...
TRZ T2,PG.BDY## ;...
SUB T2,T1 ;CONVERT INTO WORD COUNT
GENBS2: IMULI T2,4 ;CONVERT WORD COUNT INTO BYTE COUNT
CAMLE T2,P1 ;COMPARE TO SEGMENT BYTE COUNT
MOVE T2,P1 ;USE SMALLER OF THE TWO
LDB T3,BSPSGL ;GET BSD SEGMENT LENGTH
ADD T3,T2 ;ADJUST COUNT
DPB T3,BSPSGL ;...
SUB P1,T2 ;UPDATE DATAGRAM SEGMENT BYTE COUNT
IDIVI T2,4 ;CONVERT BYTE COUNT INTO WORD COUNT
ADD P3,T2 ;UPDATE SEGMENT DATA ADDRESS
JUMPE P1,GENBS3 ;RETURN AT END OF DATAGRAM SEGMENT
MAP T2,0(P3) ;GET PHYSICAL ADDRESS OF NEXT DATA CHUNK
TXZ T2,MP.NAD ;...
SUB T2,T1 ;COMPUTE OFFSET FROM PREVIOUS PAGE
SKIPL T2 ;PHYSICALLY CONTINGUOUS WITH PREVIOUS PAGE?
CAILE T2,PAGSIZ## ;...
JRST GENBS3 ;NO, RETURN
MOVEI T2,PAGSIZ## ;GET SIZE OF NEXT POSSIBLE CHUNK
MOVE T1,T2 ;GET BASE ADDRESS OF NEXT PAGE
JRST GENBS2 ;LOOP BACK TO PROCESS SEGMENT
GENBS3: DMOVE T1,P1 ;GET UPDATED BYTE COUNT AND BYTE OFFSET
DMOVE T3,P3 ;AND UPDATED SEGMENT ADDRESS AND BSD ADDRESS
PJRST CPOPJ1## ;RETURN
SUBTTL KLNI DEVICE SERVICE -- RELEASE A BSD CHAIN
;ROUTINE CALLED TO RELEASE A BSD CHAIN
;LINKAGE:
; T1/ ADDRESS OF BSD CHAIN
; PUSHJ P,GIVBSC
;RETURNS:
; CPOPJ ALWAYS
GIVBSC: PUSHJ P,SAVE1## ;SAVE P1
MOVE P1,T1 ;SAVE ADDRESS OF FIRST BSD
GIVBC1: PUSH P,.BSVNB(P1) ;SAVE ADDRESS OF NEXT BSD
MOVEI T1,.BSLEN ;GET LENGTH OF BSD
MOVE T2,P1 ;AND ADDRESS OF CURRENT BSD
PUSHJ P,GIVNWS## ;RELEASE THE CORE
POP P,P1 ;GET ADDRESS OF NEXT BSD
JUMPN P1,GIVBC1 ;LOOP BACK TO RELEASE ENTIRE CHAIN
POPJ P, ;RETURN
SUBTTL KLNI DEVICE SERVICE -- ALLOCATE KLNI COMMAND BUFFER
;ROUTINE CALLED TO ALLOCATE A KLNI COMMAND BUFFER
;LINKAGE:
; T1/ KLNI COMMAND OPCODE
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,GETCMD
;RETURNS:
; CPOPJ ON ERROR WITH:
; T1/ ERROR CODE (UNXXX%)
; CPOPJ1 ON SUCCESS WITH:
; Q1/ ADDRESS OF KLNI COMMAND BUFFER
GETCMD: PUSH P,T1 ;SAVE KLNI COMMAND CODE
MOVEI T2,.CMLEN ;GET LENGTH OF COMMAND BUFFER
PUSHJ P,GETNWZ## ;ALLOCATE CORE FOR COMMAND BUFFER
PJRST [POP P,(P) ;ERROR, CLEAR STACK
ERRRET (UNRES%)] ;AND GIVE ERROR RETURN
MOVE Q1,T1 ;GET ADDRESS OF COMMAND BUFFER
POP P,T1 ;GET BACK KLNI COMMAND CODE
DPB T1,CMPCMD ;STORE OPCODE IN KLNI COMMAND BUFFER
MOVX T1,CMFRSP ;SET RESPONSE REQUIRED FLAG
DPB T1,CMPFLG ;...
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- RELEASE KLNI COMMAND BUFFER
;ROUTINE CALLED TO RELEASE A KLNI COMMAND BUFFER
;LINKAGE:
; Q1/ ADDRESS OF KLNI COMMAND BUFFER
; PUSHJ P,GIVCMD
;RETURNS:
; CPOPJ ALWAYS
GIVCMD: PJUMPE Q1,CPOPJ## ;RETURN IF NO BUFFER ALLOCATED
MOVEI T1,.CMLEN ;GET LENGTH OF COMMAND BUFFER
MOVE T2,Q1 ;AND ADDRESS OF COMMAND BUFFER
SETZ Q1, ;NO KLNI COMMAND BUFFER
PJRST GIVNWS## ;RELEASE CORE AND RETURN
SUBTTL KLNI DEVICE SERVICE -- QUEUE KLNI COMMAND TO FREE QUEUE
;ROUTINE TO QUEUE A COMMAND BUFFER TO A PROTOCOL'S FREE QUEUE
;LINKAGE:
; T1/ ADDRESS OF CALLBACK ROUTINE
; Q1/ ADDRESS OF KLNI COMMAND BUFFER
; Q2/ ADDRESS OF PROTOCOL USER BLOCK
; PUSHJ P,KNICMF
;RETURNS:
; CPOPJ ALWAYS
KNICMF: MOVEM T1,.CMCBA(Q1) ;STORE CALLBACK ROUTINE ADDRESS
AOS .PBKFC(Q3) ;UPDATE COUNT OF FREE COMMANDS QUEUED
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
MOVEM T1,.PBKFT(Q3) ;REMEMBER WHEN LAST COMMAND QUEUED
XMOVEI T1,.PUFQH(Q2) ;GET ADDRESS OF PROTOCOL'S FREE QUEUE
XMOVEI T2,.CMQUE(Q1) ;AND ADDRESS OF QUEUE ENTRY
PJRST PUTQUE ;INSERT COMMAND INTO QUEUE AND RETURN
SUBTTL KLNI DEVICE SERVICE -- QUEUE KLNI COMMAND TO COMMAND QUEUE
;ROUTINE TO QUEUE A COMMAND BUFFER TO THE KLNI'S COMMAND QUEUE
;LINKAGE:
; T1/ ADDRESS OF CALLBACK ROUTINE
; Q1/ ADDRESS OF KLNI COMMAND BUFFER
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNICMD
;RETURNS:
; CPOPJ ALWAYS
KNICMD: MOVEM T1,.CMCBA(Q1) ;STORE CALLBACK ROUTINE ADDRESS
XMOVEI T1,.PBCMQ(Q3) ;GET ADDRESS OF KLNI COMMAND QUEUE
XMOVEI T2,.CMQUE(Q1) ;AND ADDRESS OF QUEUE ENTRY
PUSHJ P,PUTQUE ;INSERT COMMAND INTO QUEUE
LDB T1,PBPCPU ;GET CPU NUMBER OF KLNI
CAME T1,.CPCPN## ;KLNI ON OUR CPU?
JRST KNICM1 ;NO, GO DO QUEUED I/O
AOS .PBKCC(Q3) ;UPDATE COUNT OF KLNI COMMANDS QUEUED
MOVE T1,.CPUPT## ;GET CPU UPTIME
MOVEM T1,.PBKCT(Q3) ;REMEMBER WHEN LAST COMMAND QUEUED
MOVX T1,PBSQIO ;CLEAR QUEUED I/O FLAG IN PCB
ANDCAM T1,.PBSTS(Q3) ;...
MOVE T1,.PBPIA(Q3) ;GET KLNI PI ASSIGNMENT
CONO KNI,CO.CQA!CO.BTS(T1) ;SET COMMAND QUEUE AVAILABLE FLAG
POPJ P, ;AND RETURN
KNICM1: AOS .PBKQC(Q3) ;UPDATE COUNT OF QUEUED I/O COMMANDS
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
MOVEM T1,.PBKQT(Q3) ;REMEMBER WHEN LAST COMMAND QUEUED
MOVX T1,PBSQIO ;SET QUEUED I/O FLAG IN PCB
IORM T1,.PBSTS(Q3) ;...
MOVE T1,.CPQPC## ;GET THIS CPU'S QUEUED I/O FLAG
IORM T1,DOORBL## ;SET QUEUED I/O FLAG
POPJ P, ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- MISCELLANEOUS
;ROUTINE TO SWAP HIGH AND LOW ORDER BYTES OF A NUMBER
;LINKAGE:
; T1/ NUMBER
; PUSHJ P,SWAB
;RETURNS:
; CPOPJ ALWAYS WITH:
; T1/ NUMBER
SWAB: DPB T1,[POINT 8,T1,19] ;REPOSITION LOW ORDER BYTE
LSH T1,-^D8 ;JUSTIFY RESULT
POPJ P, ;RETURN
;ROUTINE TO CONVERT TRANSMIT/RECEIVE DATAGRAM ERROR CODE INTO
;APPROPRIATE ETHSER ERROR CODE
;LINKAGE:
; T1/ KLNI ERROR CODE
; PUSHJ P,CVTETY
;RETURNS:
; CPOPJ ALWAYS WITH:
; T1/ ETHSER ERROR CODE (UNXXX%)
CVTETY: MOVEI T1,UNRAB% ;THESE HAVE TO BE DEFINED
POPJ P, ;RETURN
SUBTTL KLNI INTERRUPT SERVICE -- INTERRUPT DISPATCH
;ROUTINE CALLED FROM CONSO SKIP CHAIN TO PROCESS KLNI INTERRUPT
;LINKAGE:
; T1/ CONI STATUS WORD
; T2/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNIINT
;RETURNS:
; CPOPJ ALWAYS
KNIINT::SE1ENT ;NEED TO RUN IN NON-ZERO SECTION
MOVE Q3,T2 ;COPY PCB ADDRESS TO STANDARD REGISTER
MOVX T2,PBSMAI ;IS KLNI IN MAINTENANCE MODE?
TDNE T2,.PBSTS(Q3) ;...
POPJ P, ;YES, RETURN NOW
SETZB Q1,Q2 ;START CLEAN
MOVEM T1,.PBCLI(Q3) ;SAVE CONI IN PORT CONTROL BLOCK
TXNE T1,CI.CPE!CI.MER!CI.EPE!CI.DPE ;ANY BAD ERROR?
JRST KNIIT2 ;YES
MOVX T1,PBSQIO ;ANY QUEUED I/O REQUESTS?
TDNN T1,.PBSTS(Q3) ;...
JRST KNIIT1 ;NO, CONTINUE NORMALLY
ANDCAM T1,.PBSTS(Q3) ;YES, CLEAR QUEUED I/O REQUEST FLAG
MOVE T1,.PBPIA(Q3) ;GET KLNI PI ASSIGNMENT
CONO KNI,CO.CQA!CO.BTS(T1) ;SET COMMAND QUEUE AVAILABLE FLAG
KNIIT1: MOVX T1,CI.FQE ;FREE QUEUE ERROR?
TDNE T1,.PBCLI(Q3) ;...
PUSHJ P,KNEFQE ;YES, PROCESS
PUSHJ P,KNIRQA ;PROCESS ANY RESPONSES
POPJ P, ;DISMISS THE INTERRUPT
KNIIT2: PUSHJ P,KNESTP ;PERFORM KLNI ERROR STOP PROCESSING
MOVX T1,CI.CPE ;CRAM PARITY ERROR?
TDNE T1,.PBCLI(Q3) ;...
PUSHJ P,KNECPE ;YES
MOVX T1,CI.MER ;MBUS ERROR?
TDNE T1,.PBCLI(Q3) ;...
PUSHJ P,KNEMBE ;YES
MOVX T1,CI.EPE ;EBUS PARITY ERROR?
TDNE T1,.PBCLI(Q3) ;...
PUSHJ P,KNEEPE ;YES
MOVX T1,CI.DPE ;DATA PATH ERROR?
TDNE T1,.PBCLI(Q3) ;...
PUSHJ P,KNEDPE ;YES
POPJ P, ;DISMISS THE INTERRUPT
SUBTTL KLNI INTERRUPT SERVICE -- PROCESS RESPONSE QUEUE
;ROUTINE CALLED TO PROCESS KLNI RESPONSE QUEUE
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNIRQA
;RETURNS:
; CPOPJ ALWAYS
KNIRQA: PUSHJ P,SAVE1## ;SAVE P1
KNIRQ1: MOVE T1,.PBPIA(Q3) ;GET KLNI PI ASSIGNMENT
MOVX T2,PBSRUN ;IS KLNI RUNNING?
TDNE T2,.PBSTS(Q3) ;...
CONO KNI,CO.RQA!CO.BTS(T1) ;YES, CLEAR RESPONSE QUEUE AVAILABLE
XMOVEI T1,.PBRSQ(Q3) ;GET VIRTUAL ADDRESS OF QUEUE HEADER
PUSHJ P,REMQUE ;REMOVE NEXT ENTRY FROM RESPONSE QUEUE
POPJ P, ;RESPONSE QUEUE EMPTY, RETURN
XMOVEI Q1,-.CMQUE(T2) ;GET ADDRESS OF KLNI COMMAND BUFFER
LDB T1,CMPCMD ;GET COMMAND OPCODE
SKIPE T1 ;VALID OPCODE?
CAILE T1,CMOMAX ;...
STOPCD .+1,DEBUG,KNIICO ;++INVALID COMMAND OPCODE
AOS .PBKRC(Q3) ;UPDATE COUNT OF KLNI RESPONSES PROCESSED
MOVE T1,.CPUPT## ;GET CPU UPTIME
MOVEM T1,.PBKRT(Q3) ;REMEMBER WHEN LAST RESPONSE PROCESSED
MOVE T1,.CMCBA(Q1) ;GET CALLBACK ROUTINE ADDRESS
MOVE Q2,.CMPUB(Q1) ;GET ADDRESS OF PROTOCOL USER BLOCK
MOVE P1,.CMEAB(Q1) ;AND ADDRESS OF EA BLOCK
PUSHJ P,(T1) ;CALL CALLBACK ROUTINE
JFCL ;...
JRST KNIRQ1 ;LOOP BACK TO EMPTY RESPONSE QUEUE
SUBTTL KLNI INTERRUPT SERVICE -- FREE QUEUE ERROR
;ROUTINE CALLED TO PROCESS A FREE QUEUE ERROR
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNEFQE
;RETURNS:
; CPOPJ ALWAYS
KNEFQE: AOS .PBFQE(Q3) ;COUNT A FREE QUEUE ERROR
MOVE T1,.PBPIA(Q3) ;GET PI ASSIGNMENT
CONO KNI,CO.FQE!CO.BTS(T1) ;CLEAR FREE QUEUE ERROR
POPJ P, ;RETURN
SUBTTL KLNI INTERRUPT SERVICE -- CRAM PARITY ERROR
;ROUTINE CALLED TO PROCESS A CRAM PARITY ERROR
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNECPE
;RETURNS:
; CPOPJ ALWAYS
;NOTE:
;MUST BE CALLED AFTER REPORT AS IT DEPENDS ON SOME
;OF THE DATA RECORDED GATHERED BY REPORT
KNECPE: MOVE T1,.PBCRA(Q3) ;GET THE CRAM ADDRESS
CAIL T1,PPEFST ;IS THIS A PLANNED CRAM PARITY ERROR?
CAILE T1,PPELST ;...
STOPCD CPOPJ,INFO,KNICPE,CPETYP ;++KLNI CRAM PARITY ERROR
STOPCD CPOPJ,INFO,KNIHLT,HLTTYP ;++KLNI MICROPROCESSOR HALT
;ROUTINE CALLED FROM DIE ON AN UNPLANNED CRAM PARITY ERROR
CPETYP: PUSHJ P,INLMES## ;PRINT TEXT
ASCIZ /NIA20 CRAM parity error
CRAM location /
MOVE T1,.PBCRA(Q3) ;GET THE CRAM ADDRESS
PUSHJ P,PRTDI8## ;PRINT IN OCTAL
PUSHJ P,INLMES## ;TYPE OUT CRAM CONTENTS
ASCIZ /, CRAM contents /
MOVE T1,.PBCRC(Q3) ;GET FIRST CRAM HALFWORD
PUSHJ P,HWDPNT## ;PRINT AS HALFWORDS
PUSHJ P,PRSPC## ;SPACE OVER
MOVE T1,.PBCRC+1(Q3) ;GET SECOND CRAM HALFWORD
PJRST HWDPNT## ;PRINT AS HALFWORDS AND RETURN (DIE ADDS CRLF)
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;ROUTINE CALLED FROM DIE ON A PLANNED CRAM PARITY ERROR
HLTTYP: PUSHJ P,INLMES## ;PRINT TEXT
ASCIZ /NIA20 microprocessor halted - /
MOVE T1,.PBCRA(Q3) ;GET THE CRAM ADDRESS
HRRZ T1,CPETXT-PPEFST(T1) ;GET ERROR TEXT ADDRESS
PJRST CONMES## ;PRINT AND RETURN (DIE ADDS CRLF)
;TABLE OF TEXT STRINGS BASED ON CRAM ADDRESS FOR PLANNED CRAM PARITY ERRORS
DEFINE ERRS,<
XALL ;;LIST GENERATED TABLE
CPE 7750, <Internal port error>
CPE 7751, <Self test failed>
CPE 7752, <EBUS parity error>
CPE 7753, <EBUS parity error>
CPE 7754, <PLI parity error>
CPE 7755, <CBUS parity error>
CPE 7756, <Data path error>
CPE 7757, <CBUS request error>
CPE 7760, <EBUS request error>
CPE 7761, <Grant CSR error>
CPE 7762, <Short word count>
CPE 7763, <Spurious channel error>
CPE 7764, <Spuriour transmit attention error>
CPE 7765, <Used buffer list parity error>
CPE 7766, <Free buffer list parity error>
CPE 7767, <Transmit buffer list parity error>
CPE 7770, <Unknown halt code 7770>
CPE 7771, <Unknown halt code 7771>
CPE 7772, <Unknown halt code 7772>
CPE 7773, <Unknown halt code 7773>
CPE 7774, <Unknown halt code 7774>
CPE 7775, <Unknown halt code 7775>
CPE 7776, <Unknown halt code 7776>
CPE 7777, <Unknown halt code 7777>
SALL ;;TURN LISTING BACK OFF
>; END DEFINE ERRS
;GENERATE ERROR TEXT TABLE
DEFINE CPE(LOC,TEXT),<
IF1,<IFN <<LOC-PPEFST>-<.-CPETXT>>,<PRINTX ?Table CPETXT entry LOC is out of order>>
IFIW [ASCIZ/TEXT/] ;LOC
>; END DEFINE CPE
CPETXT: ERRS ;GENERATE ERROR TEXT TABLE
IF1,<IFN <<PPELST-PPEFST>-<.-CPETXT-1>>,<PRINTX ?Table CPETXT is missing entries>>
SUBTTL KLNI INTERRUPT SERVICE -- MBUS ERROR
;ROUTINE CALLED TO PROCESS AN MBUS ERROR
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNEMBE
;RETURNS:
; CPOPJ ALWAYS
;NOTE:
;MUST BE CALLED AFTER REPORT AS IT DEPENDS ON SOME
;OF THE DATA WHICH REPORT STORES IN THE PCB
KNEMBE: STOPCD CPOPJ##,INFO,KNIMBE ;++KLNI MBUS ERROR
SUBTTL KLNI INTERRUPT SERVICE -- EBUS PARITY ERROR
;ROUTINE CALLED TO PROCESS AN EBUS PARITY ERROR
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNEEPE
;RETURNS:
; CPOPJ ALWAYS
;NOTE:
;MUST BE CALLED AFTER REPORT AS IT DEPENDS ON SOME
;OF THE DATA WHICH REPORT STORES IN THE PCB
KNEEPE: STOPCD CPOPJ##,INFO,KNIEPE ;++KLNI EBUS PARITY ERROR
SUBTTL KLNI INTERRUPT SERVICE -- DATA PATH ERROR
;ROUTINE CALLED TO PROCESS AN DATA PATH ERROR
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNEDPE
;RETURNS:
; CPOPJ ALWAYS
;NOTE:
;MUST BE CALLED AFTER REPORT AS IT DEPENDS ON SOME
;OF THE DATA WHICH REPORT STORES IN THE PCB
KNEDPE: STOPCD CPOPJ##,INFO,KNIDPE ;++KLNI DATA PATH ERROR
SUBTTL KLNI INTERRUPT SERVICE -- KLNI ERROR STOP PROCESSING
;ROUTINE CALLED WHEN KLNI STOPS
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNESTP
;RETURNS:
; CPOPJ ALWAYS
KNESTP: PUSHJ P,STPKNI ;STOP KLNI MICROCODE AND CLEAN UP
PUSHJ P,REPORT ;MAKE AN ERROR.SYS ENTRY
MOVE T1,.PBKHT(Q3) ;GET UPTIME WHEN KLNI HALTED
SUB T1,.PBKST(Q3) ;CALCULATE TIME KLNI WAS UP
IMULI T1,^D1000 ;CONVERT TO MILLISECONDS
IDIV T1,TICSEC## ;...
CAXL T1,UPTTIM ;WAS KLNI UP MINIMUM LENGTH OF TIME?
PJRST RLDKND ;YES, REQUEST KLNI DUMP AND RELOAD
STOPCD CPOPJ##,INFO,KNIARD ;++KLNI AUTO-RELOAD DISABLED
SUBTTL KLNI INTERRUPT SERVICE -- SPEAR ERROR LOGGING
;ROUTINE TO RECORD PORT ERROR INFORMATION AND MAKE A SPEAR ENTRY
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,REPORT
;RETURNS:
; CPOPJ ALWAYS
REPORT: AOS .PBKEC(Q3) ;UPDATE COUNT OF KLNI ERRORS
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
MOVEM T1,.PBKET(Q3) ;REMEMBER TIME OF LAST KLNI ERROR
MOVE T1,.PBCLI(Q3) ;GET CONI FROM THIS INTERRUPT
MOVEM T1,.PBCLE(Q3) ;SAVE AS CONI FROM LAST ERROR
PUSHJ P,REDLAR ;READ LATCHED ADDRESS REGISTER CONTENTS
SETZ T1, ;ERROR?
MOVEM T1,.PBCRA(Q3) ;SAVE IT
PUSHJ P,REDKNI ;READ THAT LOCATION'S CONTENTS
SETZB T2,T3 ;ERROR?
DMOVEM T2,.PBCRC(Q3) ;SAVE IN PCB
MOVE T1,.CPEPT## ;GET OUR EPT ADDRESS
DMOVE T2,KNIICH*4(T1) ;GET FIRST TWO WORDS OF CHANNEL LOGOUT AREA
DMOVEM T2,.PBLG0(Q3) ;SAVE THEM
MOVE T2,KNIICH*4+2(T1) ;GET THIRD WORD
MOVEM T2,.PBLG2(Q3) ;SAVE IT
MOVE T1,.PBCCW(Q3) ;GET PORT'S CCW
MOVEM T1,.PBECW(Q3) ;SAVE IT
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
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,.PBCLE(Q3) ;GET CONI ON ERROR
MOVEM T2,.EBHDR+KP%CSR(T1) ;STORE IT
MOVE T2,.PBUVR(Q3) ;GET KLNI MICROCODE VERSION
TXO T2,KP%NI!FLD(KNIICH,KP%CHN) ;SET KLNI FLAG AND RH20 CHANNEL
MOVEM T2,.EBHDR+KP%VER(T1) ;STORE IT
MOVEI T2,2(P1) ;GET DISPOSITION CODE
MOVEM T2,.EBHDR+KP%DSP(T1) ;STORE IT
MOVE T2,.PBCRA(Q3) ;GET CRAM ADDRESS
MOVEM T2,.EBHDR+KP%CRA(T1) ;STORE IT
DMOVE T2,.PBCRC(Q3) ;GET CRAM CONTENTS
DMOVEM T2,.EBHDR+KP%CRD(T1) ;STORE IT
DMOVE T2,.PBLG0(Q3) ;GET FIRST TWO LOGOUT WORDS
DMOVEM T2,.EBHDR+KP%LG0(T1) ;STORE THEM
MOVE T2,.PBLG2(Q3) ;GET THIRD LOGOUT WORD
MOVEM T2,.EBHDR+KP%LG2(T1) ;STORE IT
MOVE T2,.PBECW(Q3) ;GET PORT'S CCW AT ERROR
MOVEM T2,.EBHDR+KP%ECW(T1) ;STORE IT
DMOVE T2,.PBER0(Q3) ;GET ERROR WORDS
DMOVEM T2,.EBHDR+KP%PE0(T1) ;STORE THEM
PJRST QUESEB## ;QUEUE THE BLOCK AND RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- DIAG. UUO
;DIAG. UUO FUNCTIONS FOR DIAGNOSTIC CONTROL OF A KLNI
;LINKAGE: (CALL FROM DIAUUO ON CORRECT CPU)
; P1/ ADDRESS OF CHANNEL DATA BLOCK
; P2/ DIAG. UUO FUNCTION CODE
; M/ ADDRESS OF USER ARGUMENT LIST
; PUSHJ P,KNIDIA
;RETURNS:
; CPOPJ ON ERROR WITH:
; USER AC/ ERROR CODE (DIXXX%)
; CPOPJ1 ON SUCCESS
ERCODX DIAPRV,DIANP% ;INSUFFICIENT PRIVILEGES
ERCODX DIAIAL,DIAIA% ;INVALID ARGUMENT LIST LENGTH
ERCODX DIAICN,DIAIC% ;ILLEGAL CONTROLLER NUMBER
ERCODX DIAILF,DIAIF% ;ILLEGAL FUNCTION
ERCODX DIANKC,DIANK% ;NO KLNI PORT ON THIS CPU
KNIDIA::PUSHJ P,SAVE4## ;SAVE P1-P4
PUSHJ P,SAVQ## ;AND Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVX T1,JP.POK ;JOB HAVE SUFFICIENT PRIVILEGES?
PUSHJ P,PRVBIT## ;...
SKIPA ;YES, CONTINUE
PJRST DIAPRV ;NO, GIVE ERROR RETURN
MOVE Q3,CHNPCB##(P1) ;GET THE PORT CONTROL BLOCK ADDRESS
CAIL P2,17 ;THESE FUNCTIONS DON'T REQUIRE MAINTENANCE MODE
CAILE P2,23 ;...
SKIPA ;NOT A SPECIAL FUNCTION
PJRST @DIAFNC(P2) ;YES, DISPATCH NOW
MOVX T1,PBSMAI ;IN MAINTENANCE MODE?
TDNN T1,.PBSTS(Q3) ;...
JRST UNNDMD## ;NO, RETURN AN ERROR
PJRST @DIAFNC(P2) ;DISPATCH BASED ON FUNCTION CODE
;DIAG. UUO FUNCTION DISPATCH TABLE
DIAFNC: IFIW CPOPJ## ;(0) DISPATCH ON ^C (DON'T GET HERE THIS WAY)
IFIW CPOPJ## ;(1) ASSIGN SINGLE UNIT
IFIW DIAAAU ;(2) ASSIGN CHANNEL AND ALL UNITS
IFIW DIARCU ;(3) RELEASE CHANNEL AND ALL UNITS
IFIW DIASCP ;(4) SPECIFY CHANNEL PROGRAM
IFIW DIARCP ;(5) RELEASE CHANNEL PROGRAM
IFIW DIACST ;(6) GET CHANNEL STATUS
IFIW CPOPJ## ;(7) GET KONTROLLER AND UNIT
IFIW CPOPJ## ;(10) ILLEGAL FOR KLNI
IFIW CPOPJ## ;(11) ILLEGAL FOR KLNI
IFIW CPOPJ## ;(12) SPECIFY CHANNEL PROGRAM FOR REVERSE
IFIW CPOPJ## ;(13) ILLEGAL FOR KLNI
IFIW CPOPJ## ;(14) ILLEGAL FOR KLNI
IFIW CPOPJ## ;(15) ILLEGAL FOR KLNI
IFIW CPOPJ## ;(16) ILLEGAL FOR KLNI
IFIW DIAELD ;(17) ENABLE MICROCODE LOADING
IFIW DIADLD ;(20) DISABLE MICROCODE LOADING
IFIW DIALOD ;(21) LOAD MICROCODE
IFIW DIAEMM ;(22) ENABLE MAINTENANCE MODE
IFIW DIADMM ;(23) DISABLE MAINTENANCE MODE
MXDIAG==:.-DIAFNC
;(2) ASSIGN "CHANNEL" AND ALL UNITS
DIAAAU: ETHLOK ;INTERLOCK AGAINST SMP RACES
LDB T1,PBPMJB ;GET JOB NUMBER OF CURRENT MAINTENANCE JOB
JUMPE T1,DIAAA1 ;JUMP IF NOT CURRENTLY OWNED
ETHULK ;RELEASE SMP INTERLOCK
JRST UNAAJB## ;RETURN ERROR
DIAAA1: MOVE T1,.CPJOB## ;GET OUR JOB NUMBER
DPB T1,PBPMJB ;SET UP OUR JOB AS MAINTENANCE JOB
ETHULK ;RELEASE SMP INTERLOCK
JRST CPOPJ1## ;AND RETURN
;(3) RELEASE "CHANNEL" AND ALL UNITS
DIARCU: LDB T1,PBPMJB ;GET MAINTENANCE JOB NUMBER
CAME T1,J ;SAME AS CALLER'S JOB?
JRST UNAAJB## ;NO, RETURN ERROR
SETZ T1, ;CLEAR MAINTENANCE JOB NUMBER
DPB T1,PBPMJB ;...
JRST CPOPJ1## ;AND RETURN
;(4) SPECIFY CHANNEL PROGRAM
DIASCP: LDB T1,PBPMJB ;GET MAINTENANCE JOB NUMBER
CAME T1,J ;SAME AS CALLER'S JOB?
JRST UNAAJB## ;NO, RETURN ERROR
MOVE P3,.PBCDB(Q3) ;GET CHANNEL DATA BLOCK ADDRESS
PUSHJ P,DIARCP ;RETURN ANY IOWD
S0PSHJ GETWD1## ;GET IOWD
HLRE T2,T1 ;LENGTH OF IOWD
JUMPE T2,IOWCPB## ;TOO BIG IF 0
MOVEM T1,.CHICW##(P3) ;UNRELOCATED IOWD
MOVEI T1,1(T1) ;START ADDRESS
MOVNS T2 ;+LENGTH
ADDI T2,-1(T1) ;TOP ADDRESS
S0PSHJ ZRNGE## ;MAKE SURE THE PAGES ARE OK
JRST [SETZM .CHICW##(P3) ;PAGE NOT THERE
JRST IOWCPB##] ;BOMB HIM OUT
SETZB P1,P4 ;SAY FIRST CALL, NOT A DX10
MOVE T2,.CHICW##(P3) ;GET IOWD
S0PSHJ MAPIO## ;RELOCATE THE IOWD
JRST [SETZM .CHICW##(P3)
JRST DINEFC##] ;NO LOW-CORE BLOCKS
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
MOVSI T1,(CC.HLT) ;LIGHT HALT BIT IN LAST CCW
IORM T1,-1(P1) ;...
SETZM (P1) ;TERMINATE LIST
MOVEM P2,.CHICW##(P3) ;STORE ADDRESS OF CHANNEL PROGRAM
TLO P2,(FLD(.CCJMP,CC.OPC)) ;MAKE ICW BE A JUMP
MOVE T1,.CPEPT## ;GET EPT ADDRESS
ADDI T1,KNIICH*4 ;OFFSET TO 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: LDB T1,PBPMJB ;GET MAINTENANCE JOB NUMBER
CAME T1,J ;SAME AS CALLER'S JOB?
JRST UNAAJB## ;NO, RETURN ERROR
MOVE P3,.PBCDB(Q3) ;GET CHANNEL DATA BLOCK ADDRESS
SKIPN T1,.CHICW##(P3) ;NOTHING TO DO IF NO IOWD
POPJ P,
SETZM .CHICW##(P3) ;FORGET WE HAD IT
S0JRST RTNIOW## ;RETURN THE SPACE AND RETURN
;(6) GET CHANNEL STATUS
DIACST: LDB T1,PBPMJB ;GET MAINTENANCE JOB NUMBER
CAME T1,J ;SAME AS CALLER'S JOB?
JRST UNAAJB## ;NO, RETURN ERROR
MOVE P2,.CPEPT## ;GET EPT ADDRESS
ADDI P2,KNIICH*4+.CSICW ;OFFSET TO ICWA ADDRESS
PJRST DIAGCS## ;FINISH UP IN UUOCON
;(17) ENABLE MICROCODE RELOAD
DIAELD: SETZ T1, ;CLEAR AUTO-RELOAD DISABLED FLAG
DPB T1,PBPARD ;...
MOVX T1,PBSRUN ;IS KLNI CURRENTLY RUNNING?
TDNN T1,.PBSTS(Q3) ;...
PUSHJ P,RLDKNI ;NO, INITIATE RELOAD OF KLNI
PJRST CPOPJ1## ;AND RETURN
;(20) DISABLE MICROCODE RELOAD
DIADLD: MOVEI T1,1 ;SET AUTO-RELOAD DISABLED FLAG
DPB T1,PBPARD ;...
PJRST CPOPJ1## ;AND RETURN
;(21) RELOAD MICROCODE
DIALOD: MOVX T1,PBSMAI ;IS KLNI IN MAINTENANCE MODE?
TDNE T1,.PBSTS(Q3) ;...
PJRST DIAILF ;YES, RETURN AN ERROR
PUSHJ P,SHTKNI ;SHUT DOWN KLNI
PUSHJ P,LODKNI ;INITIATE RELOAD OF KLNI
MOVEI T2,10 ;WAIT AT MOST TEN SECONDS FOR RELOAD
DIALO1: MOVX T1,PBSONL ;IS KLNI ONLINE?
TDNE T1,.PBSTS(Q3) ;...
PJRST CPOPJ1## ;YES, RETURN
SOJL T2,DIAMRF## ;ERROR IF KLNI DIDN'T RELOAD IN TIME
MOVEI T1,1 ;SLEEP FOR A SECOND
PUSHJ P,SLEEPF## ;...
JRST DIALO1 ;AND LOOP BACK TO CHECK AGAIN
;(22) ENABLE MAINTENANCE MODE
DIAEMM: MOVX T1,PBSMAI ;MAINTENANCE MODE ALREADY SET?
TDNE T1,.PBSTS(Q3) ;...
PJRST CPOPJ1## ;YES, RETURN NOW
IORM T1,.PBSTS(Q3) ;SET MAINTENANCE MODE
PUSHJ P,SHTKNI ;SHUT DOWN KLNI
SETZM CHNBTS##(P1) ;ZAP BITS TO TEST FOR ON INTERRUPT
PJRST CPOPJ1## ;AND RETURN
;(23) DISABLE MAINTENANCE MODE
DIADMM: MOVX T1,PBSMAI ;MAINTENANCE MODE ALREADY CLEAR?
TDNN T1,.PBSTS(Q3) ;...
PJRST CPOPJ1## ;YES, RETURN NOW
ANDCAM T1,.PBSTS(Q3) ;CLEAR MAINTENANCE MODE
SETZ T1, ;CLEAR MAINTENANCE JOB NUMBER
DPB T1,PBPMJB ;...
CONO KNI,CO.CPT ;MAKE SURE KLNI IS STOPPED
MOVE T1,[KNIBTS] ;BITS TO TEST FOR ON INTERRUPT
MOVEM T1,CHNBTS##(P1) ;STORE IN CHANNEL DATA BLOCK
PUSHJ P,RLDKNI ;INITIATE AUTO-RELOAD OF KLNI
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- KNIBT. UUO
;UUO FOR BOOTING/DUMPING A KLNI
;LINKAGE:
; XMOVEI AC,ADDR
; KNIBT. AC,
; ERROR RETURN, CODE IN AC
; NORMAL RETURN
;
;ADDR: FUNCTION CODE,,LENGTH
; ARGUMENTS
ERCODX KBTPRV,KBPRV% ;INSUFFICIENT PRIVILEGES
ERCODX KBTADC,KBADC% ;ADDRESS CHECK
ERCODX KBTIAL,KBIAL% ;INVALID ARGUMENT LIST LENGTH
ERCODX KBTILF,KBILF% ;ILLEGAL FUNCTION
ERCODX KBTICS,KBICS% ;ILLEGAL CPU SPECIFICATION
ERCODX KBTCNA,KBCNA% ;CPU IS NOT AVAILABLE
ERCODX KBTKDE,KBKDE% ;KLNI DOESN'T EXIST
ERCODX KBTKMM,KBKMM% ;KLNI IS IN MAINTENANCE MODE
ERCODX KBTDNS,KBDNS% ;KLNI DID NOT START
ERCODX KBTDNI,KBDNI% ;KLNI DID NOT INITIALIZE
ERCODX KBTICA,KBICA% ;INVALID CRAM ADDRESS
ERCODX KBTCRE,KBCRE% ;CRAM READ ERROR
ERCODX KBTCWE,KBCWE% ;CRAM WRITE ERROR
ERCODX KBTNRJ,KBNRJ% ;NOT THE RELOAD JOB
KNIBT.::PUSHJ P,SAVE4## ;SAVE P1-P4
PUSHJ P,SAVQ## ;AND Q1-Q3
SE1ENT ;RUN IN SECTION 1
PUSHJ P,SSPCS## ;SAVE CURRENT PCS
PUSHJ P,SXPCS## ;SET UP PCS FOR USER ARGUMENT
PJRST KBTADC ;ADDRESS CHECK
MOVE M,T1 ;SET UP FOR GETEWD
MOVX T1,JP.POK ;JOB HAVE SUFFICIENT PRIVILEGES?
PUSHJ P,PRVBIT## ;...
SKIPA ;YES, CONTINUE
PJRST KBTPRV ;NO, GIVE ERROR RETURN
PUSHJ P,GETEWD## ;GET FUNCTION CODE AND LENGTH
PJRST KBTADC ;ADDRESS CHECK
HRRE P1,T1 ;SAVE LENGTH OF ARGUMENT BLOCK
HLRE P2,T1 ;ISOLATE FUNCTION CODE
SOJL P1,KBTIAL ;VALIDITY CHECK ARGUMENT BLOCK LENGTH
SKIPLE P2 ;RANGE CHECK FUNCTION CODE
CAILE P2,KBTMAX ;...
PJRST KBTILF ;ILLEGAL FUNCTION CODE
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
SOJL P1,KBTIAL ;VALIDITY CHECK ARGUMENT BLOCK LENGTH
PUSHJ P,GETEW1## ;YES, GET CPU NUMBER OF KLNI
PJRST KBTADC ;ADDRESS CHECK
MOVE P3,T1 ;SAVE IN P3
HLRE T1,P3 ;GET CPU NUMBER
PJUMPL T1,KBTICS ;RANGE CHECK CPU NUMBER
CAIL T1,CPUN## ;...
PJRST KBTICS ;ILLEGAL CPU SPECIFICATION
IFN FTMP,<
PUSHJ P,ONCPUS## ;SET TO RUN ON THAT CPU
PJRST KBTCNA ;KLNI CPU IS NOT AVAILABLE
> ;END IFN FTMP
HRRE T1,P3 ;GET RH20 CHANNEL NUMBER OF KLNI
CAIE T1,KNIICH ;CORRECT RH20 CHANNEL NUMBER
PJRST KBTKDE ;NO, KLNI DOESN'T EXIST
SKIPN Q3,.CPNPB## ;GET ADDRESS OF PORT CONTROL BLOCK
PJRST KBTKDE ;KLNI DOESN'T EXIST
MOVX T1,DF.IMM ;IS FUNCTION ILLEGAL IN MAINTENANCE MODE?
TDNN T1,KBTDSF(P2) ;...
JRST KNIBT1 ;NO, CONTINUE
MOVX T1,PBSMAI ;IS KLNI IN MAINTENANCE MODE?
TDNE T1,.PBSTS(Q3) ;...
PJRST KBTKMM ;YES, KLNI IS IN MAINTENANCE MODE
KNIBT1: MOVX T1,DF.RJB ;NEED TO CHECK JOB NUMBER?
TDNN T1,KBTDSF(P2) ;...
JRST KNIBT2 ;NO, JUST DISPATCH
LDB T1,PBPRJB ;GET JOB NUMBER OF KNILDR
CAME T1,.CPJOB## ;IS THIS JOB THE CORRECT JOB?
PJUMPN T1,KBTNRJ ;NO, ERROR IF RELOAD JOB IS SET
KNIBT2: MOVE T1,KBTDSP(P2) ;GET ADDRESS OF FUNCTION SPECIFIC ROUTINE
PJRST (T1) ;DISPATCH TO FUNCTION SPECIFIC ROUTINE
;KNIBT. UUO DISPATCH TABLE
DEFINE FNC,<
DISP 0, 0, KBTILF ;;(0) ILLEGAL, PLACE HOLDER
DISP 0, .KBSTS, KBTSTS ;;(1) GET KLNI STATUS
DISP DF.IMM, .KBSRJ, KBTSRJ ;;(2) SET RELOAD JOB
DISP DF.IMM!DF.RJB, .KBSTP, KBTSTP ;;(3) STOP KLNI
DISP DF.IMM!DF.RJB, .KBSTA, KBTSTA ;;(4) START KLNI
DISP DF.IMM!DF.RJB, .KBRED, KBTRED ;;(5) READ CRAM LOCATION
DISP DF.IMM!DF.RJB, .KBWRT, KBTWRT ;;(6) WRITE CRAM LOCATION
>; END DEFINE FNC
;GENERATE FUNCTION FLAGS TABLE
DF.IMM==400000,,000000 ;FUNCTION ILLEGAL IN MAINTENANCE MODE
DF.RJB==200000,,000000 ;REQUIRE JOB TO BE THE RELOAD JOB
DEFINE DISP(FLAG,CODE,ADDR),<
EXP FLAG ;(CODE) ADDR
>; END DEFINE DISP
KBTDSF: FNC ;GENERATE FUNCTION FLAGS TABLE
;GENERATE FUNCTION DISPATCH TABLE
DEFINE DISP(FLAG,CODE,ADDR),<
IF1,<IFN <CODE-<.-KBTDSP>>,<PRINTX ?Table KBTDSP entry CODE is out of order>>
IFIW ADDR ;(CODE) ADDR
>; END DEFINE DISP
KBTDSP: FNC ;GENERATE FUNCTION DISPATCH TABLE
KBTMAX==.-KBTDSP-1 ;MAXIMUM KNIBT. UUO FUNCTION CODE
;KNIBT. UUO FUNCTION .KBSTS (RETURN KLNI STATUS)
KBTSTS: SETZ T1, ;START WITH ZERO
MOVE T2,.PBSTS(Q3) ;GET CURRENT KLNI STATUS
TXNE T2,PBSRUN ;IS KLNI RUNNING?
TXOA T1,KS.RUN ;YES, MARK AS RUNNING
TXO T1,KS.RLD ;NO, MARK AS NEEDING TO BE RELOADED
TXNE T2,PBSRLD ;RELOAD REQUESTED?
TXO T1,KS.RRQ ;YES, MARK RELOAD REQUESTED BY SYSTEM
TXNE T2,PBSDMP ;DUMP REQUESTED?
TXO T1,KS.DRQ ;YES, MARK DUMP REQUESTED BY SYSTEM
TXNE T2,PBSMAI ;IS KLNI IN MAINTENANCE MODE?
TXO T1,KS.MAI ;YES, MARK IN RETURNED STATUS
TXNE T2,PBSARD ;IS AUTO-RELOAD DISABLED?
TXO T1,KS.ARD ;YES, MARK IN RETURNED STATUS
TXNE T2,PBSADD ;IS AUTO-DUMP DISABLED?
TXO T1,KS.ADD ;YES, MARK IN RETURNED STATUS
LDB T2,PBPRJB ;GET JOB NUMBER OF KNILDR
DPB T2,[POINTR (T1,KS.RJB)] ;STORE IN RETURN AC
MOVS M,.USMUO ;RESTORE POINTER TO USER'S AC
PJRST STOTC1## ;STORE STATUS IN USER AC AND RETURN
;KNIBT. UUO FUNCTION .KBSRJ (SET RELOAD JOB)
KBTSRJ: ETHLOK ;INTERLOCK AGAINST SMP RACES
LDB T1,PBPRJB ;GET JOB NUMBER OF KNILDR
SKIPE T1 ;JOB NUMBER OF KNILDR ALREADY SET?
CAMN T1,.CPJOB## ;YES, SAME AS THIS JOB'S JOB NUMBER?
SKIPA ;YES, CONTINUE
PJRST [ETHULK ;NO, RELEASE SMP INTERLOCK
PJRST KBTNRJ] ;NOT THE RELOAD JOB
MOVE T1,.CPJOB## ;GET JOB NUMBER OF THIS JOB
DPB T1,PBPRJB ;SET THE JOB NUMBER OF KNILDR
ETHULK ;RELEASE SMP INTERLOCK
PJRST CPOPJ1## ;AND RETURN
;KNIBT. UUO FUNCTION .KBSTP (STOP KLNI)
KBTSTP: PUSHJ P,SHTKNI ;SHUT DOWN KLNI
PJRST CPOPJ1## ;AND RETURN
;KNIBT. UUO FUNCTION .KBSTA (START KLNI)
KBTSTA: SOJL P1,KBTIAL ;VALIDITY CHECK ARGUMENT BLOCK LENGTH
PUSHJ P,GETEW1## ;GET KLNI START ADDRESS
PJRST KBTADC ;ADDRESS CHECK
SKIPL T1 ;VALID CRAM ADDRESS?
CAILE T1,MAXCRA ;...
PJRST KBTICA ;NO, INVALID CRAM ADDRESS
MOVEM T1,.PBKSA(Q3) ;SAVE KLNI START ADDRESS IN PCB
PUSHJ P,STAKNI ;START THE KLNI
PJRST KBTDNS ;KLNI DID NOT START
PUSHJ P,INIKNI ;BEGIN INITIALIZATION OF KLNI
PJRST KBTDNI ;ERROR, KLNI DID NOT INITIALIZE
MOVEI T1,5 ;WAIT AT MOST 5 SECONDS
PUSHJ P,SLEEPF## ;...
SETZ T1, ;CLEAR JOB NUMBER OF KNILDR
DPB T1,PBPRJB ;...
MOVX T1,PBSONL ;IS KLNI NOW ONLINE?
TDNN T1,.PBSTS(Q3) ;...
PJRST KBTDNI ;NO, KLNI DID NOT INITIALIZE
PJRST CPOPJ1## ;RETURN
;KNIBT. UUO FUNCTION .KBRED (READ CRAM LOCATION)
KBTRED: SUBI P1,3 ;CHECK FOR ARGUMENT LENGTH ERROR
PJUMPL P1,KBTIAL ;...
PUSHJ P,GETEW1## ;GET CRAM LOCATION
PJRST KBTADC ;ADDRESS CHECK
SKIPL T1 ;VALID CRAM ADDRESS?
CAILE T1,MAXCRA ;...
PJRST KBTICA ;NO, INVALID CRAM ADDRESS
PUSHJ P,REDKNI ;READ KLNI CRAM LOCATION
PJRST KBTCRE ;CRAM READ ERROR
MOVE P1,T3 ;SAVE LOW-ORDER CRAM CONTENTS
MOVE T1,T2 ;GET HIGH ORDER CRAM CONTENTS
PUSHJ P,PUTEW1## ;STORE INTO ARGUMENT BLOCK
PJRST KBTADC ;ADDRESS CHECK
MOVE T1,P1 ;GET LOW-ORDER CRAM CONTENTS
PUSHJ P,PUTEW1## ;STORE INTO ARGUMENT BLOCK
PJRST KBTADC ;ADDRESS CHECK
PJRST CPOPJ1## ;AND RETURN
;KNIBT. UUO FUNCTION .KBWRT (WRITE CRAM LOCATION)
KBTWRT: SUBI P1,3 ;CHECK FOR ARGUMENT LENGTH ERROR
PJUMPL P1,KBTIAL ;...
PUSHJ P,GETEW1## ;GET CRAM ADDRESS
PJRST KBTADC ;ADDRESS CHECK
SKIPL T1 ;VALID CRAM ADDRESS?
CAILE T1,MAXCRA ;...
PJRST KBTICA ;NO, INVALID CRAM ADDRESS
MOVE P2,T1 ;SAVE FOR LATER
PUSHJ P,GETEW1## ;GET HI-ORDER CRAM CONTENTS
PJRST KBTADC ;ADDRESS CHECK
MOVE P1,T1 ;SAVE FOR LATER
PUSHJ P,GETEW1## ;GET LOW-ORDER CRAM CONTENTS
PJRST KBTADC ;ADDRESS CHECK
EXCH T1,P2 ;SAVE LOW-ORDER CONTENTS, GET CRAM ADDRESS
DMOVE T2,P1 ;GET CRAM CONTENTS
PUSHJ P,WRTKNI ;WRITE CRAM LOCATION
PJRST KBTCWE ;CRAM WRITE ERROR
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- SHUT DOWN KLNI MICROCODE
;ROUTINE CALLED TO CLEANLY SHUT DOWN THE KLNI
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,SHTKNI
;RETURNS:
; CPOPJ ALWAYS
SHTKNI: MOVX T1,PBSRUN ;IS KLNI CURRENTLY RUNNING?
TDNE T1,.PBSTS(Q3) ;...
PUSHJ P,DISKNI ;YES, MAKE KLNI ENTER DISABLED STATE
JFCL ;DON'T CARE IF ERROR
PJRST STPKNI ;STOP KLNI MICROCODE AND RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- STOP KLNI MICROCODE
;ROUTINE CALLED TO STOP THE KLNI
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,STPKNI
;RETURNS:
; CPOPJ ALWAYS
STPKNI: CONO KNI,CO.CPT ;NO, MAKE SURE THE KLNI IS STOPPED
STPKNX: PUSHJ P,SAVE2## ;SAVE P1-P2
MOVX T1,PBSRUN!PBSONL ;CLEAR KLNI RUN AND ONLINE FLAGS
ANDCAM T1,.PBSTS(Q3) ;...
AOS .PBKHC(Q3) ;UPDATE COUNT OF TIMES KLNI HALTED
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
MOVEM T1,.PBKHT(Q3) ;REMEMBER WHEN KLNI LAST HALTED
XMOVEI T1,.PBRSQ(Q3) ;GET ADDRESS OF RESPONSE QUEUE
PUSHJ P,FIXQUE ;FIX IT UP IF NEEDED
PUSHJ P,KNIRQA ;PROCESS THE RESPONSE QUEUE
XMOVEI T1,.PBCMQ(Q3) ;GET ADDRESS OF COMMAND QUEUE
PUSHJ P,FIXQUE ;FIX IT UP AS NEEDED
XMOVEI T1,.PBCMQ(Q3) ;GET ADDRESS OF COMMAND QUEUE
PUSHJ P,STPKNQ ;EMPTY THE QUEUE
PUSH P,Q2 ;SAVE Q2
MOVE P1,.PBLPT(Q3) ;GET LENGTH OF PTT TABLE
MOVE P2,.PBVPT(Q3) ;AND ADDRESS OF PTT TABLE
STPKN1: JUMPE P1,STPKN3 ;EXIT LOOP IF NO MORE ENTRIES
LDB T1,PTPENA ;GET PROTOCOL ENABLED BIT
JUMPE T1,STPKN2 ;IF NOT ENABLED, SKIP PROTOCOL FREE QUEUE
MOVE Q2,.PTPUB(P2) ;GET ADDRESS OF PROTOCOL USER BLOCK
XMOVEI T1,.PUFQH(Q2) ;GET ADDRESS OF PROTOCOL'S FREE QUEUE
PUSHJ P,FIXQUE ;FIX IT UP AS NEEDED
XMOVEI T1,.PUFQH(Q2) ;GET ADDRESS OF PROTOCOL'S FREE QUEUE
PUSHJ P,STPKNQ ;EMPTY THE QUEUE
STPKN2: ADDI P2,.PTLEN ;BUMP PTT TABLE POINTER TO NEXT ENTRY
SOJA P1,STPKN1 ;LOOP BACK TO PROCESS ENTIRE PTT TABLE
STPKN3: POP P,Q2 ;RESTORE Q2
MOVE T1,.PBEKB(Q3) ;GET ADDRESS OF KONTROLLER BLOCK
PJRST ETKOFL## ;INFORM ETHSER OF KONTROLLER OFFLINE AND RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- PROCESS KLNI QUEUE
;ROUTINE CALLED WHEN KLNI STOPPED TO PROCESS A KLNI QUEUE
;LINKAGE:
; T1/ ADDRESS OF QUEUE HEADER
; PUSHJ P,STPKNQ
;RETURNS:
; CPOPJ ALWAYS
STPKNQ: PUSHJ P,SAVE2## ;SAVE P1-P2
PUSHJ P,SAVQ## ;AND Q1-Q3
MOVE P2,T1 ;SAVE ADDRESS OF QUEUE HEADER
STPKQ1: MOVE T1,P2 ;GET ADDRESS OF QUEUE HEADER
PUSHJ P,REMQUE ;REMOVE NEXT ENTRY FROM QUEUE
POPJ P, ;QUEUE EMPTY, RETURN
XMOVEI Q1,-.CMQUE(T2) ;GET ADDRESS OF KLNI COMMAND BUFFER
LDB T1,CMPSTS ;GET COMMAND STATUS BYTE
IORX T1,CMSERR ;SET COMMAND ERROR FLAG
DPB T1,CMPSTS ;STORE BACK INTO COMMAND
MOVE T1,.CMCBA(Q1) ;GET CALLBACK ROUTINE ADDRESS
MOVE Q2,.CMPUB(Q1) ;GET ADDRESS OF PROTOCOL USER BLOCK
MOVE P1,.CMEAB(Q1) ;AND ADDRESS OF EA BLOCK
PUSHJ P,(T1) ;CALL CALLBACK ROUTINE
JFCL ;...
JRST STPKQ1 ;LOOP BACK TO EMPTY QUEUE
SUBTTL KLNI MAINTENANCE SERVICE -- START KLNI MICROCODE
;ROUTINE CALLED TO START THE KLNI MICROCODE
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,STAKNI
;RETURNS:
; CPOPJ IF COULDN'T START KLNI
; CPOPJ1 IF KLNI STARTED
STAKNI: AOS .PBKSC(Q3) ;UPDATE COUNT OF TIMES KLNI STARTED
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
MOVEM T1,.PBKST(Q3) ;REMEMBER WHEN KLNI LAST STARTED
MOVX T1,PBSDMP!PBSRLD ;CLEAR DUMP AND RELOAD REQUEST FLAGS
ANDCAM T1,.PBSTS(Q3) ;...
CONO KNI,CO.CPT ;RESET KLNI
MOVE T2,.PBLGO(Q3) ;GET ADDRESS OF RH20 LOGOUT AREA
MOVE T1,.PBPBA(Q3) ;GET PHYSICAL ADDRESS OF PCB
ADD T1,[FLD(.CCFTH,CC.OPC)!FLD(3,CC.WDC)!FLD(<.PBPBA-.PBPCB>,CC.ADR)]
; SET INITIAL CCW TO TRANSFER .PBPBA, .PBPIA,
; AND .PBRP0 TO THE KLNI
MOVEM T1,.CSICW(T2) ;STORE IN THE CHANNEL LOGOUT AREA
MOVE T1,.PBKSA(Q3) ;GET KLNI START ADDRESS
IORX T1,.DOLRA ;LOAD RAM ADDRESS REGISTER
DATAO KNI,T1 ;...
PUSHJ P,DISKNI ;START THE KLNI IN DISABLED STATE
PJRST STPKNI ;COULDN'T, STOP KLNI AND RETURN
MOVX T1,PBSRUN ;MARK KLNI AS RUNNING
IORM T1,.PBSTS(Q3) ;...
SKIPE T1,.PBVPT(Q3) ;PTT TABLE ALREADY ALLOCATED?
JRST STAKN1 ;YES, GO RECOMPUTE PHYSICAL ADDRESS
MOVEI T2,MAXPTT ;GET COUNT OF PTT ENTRIES SUPPORTED
MOVEM T2,.PBLPT(Q3) ;SAVE IN PORT CONTROL BLOCK
IMULI T2,.PTLEN ;CALCULATE LENGTH OF PTT TABLE
PUSHJ P,GETNWZ## ;ALLOCATE ZEROED CORE FOR TABLE
STOPCD STPKNI,DEBUG,KNICAP ;++CAN'T ALLOCATE PTT TABLE
MOVEM T1,.PBVPT(Q3) ;SAVE ADDRESS OF TABLE
STAKN1: MAP T1,(T1) ;CALCULATE PHYSICAL ADDRESS OF TABLE
TXZ T1,MP.NAD ;...
MOVEM T1,.PBPTT(Q3) ;AND SAVE FOR KLNI
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
SKIPE T1,.PBVMC(Q3) ;MCAT TABLE ALREADY ALLOCATED?
JRST STAKN2 ;YES, GO RECOMPUTE PHYSICAL ADDRESS
MOVEI T2,MAXMCT ;GET COUNT OF MCAT ENTRIES SUPPORTED
MOVEM T2,.PBLMC(Q3) ;SAVE IN PORT CONTROL BLOCK
IMULI T2,.MCLEN ;CALCULATE LENGTH OF MCAT TABLE
PUSHJ P,GETNWZ## ;ALLOCATE ZEROED CORE FOR TABLE
STOPCD STPKNI,DEBUG,KNICAM ;++CAN'T ALLOCATE MCAT TABLE
MOVEM T1,.PBVMC(Q3) ;SAVE ADDRESS OF TABLE
STAKN2: MAP T1,(T1) ;CALCULATE PHYSICAL ADDRESS OF TABLE
TXZ T1,MP.NAD ;...
MOVEM T1,.PBMCT(Q3) ;AND SAVE FOR KLNI
SKIPE T1,.PBVCD(Q3) ;COUNTERS BUFFER ALREADY ALLOCATED?
JRST STAKN3 ;YES, GO RECOMPUTE PHYSICAL ADDRESS
MOVEI T2,MAXKCB ;GET NUMBER OF COUNTERS SUPPORTED
MOVEM T2,.PBLCD(Q3) ;SAVE IN PORT CONTROL BLOCK
PUSHJ P,GETNWZ## ;ALLOCATE ZEROED CORE FOR TABLE
STOPCD STPKNI,DEBUG,KNICAD ;++CAN'T ALLOCATE COUNTERS DATA BUFFER
MOVEM T1,.PBVCD(Q3) ;SAVE ADDRESS OF TABLE
STAKN3: MAP T1,(T1) ;CALCULATE PHYSICAL ADDRESS OF TABLE
TXZ T1,MP.NAD ;...
MOVEM T1,.PBKCB(Q3) ;AND SAVE FOR KLNI
SKIPE T1,.PBVCT(Q3) ;KLNI COUNTERS AREA ALREADY ALLOCATED?
JRST STAKN4 ;YES, GO ENABLE KLNI AND RETURN
MOVE T2,.PBLCD(Q3) ;GET SIZE OF COUNTERS DATA BUFFER
PUSHJ P,GETNWZ## ;ALLOCATE ZEROED CORE FOR TABLE
STOPCD STPKNI,DEBUG,KNICAC ;++CAN'T ALLOCATE KLNI COUNTERS AREA
MOVEM T1,.PBVCT(Q3) ;SAVE ADDRESS OF TABLE
STAKN4: MOVE T2,.PBLGO(Q3) ;GET ADDRESS OF RH20 LOGOUT AREA
MOVE T1,.PBPBA(Q3) ;GET PHYSICAL ADDRESS OF PCB
ADD T1,[FLD(.CCJMP,CC.OPC)!FLD(<.PBCCW-.PBPCB>,CC.ADR)] ;GET A JUMP
; CCW FOR THE KLNI TO USE
MOVEM T1,.CSICW(T2) ;STORE IN THE CHANNEL LOGOUT AREA
PUSHJ P,ENAKNI ;PUT KLNI IN ENABLED STATE
PJRST STPKNI ;COULDN'T, STOP KLNI AND RETURN
PJRST CPOPJ1## ;SUCCESS, RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- DISABLE KLNI MICROCODE
;ROUTINE TO MAKE THE KLNI ENTER THE DISABLED STATE
;LINKAGE:
; PUSHJ P,DISKNI
;RETURNS:
; CPOPJ IF DIDN'T ENTER DISABLED STATE
; CPOPJ1 IF KLNI IN DISABLED STATE
DISKNI: MOVE T1,.PBPIA(Q3) ;GET KLNI PI ASSIGNMENT
CONO KNI,CO.DIS!CO.BTS(T1) ;ENTER DISABLED STATE
MOVEI T2,5000 ;LOOP COUNT
DISKN1: CONI KNI,T1 ;GET STATUS
TXNE T1,CI.DCP ;DISABLE COMPLETE?
AOSA (P) ;YES, SET FOR SKIP RETURN
SOJG T2,DISKN1 ;NO, WAIT A BIT
POPJ P, ;DIDN'T MAKE IT
SUBTTL KLNI MAINTENANCE SERVICE -- ENABLE KLNI MICROCODE
;ROUTINE TO MAKE THE KLNI ENTER THE ENABLED STATE
;LINKAGE:
; PUSHJ P,ENAKNI
;RETURNS:
; CPOPJ IF DIDN'T ENTER ENABLED STATE
; CPOPJ1 IF KLNI ENABLED
ENAKNI: MOVE T1,.PBPIA(Q3) ;GET KLNI PI ASSIGNMENT
CONO KNI,CO.ENA!CO.BTS(T1) ;GO FROM DISABLED TO ENABLED
MOVEI T2,5000 ;LOOP COUNT
ENAKN1: CONI KNI,T1 ;GET STATUS
TXNE T1,CI.ECP ;ENABLE COMPLETE?
AOSA (P) ;YES, SET FOR SKIP RETURN
SOJG T2,ENAKN1 ;NO, WAIT A BIT
POPJ P, ;DIDN'T MAKE IT
SUBTTL KLNI MAINTENANCE SERVICE -- INITIALIZE KLNI MICROCODE
;ROUTINE CALLED TO INITIALIZE KLNI MICROCODE
;LINKAGE:
; T1/ ADDRESS OF COMPLETION ROUTINE
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,INIKNI
;RETURNS:
; CPOPJ ALWAYS
INIKNI: PUSHJ P,SAVQ1## ;AND Q1
MOVEI T1,CMORSA ;READ NI STATION ADDRESS COMMAND FUNCTION
PUSHJ P,GETCMD ;GENERATE KLNI COMMAND BUFFER
PJRST INIKNX ;ERROR, GIVE COMPLETION NOW
XMOVEI T1,INIKN1 ;GET ADDRESS OF CALLBACK ROUTINE
PUSHJ P,KNICMD ;QUEUE READ NI STATION ADDRESS COMMAND
PJRST CPOPJ1## ;AND RETURN
INIKNX: PUSHJ P,SHTKNI ;SHUT DOWN KLNI
LDB T1,PBPRJB ;GET JOB NUMBER OF KNILDR
PJUMPE T1,CPOPJ## ;RETURN NOW IF NO JOB NUMBER
PJRST WAKJOB## ;WAKE UP RELOAD JOB AND RETURN
;HERE ON COMPLETION OF READ NI STATION ADDRESS COMMAND FUNCTION
;DURING INITIALIZATION OF KLNI MICROCODE
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; Q1/ ADDRESS OF KLNI COMMAND BUFFER
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,INIKN1
;RETURNS:
; CPOPJ ALWAYS
INIKN1: PUSHJ P,SAVQ1## ;AND Q1
LDB T1,CMPUCV ;GET KLNI MICROCODE VERSION
CAIGE T1,MINUVR&377 ;WITHIN REASON?
STOPCD INIKNX,INFO,KNIWUV ;++WRONG MICROCODE VERSION
MOVEM T1,.PBUVR(Q3) ;SAVE IN PORT CONTROL BLOCK
DMOVE T1,.CMNEA(Q1) ;GET HARDWARE ETHERNET ADDRESS
DMOVEM T1,.PBHEA(Q3) ;SAVE IN PORT CONTROL BLOCK
SKIPN .PBEAD(Q3) ;DO WE HAVE ANY CURRENT ETHERNET ADDRESS?
DMOVEM T1,.PBEAD(Q3) ;NO, USE THE HARDWARE ETHERNET ADDRESS
LDB T1,CMPLPT ;GET SIZE OF PTT TABLE
CAME T1,.PBLPT(Q3) ;SAME SIZE AS CURRENT PTT TABLE?
STOPCD INIKNX,DEBUG,KNIPWS ;++KLNI PTT TABLE IS WRONG SIZE
LDB T1,CMPLMC ;GET SIZE OF MCAT TABLE
CAME T1,.PBLMC(Q3) ;SAME SIZE AS CURRENT MCAT TABLE?
STOPCD INIKNX,DEBUG,KNIMWS ;++KLNI MCAT TABLE IS WRONG SIZE
REPEAT 0,< ;NEED KLNI MICROCODE CHANGE FOR THIS
LDB T1,CMPLCB ;GET SIZE OF COUNTERS BUFFER
CAME T1,.PBLCD(Q3) ;SAME SIZE AS CURRENT BUFFER?
STOPCD INIKNX,DEBUG,KNICWS ;++KLNI COUNTERS BUFFER IS WRONG SIZE
>; END REPEAT 0
PUSHJ P,GIVCMD ;RELEASE PREVIOUS KLNI COMMAND
MOVEI T1,CMOWSA ;WRITE NI STATION ADDRESS COMMAND FUNCTION
PUSHJ P,GETCMD ;GENERATE KLNI COMMAND BUFFER
PJRST INIKNX ;ERROR, GIVE CALLBACK NOW
DMOVE T1,.PBEAD(Q3) ;GET CURRENT ETHERNET ADDRESS
DMOVEM T1,.CMNEA(Q1) ;SET IN KLNI COMMAND BUFFER
LDB T1,PBPPRM ;GET PROMISCUOUS RECEIVER FLAG
DPB T1,CMPPRM ;SET AS APPROPRIATE IN COMMAND
LDB T1,PBPPMM ;GET PROMISCUOUS MULTI-CAST FLAG
DPB T1,CMPAAM ;SET AS APPROPRIATE IN COMMAND
XMOVEI T1,INIKN2 ;GET ADDRESS OF CALLBACK ROUTINE
PJRST KNICMD ;QUEUE WRITE NI STATION ADDRESS AND RETURN
;HERE ON COMPLETION OF WRITE NI STATION ADDRESS COMMAND FUNCTION
;DURING INITIALIZATION OF KLNI MICROCODE
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; Q1/ ADDRESS OF KLNI COMMAND BUFFER
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,INIKN2
;RETURNS:
; CPOPJ ALWAYS
INIKN2: PUSHJ P,GIVCMD ;RELEASE COMMAND BUFFER
MOVEI T1,CMOLDP ;LOAD PTT TABLE COMMAND FUNCTION
PUSHJ P,GETCMD ;GENERATE KLNI COMMAND BUFFER
PJRST INIKNX ;ERROR, GIVE CALLBACK NOW
MOVE T1,.PBVPT(Q3) ;GET VIRTUAL ADDRESS OF PTT
MAP T1,0(T1) ;CALCULATE PHYSICAL ADDRESS OF PTT
TXZ T1,MP.NAD ;...
MOVEM T1,.PBPTT(Q3) ;SAVE IN PORT CONTROL BLOCK
XMOVEI T1,INIKN3 ;GET ADDRESS OF CALLBACK ROUTINE
PJRST KNICMD ;QUEUE LOAD PTT TABLE COMMAND AND RETURN
;HERE ON COMPLETION OF LOAD PTT TABLE COMMAND FUNCTION
;DURING INITIALIZATION OF KLNI MICROCODE
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; Q1/ ADDRESS OF KLNI COMMAND BUFFER
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,INIKN3
;RETURNS:
; CPOPJ ALWAYS
INIKN3: PUSHJ P,GIVCMD ;RELEASE COMMAND BUFFER
MOVEI T1,CMOLDM ;LOAD MCAT TABLE COMMAND FUNCTION
PUSHJ P,GETCMD ;GENERATE KLNI COMMAND BUFFER
PJRST INIKNX ;ERROR, GIVE CALLBACK NOW
MOVE T1,.PBVMC(Q3) ;GET VIRTUAL ADDRESS OF MCAT
MAP T1,0(T1) ;CALCULATE PHYSICAL ADDRESS OF MCAT
TXZ T1,MP.NAD ;...
MOVEM T1,.PBMCT(Q3) ;SAVE IN PORT CONTROL BLOCK
XMOVEI T1,INIKN4 ;GET ADDRESS OF CALLBACK ROUTINE
PJRST KNICMD ;QUEUE LOAD MCAT TABLE COMMAND AND RETURN
;HERE ON COMPLETION OF LOAD MCAT TABLE COMMAND FUNCTION
;DURING INITIALIZATION OF KLNI MICROCODE
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; Q1/ ADDRESS OF KLNI COMMAND BUFFER
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,INIKN4
;RETURNS:
; CPOPJ ALWAYS
INIKN4: PUSHJ P,GIVCMD ;RELEASE COMMAND BUFFER
MOVEI T1,CMORCC ;READ AND CLEAR COUNTERS COMMAND FUNCTION
PUSHJ P,GETCMD ;GENERATE KLNI COMMAND BUFFER
PJRST INIKNX ;ERROR, GIVE CALLBACK NOW
MOVE T1,.PBVCD(Q3) ;GET VIRTUAL ADDRESS OF COUNTERS BUFFER
MAP T1,0(T1) ;CALCULATE PHYSICAL ADDRESS OF BUFFER
TXZ T1,MP.NAD ;...
MOVEM T1,.PBKCB(Q3) ;SAVE IN PORT CONTROL BLOCK
LDB T1,CMPFLG ;GET CURRENT FLAGS
IORX T1,CMFCLR ;SET CLEAR COUNTERS FLAG
DPB T1,CMPFLG ;...
XMOVEI T1,INIKN5 ;GET ADDRESS OF CALLBACK ROUTINE
PJRST KNICMD ;QUEUE READ AND CLEAR COUNTERS AND RETURN
;HERE ON COMPLETION OF READ AND CLEAR COUNTERS COMMAND FUNCTION
;DURING INITIALIZATION OF KLNI MICROCODE
;LINKAGE: (CALLED AT INTERRUPT LEVEL)
; Q1/ ADDRESS OF KLNI COMMAND BUFFER
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,INIKN5
;RETURNS:
; CPOPJ ALWAYS
INIKN5: PUSHJ P,GIVCMD ;RELEASE COMMAND BUFFER
MOVE T1,.PBLCD(Q3) ;GET LENGTH OF COUNTERS BUFFER
SUBI T1,1 ;ADJUST FOR XBLT TO ZERO COUNTERS
MOVE T2,.PBVCD(Q3) ;GET ADDRESS OF COUNTERS BUFFER
XMOVEI T3,1(T2) ;AND ADDRESS+1 OF COUNTERS BUFFER
SETZM (T2) ;ZERO FIRST WORD OF BUFFER
EXTEND T1,[XBLT] ;ZERO REMAINDER OF COUNTERS BUFFER
MOVX T1,PBSONL ;MARK KLNI AS ONLINE
IORM T1,.PBSTS(Q3) ;...
LDB T1,PBPRJB ;GET JOB NUMBER OF RELOAD JOB
SKIPE T1 ;JOB NUMBER SET?
PUSHJ P,WAKJOB## ;YES, WAKE IT UP
MOVE T1,.PBEKB(Q3) ;GET ADDRESS OF ETHSER'S KONTROLLER BLOCK
DMOVE T2,.PBHEA(Q3) ;GET HARDWARE ETHERNET ADDRESS
PJRST ETKONL## ;INFORM ETHSER OF KONTROLLER ONLINE AND RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- READ LATCHED ADDRESS REGISTER
;ROUTINE CALLED TO READ CONTENTS OF LATCHED ADDRESS REGISTER
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,REDLAR
;RETURNS:
; CPOPJ ON ERROR
; CPOPJ1 ON SUCCESS WITH:
; T1/ CRAM ADDRESS
REDLAR: MOVX T4,PBSRUN ;IS KLNI RUNNING?
TDNE T4,.PBSTS(Q3) ;...
POPJ P, ;YES, ERROR
CONO KNI,CO.LAR ;SET LATCHED ADDRESS REGISTER FLAG
DATAI KNI,T1 ;READ CONTENTS OF REGISTER
LDB T1,[POINTR (T1,DT.LAR)] ;GET CORRECT FIELD
CONO KNI,0 ;MAKE SURE CO.LAR IS CLEAR
PJRST CPOPJ1## ;RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- READ CRAM CONTENTS
;ROUTINE CALLED TO READ THE CONTENTS OF A CRAM LOCATION
;LINKAGE:
; T1/ CRAM ADDRESS
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,REDKNI
;RETURNS:
; CPOPJ ON ERROR
; CPOPJ1 ON SUCCESS WITH:
; T2-T3/ CRAM CONTENTS
REDKNI: MOVX T4,PBSRUN ;IS KLNI RUNNING?
TDNE T4,.PBSTS(Q3) ;...
POPJ P, ;YES, ERROR
CONO KNI,0 ;MAKE SURE CO.LAR IS CLEAR
DPB T1,[POINTR (T1,DO.RAR)] ;PUT ADDRESS INTO CORRECT FIELD
ANDX T1,DO.RAR ;...
IORX T1,.DOLRA!DO.LHW ;SET UP TO READ LEFT HALF CRAM MICRO-WORD
DATAO KNI,T1 ;...
DATAI KNI,T2 ;READ LEFT HALF CRAM MICRO-WORD
ANDX T2,DT.CRM ;MASK OUT EXTRANEOUS BITS
TXZ T1,DO.LHW ;SET UP TO READ RIGHT HALF CRAM MICRO-WORD
DATAO KNI,T1 ;...
DATAI KNI,T3 ;READ LEFT HALF CRAM MICRO-WORD
ANDX T3,DT.CRM ;MASK OUT EXTRANEOUS BITS
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- WRITE CRAM CONTENTS
;ROUTINE CALLED TO WRITE THE CONTENTS OF A CRAM LOCATION
;LINKAGE:
; T1/ CRAM ADDRESS
; T2-T3/ CRAM CONTENTS
; Q3/ ADDRESS OF PORT CONTROL BLOCK
;RETURNS:
; CPOPJ ON ERROR
; CPOPJ1 ON SUCCESS
WRTKNI: MOVX T4,PBSRUN ;IS KLNI RUNNING?
TDNE T4,.PBSTS(Q3) ;...
POPJ P, ;YES, ERROR
CONO KNI,0 ;MAKE SURE CO.LAR IS CLEAR
DPB T1,[POINTR (T1,DO.RAR)] ;PUT ADDRESS INTO CORRECT FIELD
ANDX T1,DO.RAR ;...
IORX T1,.DOLRA!DO.LHW ;SET UP TO WRITE LEFT HALF CRAM MICRO-WORD
DATAO KNI,T1 ;...
ANDX T2,DT.CRM ;MASK OUT EXTRANEOUS BITS
DATAO KNI,T2 ;WRITE LEFT HALF CRAM MICRO-WORD
TXZ T1,DO.LHW ;SET UP TO WRITE RIGHT HALF CRAM MICRO-WORD
DATAO KNI,T1 ;...
ANDX T3,DT.CRM ;MASK OUT EXTRANEOUS BITS
DATAO KNI,T3 ;WRITE LEFT HALF CRAM MICRO-WORD
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- REQUEST MICROCODE DUMP/LOAD
;ROUTINE TO REQUEST THE DUMP/LOAD OF KLNI MICROCODE
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,RLDKNI
;RETURNS:
; CPOPJ ALWAYS
DMPKNI: SKIPA T1,[PBSDMP!PBSRLD] ;GET DUMP AND RELOAD REQUEST FLAGS
LODKNI: MOVX T1,PBSRLD ;GET RELOAD REQUEST FLAG
JRST RLDKN1 ;AND CONTINUE
RLDKND: SKIPA T1,[PBSDMP!PBSRLD] ;GET DUMP AND RELOAD REQUEST FLAGS
RLDKNI: MOVX T1,PBSRLD ;GET RELOAD REQUEST FLAG
MOVE T2,.PBSTS(Q3) ;GET KLNI STATUS WORD
TXNE T2,PBSMAI ;IS KLNI IN MAINTENANCE MODE?
POPJ P, ;YES, RETURN NOW
TXNE T2,PBSADD ;IS AUTO DUMP DISABLED?
TXZ T1,PBSDMP ;YES, CLEAR DUMP REQUEST FLAG
TXNE T2,PBSARD ;IS AUTO RELOAD DISABLED?
TXZ T1,PBSDMP!PBSRLD ;YES, CLEAR DUMP AND RELOAD REQUEST FLAGS
RLDKN1: IORM T1,.PBSTS(Q3) ;SET DUMP/RELOAD REQUEST FLAG(S)
AOS .PBKLC(Q3) ;UPDATE COUNT OF TIMES DUMP/RELOAD REQUESTED
MOVE T1,SYSUPT## ;GET SYSTEM UPTIME
MOVEM T1,.PBKLT(Q3) ;REMEMBER WHEN DUMP/RELOAD REQUESTED
SETZ T1, ;CLEAR ANY RELOAD JOB
DPB T1,PBPRJB ;...
MOVX T1,PBSDMP ;DUMP REQUESTED?
TDNE T1,.PBSTS(Q3) ;...
PJRST KNQLDR ;YES, QUEUE REQUEST FOR KNILDR
XMOVEI T1,.PBULB(Q3) ;GET ADDRESS OF MICROCODE LOADER BLOCK
PUSHJ P,BTUCOD## ;LOCATE KLNI MICROCODE
PJRST KNQLDR ;NONE AVAILABLE, QUEUE REQUEST FOR KNILDR
PJRST KNILOD ;LOAD KLNI MICROCODE AND RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- LOAD MICROCODE
;ROUTINE TO LOAD KLNI MICROCODE
;LINKAGE:
; Q3/ ADDRESS OF PORT CONTROL BLOCK
; PUSHJ P,KNILOD
;RETURNS:
; CPOPJ ALWAYS
KNILOD: MOVX T1,PBSQRR ;CLEAR QUEUED RELOAD REQUEST FLAG
ANDCAM T1,.PBSTS(Q3) ;...
SKIPL T2,DINITF## ;BIT MAPPED CORE ALLOCATED?
LDB T2,PBPCPU ;GET CPU NUMBER OF KLNI
CAMN T2,.CPCPN## ;KLNI ON OUR CPU?
PJRST KNILO1 ;YES, GO SERVICE RELOAD REQUEST
IORM T1,.PBSTS(Q3) ;SET QUEUED RELOAD REQUEST FLAG
POPJ P, ;AND RETURN
KNILO1: PUSHJ P,SAVE4## ;SAVE P1-P4
XMOVEI P1,.PBULB(Q3) ;POINT TO MICROCODE LOADER BLOCK
SETZ P2, ;CRAM ADDR
MOVSI P3,(<POINT 12,,>!1B12) ;MAKE A TWO WORD BYTE POINTER
MOVE P4,.ULADR(P1) ;30-BIT ADDRESS IN SECOND WORD
PUSHJ P,SHTKNI ;SHUTDOWN KLNI
KNILO2: MOVEI T1,5 ;5 BYTES PER CRAM MICROWORD
SETZB T2,T3 ;START WITH EMPTY WORDS
KNILO3: ILDB T4,P3 ;GET A BYTE
LSHC T2,^D12 ;APPEND IT TO THE WORD
ADD T3,T4 ;...
SOJN T1,KNILO3 ;LOOP BACK FOR ALL 5 BYTES
MOVE T1,P2 ;GET CRAM ADDRESS
LSHC T2,6 ;SEPERATE CRAM HALFWORDS
LSH T3,-6 ;...
PUSHJ P,WRTKNI ;WRITE THIS WORD INTO KLNI CRAM
JRST KNILOX ;ERROR
CAIE P2,MAXCRA ;AT END OF KLNI CRAM?
AOJA P2,KNILO2 ;NO, LOOP BACK FOR ENTIRE CRAM
MOVX T1,UCODSA ;GET MICROCODE START ADDRESS
MOVEM T1,.PBKSA(Q3) ;SAVE IN KLNI PCB
PUSHJ P,STAKNI ;START THE MICROCODE
JRST KNILOX ;ERROR STARTING MICROCODE
PUSHJ P,INIKNI ;BEGIN INITIALIZATION OF KLNI
JRST KNILOX ;ERROR INITIALIZING KLNI
MOVE T1,P1 ;POINT TO ULB
PJRST BTURPT## ;GO REPORT A SUCCESSFUL LOAD
KNILOX: POPJ P,
SUBTTL KLNI MAINTENANCE SERVICE -- REQUEST KNILDR
;ROUTINE CALLED TO QUEUE REQUEST FOR KNILDR
;LINKAGE:
; PUSHJ P,KNQLDR
;RETURNS:
; CPOPJ ALWAYS
KNQLDR: MOVX T1,DF.RQN ;REQUEST KNILDR NEXT CLOCK TICK
IORM T1,DEBUGF## ;...
POPJ P, ;RETURN
;ROUTINE CALLED AT CLOCK LEVEL TO INITIATE RUN OF KNILDR
;LINKAGE:
; PUSHJ P,KNILDR
;RETURNS:
; CPOPJ ALWAYS
KNILDR::PUSHJ P,FRCSET## ;SET UP TO TYPE ON FRCLIN
PUSHJ P,INLMES## ;RUN KNILDR
ASCIZ /KNILDR/
PJRST PCRLF## ;END LINE AND RETURN
SUBTTL QUEUE MANIPULATION -- INITIALIZE QUEUE HEADER
;ROUTINE TO INITIALIZE A QUEUE HEADER
;LINKAGE:
; T1/ ADDRESS OF QUEUE HEADER
; PUSHJ P,INIQUE
;RETURNS:
; CPOPJ ALWAYS
INIQUE: SETOM .QHIWD(T1) ;RESET QUEUE INTERLOCK WORD
MAP T2,.QHFLI(T1) ;GET PHYSICAL ADDRESS OF FLINK
TXZ T2,MP.NAD ;...
MOVEM T2,.QHFLI(T1) ;MAKE FLINK POINT TO ITSELF
MOVEM T2,.QHBLI(T1) ;AND BLINK POINT TO FLINK
SETZM .QHELN(T1) ;CLEAR QUEUE ENTRY LENGTH
POPJ P, ;AND RETURN
SUBTTL QUEUE MANIPULATION -- FIX A QUEUE
;ROUTINE CALLED ON AN ERROR STOP TO FIX A QUEUE (IF POSSIBLE)
;LINKAGE:
; T1/ ADDRESS OF QUEUE HEADER
; PUSHJ P,FIXQUE
;RETURNS:
; CPOPJ ALWAYS
FIXQUE: POPJ P,
SUBTTL QUEUE MANIPULATION -- REMOVE AN ENTRY FROM QUEUE
;ROUTINE TO REMOVE FIRST QUEUE ENTRY FROM A QUEUE
;LINKAGE:
; T1/ ADDRESS OF QUEUE HEADER
; PUSHJ P,REMQUE
;RETURNS:
; CPOPJ IF QUEUE WAS EMPTY
; CPOPJ1 IF SUCCESS WITH:
; T2/ ADDRESS OF QUEUE ENTRY
REMQUE: SYSPIF ;NO INTERRUPTS
SETZ T3, ;INITIALIZE TIMEOUT COUNTER
REMQU1: SKIPGE .QHIWD(T1) ;SKIP IF INTERLOCK NOT AVAILABLE
AOSE .QHIWD(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 .PBCIB(Q3) ;INCREMENT COUNT OF BROKEN INTERLOCKS
STOPCD .+1,INFO,KNIRIT ;++REMQUE INTERLOCK TIMEOUT
REMQU2: MAP T3,.QHFLI(T1) ;GET PHYSICAL ADDRESS OF QUEUE HEADER
TXZ T3,MP.NAD ;...
CAMN T3,.QHFLI(T1) ;IS QUEUE EMPTY?
JRST REMQU3 ;YES, RETURN
MOVE T2,.QHFLI(T1) ;GET PHYSICAL ADDRESS OF FIRST QUEUE ENTRY
ADDI T2,.QEVAD ;GET VIRTUAL ADDRESS OF FIRST QUEUE ENTRY
PUSHJ P,PHMOV## ;...
PUSH P,T2 ;SAVE ADDRESS OF QUEUE ENTRY
MOVE T2,.QEFLI(T2) ;GET ADDRESS OF NEXT QUEUE ENTRY
MOVEM T2,.QHFLI(T1) ;STORE AS NEW FIRST ENTRY IN QUEUE
ADDI T2,.QEBLI ;POINT NEW FIRST ENTRY BACK AT QUEUE HEADER
PUSHJ P,PHMOVM## ;...
POP P,T2 ;GET BACK ADDRESS OF QUEUE ENTRY
AOS (P) ;SET FOR SKIP RETURN
REMQU3: SETOM .QHIWD(T1) ;RELEASE QUEUE INTERLOCK
SYSPIN ;ALLOW INTERRUPTS AGAIN
POPJ P, ;AND RETURN
SUBTTL QUEUE MANIPULATION -- INSERT AN ENTRY INTO QUEUE
;ROUTINE TO INSERT A QUEUE ENTRY ONTO A QUEUE
;LINKAGE:
; T1/ ADDRESS OF QUEUE HEADER
; T2/ ADDRESS OF QUEUE ENTRY
; PUSHJ P,PUTQUE
;RETURNS:
; CPOPJ ALWAYS
PUTQUE: SYSPIF ;NO INTERRUPTS
SETZ T3, ;INITIALIZE TIMEOUT COUNTER
PUTQU1: SKIPGE .QHIWD(T1) ;SKIP IF INTERLOCK NOT AVAILABLE
AOSE .QHIWD(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 .PBCIB(Q3) ;INCREMENT COUNT OF BROKEN INTERLOCKS
STOPCD .+1,INFO,KNIPIT ;++PUTQUE INTERLOCK TIMEOUT
PUTQU2: MOVEM T2,.QEVAD(T2) ;SAVE VIRTUAL ADDRESS IN QUEUE ENTRY
MAP T3,.QEFLI(T2) ;GET PHYSICAL ADDRESS OF NEW QUEUE ENTRY
TXZ T3,MP.NAD ;...
PUSH P,T2 ;SAVE ADDRESS OF QUEUE ENTRY
MOVE T2,.QHBLI(T1) ;GET PHYSICAL ADDRESS OF LAST QUEUE ENTRY
ADDI T2,.QEFLI ;POINT IT AT NEW ENTRY
PUSHJ P,PHMOVM## ;...
POP P,T2 ;GET BACK ADDRESS OF QUEUE ENTRY
EXCH T3,.QHBLI(T1) ;SET NEW LAST ENTRY ADDRESS, GET PREVIOUS
MOVEM T3,.QEBLI(T2) ;POINT LAST ENTRY BACK TO PREVIOUS ENTRY
MAP T3,.QHFLI(T1) ;GET PHYSICAL ADDRESS OF QUEUE HEADER
TXZ T3,MP.NAD ;...
MOVEM T3,.QEFLI(T2) ;POINT NEW LAST ENTRY AT QUEUE HEADER
PUTQU3: SETOM .QHIWD(T1) ;RELEASE QUEUE INTERLOCK
SYSPIN ;ALLOW INTERRUPTS AGAIN
POPJ P, ;AND RETURN
SUBTTL BYTE POINTERS
;BYTE POINTERS FOR PORT CONTROL BLOCK
PBPCPU: POINTR (.PBSTS(Q3),PBSCPU) ;CPU NUMBER OF KLNI
PBPMAI: POINTR (.PBSTS(Q3),PBSMAI) ;KLNI IS IN MAINTENANCE MODE
PBPPRM: POINTR (.PBSTS(Q3),PBSPRM) ;KLNI IS IN PROMISCUOUS RECEIVER MODE
PBPPMM: POINTR (.PBSTS(Q3),PBSPMM) ;KLNI IS IN PROMISCUOUS MULTI-CAST MODE
PBPARD: POINTR (.PBSTS(Q3),PBSARD) ;KLNI AUTO-RELOAD DISABLED
PBPMJB: POINTR (.PBSTS(Q3),PBSMJB) ;JOB NUMBER OF MAINTENANCE JOB
PBPRJB: POINTR (.PBSTS(Q3),PBSRJB) ;JOB NUMBER OF KNILDR
;BYTE POINTERS FOR PROTOCOL USER BLOCK
PUPPAD: POINTR (.PUSTS(Q2),PUSPAD) ;PROTOCOL USES PADDING
PUPPTT: POINTR (.PUSTS(Q2),PUSPTT) ;PTT TABLE INDEX OF THIS PROTOCOL
;BYTE POINTERS FOR PTT AND MCAT TABLES
PTPENA: POINTR (.PTPTY(P2),PTTENA) ;PROTOCOL ENABLED FLAG
PTPPTY: POINTR (.PTPTY(P2),PTTPTY) ;PROTOCOL TYPE CODE
MCPENA: POINTR (.MCLAD(P2),MCTENA) ;MULTI-CAST ADDRESS ENABLED FLAG
;BYTE POINTERS FOR KLNI COMMAND BUFFERS
CMPSTS: POINTR (.CMCSW(Q1),CMCSTS) ;COMMAND STATUS
CMPFLG: POINTR (.CMCSW(Q1),CMCFLG) ;COMMAND FLAGS
CMPCMD: POINTR (.CMCSW(Q1),CMCCMD) ;COMMAND OPCODE
CMPTDR: POINTR (.CMCSW(Q1),CMCTDR) ;TIME DOMAIN REFLECTOMETRY VALUE
CMPXDL: POINTR (.CMXDL(Q1),CMXXDL) ;TRANSMIT DATAGRAM LENGTH
CMPXPT: POINTR (.CMXPT(Q1),CMXXPT) ;TRANSMIT DATAGRAM PROTOCOL TYPE
CMPRDL: POINTR (.CMRDL(Q1),CMRRDL) ;RECEIVE DATAGRAM LENGTH
CMPRPT: POINTR (.CMRPT(Q1),CMRRPT) ;RECEIVE DATAGRAM PROTOCOL TYPE
CMPACE: POINTR (.CMNSM(Q1),CMMACE) ;ACCEPT PACKETS WITH CRC ERRORS
CMPAAM: POINTR (.CMNSM(Q1),CMMAAM) ;ACCEPT ALL MULTI-CAST PACKETS
CMPH4K: POINTR (.CMNSM(Q1),CMMH4K) ;H400 MODE TRANSCEIVER
CMPPRM: POINTR (.CMNSM(Q1),CMMPRM) ;PROMISCUOUS MODE
CMPUCV: POINTR (.CMNSW(Q1),CMWUCV) ;KLNI MICROCODE VERSION
CMPLMC: POINTR (.CMNSW(Q1),CMWLMC) ;LENGTH OF MCAT TABLE
CMPLPT: POINTR (.CMNSW(Q1),CMWLPT) ;LENGTH OF PTT TABLE
CMPERC: POINTR (.CMNSW(Q1),CMWERC) ;ERROR RETRY COUNT
;BYTE POINTERS FOR BUFFER SEGMENT DESCRIPTORS
BSPSBA: POINTR (.BSSBA(P4),BSASBA) ;SEGMENT BASE ADDRESS
BSPNXT: POINTR (.BSNXT(P4),BSNNXT) ;ADDRESS OF NEXT BSD
BSPSGL: POINTR (.BSSGL(P4),BSSSGL) ;SEGMENT LENGTH
SUBTTL PROTOTYPE MICROCODE PARAMETER BLOCK
;PROTOTYPE MICROCODE PARAMETER BLOCK
KNIULB: EXP .BTKNI## ;MICROCODE INDEX
XWD KNI,-1 ;DEVICE CODE,,UNIT NUMBER
SIXBIT /KLNI/ ;INTERFACE NAME
SIXBIT /NIA20/ ;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
CONI 0,T2 ;CONI
CONO 0,(T2) ;CONO
DATAI 0,T2 ;DATAI
DATAO 0,T2 ;DATAO
SUBTTL THE END
KNILIT:!XLIST ;LITERALS
LIT
LIST
KNIEND:!END