Trailing-Edge
-
PDP-10 Archives
-
BB-BT99T-BB_1990
-
10,7/mon/kniser.mac
There are 8 other files named kniser.mac in the archive. Click here to see a list.
TITLE KNISER - KLNI DEVICE DRIVER V120
SUBTTL WILLIAM C. DAVENPORT/WXD 17-APR-90
SEARCH F,S,DEVPRM,ETHPRM,MACSYM
T20SYM
$RELOC
$HIGH
;THIS MODULE IMPLEMENTS THE KLNI INTERFACE DRIVER FOR ETHERNET
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1985,1986,1988,1990.
;ALL RIGHTS RESERVED.
.CPYRT<1985,1990>
XP VKNISR,120 ;KNISER VERSION NUMBER
IFNDEF FTKNILDR,<FTKNILDR==0> ;-1 TO SUPPORT OLD KNILDR & KNIBT. UUO
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 HARDWARE DEFINITIONS -- MICROCODE VALUES
;MICROCODE ADDRESSES
UCODSA==0 ;MICROCODE STARTING ADDRESS
UCODVR==137 ;MICROCODE VERSION ADDRESS
;MICROCODE VERSION RESTRICTIONS
MINUVR==100,,167 ;MINIMUM ALLOWABLE MICROCODE VERSION
;MICROCODE TABLE SIZES
MAXPTT==17 ;SIZE OF PTT TABLE
MAXMCT==17 ;SIZE OF MCAT TABLE
MAXKCB==54 ;SIZE OF COUNTERS DATA BUFFER
SUBTTL KLNI HARDWARE DEFINITIONS -- QUEUE BLOCKS
;QUEUE HEADER BLOCK
PHASE 0 ;THESE ARE OFFSETS
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.QHIWD:! BLOCK 1 ;INTERLOCK WORD
.QHFLI:! BLOCK 1 ;FORWARD LINK WORD (FLINK)
.QHBLI:! BLOCK 1 ;BACKWARD LINK WORD (BLINK)
.QHELN:! BLOCK 1 ;QUEUE ENTRY LENGTH
.QHLEN:! ;LENGTH OF QUEUE HEADER
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
DEPHASE
;QUEUE ENTRY BLOCK
PHASE 0 ;THESE ARE OFFSETS
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.QEFLI:! BLOCK 1 ;FORWARD LINK WORD (FLINK)
.QEBLI:! BLOCK 1 ;BACKWARD LINK WORD (BLINK)
.QERS0:! BLOCK 1 ;RESERVED FOR SOFTWARE
.QELEN:! ;LENGTH OF QUEUE ENTRY HEADER
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
.QEVAD==.QERS0 ;VIRTUAL ADDRESS OF QUEUE ENTRY
DEPHASE
SUBTTL KLNI HARDWARE DEFINITIONS -- BUFFER SEGMENT DESCRIPTOR BLOCK
;A BUFFER SEGMENT DESCRIPTOR DESCRIBES A PHYSICALLY CONTIGUOUS
;SECTION OF MEMORY. SEVERAL BUFFER SEGMENT DESCRIPTORS MAY BE
;LINKED TOGETHER TO DESCRIBE A BUFFER BEING SENT OR RECEIVED.
PHASE 0 ;THESE ARE OFFSETS
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.BSSBA:! BLOCK 1 ;PHYSICAL BASE ADDRESS OF SEGMENT
BSASBA==000077,,777777 ;SEGMENT BASE ADDRESS
.BSNXT:! BLOCK 1 ;PHYSICAL ADDRESS OF NEXT BSD
BSNNXT==000077,,777777 ;ADDRESS OF NEXT BSD
.BSSGL:! BLOCK 1 ;BUFFER SEGMENT LENGTH
BSSSGL==000000,,177777 ;SEGMENT LENGTH
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
.BSVNB:! BLOCK 1 ;VIRTUAL ADDRESS OF NEXT BSD
.BSRWB:! BLOCK 1 ;RE-ALIGNED WORD BYTE OFFSET
.BSRWA:! BLOCK 1 ;RE-ALIGNED WORD ADDRESS
.BSRWD:! BLOCK 1 ;RE-ALIGNED WORD DATA
.BSLEN:! ;LENGTH OF BSD
DEPHASE
SUBTTL KLNI HARDWARE DEFINITIONS -- COMMAND BLOCK
;KLNI COMMAND BLOCK
PHASE 0 ;THESE ARE OFFSETS
.CMPUB:! BLOCK 1 ;ADDRESS OF PROTOCOL USER BLOCK
.CMCBA:! BLOCK 1 ;CALLBACK ROUTINE ADDRESS
.CMEAB:! BLOCK 1 ;ADDRESS OF EA BLOCK
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.CMCMD:! ;START OF KLNI COMMAND
.CMQUE:! BLOCK .QELEN ;QUEUE ENTRY WORDS
.CMCSW:! BLOCK 1 ;KLNI COMMAND STATUS WORD
CMCSTS==776000,,000000 ;COMMAND STATUS
CMSSND==100 ;SEND DATAGRAM FLAG
CMSETY==076 ;ERROR TYPE
CMEEXC==00 ;EXCESSIVE COLLISIONS
CMECCF==01 ;CARRIER CHECK FAILED
CMECDF==02 ;COLLISION DETECT FAILED
CMESHT==03 ;SHORT CIRCUIT
CMEOPN==04 ;OPEN CIRCUIT
CMEFTL==05 ;FRAME TOO LONG
CMERFD==06 ;REMOTE FAILURE TO DEFER
CMEBCE==07 ;BLOCK CHECK ERROR
CMEFRE==10 ;FRAMING ERROR
CMEDOV==11 ;DATA OVERRUN
CMEUPT==12 ;UNRECOGNIZED PROTOCOL TYPE
CMEFTS==13 ;FRAME TOO SHORT
CMESCE==27 ;SPURIOUS CHANNEL ERROR
CMEWNZ==30 ;CHANNEL WORD COUNT NOT ZERO
CMEQLV==31 ;QUEUE LENGTH VIOLATION
CMEIPF==32 ;ILLEGAL PLI FUNCTION
CMEUCM==33 ;UNRECOGNIZED COMMAND
CMEBLV==34 ;BUFFER LENGTH VIOLATION
CMEXBP==36 ;TRANSMIT BUFFER PARITY ERROR
CMEINT==37 ;INTERNAL ERROR
CMSERR==001 ;ERROR FLAG
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
CMCFLG==001774,,000000 ;COMMAND FLAGS
CMFCRC==100 ;INTERNALLY GENERATED CRC
CMFPAD==040 ;PAD DATAGRAM
CMFBSD==010 ;BSD STYLE BUFFERS
CMFCLR==002 ;CLEAR COUNTERS AFTER READ
CMFRSP==001 ;COMMAND RESPONSE REQUIRED
CMCCMD==000003,,770000 ;COMMAND OPCODE
CMOXDG==1 ;SEND DATAGRAM
CMOLDM==2 ;LOAD MCAT TABLE
CMOLDP==3 ;LOAD PTT TABLE
CMORCC==4 ;READ AND CLEAR COUNTERS
CMORDG==5 ;RECEIVE DATAGRAM
CMOWPL==6 ;WRITE PLI
CMORPL==7 ;READ PLI
CMORSA==10 ;READ NI STATION ADDRESS
CMOWSA==11 ;WRITE NI STATION ADDRESS
CMOMAX==CMOWSA ;MAXIMUM DEFINED COMMAND OPCODE
CMCTDR==000000,,001777 ;TIME DOMAIN REFLECTOMETRY VALUE ON ERROR
.CMHLN:! ;LENGTH OF COMMON COMMAND HEADER
.CMLNX==. ;CALCULATE LENGTH OF COMMAND BLOCK
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
DEPHASE
;SNDDG (1) - SEND DATAGRAM COMMAND
PHASE .CMHLN ;FOLLOWING FIXED COMMAND HEADER
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.CMXDL:! BLOCK 1 ;LENGTH OF TEXT DATA
CMXXDL==000000,,177777 ;TRANSMIT DATAGRAM LENGTH
.CMXPT:! BLOCK 1 ;PROTOCOL TYPE CODE
CMXXPT==000003,,777760 ;TRANSMIT PROTOCOL TYPE
.CMXFQ:! BLOCK 1 ;PHYSICAL ADDRESS OF FREE QUEUE HEADER
.CMXDA:! BLOCK 2 ;DESTINATION ETHERNET ADDRESS
.CMXBA:! BLOCK 1 ;PHYSICAL ADDRESS OF BSD CHAIN
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
.CMXVB:! BLOCK 1 ;VIRTUAL ADDRESS OF BSD CHAIN
IFG <.-.CMLNX>,<.CMLNX==.> ;COMPUTE MAXIMUM LENGTH OF COMMAND BLOCK
DEPHASE
;DGRCV (5) - DATAGRAM RECEIVED COMMAND
PHASE .CMHLN ;FOLLOWING FIXED COMMAND HEADER
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.CMRDL:! BLOCK 1 ;LENGTH OF TEXT DATA
CMRRDL==000000,,177777 ;RECEIVE DATAGRAM LENGTH
.CMRDA:! BLOCK 2 ;DESTINATION ETHERNET ADDRESS
.CMRSA:! BLOCK 2 ;SOURCE ETHERNET ADDRESS
.CMRPT:! BLOCK 1 ;PROTOCOL TYPE CODE
CMRRPT==000003,,777760 ;RECEIVE PROTOCOL TYPE
.CMRBA:! BLOCK 1 ;PHYSICAL ADDRESS OF BSD CHAIN
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
.CMRVB:! BLOCK 1 ;VIRTUAL ADDRESS OF BSD CHAIN
IFG <.-.CMLNX>,<.CMLNX==.> ;COMPUTE MAXIMUM LENGTH OF COMMAND BLOCK
DEPHASE
;RDNSA (10) - READ NI STATION ADDRESS
;WRTNSA (11) - WRITE NI STATION ADDRESS
PHASE .CMHLN ;FOLLOWING FIXED COMMAND HEADER
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.CMNEA:! BLOCK 2 ;ETHERNET ADDRESS
.CMNSM:! BLOCK 1 ;SOFTWARE MODE WORD
CMMACE==000000,,000010 ;ACCEPT PACKETS WITH CRC ERRORS
CMMAAM==000000,,000004 ;ACCEPT ALL MULTI-CAST PACKETS
CMMH4K==000000,,000002 ;H4000 MODE TRANSCEIVER
CMMPRM==000000,,000001 ;PROMISCUOUS MODE
.CMNSW:! BLOCK 1 ;SOFTWARE WORD
;RDNSA COMMAND
CMWUCV==000003,,770000 ;KLNI MICROCODE VERSION
CMWLMC==000000,,007700 ;LENGTH OF MCAT TABLE
CMWLPT==000000,,000077 ;LENGTH OF PTT TABLE
;WRTNSA COMMAND
CMWERC==000000,,007777 ;ERROR RETRY COUNT
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
IFG <.-.CMLNX>,<.CMLNX==.> ;COMPUTE MAXIMUM LENGTH OF COMMAND BLOCK
DEPHASE
;DEFINE COMMAND BLOCK LENGTH AS LONGEST COMMAND
PHASE .CMLNX
.CMLEN:! ;LENGTH OF COMMAND BLOCK
DEPHASE
SUBTTL KLNI HARDWARE DEFINITIONS -- PORT CONTROL BLOCK
;THE PORT CONTROL BLOCK (PCB) IS THE BASIC MEANS OF COMMUNICATION
;BETWEEN THE KLNI AND THE KLNI DEVICE DRIVER. IT CONTAINS ALL
;ADDRESSES NEEDED BY THE KLNI AND HEADERS OF SEVERAL QUEUES
;USED IN COMMUNICATIONS BETWEEN THE KLNI AND ITS DRIVER.
PHASE IPKSIZ ;THESE ARE OFFSETS
.PBSTS:! BLOCK 1 ;KLNI STATUS FLAGS
PBSRUN==400000,,000000 ;KLNI IS RUNNING
PBSONL==200000,,000000 ;KLNI IS ONLINE
PBSMAI==100000,,000000 ;KLNI IS IN MAINTENANCE MODE
PBSPRM==040000,,000000 ;KLNI IS IN PROMISCUOUS RECEIVE MODE
PBSPMM==020000,,000000 ;KLNI IS IN PROMISCUOUS MULTI-CAST MODE
PBSADD==010000,,000000 ;KLNI AUTO-DUMP DISABLED
PBSARD==004000,,000000 ;KLNI AUTO-RELOAD DISABLED
PBSMOF==002000,,000000 ;SET MEMORY OFFLINE IS IN PROGRESS
PBSINI==001000,,000000 ;INITIALIZE KLNI AFTER MEMORY OFFLINE
PBSDMP==000400,,000000 ;KLNI DUMP REQUESTED
PBSRLD==000200,,000000 ;KLNI RELOAD REQUESTED
PBSQRR==000020,,000000 ;QUEUED RELOAD REQUEST FLAG
PBSQIO==000010,,000000 ;QUEUED I/O REQUEST FLAG
PBSCPU==000007,,000000 ;CPU NUMBER OF KLNI
PBSMJB==000000,,777000 ;JOB NUMBER OF MAINTENANCE JOB
PBSRJB==000000,,000777 ;JOB NUMBER OF KNILDR
.PBUVR:! BLOCK 1 ;KLNI MICROCODE VERSION
.PBKSA:! BLOCK 1 ;KLNI MICROCODE START ADDRESS
.PBLGO:! BLOCK 1 ;ADDRESS OF RH20 CHANNEL LOGOUT AREA
.PBCLI:! BLOCK 1 ;CONI AT LAST INTERRUPT
.PBCDB:! BLOCK 1 ;ADDRESS OF CHANNEL DATA BLOCK
.PBEKB:! BLOCK 1 ;ADDRESS OF ETHSER'S KONTROLLER BLOCK
.PBHEA:! BLOCK 2 ;HARDWARE ETHERNET ADDRESS
.PBEAD:! BLOCK 2 ;CURRENT ETHERNET ADDRESS
.PBLPT:! BLOCK 1 ;LENGTH OF PTT
.PBCPT:! BLOCK 1 ;COUNT OF ENTRIES USED IN PTT
.PBVPT:! BLOCK 1 ;VIRTUAL ADDRESS OF PTT
.PBLMC:! BLOCK 1 ;LENGTH OF MCAT
.PBCMC:! BLOCK 1 ;COUNT OF ENTRIES USED IN MCAT
.PBVMC:! BLOCK 1 ;VIRTUAL ADDRESS OF MCAT
.PBLCD:! BLOCK 1 ;LENGTH OF COUNTERS DATA BUFFER
.PBVCD:! BLOCK 1 ;VIRTUAL ADDRESS OF KLNI COUNTERS BUFFER
.PBVCT:! BLOCK 1 ;VIRTUAL ADDRESS OF KLNI COUNTERS AREA
.PBOLD:! BLOCK 1 ;NON-ZERO IF ALREADY CONFIGURED
.PBULB:! BLOCK .ULLEN ;MICROCODE LOADER PARAMETER BLOCK
.PBMPP:! BLOCK 1 ;MAX PACKETS PROCESSED PER INTERRUPT
.PBNPP:! BLOCK 1 ;NUMBER OF PACKETS PROCESSED THIS INTERRUPT
.PBOVF:! BLOCK 1 ;OVERRUN TIMER (SEC. BETWEEN PAUSE STOPCODES)
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
.PBBIT:! BLOCK 1 ;ADDRESS OF CONI BITS TO TEST ON INTERRUPT
.PBKSC:! BLOCK 1 ;COUNT OF TIMES KLNI STARTED
.PBKST:! BLOCK 1 ;SYSTEM UPTIME WHEN KLNI LAST STARTED
.PBKAC:! BLOCK 1 ;COUNT OF TIMES KLNI KEEP ALIVE FAILED
.PBKAT:! BLOCK 1 ;SYSTEM UPTIME OF LAST KLNI KEEP ALIVE FAILURE
.PBKEC:! BLOCK 1 ;COUNT OF KLNI ERRORS
.PBKET:! BLOCK 1 ;SYSTEM UPTIME OF LAST KLNI ERROR
.PBKHC:! BLOCK 1 ;COUNT OF TIMES KLNI HALTED
.PBKHT:! BLOCK 1 ;SYSTEM UPTIME WHEN KLNI LAST HALTED
.PBKLC:! BLOCK 1 ;COUNT OF TIMES KLNI RELOAD REQUESTED
.PBKQC:! BLOCK 1 ;COUNT OF QUEUED I/O COMMANDS QUEUED
.PBKQT:! BLOCK 1 ;SYSTEM UPTIME OF LAST QUEUED I/O COMMAND
.PBKFC:! BLOCK 1 ;COUNT OF PROTOCOL FREE QUEUE COMMANDS QUEUED
.PBKFT:! BLOCK 1 ;SYSTEM UPTIME OF LAST FREE QUEUE COMMAND
.PBKCC:! BLOCK 1 ;COUNT OF KLNI COMMANDS QUEUED
.PBKCT:! BLOCK 1 ;CPU UPTIME OF LAST KLNI COMMAND
.PBKRC:! BLOCK 1 ;COUNT OF KLNI RESPONSES PROCESSED
.PBKRT:! BLOCK 1 ;CPU UPTIME OF LAST KLNI RESPONSE
;ERROR INFORMATION
.PBMCE:! BLOCK 1 ;COUNT OF MULTICAST CHECKSUM ERRORS
.PBFQE:! BLOCK 1 ;COUNT OF FREE QUEUE EMPTY ERRORS
.PBCIB:! BLOCK 1 ;COUNT OF INTERLOCKS BROKEN
.PBCLE:! BLOCK 1 ;CONI ON LAST ERROR INTERRUPT
.PBCRA:! BLOCK 1 ;CRAM ADDRESS FROM LAST ERROR
.PBCRC:! BLOCK 2 ;CRAM CONTENTS FROM LAST ERROR
.PBLG0:! BLOCK 1 ;CHANNEL LOGOUT WORD 0 FROM LAST ERROR
.PBLG1:! BLOCK 1 ;CHANNEL LOGOUT WORD 1 FROM LAST ERROR
.PBLG2:! BLOCK 1 ;CHANNEL LOGOUT WORD 2 FROM LAST ERROR
.PBECW:! BLOCK 1 ;PORT'S CCW FROM LAST ERROR
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.PBPCB:!
.PBCMQ:! BLOCK .QHLEN ;COMMAND QUEUE
.PBRSQ:! BLOCK .QHLEN ;RESPONSE QUEUE
.PBUPQ:! BLOCK .QHLEN ;UNKNOWN PROTOCOL TYPE QUEUE
.PBRS0:! BLOCK 1 ;RESERVED FOR SOFTWARE
.PBPTT:! BLOCK 1 ;PHYSICAL ADDRESS OF PTT
.PBMCT:! BLOCK 1 ;PHYSICAL ADDRESS OF MCAT
.PBRS1:! BLOCK 1 ;RESERVED FOR SOFTWARE
.PBER0:! BLOCK 1 ;ERROR WORD 0
PBECMD==1B0 ;ERROR WHILE READING A COMMAND
PBERES==1B3 ;ERROR WHILE BUILDING RESPONSE
PBEFLI==77777777B35 ;FLINK OF QUEUE IN ERROR
.PBER1:! BLOCK 1 ;ERROR WORD 1 (API FUNCTION WORD)
.PBER2:! BLOCK 1 ;ERROR WORD 2 (CHANNEL LOGOUT WORD 1)
.PBER3:! BLOCK 1 ;ERROR WORD 3 (CHANNEL LOGOUT WORD 2)
.PBPBA:! BLOCK 1 ;PHYSICAL ADDRESS OF PCB
.PBPIA:! BLOCK 1 ;PRIORITY INTERRUPT ASSIGNMENT
.PBRP0:! BLOCK 1 ;RESERVED TO KLNI MICROCODE
.PBCCW:! BLOCK 1 ;CHANNEL COMMAND WORD
.PBKCB:! BLOCK 1 ;PHYSICAL ADDRESS OF KLNI COUNTERS BUFFER
.PBPCL==.-.PBPCB ;LENGTH OF PCB AREA DEFINED BY KLNI MICROCODE
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
.PBLEN:! ;LENGTH OF PORT CONTROL BLOCK
DEPHASE
SUBTTL KLNI HARDWARE DEFINITIONS -- PROTOCOL TYPE TABLE
;THE PROTOCOL TYPE TABLE SPECIFIES A SET OF PROTOCOL TYPES, WITH
;THEIR ASSOCIATED FREE QUEUE POINTERS THAT ARE CONSIDERED ENABLED
;BY THE PORT.
;
;THE PROTOCOL TYPES IN THIS TABLE COME INTO EFFECT ONLY AFTER
;THE EXECUTION OF A LOAD PTT COMMAND.
PHASE 0 ;THESE ARE OFFSETS
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.PTPTY:! BLOCK 1 ;PROTOCOL TYPE WORD
PTTENA==400000,,000000 ;PROTOCOL ENABLED
PTTPTY==000003,,777760 ;PROTOCOL TYPE CODE
.PTFRQ:! BLOCK 1 ;PHYSICAL ADDRESS OF FREE QUEUE HEADER
.PTRS0:! BLOCK 1 ;RESERVED TO SOFTWARE
.PTLEN:! ;LENGTH OF PTT ENTRY
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
.PTPUB==.PTRS0 ;ADDRESS OF PROTOCOL USER BLOCK
DEPHASE
SUBTTL KLNI HARDWARE DEFINITIONS -- MULTI-CAST ADDRESS TABLE
;THE MCAT IS THE MULTI-CAST ADDRESS TABLE. THIS TABLE SPECIFIES
;WHICH MULTI-CAST ADDRESSES ARE TO BE ACCEPTED BY THE KLNI
;ADDRESS FILTER.
;
;THE ADDRESSES IN THIS TABLE COME INTO EFFECT ONLY AFTER THE
;EXECUTION OF A LOAD MCAT COMMAND.
PHASE 0 ;THESE ARE OFFSETS
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.MCHAD:! BLOCK 1 ;HIGH ORDER MULTI-CAST ADDRESS
MCTHAD==777777,,777760 ;HIGH ORDER MULTI-CAST ADDRESS
.MCLAD:! BLOCK 1 ;LOW ORDER MULTI-CAST ADDRESS
MCTLAD==777774,,000000 ;LOW ORDER MULTI-CAST ADDRESS
MCTENA==000000,,000001 ;MULTI-CAST ADDRESS ENABLED
.MCLEN:! ;LENGTH OF MCAT ENTRY
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
DEPHASE
SUBTTL KLNI HARDWARE DEFINITIONS -- COUNTERS BLOCK
;THE COUNTERS BLOCK CONTAINS ERROR COUNTERS ACCUMULATED BY THE KLNI.
;IT IS UPDATED UPON EXECUTION OF A READ/CLEAR COUNTERS COMMAND.
PHASE 0 ;THESE ARE OFFSETS
;***** START OF WORDS DEFINED BY THE KLNI MICROCODE *****
.KCBYR:! BLOCK 1 ;BYTES RECEIVED
.KCBYX:! BLOCK 1 ;BYTES TRANSMITTED
.KCDGR:! BLOCK 1 ;DATAGRAMS RECEIVED
.KCDGX:! BLOCK 1 ;DATAGRAMS TRANSMITTED
.KCMBR:! BLOCK 1 ;MULTI-CAST BYTES RECEIVED
.KCMDR:! BLOCK 1 ;MULTI-CAST DATAGRAMS RECEIVED
.KCDXD:! BLOCK 1 ;DATAGRAMS TRANSMITTED, INITIALLY DEFERRED
.KCDX1:! BLOCK 1 ;DATAGRAMS TRANSMITTED, SINGLE COLLISION
.KCDXM:! BLOCK 1 ;DATAGRAMS TRANSMITTED, MULTIPLE COLLISIONS
.KCXMF:! BLOCK 1 ;TRANSMIT FAILURES
.KCXFM:! BLOCK 1 ;TRANSMIT FAILURE BIT MASK
CXFCRL==004000 ;CARRIER LOST
CXFBPE==002000 ;BUFFER PARITY ERROR
CXFRFD==001000 ;REMOTE FAILURE TO DEFER
CXFFTL==000400 ;FRAME TOO LONG
CXFOPN==000200 ;OPEN CIRCUIT
CXFSHT==000100 ;SHORT CIRCUIT
CXFCDF==000040 ;COLLISION DETECT CHECK FAILED
CXFEXC==000020 ;EXCESSIVE COLLISIONS
.KCCDF:! BLOCK 1 ;COLLISION DETECT CHECK FAILURES
.KCRCF:! BLOCK 1 ;RECEIVE FAILURES
.KCRFM:! BLOCK 1 ;RECEIVE FAILURE BIT MASK
CRFFPE==000400 ;FREE LIST PARITY ERROR
CRFNFB==000200 ;NO FREE BUFFERS
CRFFTL==000100 ;FRAME TOO LONG
CRFFRE==000040 ;FRAMING ERROR
CRFBCE==000020 ;BLOCK CHECK ERROR
.KCFQU:! BLOCK 1 ;FREE QUEUE ERRORS, UNKNOWN PROTOCOL QUEUE
.KCFQP:! BLOCK ^D16 ;FREE QUEUE ERRORS, INDIVIDUAL PROTOCOL TYPES
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
.KCUFD:! BLOCK 1 ;UNRECOGNIZED FRAME DESTINATION
.KCDOV:! BLOCK 1 ;DATA OVERRUN ERRORS
.KCSBU:! BLOCK 1 ;UNUSED
.KCFQE:! BLOCK 1 ;FREE QUEUE ERRORS, ALL QUEUES
.KCHE1:! BLOCK 1 ;HARDWARE ERROR COUNTS
CH1PRP==777777,,000000 ;PLI REGISTER READ PARITY ERRORS
CH1PPE==000000,,777777 ;PLI PARITY ERRORS
.KCHE2:! BLOCK 1 ;HARDWARE ERROR COUNTS
CH2MPE==777777,,000000 ;DATA MOVER PARITY ERRORS
CH2CPE==000000,,777777 ;CBUS PARITY ERRORS
.KCHE3:! BLOCK 1 ;HARDWARE ERROR COUNTS
CH3EPE==777777,,000000 ;EBUS PARITY ERRORS
CH3EQP==000000,,777777 ;EBUS QUEUE PARITY ERRORS
.KCHE4:! BLOCK 1 ;HARDWARE ERROR COUNTS
CH4CHN==777777,,000000 ;CHANNEL ERRORS
CH4SCE==000000,,777777 ;SPURIOUS CHANNEL ERRORS
.KCHE5:! BLOCK 1 ;HARDWARE ERROR COUNTS
CH5SXA==777777,,000000 ;SPURIOUS TRANSMIT ATTENTION ERRORS
CH5CRT==000000,,777777 ;CBUS REQUEST TIMEOUT ERRORS
.KCHE6:! BLOCK 1 ;HARDWARE ERROR COUNTS
CH6UBP==777777,,000000 ;USER BUFFER PARITY ERRORS
CH6XBP==000000,,777777 ;TRANSMIT BUFFER PARITY ERRORS
.KCHEX:! BLOCK 3 ;RESERVED
.KCLEN:! ;LENGTH OF COUNTERS DATA BUFFER
IF1,<IFN <.KCLEN-MAXKCB>,<PRINTX ?KLNI counters definition is in error>>
;***** END OF WORDS DEFINED BY THE KLNI MICROCODE *****
DEPHASE
SUBTTL KLNI SOFTWARE DEFINITIONS -- TIMER VALUES
;TIMEOUTS
TIMOUT==^D5000 ;INTERLOCK WORD TIMEOUT VALUE
IDLTIM==^D1*^D1000 ;KLNI IDLE TIMER (MILLISECONDS)
KAFTIM==^D35*^D1000 ;KLNI KEEP ALIVE TIMER (MILLISECONDS)
UPTTIM==^D5*^D60*^D1000 ;KLNI UPTIME TIMER (MILLISECONDS)
SUBTTL KLNI SOFTWARE DEFINITIONS -- PROTOCOL USER BLOCK
;KNISER MAINTAINS A PROTOCOL USER BLOCK FOR EACH PROTOCOL ENABLED
;ON THE KLNI. THIS BLOCK CONTAINS INFORMATION NEEDED TO PROPERLY
;PROCESS INCOMING DATAGRAMS AND TO INTERFACE WITH ETHSER.
PHASE 0 ;THESE ARE OFFSETS
.PUPTY:! BLOCK 1 ;PROTOCOL TYPE CODE (KLNI FORMAT)
.PUSTS:! BLOCK 1 ;PROTOCOL STATUS WORD
PUSPAD==400000,,000000 ;PROTOCOL USES PADDING
PUSPTT==000000,,000077 ;PTT TABLE INDEX OF THIS PROTOCOL
.PUEPB:! BLOCK 1 ;ADDRESS OF ETHSER'S PORTAL BLOCK
.PUFQH:! BLOCK .QHLEN ;FREE QUEUE HEADER FOR THIS PROTOCOL
.PULEN:! ;LENGTH OF PROTOCOL USER BLOCK
DEPHASE
SUBTTL KLNI SOFTWARE DEFINITIONS -- DIAG. UUO
;DIAG. ERROR CODES
DIANP%==1 ;INSUFFICIENT PRIVILEGES
DIAIA%==2 ;ILLEGAL NUMBER OF ARGUMENTS
DIAIC%==3 ;ILLEGAL CONTROLLER NUMBER
DIAIU%==4 ;ILLEGAL UNIT NUMBER
DIAAA%==5 ;SOME UNITS ALREADY ASSIGNED
DIADM%==6 ;UNIT NOT IN DIAGNOSTIC MODE
DIAAJ%==7 ;UNIT ASSIGNED TO ANOTHER JOB
DIAFC%==10 ;NOT ENOUGH FREE CORE
DIAAU%==11 ;NO ASSIGNED UNITS
DIACP%==12 ;IOWD CROSSES PAGE BOUNDARY
DIAIF%==13 ;ILLEGAL FUNCTION
DIAVC%==14 ;JOB MUST NOT BE VIRTUAL
DIANC%==15 ;NO SUCH CPU
DIANR%==16 ;CPU NOT RUNNING
DIABA%==17 ;BAD ARGUMENT LIST
DIACI%==20 ;NO CI PORT ON SPECIFIED CPU
DIATO%==21 ;READ PORT COUNTERS FUNCTION TIMED OUT
DIANK%==22 ;NO KLNI PRESENT ON CPU
SUBTTL KLNI SOFTWARE DEFINITIONS -- KNIBT. UUO
IFN FTKNILDR,<
;KNIBT. FUNCTION CODES
.KBSTS==1 ;CHECK KLNI STATUS
.KBSRJ==2 ;SET KLNI RELOAD JOB
.KBSTP==3 ;STOP KLNI
.KBSTA==4 ;START KLNI
.KBRED==5 ;READ KLNI CRAM
.KBWRT==6 ;WRITE KLNI CRAM
;KNIBT. FUNCTION .KBSTS STATUS BITS
KS.RUN==400000,,000000 ;KLNI IS RUNNING
KS.MAI==200000,,000000 ;KLNI IS IN MAINTENANCE MODE
KS.RLD==100000,,000000 ;KLNI NEEDS RELOADING
KS.ARD==040000,,000000 ;KLNI AUTO-RELOAD IS DISABLED
KS.RRQ==020000,,000000 ;KLNI RELOAD REQUESTED BY SYSTEM
KS.DRQ==010000,,000000 ;KLNI DUMP REQUESTED BY SYSTEM
KS.ADD==004000,,000000 ;KLNI AUTO-DUMP IS DISABLED
KS.RJB==000000,,777777 ;JOB NUMBER OF KNILDR
;KNIBT. ERROR CODES
KBPRV%==1 ;INSUFFICIENT PRIVILEGES
KBADC%==2 ;ADDRESS CHECK
KBIAL%==3 ;INVALID ARGUMENT LIST
KBILF%==4 ;ILLEGAL FUNCTION
KBICS%==5 ;ILLEGAL CPU SPECIFICATION
KBCNA%==6 ;CPU NOT AVAILABLE
KBKDE%==7 ;KLNI DOESN'T EXIST
KBKMM%==10 ;KLNI IS IN MAINTENANCE MODE
KBDNS%==11 ;KLNI DID NOT START
KBDNI%==12 ;KLNI DID NOT INITIALIZE
KBICA%==13 ;INVALID CRAM ADDRESS
KBCRE%==14 ;CRAM READ ERROR
KBCWE%==15 ;CRAM WRITE ERROR
KBNRJ%==16 ;NOT THE RELOAD JOB
>;END IFN FTKNILDR
SUBTTL KLNI DEVICE SERVICE -- AUTCON PARAMETERS
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
;DRIVER CHARARCTERISTICS
; KNI = KNICNF
; KNI = KLNI
; M.CPU = MAXIMUM DEVICES IN SYSTEM
; .KTKNI = KONTROLLER TYPE
; 0 = MAXIMUM DRIVES PER KONTROLLER
; 0 = HIGHEST DFRIVE NUMBER ON KONTROLLER
; MDSEC0 = SECTION FOR KDB/UDB
; MDSEC0 = SECTION FOR DDB
DRVCHR (KNI,KNI,M.CPU##,.KTKNI,0,0,MDSEC0,MDSEC0,<DR.XAD!DR.NMC>)
.ORG IPKSIZ
BLOCK .PBLEN ;PCB
KNIKLN:! ;LENGTH OF KDB
.ORG
KNIKDB: KDBBEG (KNI,KNIKLN)
SETWRD (KDBNAM,<SIXBIT/KNI/>) ;KONTROLLER NAME
SETWRD (KDBPCC,<.PBPCL,,.PBPCB>) ;PHYSICALLY CONTIGUOUS CORE
SETWRD (.PBOLD,<EXP -1>) ;FULL CONFIGURE FIRST TIME
SETWRD (.PBMPP,<^D2000>) ;MAX PACKETS PROCESSED PER INTERRUPT
KDBEND
EQUATE (LOCAL,0,<KNICKT,KNIUDB,KNIULN>)
KNIULB==.PBULB ;OFFSET OF UCODE LOADER BLOCK
KNIICD==IPAICD## ;PROTOTYPE INTERRUPT CODE ADDRESS
KNIICL==IPAICL## ;PROTOTYPE INTERRUPT CODE LENGTH
KNIDSP: DRVDSP (KNI,KNICHN##,,,KNIDIA)
;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT: MDKL10 (7,564,0,0,<MD.KON>) ;DEVICE CODE 564
MDTERM ;TERMINATE TABLE
;PROTOTYPE MICROCODE PARAMETER BLOCK
KNIULP: EXP .BTKNI## ;MICROCODE INDEX
XWD 000,0 ;DEVICE CODE,,MASSBUS 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
SUBTTL KLNI DEVICE SERVICE -- KLNI CONFIGURATION
;ROUTINE CALLED WHEN AUTCON
;LINKAGE:
; T1/ DEVICE CODE
; T2/ CONI BITS
; PUSHJ P,KNICFG
;RETURNS:
; CPOPJ TO STOP SCANNING DRIVERS
; CPOPJ1 TO SCAN OTHER DRIVERS
KNICFG: CAIL T1,FSTICD/4 ;AN RH20?
CAILE T1,LSTICD/4 ;...
JRST CPOPJ1## ;WRONG DRIVER
TLNN T2,(CI.PPT) ;IPA CHANNEL?
JRST CPOPJ1## ;NO
PUSHJ P,TYIPA## ;TRY TO DETERMINE THE PORT TYPE
JRST KNICF1 ;CAN'T
CAIN T1,.CIKNI ;KLNI?
JRST KNICF2 ;YES
JRST CPOPJ1## ;ON TO THE NEXT DRIVER
KNICF1: XMOVEI T1,KNIMDT## ;MONGEN'ED DEVICE TABLE
XMOVEI T2,DEFMDT ;DEFAULT TABLE
MOVNI T3,1 ;NO MASSBUS UNIT OR DRIVE INFORMATION
MOVEI T4,MD.KON ;MATCH ON KONTROLLER DEFINITION
PUSHJ P,AUTMDT## ;SCAN THE TABLES
JRST CPOPJ1## ;NO MATCHES
KNICF2: MOVSI T1,CP.KNI ;KLNI CHANNEL
PUSHJ P,AUTCHN## ;BUILD A CHANNEL DATA BLOCK
POPJ P, ;NO CORE
MOVNI T1,1 ;NOT MULTI-UNIT, BUT MUST DO ANYWAY
PUSHJ P,AUTKDB## ;BUILD A KDB
POPJ P, ;GIVE UP IF NO CORE
AOSE .PBOLD(W) ;BEEN HERE BEFORE?
POPJ P, ;YES--DO NOTHING OR I/O WILL STOP
MOVE T1,.CPCHA## ;GET CHANNEL DATA BLOCK ADDRESS
MOVEM T1,.PBCDB(W) ;SAVE IN THE PCB
HRRZ T1,@KDBCSO(W) ;ADDRESS OF CONI BITS TO TEST IN SKIP CHAIN
MOVEM T1,.PBBIT(W) ;UPDATE
MOVE T1,[KNIBTS] ;BITS TO TEST FOR ON INTERRUPT
MOVEM T1,@.PBBIT(W) ;SET IN THE CONSO SKIP CHAIN CODE
PUSHJ P,IPAADB## ;ALLOCATE DRAM DUMP BUFFER
PJRST KNIINI ;INITIALIZE THE KLNI AND RETURN
SUBTTL KLNI DEVICE SERVICE -- SYSINI INITIALIZATION
;ROUTINE TO DO ONCE-ONLY SYSINI INITIALIZATION.
;LINKAGE:
; PUSHJ P,KNISYS
;RETURNS:
; CPOPJ ALWAYS
$INIT
KNISYS::
IFE FTXMON,<
MOVEI T1,KNISIZ## ;SIZE OF KLNI FREECORE NEEDED
PUSHJ P,INICOR## ;ALLOCATE CORE
MOVEM T2,KNILOC## ;SAVE STARTING ADDRESS
>; END IFN FTXMON
IFN FTXMON,<
MOVEI T2,KNISIZ## ;SIZE OF FREECORE
MOVEI T1,(MS.DCN) ;SECTION NUMBER
PUSHJ P,GFWNZN## ;ASK ONCMOD FOR NON-ZERO SECTION CORE
HALT . ;*** FOR NOW
MOVEM T1,KNILOC## ;SAVE AS LOWEST ADDRESS IN FREECORE
>; END IFN FTXMON
POPJ P, ;RETURN
$HIGH
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
XMOVEI P1,SYSCHN##-CHNSYS ;SET PREDECESSOR
MOVEI T1,CP.KNI ;KLNI CHANNEL BITS
KNIIN1: MOVE P1,CHNSYS(P1) ;GET CHANNEL ADDRESS
HLRZS P1 ;ADDRESS IN LH QUANTITY
JUMPE P1,CPOPJ## ;THERE MUST BE ONE!
HLRZ T2,CHNTYP(P1) ;GET INTERESTING BITS
CAIE T1,(T2) ;A KLNI?
JRST KNIIN1 ;TRY AGAIN
LDB T2,CHYCPU## ;GET CPU NUMBER
CAME T2,.CPCPN## ;OURS?
JRST KNIIN1 ;NO
MOVE T1,CHNTBP(P1) ;FETCH THE KDB (PCB) TABLE POINTER
SKIPN Q3,(T1) ;AND GET THE PORT CONTROL BLOCK
POPJ P, ;NO KLNI ON THIS CPU
SKIPE .CPNPB## ;RESTART?
JRST [PUSHJ P,SHTKNI ;YES, SHUT DOWN KLNI
PUSHJ P,PCBINI ;RESET THE PORT CONTROL BLOCK
JRST KNIIN2] ;POSSIBLY RELOAD KLNI
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
KNIIN2: MOVE T1,.CPBIT## ;GET OUR CPU'S BIT
TDNN T1,IPAMSK## ;WANT TO SKIP STARTING THE NI?
PJRST RLDKNI ;REQUEST RELOAD OF KLNI AND RETURN
POPJ P, ;SKIP RELOAD 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
TXO T1,CO.CQA!CO.BTS ;PLUS COMMAND QUEUE AVAILABLE FLAG
XCT KDBCNO(Q3) ;TELL KLNI
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
; MOVSI T1,(CR.ATO) ;BIT TO TEST
; TDNE T1,.CPRUN## ;WAITING FOR AUTCON TO RUN?
; POPJ P, ;THEN DO NOTHING
PUSHJ P,SAVQ## ;SAVE Q1-Q3
SE1ENT ;RUN IN SECTION 1
MOVE Q3,.CPNPB## ;GET ADDRESS OF PORT CONTROL BLOCK
SKIPLE .PBOVF(Q3) ;OVERRUN TIMER ACTIVE?
SOS .PBOVF(Q3) ;YES--COUNT IT DOWN
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 KNISE2 ;YES, GO PERFORM KEEP ALIVE CHECKS
TXNN T1,PBSINI ;NEED TO INITIALIZE KLNI?
JRST KNISE1 ;NO
MOVX T1,PBSINI ;GET INIT BIT
ANDCAM T1,.PBSTS(Q3) ;CLEAR IT
PUSHJ P,PCBINI ;INITIALIZE PORT CONTROL BLOCK
PJRST RLDKNI ;REQUEST KLNI RELOAD AND RETURN
KNISE1: TXNE T1,PBSQRR ;QUEUED RELOAD REQUESTED?
PJRST KNILOD ;YES, RELOAD MICROCODE AND RETURN
POPJ P, ;RETURN
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;AT THIS POINT, WE ASSUME THE KLNI IS RUNNING BECAUSE NO FLAVOR OF
;RELOAD OR INITIALIZATION HAS BEEN REQUESTED
KNISE2: 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 KNISE3 ;NO, GO CHECK KLNI IDLE TIMER
XCT KDBCNI(Q3) ;CONI DEV,T1
PUSH P,T1 ;SAVE FOR A MOMENT
MOVEI T1,CO.CPT ;MAKE SURE THE KLNI IS REALLY STOPPED
XCT KDBCNO(Q3) ;CONO DEV,(T1)
POP P,T1 ;GET CONI BITS BACK
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
KNISE3: 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::XMOVEI T1,KNIMF1 ;GET ADDRESS OF ROUTINE
PJRST CPUAPP## ;CALL ROUTINE FOR ALL CPUS
;ROUTINE CALLED FOR ALL CPUS
KNIMF1: MOVE T1,.CPBIT##-.CPCDB##(P1) ;GET CPU'S BIT
TDNN T1,IPAMSK## ;WANT TO SKIP STARTING THE NI?
SKIPN T2,.CPNPB##-.CPCDB##(P1) ;THIS CPU HAVE A KLNI?
POPJ P, ;NO, RETURN NOW
MOVX T1,PBSMOF ;SET MEMORY OFFLINE FLAG
IORM T1,.PBSTS(T2) ;...
POPJ P, ;AND RETURN
;ROUTINE CALLED ON CPU0 WHEN SET MEMORY OFFLINE HAS COMPLETED
;LINKAGE:
; PUSHJ P,KNIMON
;RETURNS:
; CPOPJ ALWAYS
KNIMON::XMOVEI T1,KNIMN1 ;GET ADDRESS OF ROUTINE
PJRST CPUAPP## ;CALL ROUTINE FOR ALL CPUS
;ROUTINE CALLED FOR ALL CPUS
KNIMN1: MOVE T1,.CPBIT##-.CPCDB##(P1) ;GET CPU'S BIT
TDNN T1,IPAMSK## ;WANT TO SKIP STARTING THE NI?
SKIPN T2,.CPNPB##-.CPCDB##(P1) ;THIS CPU HAVE A KLNI?
POPJ P, ;NO, RETURN NOW
MOVX T1,PBSMOF ;GET MEMORY OFFLINE FLAG
TDNN T1,.PBSTS(T2) ;KLNI STOPPED BECAUSE OF SET MEMORY OFFLINE?
POPJ P, ;NO, RETURN NOW
ANDCAM T1,.PBSTS(T2) ;YES, CLEAR MEMORY OFFLINE FLAG
MOVX T1,PBSINI ;SET INITIALIZE KLNI FLAG
IORM T1,.PBSTS(T2) ;...
POPJ P, ;AND RETURN
SUBTTL KLNI DEVICE SERVICE -- PAUSE SERVICE
;ROUTINE TO PAUSE SERVICE WHEN WE'RE IN DANGER OF KAF'ING
;LINKAGE:
; PUSHJ P,KNIMON
;RETURNS:
; CPOPJ ALWAYS
KNIPAU: SKIPLE .PBOVF(Q3) ;OVERRUN PROTECTION?
JRST KNIPA1 ;YES--KEEP QUIET ABOUT THIS ONE
STOPCD .+1,INFO,KNIKSP, ;++KLNI SERVICE PAUSING
MOVE T1,KNIOVC ;GET SECONDS OF SILENCE
MOVEM T1,.PBOVF(Q3) ;SET THE OVERRUN FLAG
KNIPA1: XCT KDBCNI(Q3) ;CONI DEV,T1
TRZ T1,7 ;CLEAR PIA
XCT KDBCNO(Q3) ;CONO DEV,(T1)
MOVE T1,.CPCPN## ;GET OUR CPU
MOVEI T2,(T1) ;MAKE A COPY
ROT T2,-4 ;POSITION FOR CLOCK1
TLO T2,(1B0) ;ONLY THIS CPU
HRR T2,Q3 ;SECTION LOCAL ADDR FOR IDENTIFICATION
MOVE T3,KNIZTM ;GET TICKS TO PAUSE
HRLI T3,KNICON ;ADDR OF ROUTINE TO CALL
SYSPIF ;INTERLOCK QUEUE
IDPB T3,CLOCK## ;STORE TIMEOUT VALUE & SUBR
IDPB T2,CLOCK## ;STORE CPU AND DATA
SETZM CLKMIN##(T1) ;FLAG CPU DEPENDENT CLOCK REQUEST
SYSPIN ;LET GO OF QUEUE
POPJ P, ;DONE
KNIOVC: DEC 5 ;SECONDS BETWEEN PAUSE STOPCODES
KNIZTM: DEC 30 ;TICKS TO PAUSE
;HERE TO CONTINUE SERVICE
KNICON: PUSHJ P,SAVW## ;SAVE W
SE1ENT ;ENTER SECTION ONE
XMOVEI W,KDBTAB##+.TYKNI-KDBNXT ;SET PREDESSOR
KNICO1: SKIPN W,KDBNXT(W) ;GET NEXT KDB
POPJ P, ;THERE ISN'T ONE
HRRZ T2,W ;COPY SECTION LOCAL ADDRESS
CAIE T1,(T2) ;THE ONE WE WANT?
JRST KNICO1 ;NO--TRY NEXT
MOVE T1,.CPUPT## ;GET CPU UPTIME
MOVEM T1,.PBKRT(W) ;AVOID KNIKAFS
XCT KDBCNI(W) ;CONI DEV,T1
IOR T1,.PBPIA(W) ;INCLUDE PI CHANNEL
XCT KDBCNO(W) ;GIVE IT A PIA
POPJ P, ;AND LETTERRIP
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
IMULI T1,.CPLEN## ;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::XMOVEI 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
IFN FTKNILDR,<
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
>;END IFN FTKNILDR
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: LDB T1,PBPPMM ;GET PROMISCUOUS MULTI-CAST FLAG
JUMPN T1,CPOPJ1## ;RETURN IF USING SOFTWARE FILTER
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,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: LDB T1,PBPPMM ;GET PROMISCUOUS MULTI-CAST FLAG
JUMPN T1,CPOPJ1## ;RETURN IF USING SOFTWARE FILTER
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
LDB T1,[POINT 3,KDBCNO(Q3),9] ;GET RH20 NUMBER
LSH T1,2 ;COMPUTE EPT OFFSET TO CHANNEL LOGOUT AREA
ADD T1,.CPEPT## ;PLUS ADDRESS OF EPT
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,M.CPU## ;$ GET NUMBER OF CPUS IN SYSTEM
CAIN T1,1 ;$ JUST ONE CPU?
TDZA T1,T1 ;$ HARDWARE FILTER WORKS ONLY WITH 1 CPU
MOVEI T1,1 ;$ MUST RESORT TO USING SOFTWARE FILTER
DPB T1,PBPPMM ;SET PROMISCUOUS MULTI-CAST FLAG
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
TXO T1,CO.CQA!CO.BTS ;PLUS COMMAND QUEUE AVAILABLE FLAG
XCT KDBCNO(Q3) ;TELL KLNI
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: MOVX T2,PBSMAI ;IS KLNI IN MAINTENANCE MODE?
TDNE T2,.PBSTS(W) ;...
POPJ P, ;YES, RETURN NOW
MOVE Q3,W ;COPY PCB ADDRESS TO STANDARD REGISTER
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
TRO T1,CO.CQA!CO.BTS ;PLUS COMMAND QUEUE AVAILABLE FLAG
XCT KDBCNO(Q3) ;TELL KLNI
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
SETZM .PBNPP(Q3) ;RESET PACKET PROCESSED COUNT ON THIS INTERRUPT
KNIRQ1: MOVE T1,.PBPIA(Q3) ;GET KLNI PI ASSIGNMENT
TXO T1,CO.RQA!CO.BTS ;PLUS RESPONSE QUEUE AVAILABLE
MOVX T2,PBSRUN ;IS KLNI RUNNING?
TDNE T2,.PBSTS(Q3) ;...
XCT KDBCNO(Q3) ;TELL KLNI RESPONSE QUEUE IS 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 ;...
AOS T1,.PBNPP(Q3) ;COUNT THE PACKET PROCESSED
MOVE T3,.CPTMF## ;GET COUNT OF JIFFIES SINCE LAST KEEP-ALIVE
CAIGE T3,^D<4*50> ;YES--MORE THAN 4 SECONDS EVEN AT 50 HZ
CAML T1,.PBMPP(Q3) ;LESS THAN LIMIT PER INTERRUPT?
JRST KNIPAU ;NO--STOP THE WORLD BEFORE WE KAF
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
TXO T1,CO.FQE!CO.BTS ;PLUS FREE QUEUE ERROR
XCT KDBCNO(Q3) ;TELL KLNI
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
PUSH P,W ;SAVE AC
MOVE W,Q3 ;PUT KDB (PCB) ADDRESS IN PROPER PLACE
PUSHJ P,RDLAR## ;READ LATCHED ADDRESS REGISTER CONTENTS
SETZ T1, ;ERROR?
MOVEM T1,.PBCRA(Q3) ;SAVE IT
PUSHJ P,RDIPA## ;READ THAT LOCATION'S CONTENTS
SETZB T2,T3 ;ERROR?
POP P,W ;RESTORE AC
DMOVEM T2,.PBCRC(Q3) ;SAVE IN PCB
MOVE T1,.PBLGO(Q3) ;ADDRESS OF CHANNEL LOGOUT AREA
DMOVE T2,0(T1) ;GET FIRST TWO WORDS OF CHANNEL LOGOUT AREA
DMOVEM T2,.PBLG0(Q3) ;SAVE THEM
MOVE T2,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
PUSH P,T1 ;SAVE ADDRESS FOR A MOMENT
LDB T1,[POINT 3,KDBCNO(Q3),9] ;GET RH20 NUMBER
MOVE T2,.PBUVR(Q3) ;GET KLNI MICROCODE VERSION
DPB T1,[POINTR (T2,KP%CHN)] ;SET RH20 CHANNEL
TXO T2,KP%NI ;AND KLNI FLAG
POP P,T1 ;RESTORE T1
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/ NUMBER OF ARGUMENTS
; P2/ DIAG. UUO FUNCTION CODE
; P3/ SUBROUTINE (FROM KNIDIA)
; W/ KDB (PCB) ADDRESS
; 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: EXP KNIPPR ;PREPROCESSOR ROUTINE
DIAFNC (AAU,DIAAAU,) ;ASSIGN ALL UNITS
DIAFNC (RAU,DIARAU,) ;RELEASE CHANNEL AND ALL UNITS
DIAFNC (SCP,DIASCP,) ;SPECIFY CHANNEL PROGRAM
DIAFNC (RCP,DIARCP,) ;RELEASE CHANNEL PROGRAM
DIAFNC (GCS,DIACST,) ;GET CHANNEL STATUS
DIAFNC (ELD,DIAELD,) ;ENABLE MICROCODE LOADING
DIAFNC (DLD,DIADLD,) ;DISABLE MICROCODE LOADING
DIAFNC (LOD,DIALOD,) ;LOAD MICROCODE
DIAFNC (ISM,DIAISM,) ;SET MAINTENANCE MODE
DIAFNC (ICM,DIAICM,) ;CLEAR MAINTENANCE MODE
DIAFNC ;TERMINATE TABLE
;PREPROCESSOR ROUTINE
KNIPPR: PUSHJ P,SAVE4## ;SAVE P1-P4
PUSHJ P,SAVQ## ;AND Q1-Q3
MOVSI T1,JP.POK ;JOB HAVE SUFFICIENT PRIVILEGES?
PUSHJ P,PRVBIT## ;...
SKIPA Q3,W ;GET PORT CONTROL BLOCK (KDB) ADDRESS
PJRST DIAPRV ;NO, GIVE ERROR RETURN
CAIL P2,.DIELD ;THESE FUNCTIONS DON'T REQUIRE MAINTENANCE MODE
CAILE P2,.DIICM ;...
SKIPA ;NOT A SPECIAL FUNCTION
PJRST (P3) ;YES, DISPATCH NOW
MOVX T1,PBSMAI ;IN MAINTENANCE MODE?
TDNN T1,.PBSTS(Q3) ;...
JRST DIAADM## ;NO, RETURN AN ERROR
PJRST (P3) ;DISPATCH BASED ON FUNCTION CODE
;(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 DIAAAJ## ;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
DIARAU: LDB T1,PBPMJB ;GET MAINTENANCE JOB NUMBER
CAME T1,J ;SAME AS CALLER'S JOB?
JRST DIAAAJ## ;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 DIAAAJ## ;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,DIAACP## ;TOO BIG IF 0
MOVEM T1,CHNICW(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 CHNICW(P3) ;PAGE NOT THERE
JRST DIAACP##] ;BOMB HIM OUT
SETZB P1,P4 ;SAY FIRST CALL, NOT A DX10
MOVE T2,CHNICW(P3) ;GET IOWD
S0PSHJ MAPIO## ;RELOCATE THE IOWD
JRST [SETZM CHNICW(P3)
JRST DIAAFC##] ;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,CHNICW(P3) ;STORE ADDRESS OF CHANNEL PROGRAM
TLO P2,(FLD(.CCJMP,CC.OPC)) ;MAKE ICW BE A JUMP
LDB T1,[POINT 3,KDBCNO(Q3),9] ;GET RH20 NUMBER
LSH T1,2 ;COMPUTE EPT OFFSET TO CHANNEL LOGOUT AREA
ADD T1,.CPEPT## ;PLUS ADDRESS OF EPT
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 DIAAAJ## ;NO, RETURN ERROR
MOVE P3,.PBCDB(Q3) ;GET CHANNEL DATA BLOCK ADDRESS
SKIPN T1,CHNICW(P3) ;NOTHING TO DO IF NO IOWD
POPJ P,
SETZM CHNICW(P3) ;FORGET WE HAD IT
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 DIAAAJ## ;NO, RETURN ERROR
LDB P2,[POINT 3,KDBCNO(Q3),9] ;GET RH20 NUMBER
LSH P2,2 ;COMPUTE EPT OFFSET TO CHANNEL LOGOUT AREA
ADDI P2,.CSICW ;PLUS OFFSET TO ICWA WORD
ADD P2,.CPEPT## ;PLUS ADDRESS OF EPT
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,DIAARF## ;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) SET MAINTENANCE MODE
DIAISM: 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 @.PBBIT(Q3) ;ZAP BITS TO TEST FOR ON INTERRUPT
MOVE T1,.CPBIT## ;GET OUR CPU'S BIT
IORM T1,IPAMSK## ;DON'T LET THIS CHANNEL START IF SUSPENDED
PJRST CPOPJ1## ;AND RETURN
;(23) CLEAR MAINTENANCE MODE
DIAICM: 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 ;...
MOVEI T1,CO.CPT ;MAKE SURE KLNI IS STOPPED
XCT KDBCNO(Q3) ;...
MOVE T1,[KNIBTS] ;BITS TO TEST FOR ON INTERRUPT
MOVEM T1,@.PBBIT(Q3) ;STORE IN CONSO SKIP CHAIN CODE
MOVE T1,.CPBIT## ;GET OUR CPU'S BIT
ANDCAM T1,IPAMSK## ;LET THIS CHANNEL START IF SUSPENDED
PUSHJ P,RLDKNI ;INITIATE AUTO-RELOAD OF KLNI
PJRST CPOPJ1## ;AND RETURN
SUBTTL KLNI MAINTENANCE SERVICE -- KNIBT. UUO
IFE FTKNILDR,<
UKNIBT:: POPJ P, ;NO KNIBT. UUO
>;END IFE FTKNILDR
IFN FTKNILDR,<
;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
UKNIBT::PUSHJ P,SAVE4## ;SAVE P1-P4
PUSHJ P,SAVQ## ;AND Q1-Q3
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
MOVSI 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,M.CPU## ;...
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
SKIPN Q3,.CPNPB## ;GET ADDRESS OF PORT CONTROL BLOCK
PJRST KBTKDE ;KLNI DOESN'T EXIST
LDB T1,[POINT 3,KDBCNO(Q3),9] ;GET RH20 NUMBER
HRL T1,.CPCPN## ;MAKE IT CPU#,,RH20#
CAME T1,P3 ;MATCH?
PJRST KBTKDE ;NO, 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
PUSH P,W ;SAVE AC
MOVE W,Q3 ;PUT KDB (PCB) ADDRESS IN PROPER PLACE
PUSHJ P,RDIPA## ;READ KLNI CRAM LOCATION
JRST [POP P,W ;RESTORE AC
PJRST KBTCRE] ;CRAM READ ERROR
POP P,W ;RESTORE AC
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
PUSH P,W ;SAVE W
MOVE W,Q3 ;PUT KDB (PCB) ADDRESS IN PROPER PLACE
PUSHJ P,WTIPA## ;WRITE CRAM LOCATION
JRST [POP P,W ;RESTORE W
PJRST KBTCWE] ;CRAM WRITE ERROR
POP P,W ;RESTORE W
PJRST CPOPJ1## ;AND RETURN
>;END IFN FTKNILDR
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: MOVEI T1,CO.CPT ;MAKE SURE THE KLNI IS STOPPED
XCT KDBCNO(Q3) ;...
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) ;...
MOVEI T1,CO.CPT ;RESET KLNI
XCT KDBCNO(Q3) ;...
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
PUSH P,T2 ;SAVE T2
MOVE T2,T1 ;COPY
XCT KDBDTO(Q3) ;DATAO DEV,T2
POP P,T2 ;RESTORE T2
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
TXO T1,CO.DIS!CO.BTS ;PLUS DISABLE STATE
XCT KDBCNO(Q3) ;TELL KLNI
MOVEI T2,5000 ;LOOP COUNT
DISKN1: XCT KDBCNI(Q3) ;CONI DEV,T1
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
TXO T1,CO.ENA!CO.BTS ;PLUS ENABLED STATE
XCT KDBCNO(Q3) ;TELL KLNI
MOVEI T2,5000 ;LOOP COUNT
ENAKN1: XCT KDBCNI(Q3) ;CONI DEV,T1
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
IFE FTKNILDR,<
POPJ P, ;RETURN
>;END IFE FTKNILDR
IFN FTKNILDR,<
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
>;END IFN FTKNILDR
;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) ;...
IFN FTKNILDR,<
LDB T1,PBPRJB ;GET JOB NUMBER OF RELOAD JOB
SKIPE T1 ;JOB NUMBER SET?
PUSHJ P,WAKJOB## ;YES, WAKE IT UP
>;END IFN FTKNILDR
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 -- 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)
TXNN T1,PBSRLD ;REALY WANT A RELOAD OR NOT NOW!?
POPJ P, ;NO - JUST FORGET IT.
AOS .PBKLC(Q3) ;UPDATE COUNT OF TIMES DUMP/RELOAD REQUESTED
XMOVEI T1,.PBULB(Q3) ;GET ADDRESS OF MICROCODE LOADER BLOCK
PUSHJ P,BTUCOD## ;LOCATE KLNI MICROCODE
JRST [XMOVEI T1,.PBULB(Q3) ;POINT TO MICROCODE LOADER BLOCK
PJRST BTURPT##] ;GO REPORT THE ERROR
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) ;...
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,SAVE1## ;SAVE P1
XMOVEI P1,.PBULB(Q3) ;POINT TO MICROCODE LOADER BLOCK
PUSHJ P,SHTKNI ;SHUTDOWN KLNI
PUSH P,W ;SAVE W
MOVE W,Q3 ;SET UP KDB FOR DMPIPA/LDIPA
MOVX T1,PBSDMP ;BIT TO TEST
TDNE T1,.PBSTS(Q3) ;WANT A DUMP?
PUSHJ P,DMPIPA## ;DUMP THE KLNI DRAM
JFCL ;FAILED, DON'T REALLY CARE
MOVE T1,.ULADR(P1) ;GET ADDRESS OF MICROCODE STORAGE
PUSHJ P,LDIPA## ;LOAD THE CRAM
JRST KNILO3 ;CHANNEL IS RUNNING
MOVX T1,UCODSA ;GET MICROCODE START ADDRESS
MOVEM T1,.PBKSA(Q3) ;SAVE IN KLNI PCB
PUSHJ P,STAKNI ;START THE MICROCODE
JRST KNILO3 ;ERROR STARTING MICROCODE
PUSHJ P,INIKNI ;BEGIN INITIALIZATION OF KLNI
JRST KNILO3 ;ERROR INITIALIZING KLNI
AOS -1(P) ;SKIP RETURN
JRST KNILO4 ;GO FINISH UP
KNILO3: MOVEI T1,.UEMPC ;MICROPROCESSOR CHECK
DPB T1,ULBEBP## ;STORE
KNILO4: POP P,W ;RESTORE W
MOVE T1,P1 ;COPY LOADER BLOCK ADDRESS
PJRST BTURPT## ;GO REPORT A SUCCESSFUL LOAD
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
PMOVE T2,T2 ;...
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
PMOVEM T3,T2 ;...
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
PMOVEM T3,T2 ;...
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 THE END
KNILIT:!XLIST ;LITERALS
LIT
LIST
KNIEND:!END